24#ifndef PXR_BASE_TF_ITERATOR_H
25#define PXR_BASE_TF_ITERATOR_H
39PXR_NAMESPACE_OPEN_SCOPE
44struct Tf_ShouldIterateOverCopy : std::false_type {};
52template <
class T,
bool Reverse>
53struct Tf_IteratorInterface {
54 typedef typename T::iterator IteratorType;
55 static IteratorType Begin(T &c) {
return c.begin(); }
56 static IteratorType End(T &c) {
return c.end(); }
59template <
class T,
bool Reverse>
60struct Tf_IteratorInterface<const T, Reverse> {
61 typedef typename T::const_iterator IteratorType;
62 static IteratorType Begin(T
const &c) {
return c.begin(); }
63 static IteratorType End(T
const &c) {
return c.end(); }
67struct Tf_IteratorInterface<T, true> {
68 typedef typename T::reverse_iterator IteratorType;
69 static IteratorType Begin(T &c) {
return c.rbegin(); }
70 static IteratorType End(T &c) {
return c.rend(); }
74struct Tf_IteratorInterface<const T, true> {
75 typedef typename T::const_reverse_iterator IteratorType;
76 static IteratorType Begin(T
const &c) {
return c.rbegin(); }
77 static IteratorType End(T
const &c) {
return c.rend(); }
175template <
class T,
bool Reverse=false>
179 struct _IteratorPairAndCopy;
180 struct _IteratorPair;
184 typedef typename std::conditional<
185 Tf_ShouldIterateOverCopy<T>::value,
186 _IteratorPairAndCopy, _IteratorPair
192 typedef Tf_IteratorInterface<T, Reverse> IterInterface;
193 typedef typename IterInterface::IteratorType Iterator;
195 typedef typename std::iterator_traits<Iterator>::reference Reference;
210 Tf_ShouldIterateOverCopy<typename std::decay<T>::type>::value,
211 "TfIterator only allows rvalues that it has been told to copy "
212 "via Tf_ShouldIterateOverCopy");
228 return _data.current == _data.end;
236 return _data.current == iterator._data.current;
242 return !(*
this == iterator);
270 if (ARCH_UNLIKELY(!*
this))
272 return *_data.current;
278 if (ARCH_UNLIKELY(!*
this))
280 return *_data.current;
286 if (ARCH_UNLIKELY(!*
this))
288 return _data.current;
293 explicit operator bool()
const {
294 return !(_data.current == _data.end);
300 operator Iterator()
const {
301 return _data.current;
308 return _data.current;
323 struct _IteratorPair {
325 explicit _IteratorPair(T &c) {
328 current = IterInterface::Begin(c);
329 end = IterInterface::End(c);
331 _IteratorPair(Iterator
const &b, Iterator
const &e) :
332 current(b), end(e) {}
339 struct _IteratorPairAndCopy :
public _IteratorPair {
340 _IteratorPairAndCopy() {}
341 explicit _IteratorPairAndCopy(T
const &c) : _IteratorPair(), _copy(c) {
342 current = IterInterface::Begin(_copy);
343 end = IterInterface::End(_copy);
345 using _IteratorPair::current;
346 using _IteratorPair::end;
362 std::forward<T>(container));
367TfMakeReverseIterator(T&& container)
370 std::forward<T>(container));
390#define TF_FOR_ALL(iter, c) \
391 for (auto iter = TfMakeIterator(c); iter; ++iter)
399#define TF_REVERSE_FOR_ALL(iter, c) \
400 for (auto iter = TfMakeReverseIterator(c); iter; ++iter)
406template <
class T,
size_t N>
418template <
typename UnderlyingIterator>
419class Tf_ProxyReferenceReverseIterator :
420 private std::reverse_iterator<UnderlyingIterator> {
423 using ReverseIterator = std::reverse_iterator<UnderlyingIterator>;
424 const ReverseIterator& _reverse_iterator()
const {
return *
this; }
425 ReverseIterator& _reverse_iterator() {
return *
this; }
426 explicit Tf_ProxyReferenceReverseIterator(
const ReverseIterator& it)
427 : ReverseIterator(it) {}
428 explicit Tf_ProxyReferenceReverseIterator(ReverseIterator&& it)
429 : ReverseIterator(it) {}
431 using iterator_type =
typename ReverseIterator::iterator_type;
432 using iterator_category =
typename ReverseIterator::iterator_category;
433 using value_type =
typename ReverseIterator::value_type;
434 using reference =
typename ReverseIterator::reference;
435 using pointer =
typename ReverseIterator::pointer;
436 using difference_type =
typename ReverseIterator::difference_type;
438 static_assert(!std::is_reference<reference>::value,
439 "Tf_ProxyReferenceReverseIterator should only be used "
440 "when the underlying iterator's reference type is a "
441 "proxy (MyTypeRef) and not a true reference (MyType&)."
442 "Use std::reverse_iterator instead.");
443 static_assert(std::is_same<iterator_category,
444 std::random_access_iterator_tag>::value,
445 "Tf_ProxyReferenceReverseIterator must wrap a random "
448 Tf_ProxyReferenceReverseIterator() =
default;
449 explicit Tf_ProxyReferenceReverseIterator(UnderlyingIterator it) :
450 ReverseIterator(it) {
455 using ReverseIterator::base;
456 using ReverseIterator::operator*;
457 using ReverseIterator::operator[];
461 pointer operator->()
const {
return std::prev(base()).operator->(); }
465 Tf_ProxyReferenceReverseIterator& operator++() {
466 ++_reverse_iterator();
470 Tf_ProxyReferenceReverseIterator operator++(
int) {
471 Tf_ProxyReferenceReverseIterator result{_reverse_iterator()};
472 ++_reverse_iterator();
476 Tf_ProxyReferenceReverseIterator& operator--() {
477 --_reverse_iterator();
481 Tf_ProxyReferenceReverseIterator operator--(
int) {
482 Tf_ProxyReferenceReverseIterator result{_reverse_iterator()};
483 --_reverse_iterator();
487 Tf_ProxyReferenceReverseIterator operator+(difference_type increment)
const {
488 return Tf_ProxyReferenceReverseIterator(_reverse_iterator() + increment);
491 Tf_ProxyReferenceReverseIterator operator-(difference_type decrement)
const {
492 return Tf_ProxyReferenceReverseIterator(_reverse_iterator() - decrement);
495 template <
typename OtherIt>
496 difference_type operator-(
497 const Tf_ProxyReferenceReverseIterator<OtherIt>& other)
const {
498 return _reverse_iterator() - other._reverse_iterator();
501 Tf_ProxyReferenceReverseIterator& operator+=(difference_type increment) {
502 _reverse_iterator() += increment;
506 Tf_ProxyReferenceReverseIterator& operator-=(difference_type decrement) {
507 _reverse_iterator() -= decrement;
511 inline friend Tf_ProxyReferenceReverseIterator
512 operator+(
const difference_type increment,
513 const Tf_ProxyReferenceReverseIterator& iterator) {
514 return Tf_ProxyReferenceReverseIterator(
515 increment + iterator._reverse_iterator());
519 template <
typename OtherIt>
520 inline friend bool operator==(
const Tf_ProxyReferenceReverseIterator& lhs,
521 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
522 return lhs._reverse_iterator() == rhs._reverse_iterator();
525 template <
typename OtherIt>
526 inline friend bool operator!=(
const Tf_ProxyReferenceReverseIterator& lhs,
527 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
528 return lhs._reverse_iterator() != rhs._reverse_iterator();
531 template <
typename OtherIt>
532 inline friend bool operator<(
const Tf_ProxyReferenceReverseIterator& lhs,
533 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
534 return lhs._reverse_iterator() < rhs._reverse_iterator();
537 template <
typename OtherIt>
538 inline friend bool operator>(
const Tf_ProxyReferenceReverseIterator& lhs,
539 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
540 return lhs._reverse_iterator() > rhs._reverse_iterator();
543 template <
typename OtherIt>
544 inline friend bool operator<=(
const Tf_ProxyReferenceReverseIterator& lhs,
545 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
546 return lhs._reverse_iterator() <= rhs._reverse_iterator();
549 template <
typename OtherIt>
550 inline friend bool operator>=(
const Tf_ProxyReferenceReverseIterator& lhs,
551 const Tf_ProxyReferenceReverseIterator<OtherIt>& rhs) {
552 return lhs._reverse_iterator() >= rhs._reverse_iterator();
556PXR_NAMESPACE_CLOSE_SCOPE
constexpr size_t TfArraySize(const T(&array)[N]) noexcept
Returns the number of elements in a statically sized array.
A simple iterator adapter for STL containers.
TfIterator operator++(int)
Post-increment operator.
Reference operator*() const
Returns the element referenced by this iterator.
Iterator & operator->()
Returns a pointer to the element referenced by this iterator.
bool operator!() const
Returns true if this iterator is exhausted.
TfIterator & operator++()
Pre-increment operator.
TfIterator(T &&container)
Allow rvalues only if the container type T should be copied by TfIterator.
TfIterator GetNext() const
Returns an iterator that is positioned at the next element in the sequence.
bool operator!=(const TfIterator &iterator) const
Returns false if (*this == iterator) returns true, returns true otherwise.
TfIterator(Iterator const &begin, Iterator const &end)
Constructs an iterator to traverse a subset of the elements in a container.
TfIterator()
Default constructor. This iterator is uninitialized.
TfIterator(T &container)
Constructs an iterator to traverse each element of the specified STL container object.
Reference operator*()
Returns the element referenced by this iterator.
bool operator==(const TfIterator &iterator) const
Returns true if this Iterator.has the same position in the sequence as the specified iterator.
const Iterator & base() const
Returns an STL iterator that has the same position as this iterator.
Stripped down version of diagnostic.h that doesn't define std::string.
TfIterator< typename std::remove_reference< T >::type > TfMakeIterator(T &&container)
Helper functions for creating TfIterator objects.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.