Loading...
Searching...
No Matches
Iterator.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
//
/// @file tree/Iterator.h
///
/// @author Peter Cucka and Ken Museth
#ifndef OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
#define OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
#include <sstream>
#include <type_traits>
#include <openvdb/util/NodeMasks.h>
#include <openvdb/Exceptions.h>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace tree {
/// @brief Base class for iterators over internal and leaf nodes
///
/// This class is typically not instantiated directly, since it doesn't provide methods
/// to dereference the iterator. Those methods (@vdblink::tree::SparseIteratorBase::operator*()
/// operator*()@endlink, @vdblink::tree::SparseIteratorBase::setValue() setValue()@endlink, etc.)
/// are implemented in the @vdblink::tree::SparseIteratorBase sparse@endlink and
/// @vdblink::tree::DenseIteratorBase dense@endlink iterator subclasses.
template<typename MaskIterT, typename NodeT>
class IteratorBase
{
public:
IteratorBase(): mParentNode(nullptr) {}
IteratorBase(const MaskIterT& iter, NodeT* parent): mParentNode(parent), mMaskIter(iter) {}
IteratorBase(const IteratorBase&) = default;
IteratorBase& operator=(const IteratorBase&) = default;
bool operator==(const IteratorBase& other) const
{
return (mParentNode == other.mParentNode) && (mMaskIter == other.mMaskIter);
}
bool operator!=(const IteratorBase& other) const
{
return !(*this == other);
}
/// Return a pointer to the node (if any) over which this iterator is iterating.
NodeT* getParentNode() const { return mParentNode; }
/// @brief Return a reference to the node over which this iterator is iterating.
/// @throw ValueError if there is no parent node.
NodeT& parent() const
{
if (!mParentNode) OPENVDB_THROW(ValueError, "iterator references a null node");
return *mParentNode;
}
/// Return this iterator's position as an index into the parent node's table.
Index offset() const { return mMaskIter.offset(); }
/// Identical to offset
Index pos() const { return mMaskIter.offset(); }
/// Return @c true if this iterator is not yet exhausted.
bool test() const { return mMaskIter.test(); }
/// Return @c true if this iterator is not yet exhausted.
operator bool() const { return this->test(); }
/// Advance to the next item in the parent node's table.
bool next() { return mMaskIter.next(); }
/// Advance to the next item in the parent node's table.
void increment() { mMaskIter.increment(); }
/// Advance to the next item in the parent node's table.
IteratorBase& operator++() { this->increment(); return *this; }
/// Advance @a n items in the parent node's table.
void increment(Index n) { mMaskIter.increment(n); }
/// @brief Return @c true if this iterator is pointing to an active value.
/// Return @c false if it is pointing to either an inactive value or a child node.
bool isValueOn() const { return parent().isValueMaskOn(this->pos()); }
/// @brief If this iterator is pointing to a value, set the value's active state.
/// Otherwise, do nothing.
void setValueOn(bool on = true) const { parent().setValueMask(this->pos(), on); }
/// @brief If this iterator is pointing to a value, mark the value as inactive.
/// @details If this iterator is pointing to a child node, then the current item
/// in the parent node's table is required to be inactive. In that case,
/// this method has no effect.
void setValueOff() const { parent().mValueMask.setOff(this->pos()); }
/// Return the coordinates of the item to which this iterator is pointing.
Coord getCoord() const { return parent().offsetToGlobalCoord(this->pos()); }
/// Return in @a xyz the coordinates of the item to which this iterator is pointing.
void getCoord(Coord& xyz) const { xyz = this->getCoord(); }
private:
/// @note This parent node pointer is mutable, because setValueOn() and
/// setValueOff(), though const, need to call non-const methods on the parent.
/// There is a distinction between a const iterator (e.g., const ValueOnIter),
/// which is an iterator that can't be incremented, and an iterator over
/// a const node (e.g., ValueOnCIter), which might be const or non-const itself
/// but can't call non-const methods like setValue() on the node.
mutable NodeT* mParentNode;
MaskIterT mMaskIter;
}; // class IteratorBase
////////////////////////////////////////
/// @brief Base class for sparse iterators over internal and leaf nodes
template<
typename MaskIterT, // mask iterator type (OnIterator, OffIterator, etc.)
typename IterT, // SparseIteratorBase subclass (the "Curiously Recurring Template Pattern")
typename NodeT, // type of node over which to iterate
typename ItemT> // type of value to which this iterator points
struct SparseIteratorBase: public IteratorBase<MaskIterT, NodeT>
{
using NodeType = NodeT;
using ValueType = ItemT;
using NonConstNodeType = typename std::remove_const<NodeT>::type;
using NonConstValueType = typename std::remove_const<ItemT>::type;
static const bool IsSparseIterator = true, IsDenseIterator = false;
SparseIteratorBase() {}
SparseIteratorBase(const MaskIterT& iter, NodeT* parent):
IteratorBase<MaskIterT, NodeT>(iter, parent) {}
/// @brief Return the item at the given index in the parent node's table.
/// @note All subclasses must implement this accessor.
ItemT& getItem(Index) const;
/// @brief Set the value of the item at the given index in the parent node's table.
/// @note All non-const iterator subclasses must implement this accessor.
void setItem(Index, const ItemT&) const;
/// Return a reference to the item to which this iterator is pointing.
ItemT& operator*() const { return this->getValue(); }
/// Return a pointer to the item to which this iterator is pointing.
ItemT* operator->() const { return &(this->operator*()); }
/// Return the item to which this iterator is pointing.
ItemT& getValue() const
{
return static_cast<const IterT*>(this)->getItem(this->pos()); // static polymorphism
}
/// @brief Set the value of the item to which this iterator is pointing.
/// (Not valid for const iterators.)
void setValue(const ItemT& value) const
{
static_assert(!std::is_const<NodeT>::value, "setValue() not allowed for const iterators");
static_cast<const IterT*>(this)->setItem(this->pos(), value); // static polymorphism
}
/// @brief Apply a functor to the item to which this iterator is pointing.
/// (Not valid for const iterators.)
/// @param op a functor of the form <tt>void op(ValueType&) const</tt> that modifies
/// its argument in place
/// @see Tree::modifyValue()
template<typename ModifyOp>
void modifyValue(const ModifyOp& op) const
{
static_assert(!std::is_const<NodeT>::value,
"modifyValue() not allowed for const iterators");
static_cast<const IterT*>(this)->modifyItem(this->pos(), op); // static polymorphism
}
}; // class SparseIteratorBase
////////////////////////////////////////
/// @brief Base class for dense iterators over internal and leaf nodes
/// @note Dense iterators have no @c %operator*() or @c %operator->(),
/// because their return type would have to vary depending on whether
/// the iterator is pointing to a value or a child node.
template<
typename MaskIterT, // mask iterator type (typically a DenseIterator)
typename IterT, // DenseIteratorBase subclass (the "Curiously Recurring Template Pattern")
typename NodeT, // type of node over which to iterate
typename SetItemT, // type of set value (ChildNodeType, for non-leaf nodes)
typename UnsetItemT> // type of unset value (ValueType, usually)
struct DenseIteratorBase: public IteratorBase<MaskIterT, NodeT>
{
using NodeType = NodeT;
using ValueType = UnsetItemT;
using ChildNodeType = SetItemT;
using NonConstNodeType = typename std::remove_const<NodeT>::type;
using NonConstValueType = typename std::remove_const<UnsetItemT>::type;
using NonConstChildNodeType = typename std::remove_const<SetItemT>::type;
static const bool IsSparseIterator = false, IsDenseIterator = true;
DenseIteratorBase() {}
DenseIteratorBase(const MaskIterT& iter, NodeT* parent):
IteratorBase<MaskIterT, NodeT>(iter, parent) {}
/// @brief Return @c true if the item at the given index in the parent node's table
/// is a set value and return either the set value in @a child or the unset value
/// in @a value.
/// @note All subclasses must implement this accessor.
bool getItem(Index, SetItemT*& child, NonConstValueType& value) const;
/// @brief Set the value of the item at the given index in the parent node's table.
/// @note All non-const iterator subclasses must implement this accessor.
void setItem(Index, SetItemT*) const;
/// @brief "Unset" the value of the item at the given index in the parent node's table.
/// @note All non-const iterator subclasses must implement this accessor.
void unsetItem(Index, const UnsetItemT&) const;
/// Return @c true if this iterator is pointing to a child node.
bool isChildNode() const { return this->parent().isChildMaskOn(this->pos()); }
/// @brief If this iterator is pointing to a child node, return a pointer to the node.
/// Otherwise, return nullptr and, in @a value, the value to which this iterator is pointing.
SetItemT* probeChild(NonConstValueType& value) const
{
SetItemT* child = nullptr;
static_cast<const IterT*>(this)->getItem(this->pos(), child, value); // static polymorphism
return child;
}
/// @brief If this iterator is pointing to a child node, return @c true and return
/// a pointer to the child node in @a child. Otherwise, return @c false and return
/// the value to which this iterator is pointing in @a value.
bool probeChild(SetItemT*& child, NonConstValueType& value) const
{
child = probeChild(value);
return (child != nullptr);
}
/// @brief Return @c true if this iterator is pointing to a value and return
/// the value in @a value. Otherwise, return @c false.
bool probeValue(NonConstValueType& value) const
{
SetItemT* child = nullptr;
const bool isChild = static_cast<const IterT*>(this)-> // static polymorphism
getItem(this->pos(), child, value);
return !isChild;
}
/// @brief Replace with the given child node the item in the parent node's table
/// to which this iterator is pointing.
void setChild(SetItemT* child) const
{
static_cast<const IterT*>(this)->setItem(this->pos(), child); // static polymorphism
}
/// @brief Replace with the given value the item in the parent node's table
/// to which this iterator is pointing.
void setValue(const UnsetItemT& value) const
{
static_cast<const IterT*>(this)->unsetItem(this->pos(), value); // static polymorphism
}
}; // struct DenseIteratorBase
} // namespace tree
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_TREE_ITERATOR_HAS_BEEN_INCLUDED
Exceptions.h
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
NodeMasks.h
openvdb::v11_0::ValueError
Definition Exceptions.h:65
openvdb::v11_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
openvdb::v11_0::tree::IteratorBase::IteratorBase
IteratorBase(const IteratorBase &)=default
openvdb::v11_0::tree::IteratorBase::pos
Index pos() const
Identical to offset.
Definition Iterator.h:60
openvdb::v11_0::tree::IteratorBase::isValueOn
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
openvdb::v11_0::tree::IteratorBase::offset
Index offset() const
Return this iterator's position as an index into the parent node's table.
Definition Iterator.h:57
openvdb::v11_0::tree::IteratorBase::getCoord
Coord getCoord() const
Return the coordinates of the item to which this iterator is pointing.
Definition Iterator.h:89
openvdb::v11_0::tree::IteratorBase::test
bool test() const
Return true if this iterator is not yet exhausted.
Definition Iterator.h:63
openvdb::v11_0::tree::IteratorBase::getParentNode
NodeT * getParentNode() const
Return a pointer to the node (if any) over which this iterator is iterating.
Definition Iterator.h:47
openvdb::v11_0::tree::IteratorBase::setValueOn
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
openvdb::v11_0::tree::IteratorBase::operator=
IteratorBase & operator=(const IteratorBase &)=default
openvdb::v11_0::tree::IteratorBase::parent
NodeT & parent() const
Return a reference to the node over which this iterator is iterating.
Definition Iterator.h:50
openvdb::v11_0::tree::IteratorBase::setValueOff
void setValueOff() const
If this iterator is pointing to a value, mark the value as inactive.
Definition Iterator.h:86
openvdb::v11_0::tree::IteratorBase::next
bool next()
Advance to the next item in the parent node's table.
Definition Iterator.h:68
openvdb::v11_0::tree::IteratorBase::operator==
bool operator==(const IteratorBase &other) const
Definition Iterator.h:37
openvdb::v11_0::tree::IteratorBase::getCoord
void getCoord(Coord &xyz) const
Return in xyz the coordinates of the item to which this iterator is pointing.
Definition Iterator.h:91
openvdb::v11_0::tree::IteratorBase::IteratorBase
IteratorBase()
Definition Iterator.h:32
openvdb::v11_0::tree::IteratorBase::IteratorBase
IteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:33
openvdb::v11_0::tree::IteratorBase::operator++
IteratorBase & operator++()
Advance to the next item in the parent node's table.
Definition Iterator.h:72
openvdb::v11_0::tree::IteratorBase::operator!=
bool operator!=(const IteratorBase &other) const
Definition Iterator.h:41
openvdb::v11_0::tree::IteratorBase::increment
void increment(Index n)
Advance n items in the parent node's table.
Definition Iterator.h:74
openvdb::v11_0::tree::IteratorBase::increment
void increment()
Advance to the next item in the parent node's table.
Definition Iterator.h:70
openvdb::v11_0::tree::iter
Definition TreeIterator.h:29
openvdb::v11_0::Index
Index32 Index
Definition Types.h:54
openvdb
Definition Exceptions.h:13
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::NonConstValueType
typename std::remove_const< ValueT >::type NonConstValueType
Definition Iterator.h:184
openvdb::v11_0::tree::DenseIteratorBase::getItem
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...
openvdb::v11_0::tree::DenseIteratorBase::DenseIteratorBase
DenseIteratorBase()
Definition Iterator.h:188
openvdb::v11_0::tree::DenseIteratorBase::setChild
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
openvdb::v11_0::tree::DenseIteratorBase::unsetItem
void unsetItem(Index, const UnsetItemT &) const
"Unset" the value of the item at the given index in the parent node's table.
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::ValueType
ValueT ValueType
Definition Iterator.h:181
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::NonConstChildNodeType
typename std::remove_const< ChildT >::type NonConstChildNodeType
Definition Iterator.h:185
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::IsSparseIterator
static const bool IsSparseIterator
Definition Iterator.h:186
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::IsDenseIterator
static const bool IsDenseIterator
Definition Iterator.h:186
openvdb::v11_0::tree::DenseIteratorBase::DenseIteratorBase
DenseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:189
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::ChildNodeType
ChildT ChildNodeType
Definition Iterator.h:182
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::NonConstNodeType
typename std::remove_const< NodeT >::type NonConstNodeType
Definition Iterator.h:183
openvdb::v11_0::tree::DenseIteratorBase::setItem
void setItem(Index, SetItemT *) const
Set the value of the item at the given index in the parent node's table.
openvdb::v11_0::tree::DenseIteratorBase::probeChild
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
openvdb::v11_0::tree::DenseIteratorBase::setValue
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
openvdb::v11_0::tree::DenseIteratorBase< MaskDenseIterator, DenseIter, NodeT, ChildT, ValueT >::NodeType
NodeT NodeType
Definition Iterator.h:180
openvdb::v11_0::tree::DenseIteratorBase::isChildNode
bool isChildNode() const
Return true if this iterator is pointing to a child node.
Definition Iterator.h:205
openvdb::v11_0::tree::DenseIteratorBase::probeChild
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
openvdb::v11_0::tree::DenseIteratorBase::probeValue
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
openvdb::v11_0::tree::SparseIteratorBase::setItem
void setItem(Index, const ItemT &) const
Set the value of the item at the given index in the parent node's table.
openvdb::v11_0::tree::SparseIteratorBase::modifyValue
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
openvdb::v11_0::tree::SparseIteratorBase::NonConstValueType
typename std::remove_const< ItemT >::type NonConstValueType
Definition Iterator.h:119
openvdb::v11_0::tree::SparseIteratorBase::getItem
ItemT & getItem(Index) const
Return the item at the given index in the parent node's table.
openvdb::v11_0::tree::SparseIteratorBase::operator*
ItemT & operator*() const
Return a reference to the item to which this iterator is pointing.
Definition Iterator.h:134
openvdb::v11_0::tree::SparseIteratorBase::SparseIteratorBase
SparseIteratorBase(const MaskIterT &iter, NodeT *parent)
Definition Iterator.h:123
openvdb::v11_0::tree::SparseIteratorBase::setValue
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
openvdb::v11_0::tree::SparseIteratorBase::SparseIteratorBase
SparseIteratorBase()
Definition Iterator.h:122
openvdb::v11_0::tree::SparseIteratorBase< MaskIterT, ValueIter, NodeT, ValueT >::IsSparseIterator
static const bool IsSparseIterator
Definition Iterator.h:120
openvdb::v11_0::tree::SparseIteratorBase< MaskIterT, ValueIter, NodeT, ValueT >::IsDenseIterator
static const bool IsDenseIterator
Definition Iterator.h:120
openvdb::v11_0::tree::SparseIteratorBase::NonConstNodeType
typename std::remove_const< NodeT >::type NonConstNodeType
Definition Iterator.h:118
openvdb::v11_0::tree::SparseIteratorBase::operator->
ItemT * operator->() const
Return a pointer to the item to which this iterator is pointing.
Definition Iterator.h:136
openvdb::v11_0::tree::SparseIteratorBase::NodeType
NodeT NodeType
Definition Iterator.h:116
openvdb::v11_0::tree::SparseIteratorBase::ValueType
ItemT ValueType
Definition Iterator.h:117
openvdb::v11_0::tree::SparseIteratorBase< MaskIterT, ValueIter, NodeT, ValueT >::getValue
ValueT & getValue() const
Definition Iterator.h:139
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212