Skip to content

Commit

Permalink
Replace boost::iterator_adaptor with explicitly specified iterator …
Browse files Browse the repository at this point in the history
…definition for `UsdPrim{Sibling,Subtree}Iterator`
  • Loading branch information
nvmkuruc committed Jul 21, 2023
1 parent 3b6dbc7 commit bc3fb3e
Showing 1 changed file with 125 additions and 100 deletions.
225 changes: 125 additions & 100 deletions pxr/usd/usd/prim.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

#include "pxr/usd/sdf/path.h"

#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/range/iterator_range.hpp>

#include <string>
Expand Down Expand Up @@ -2213,34 +2212,6 @@ class UsdPrim : public UsdObject
};

#ifdef doxygen

/// Forward traversal iterator of sibling ::UsdPrim s. This is a
/// standard-compliant iterator that may be used with STL algorithms, etc.
class UsdPrimSiblingIterator {
public:
/// Iterator value type.
typedef UsdPrim value_type;
/// Iterator reference type, in this case the same as \a value_type.
typedef value_type reference;
/// Iterator difference type.
typedef unspecified-integral-type difference_type;
/// Dereference.
reference operator*() const;
/// Indirection.
unspecified-type operator->() const;
/// Postincrement.
UsdPrimSiblingIterator &operator++();
/// Preincrement.
UsdPrimSiblingIterator operator++(int);
private:
/// Equality.
friend bool operator==(const UsdPrimSiblingIterator &lhs,
const UsdPrimSiblingIterator &rhs);
/// Inequality.
friend bool operator!=(const UsdPrimSiblingIterator &lhs,
const UsdPrimSiblingIterator &rhs);
};

