HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
maskedIterator.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_EXEC_VDF_MASKED_ITERATOR_H
8 #define PXR_EXEC_VDF_MASKED_ITERATOR_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/iterator.h"
15 #include "pxr/exec/vdf/mask.h"
16 
18 
19 ////////////////////////////////////////////////////////////////////////////////
20 ///
21 /// Enum to specify the behavior of VdfMaskedIterator as template parameter.
22 ///
24 {
25  /// The elements in the visitMask are skipped (default).
26  ///
27  VisitUnset = 0,
28 
29  /// Visit the elements in the visitMask instead of skipping them.
30  ///
31  VisitSet
32 };
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 ///
36 /// \class VdfMaskedIterator
37 ///
38 /// An iterator that can be used to refine the given iterator \p IteratorType to
39 /// iterate over a given mask by either visiting or skipping over set bits
40 /// in the mask.
41 ///
42 template<class IteratorType, VdfMaskedIteratorMode mode>
43 class VdfMaskedIterator final : public VdfIterator
44 {
45 public:
46 
47  /// The value type of this iterator.
48  ///
50 
51  /// The dereference type of this iterator.
52  ///
54 
55  /// Constructor. Creates a masked iterator using \p visitMask and \p args.
56  ///
57  template<typename... Args>
59  const VdfContext &context, const VdfMask &visitMask, Args&&... args);
60 
61  /// Increment operator to point to the next element.
62  ///
64 
65  /// Returns reference to current element.
66  ///
67  reference operator*() const {
68  return _iterator.operator*();
69  }
70 
71  /// Returns true if the iterator is done iterating and false otherwise.
72  ///
73  bool IsAtEnd() const {
74  return _iterator.IsAtEnd();
75  }
76 
77  /// Advance the iterator to the end.
78  ///
79  void AdvanceToEnd() {
80  _iterator.AdvanceToEnd();
81  }
82 
83 private:
84 
85  // Returns the current index into the data source.
86  friend int Vdf_GetIteratorIndex(const VdfMaskedIterator &it) {
87  return Vdf_GetIteratorIndex(it._iterator);
88  }
89 
90  // Advance the underlying iterator as needed.
91  void _AdvanceToIndexWithVisitMask();
92 
93  // The underlying iterator.
94  IteratorType _iterator;
95 
96  // Mask of elements that are skipped during iteration.
97  VdfMask::iterator _visitMaskIterator;
98 };
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 
102 template<class IteratorType, VdfMaskedIteratorMode mode>
103 template<typename... Args>
105  const VdfContext &context, const VdfMask &visitMask, Args&&... args) :
106  _iterator(context, std::forward<Args>(args)...),
107  _visitMaskIterator(visitMask.begin())
108 {
109  // If we get an empty mask passed in, advance the iterator to the end.
110  if (visitMask.GetSize() == 0) {
111  _iterator.AdvanceToEnd();
112  }
113 
114  _AdvanceToIndexWithVisitMask();
115 }
116 
117 template<class IteratorType, VdfMaskedIteratorMode mode>
120 {
121  _iterator.operator++();
122  _AdvanceToIndexWithVisitMask();
123  return *this;
124 }
125 
126 template<class IteratorType, VdfMaskedIteratorMode mode>
127 void
129 {
130  // XXX: this could be more efficient by
131  // - exposing a method to advance to the next element after a given
132  // index in the base iterator.
133  // - using those functions in the below while loop so that we skip one
134  // contiguous block of elements in visitMask at a time.
135  // - this scheme also makes it hard to set the masked iterator to
136  // "IsAtEnd" in the constructor, because advancing the mask iterator to
137  // the end (none set) doesn't mean that this iterator is at end due to
138  // the logic below. That in turn makes it hard to check if the mask size
139  // and iterator data matches up.
140 
141  while (!_iterator.IsAtEnd()) {
142  // Pull the visit mask iterator forward.
144  Vdf_GetIteratorIndex(_iterator));
145  if (*_visitMaskIterator < idx) {
146  _visitMaskIterator.AdvanceTo(idx);
147  }
148 
149  const VdfMask::iterator::value_type visitIdx = *_visitMaskIterator;
151  // If we hit an element we don't want to skip, stop. Also stop,
152  // if we were unable to pull the visit mask forward (invalid visit
153  // mask case).
154  if (visitIdx > idx || visitIdx < idx) {
155  break;
156  }
157  } else {
158  // If we hit an element we want to visit, stop. Also stop, if we
159  // were unable to pull the visit mask forward (invalid visit mask
160  // case).
161  if (visitIdx == idx || visitIdx < idx) {
162  break;
163  }
164  }
165  // Otherwise continue iterating.
166  _iterator.operator++();
167  }
168 }
169 
171 
172 #endif
VdfMaskedIterator & operator++()
friend int Vdf_GetIteratorIndex(const VdfMaskedIterator &it)
VdfMaskedIterator(const VdfContext &context, const VdfMask &visitMask, Args &&...args)
_BaseIterator::value_type value_type
Definition: mask.h:403
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
uint64 value_type
Definition: GA_PrimCompat.h:29
bool IsAtEnd() const
reference operator*() const
GLenum mode
Definition: glcorearb.h:99
size_t GetSize() const
Definition: mask.h:158
IteratorType::value_type value_type
IteratorType::reference reference
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:587
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
**If you just want to fire and args
Definition: thread.h:618
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression reference
VdfMaskedIteratorMode