OpenVDB 10.0.1
Loading...
Searching...
No Matches
Iterator.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3//
4/// @file tree/Iterator.h
5///
6/// @author Peter Cucka and Ken Museth
7
8#ifndef OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
9#define OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
10
11#include <sstream>
12#include <type_traits>
14#include <openvdb/Exceptions.h>
15
16namespace openvdb {
18namespace OPENVDB_VERSION_NAME {
19namespace tree {
20
21/// @brief Base class for iterators over internal and leaf nodes
22///
23/// This class is typically not instantiated directly, since it doesn't provide methods
24/// to dereference the iterator. Those methods (@vdblink::tree::SparseIteratorBase::operator*()
25/// operator*()@endlink, @vdblink::tree::SparseIteratorBase::setValue() setValue()@endlink, etc.)
26/// are implemented in the @vdblink::tree::SparseIteratorBase sparse@endlink and
27/// @vdblink::tree::DenseIteratorBase dense@endlink iterator subclasses.
28template<typename MaskIterT, typename NodeT>
30{
31public:
32 IteratorBase(): mParentNode(nullptr) {}
33 IteratorBase(const MaskIterT& iter, NodeT* parent): mParentNode(parent), mMaskIter(iter) {}
34 IteratorBase(const IteratorBase&) = default;
36
37 bool operator==(const IteratorBase& other) const
38 {
39 return (mParentNode == other.mParentNode) && (mMaskIter == other.mMaskIter);
40 }
41 bool operator!=(const IteratorBase& other) const
42 {
43 return !(*this == other);
44 }
45
46 /// Return a pointer to the node (if any) over which this iterator is iterating.
47 NodeT* getParentNode() const { return mParentNode; }
48 /// @brief Return a reference to the node over which this iterator is iterating.
49 /// @throw ValueError if there is no parent node.
50 NodeT& parent() const
51 {
52 if (!mParentNode) OPENVDB_THROW(ValueError, "iterator references a null node");
53 return *mParentNode;
54 }
55
56 /// Return this iterator's position as an index into the parent node's table.
57 Index offset() const { return mMaskIter.offset(); }
58
59 /// Identical to offset
60 Index pos() const { return mMaskIter.offset(); }
61
62 /// Return @c true if this iterator is not yet exhausted.
63 bool test() const { return mMaskIter.test(); }
64 /// Return @c true if this iterator is not yet exhausted.
65 operator bool() const { return this->test(); }
66
67 /// Advance to the next item in the parent node's table.
68 bool next() { return mMaskIter.next(); }
69 /// Advance to the next item in the parent node's table.
70 void increment() { mMaskIter.increment(); }
71 /// Advance to the next item in the parent node's table.
72 IteratorBase& operator++() { this->increment(); return *this; }
73 /// Advance @a n items in the parent node's table.
74 void increment(Index n) { mMaskIter.increment(n); }
75
76 /// @brief Return @c true if this iterator is pointing to an active value.
77 /// Return @c false if it is pointing to either an inactive value or a child node.
78 bool isValueOn() const { return parent().isValueMaskOn(this->pos()); }
79 /// @brief If this iterator is pointing to a value, set the value's active state.
80 /// Otherwise, do nothing.
81 void setValueOn(bool on = true) const { parent().setValueMask(this->pos(), on); }
82 /// @brief If this iterator is pointing to a value, mark the value as inactive.
83 /// @details If this iterator is pointing to a child node, then the current item
84 /// in the parent node's table is required to be inactive. In that case,
85 /// this method has no effect.
86 void setValueOff() const { parent().mValueMask.setOff(this->pos()); }
87
88 /// Return the coordinates of the item to which this iterator is pointing.
89 Coord getCoord() const { return parent().offsetToGlobalCoord(this->pos()); }
90 /// Return in @a xyz the coordinates of the item to which this iterator is pointing.
91 void getCoord(Coord& xyz) const { xyz = this->getCoord(); }
92
93private:
94 /// @note This parent node pointer is mutable, because setValueOn() and
95 /// setValueOff(), though const, need to call non-const methods on the parent.
96 /// There is a distinction between a const iterator (e.g., const ValueOnIter),
97 /// which is an iterator that can't be incremented, and an iterator over
98 /// a const node (e.g., ValueOnCIter), which might be const or non-const itself
99 /// but can't call non-const methods like setValue() on the node.
100 mutable NodeT* mParentNode;
101 MaskIterT mMaskIter;
102}; // class IteratorBase
103
104
105////////////////////////////////////////
106
107
108/// @brief Base class for sparse iterators over internal and leaf nodes
109template<
110 typename MaskIterT, // mask iterator type (OnIterator, OffIterator, etc.)
111 typename IterT, // SparseIteratorBase subclass (the "Curiously Recurring Template Pattern")
112 typename NodeT, // type of node over which to iterate
113 typename ItemT> // type of value to which this iterator points
114struct SparseIteratorBase: public IteratorBase<MaskIterT, NodeT>
115{
116 using NodeType = NodeT;
117 using ValueType = ItemT;
118 using NonConstNodeType = typename std::remove_const<NodeT>::type;
119 using NonConstValueType = typename std::remove_const<ItemT>::type;
120 static const bool IsSparseIterator = true, IsDenseIterator = false;
121
123 SparseIteratorBase(const MaskIterT& iter, NodeT* parent):
124 IteratorBase<MaskIterT, NodeT>(iter, parent) {}
125
126 /// @brief Return the item at the given index in the parent node's table.
127 /// @note All subclasses must implement this accessor.
128 ItemT& getItem(Index) const;
129 /// @brief Set the value of the item at the given index in the parent node's table.
130 /// @note All non-const iterator subclasses must implement this accessor.
131 void setItem(Index, const ItemT&) const;
132
133 /// Return a reference to the item to which this iterator is pointing.
134 ItemT& operator*() const { return this->getValue(); }
135 /// Return a pointer to the item to which this iterator is pointing.
136 ItemT* operator->() const { return &(this->operator*()); }
137
138 /// Return the item to which this iterator is pointing.
139 ItemT& getValue() const
140 {
141 return static_cast<const IterT*>(this)->getItem(this->pos()); // static polymorphism
142 }
143 /// @brief Set the value of the item to which this iterator is pointing.
144 /// (Not valid for const iterators.)
145 void setValue(const ItemT& value) const
146 {
147 static_assert(!std::is_const<NodeT>::value, "setValue() not allowed for const iterators");
148 static_cast<const IterT*>(this)->setItem(this->pos(), value); // static polymorphism
149 }
150 /// @brief Apply a functor to the item to which this iterator is pointing.
151 /// (Not valid for const iterators.)
152 /// @param op a functor of the form <tt>void op(ValueType&) const</tt> that modifies
153 /// its argument in place
154 /// @see Tree::modifyValue()
155 template<typename ModifyOp>
156 void modifyValue(const ModifyOp& op) const
157 {
158 static_assert(!std::is_const<NodeT>::value,
159 "modifyValue() not allowed for const iterators");
160 static_cast<const IterT*>(this)->modifyItem(this->pos(), op); // static polymorphism
161 }
162}; // class SparseIteratorBase
163
164
165////////////////////////////////////////
166
167
168/// @brief Base class for dense iterators over internal and leaf nodes
169/// @note Dense iterators have no @c %operator*() or @c %operator->(),
170/// because their return type would have to vary depending on whether
171/// the iterator is pointing to a value or a child node.
172template<
173 typename MaskIterT, // mask iterator type (typically a DenseIterator)
174 typename IterT, // DenseIteratorBase subclass (the "Curiously Recurring Template Pattern")
175 typename NodeT, // type of node over which to iterate
176 typename SetItemT, // type of set value (ChildNodeType, for non-leaf nodes)
177 typename UnsetItemT> // type of unset value (ValueType, usually)
178struct DenseIteratorBase: public IteratorBase<MaskIterT, NodeT>
179{
180 using NodeType = NodeT;
181 using ValueType = UnsetItemT;
182 using ChildNodeType = SetItemT;
183 using NonConstNodeType = typename std::remove_const<NodeT>::type;
184 using NonConstValueType = typename std::remove_const<UnsetItemT>::type;
185 using NonConstChildNodeType = typename std::remove_const<SetItemT>::type;
186 static const bool IsSparseIterator = false, IsDenseIterator = true;
187
189 DenseIteratorBase(const MaskIterT& iter, NodeT* parent):
190 IteratorBase<MaskIterT, NodeT>(iter, parent) {}
191
192 /// @brief Return @c true if the item at the given index in the parent node's table
193 /// is a set value and return either the set value in @a child or the unset value
194 /// in @a value.
195 /// @note All subclasses must implement this accessor.
196 bool getItem(Index, SetItemT*& child, NonConstValueType& value) const;
197 /// @brief Set the value of the item at the given index in the parent node's table.
198 /// @note All non-const iterator subclasses must implement this accessor.
199 void setItem(Index, SetItemT*) const;
200 /// @brief "Unset" the value of the item at the given index in the parent node's table.
201 /// @note All non-const iterator subclasses must implement this accessor.
202 void unsetItem(Index, const UnsetItemT&) const;
203
204 /// Return @c true if this iterator is pointing to a child node.
205 bool isChildNode() const { return this->parent().isChildMaskOn(this->pos()); }
206
207 /// @brief If this iterator is pointing to a child node, return a pointer to the node.
208 /// Otherwise, return nullptr and, in @a value, the value to which this iterator is pointing.
210 {
211 SetItemT* child = nullptr;
212 static_cast<const IterT*>(this)->getItem(this->pos(), child, value); // static polymorphism
213 return child;
214 }
215 /// @brief If this iterator is pointing to a child node, return @c true and return
216 /// a pointer to the child node in @a child. Otherwise, return @c false and return
217 /// the value to which this iterator is pointing in @a value.
218 bool probeChild(SetItemT*& child, NonConstValueType& value) const
219 {
220 child = probeChild(value);
221 return (child != nullptr);
222 }
223
224 /// @brief Return @c true if this iterator is pointing to a value and return
225 /// the value in @a value. Otherwise, return @c false.
227 {
228 SetItemT* child = nullptr;
229 const bool isChild = static_cast<const IterT*>(this)-> // static polymorphism
230 getItem(this->pos(), child, value);
231 return !isChild;
232 }
233
234 /// @brief Replace with the given child node the item in the parent node's table
235 /// to which this iterator is pointing.
236 void setChild(SetItemT* child) const
237 {
238 static_cast<const IterT*>(this)->setItem(this->pos(), child); // static polymorphism
239 }
240
241 /// @brief Replace with the given value the item in the parent node's table
242 /// to which this iterator is pointing.
243 void setValue(const UnsetItemT& value) const
244 {
245 static_cast<const IterT*>(this)->unsetItem(this->pos(), value); // static polymorphism
246 }
247}; // struct DenseIteratorBase
248
249} // namespace tree
250} // namespace OPENVDB_VERSION_NAME
251} // namespace openvdb
252
253#endif // OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
ValueT value
Definition GridBuilder.h:1290
ChildT * child
Definition GridBuilder.h:1289
Definition Exceptions.h:65
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
Base class for iterators over internal and leaf nodes.
Definition Iterator.h:30
IteratorBase(const IteratorBase &)=default
Index pos() const
Identical to offset.
Definition Iterator.h:60
bool isValueOn() const
Return true if this iterator is pointing to an active value. Return false if it is pointing to either...
Definition Iterator.h:78
Index offset() const
Return this iterator's position as an index into the parent node's table.
Definition Iterator.h:57
Coord getCoord() const
Return the coordinates of the item to which this iterator is pointing.
Definition Iterator.h:89
bool test() const
Return true if this iterator is not yet exhausted.
Definition Iterator.h:63
NodeT * getParentNode() const
Return a pointer to the node (if any) over which this iterator is iterating.
Definition Iterator.h:47
void setValueOn(bool on=true) const
If this iterator is pointing to a value, set the value's active state. Otherwise, do nothing.
Definition Iterator.h:81
IteratorBase & operator=(const IteratorBase &)=default
NodeT & parent() const
Return a reference to the node over which this iterator is iterating.
Definition Iterator.h:50
void setValueOff() const
If this iterator is pointing to a value, mark the value as inactive.
Definition Iterator.h:86
bool next()
Advance to the next item in the parent node's table.
Definition Iterator.h:68
bool operator==(const IteratorBase &other) const
Definition Iterator.h:37
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which this iterator is pointing.
Definition Iterator.h:91
IteratorBase()
Definition Iterator.h:32
IteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:33
IteratorBase & operator++()
Advance to the next item in the parent node's table.
Definition Iterator.h:72
bool operator!=(const IteratorBase &other) const
Definition Iterator.h:41
void increment(Index n)
Advance n items in the parent node's table.
Definition Iterator.h:74
void increment()
Advance to the next item in the parent node's table.
Definition Iterator.h:70
Index32 Index
Definition Types.h:54
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Base class for dense iterators over internal and leaf nodes.
Definition Iterator.h:179
typename std::remove_const< UnsetItemT >::type NonConstValueType
Definition Iterator.h:184
bool getItem(Index, SetItemT *&child, NonConstValueType &value) const
Return true if the item at the given index in the parent node's table is a set value and return eithe...
DenseIteratorBase()
Definition Iterator.h:188
void setChild(SetItemT *child) const
Replace with the given child node the item in the parent node's table to which this iterator is point...
Definition Iterator.h:236
void unsetItem(Index, const UnsetItemT &) const
"Unset" the value of the item at the given index in the parent node's table.
UnsetItemT ValueType
Definition Iterator.h:181
typename std::remove_const< SetItemT >::type NonConstChildNodeType
Definition Iterator.h:185
DenseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:189
SetItemT ChildNodeType
Definition Iterator.h:182
typename std::remove_const< NodeT >::type NonConstNodeType
Definition Iterator.h:183
void setItem(Index, SetItemT *) const
Set the value of the item at the given index in the parent node's table.
SetItemT * probeChild(NonConstValueType &value) const
If this iterator is pointing to a child node, return a pointer to the node. Otherwise,...
Definition Iterator.h:209
void setValue(const UnsetItemT &value) const
Replace with the given value the item in the parent node's table to which this iterator is pointing.
Definition Iterator.h:243
NodeT NodeType
Definition Iterator.h:180
bool isChildNode() const
Return true if this iterator is pointing to a child node.
Definition Iterator.h:205
bool probeChild(SetItemT *&child, NonConstValueType &value) const
If this iterator is pointing to a child node, return true and return a pointer to the child node in c...
Definition Iterator.h:218
bool probeValue(NonConstValueType &value) const
Return true if this iterator is pointing to a value and return the value in value....
Definition Iterator.h:226
Base class for sparse iterators over internal and leaf nodes.
Definition Iterator.h:115
void setItem(Index, const ItemT &) const
Set the value of the item at the given index in the parent node's table.
void modifyValue(const ModifyOp &op) const
Apply a functor to the item to which this iterator is pointing. (Not valid for const iterators....
Definition Iterator.h:156
typename std::remove_const< ItemT >::type NonConstValueType
Definition Iterator.h:119
ItemT & getItem(Index) const
Return the item at the given index in the parent node's table.
ItemT & operator*() const
Return a reference to the item to which this iterator is pointing.
Definition Iterator.h:134
SparseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:123
void setValue(const ItemT &value) const
Set the value of the item to which this iterator is pointing. (Not valid for const iterators....
Definition Iterator.h:145
SparseIteratorBase()
Definition Iterator.h:122
typename std::remove_const< NodeT >::type NonConstNodeType
Definition Iterator.h:118
ItemT * operator->() const
Return a pointer to the item to which this iterator is pointing.
Definition Iterator.h:136
NodeT NodeType
Definition Iterator.h:116
ItemT ValueType
Definition Iterator.h:117
ItemT & getValue() const
Return the item to which this iterator is pointing.
Definition Iterator.h:139
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212