/// Forward iterator range of sibling ::UsdPrim s. This range type contains a
/// pair of UsdPrimSiblingIterator s, denoting a half-open range of UsdPrim
/// siblings. It provides a subset of container-like API, such as begin(),
Expand Down Expand Up @@ -2305,53 +2276,93 @@ class UsdPrimSiblingRange {

#else

// Sibling iterator class. Converts ref to weak and filters according to a
// supplied predicate.
class UsdPrimSiblingIterator : public boost::iterator_adaptor<
UsdPrimSiblingIterator, // crtp base.
const Usd_PrimData *, // base iterator.
UsdPrim, // value type.
boost::forward_traversal_tag, // traversal
UsdPrim> // reference type.
{

/// Forward traversal iterator of sibling ::UsdPrim s. This is a
/// standard-compliant iterator that may be used with STL algorithms, etc.
/// Filters according to a supplied predicate.
class UsdPrimSiblingIterator {
using _UnderlyingIterator = const Usd_PrimData*;
class _PtrProxy {
public:
UsdPrim* operator->() { return &_prim; }
private:
friend class UsdPrimSiblingIterator;
explicit _PtrProxy(const UsdPrim& prim) : _prim(prim) {}
UsdPrim _prim;
};
public:
using iterator_category = std::forward_iterator_tag;
using value_type = UsdPrim;
using reference = UsdPrim;
using pointer = _PtrProxy;
using difference_type = std::ptrdiff_t;

// Default ctor.
UsdPrimSiblingIterator() {}
UsdPrimSiblingIterator() = default;

/// Dereference.
reference operator*() const { return dereference(); }

/// Indirection.
pointer operator->() const { return pointer(dereference()); }

/// Preincrement.
UsdPrimSiblingIterator &operator++() {
increment();
return *this;
}

/// Postincrement.
UsdPrimSiblingIterator operator++(int) {
UsdPrimSiblingIterator result = *this;
increment();
return result;
}

bool operator==(const UsdPrimSiblingIterator& other) const {
return equal(other);
}

bool operator!=(const UsdPrimSiblingIterator& other) const {
return !equal(other);
}

private:
friend class UsdPrim;

// Constructor used by Prim.
UsdPrimSiblingIterator(const base_type &i, const SdfPath& proxyPrimPath,
UsdPrimSiblingIterator(const _UnderlyingIterator &i,
const SdfPath& proxyPrimPath,
const Usd_PrimFlagsPredicate &predicate)
: iterator_adaptor_(i)
: _underlyingIterator(i)
, _proxyPrimPath(proxyPrimPath)
, _predicate(predicate) {
// Need to advance iterator to first matching element.
if (base() && !Usd_EvalPredicate(_predicate, base(), _proxyPrimPath))
if (_underlyingIterator &&
!Usd_EvalPredicate(_predicate, _underlyingIterator,
_proxyPrimPath))
increment();
}

// Core implementation invoked by iterator_adaptor.
friend class boost::iterator_core_access;
bool equal(const UsdPrimSiblingIterator &other) const {
return base() == other.base() &&
return _underlyingIterator == other._underlyingIterator &&
_proxyPrimPath == other._proxyPrimPath &&
_predicate == other._predicate;
}

void increment() {
base_type &base = base_reference();
if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath, _predicate)) {
base = nullptr;
if (Usd_MoveToNextSiblingOrParent(_underlyingIterator, _proxyPrimPath,
_predicate)) {
_underlyingIterator = nullptr;
_proxyPrimPath = SdfPath();
}
}

reference dereference() const {
return UsdPrim(base(), _proxyPrimPath);
return UsdPrim(_underlyingIterator, _proxyPrimPath);
}

_UnderlyingIterator _underlyingIterator = nullptr;
SdfPath _proxyPrimPath;
Usd_PrimFlagsPredicate _predicate;
};
Expand Down Expand Up @@ -2406,33 +2417,6 @@ UsdPrim::_MakeSiblingRange(const Usd_PrimFlagsPredicate &pred) const {

#ifdef doxygen

/// Forward traversal iterator of sibling ::UsdPrim s. This is a
/// standard-compliant iterator that may be used with STL algorithms, etc.
class UsdPrimSubtreeIterator {
public:
/// Iterator value type.
typedef UsdPrim value_type;
/// Iterator reference type, in this case the same as \a value_type.
typedef value_type reference;
/// Iterator difference type.
typedef unspecified-integral-type difference_type;
/// Dereference.
reference operator*() const;
/// Indirection.
unspecified-type operator->() const;
/// Postincrement.
UsdPrimSubtreeIterator &operator++();
/// Preincrement.
UsdPrimSubtreeIterator operator++(int);
private:
/// Equality.
friend bool operator==(const UsdPrimSubtreeIterator &lhs,
const UsdPrimSubtreeIterator &rhs);
/// Inequality.
friend bool operator!=(const UsdPrimSubtreeIterator &lhs,
const UsdPrimSubtreeIterator &rhs);
};

/// Forward iterator range of sibling ::UsdPrim s. This range type contains a
/// pair of UsdPrimSubtreeIterator s, denoting a half-open range of UsdPrim
/// siblings. It provides a subset of container-like API, such as begin(),
Expand Down Expand Up @@ -2497,59 +2481,100 @@ class UsdPrimSubtreeRange {

#else

// Subtree iterator class. Converts ref to weak and filters according to a
// supplied predicate.
class UsdPrimSubtreeIterator : public boost::iterator_adaptor<
UsdPrimSubtreeIterator, // crtp base.
const Usd_PrimData *, // base iterator.
UsdPrim, // value type.
boost::forward_traversal_tag, // traversal
UsdPrim> // reference type.
{
/// Forward traversal iterator of sibling ::UsdPrim s. This is a
/// standard-compliant iterator that may be used with STL algorithms, etc.
/// Filters according to a supplied predicate.
class UsdPrimSubtreeIterator {
using _UnderlyingIterator = Usd_PrimDataConstPtr;
class _PtrProxy {
public:
UsdPrim* operator->() { return &_prim; }
private:
friend class UsdPrimSubtreeIterator;
explicit _PtrProxy(const UsdPrim& prim) : _prim(prim) {}
UsdPrim _prim;
};
public:
using iterator_category = std::forward_iterator_tag;
using value_type = UsdPrim;
using reference = UsdPrim;
using pointer = _PtrProxy;
using difference_type = std::ptrdiff_t;

// Default ctor.
UsdPrimSubtreeIterator() {}
UsdPrimSubtreeIterator() = default;

/// Dereference.
reference operator*() const { return dereference(); }
/// Indirection.
pointer operator->() const { return pointer(dereference()); }

/// Preincrement.
UsdPrimSubtreeIterator &operator++() {
increment();
return *this;
}

/// Postincrement.
UsdPrimSubtreeIterator operator++(int) {
UsdPrimSubtreeIterator result;
increment();
return result;
}

/// Equality.
bool operator==(const UsdPrimSubtreeIterator &other) const {
return equal(other);
}

/// Inequality.
bool operator!=(const UsdPrimSubtreeIterator &other) const {
return !equal(other);
}


private:
friend class UsdPrim;

// Constructor used by Prim.
UsdPrimSubtreeIterator(const base_type &i, const SdfPath &proxyPrimPath,
UsdPrimSubtreeIterator(const _UnderlyingIterator &i,
const SdfPath &proxyPrimPath,
const Usd_PrimFlagsPredicate &predicate)
: iterator_adaptor_(i)
: _underlyingIterator(i)
, _proxyPrimPath(proxyPrimPath)
, _predicate(predicate) {
// Need to advance iterator to first matching element.
base_type &base = base_reference();
if (base && !Usd_EvalPredicate(_predicate, base, _proxyPrimPath)) {
if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
_predicate)) {
base = nullptr;
if (_underlyingIterator &&
!Usd_EvalPredicate(_predicate, _underlyingIterator,
_proxyPrimPath)) {
if (Usd_MoveToNextSiblingOrParent(_underlyingIterator,
_proxyPrimPath, _predicate)) {
_underlyingIterator = nullptr;
_proxyPrimPath = SdfPath();
}
}
}

// Core implementation invoked by iterator_adaptor.
friend class boost::iterator_core_access;
bool equal(const UsdPrimSubtreeIterator &other) const {
return base() == other.base() &&
return _underlyingIterator == other._underlyingIterator &&
_proxyPrimPath == other._proxyPrimPath &&
_predicate == other._predicate;
}

void increment() {
base_type &base = base_reference();
if (!Usd_MoveToChild(base, _proxyPrimPath, _predicate)) {
while (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
if (!Usd_MoveToChild(_underlyingIterator, _proxyPrimPath,
_predicate)) {
while (Usd_MoveToNextSiblingOrParent(_underlyingIterator,
_proxyPrimPath,
_predicate)) {}
}
}

reference dereference() const {
return UsdPrim(base(), _proxyPrimPath);
return UsdPrim(_underlyingIterator, _proxyPrimPath);
}

_UnderlyingIterator _underlyingIterator = nullptr;
SdfPath _proxyPrimPath;
Usd_PrimFlagsPredicate _predicate;
};
Expand Down

0 comments on commit bc3fb3e

Please sign in to comment.