VTK  9.5.20250603
vtkDataObjectTreeRange.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef vtkDataObjectTreeRange_h
5#define vtkDataObjectTreeRange_h
6
8#include "vtkDataObjectTree.h"
10#include "vtkMeta.h"
11#include "vtkRange.h"
12#include "vtkSmartPointer.h"
13
14#include <cassert>
15
16namespace vtk
17{
18VTK_ABI_NAMESPACE_BEGIN
19
20// Pass these to vtk::Range(cds, options):
21enum class DataObjectTreeOptions : unsigned int
22{
23 None = 0,
24 SkipEmptyNodes = 1 << 1, // Skip null datasets.
25 VisitOnlyLeaves = 1 << 2, // Skip child composite datasets.
26 TraverseSubTree = 1 << 3, // Descend into child composite datasets.
27};
28
29VTK_ABI_NAMESPACE_END
30} // end namespace vtk (for bitflag op definition)
31
32VTK_ABI_NAMESPACE_BEGIN
33VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
34VTK_ABI_NAMESPACE_END
35
36namespace vtk
37{
38namespace detail
39{
40VTK_ABI_NAMESPACE_BEGIN
41
42struct DataObjectTreeRange;
43struct DataObjectTreeIterator;
44
47
49{
50private:
53
54public:
55 using iterator_category = std::forward_iterator_tag;
57 using difference_type = int;
60
62 : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
63 {
64 this->CopyState(o.Iterator);
65 }
66
68
70 {
71 this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
72 this->CopyState(o.Iterator);
73 return *this;
74 }
75
77 {
78 this->Increment();
79 return *this;
80 }
81
83 {
84 DataObjectTreeIterator other(*this);
85 this->Increment();
86 return other;
87 }
88
89 reference operator*() const { return this->GetData(); }
90
91 pointer operator->() const { return this->GetData(); }
92
93 friend bool operator==(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
94 {
95 // A null internal iterator means it is an 'end' sentinel.
96 InternalIterator* l = lhs.Iterator;
97 InternalIterator* r = rhs.Iterator;
98
99 if (!r && !l)
100 { // end == end
101 return true;
102 }
103 else if (!r)
104 { // right is end
105 return l->IsDoneWithTraversal() != 0;
106 }
107 else if (!l)
108 { // left is end
109 return r->IsDoneWithTraversal() != 0;
110 }
111 else
112 { // Both iterators are valid, check unique idx:
113 return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
114 }
115 }
116
117 friend bool operator!=(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
118 {
119 return !(lhs == rhs); // let the compiler handle this one =)
120 }
121
122 friend void swap(DataObjectTreeIterator& lhs, DataObjectTreeIterator& rhs) noexcept
123 {
124 using std::swap;
125 swap(lhs.Iterator, rhs.Iterator);
126 }
127
128 friend struct DataObjectTreeRange;
129
130protected:
131 // Note: This takes ownership of iter and manages its lifetime.
132 // Iter should not be used past this point by the caller.
134 : Iterator(std::move(iter))
135 {
136 }
137
138 // Note: Iterators constructed using this ctor will be considered
139 // 'end' iterators via a sentinel pattern.
141 : Iterator{ nullptr }
142 {
143 }
144
145private:
146 void CopyState(InternalIterator* source)
147 {
148 if (source)
149 {
150 assert(this->Iterator != nullptr);
151 this->Iterator->SetDataSet(source->GetDataSet());
152 this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
153 this->Iterator->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
154 this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
155 this->Iterator->InitTraversal();
156 this->AdvanceTo(source->GetCurrentFlatIndex());
157 }
158 }
159
160 void AdvanceTo(const unsigned int flatIdx)
161 {
162 assert(this->Iterator != nullptr);
163 assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
164 while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
165 {
166 this->Increment();
167 }
168 }
169
170 void Increment()
171 {
172 assert(this->Iterator != nullptr);
173 assert(!this->Iterator->IsDoneWithTraversal());
174 this->Iterator->GoToNextItem();
175 }
176
177 DataObjectTreeIteratorReference GetData() const
178 {
179 assert(this->Iterator != nullptr);
180 assert(!this->Iterator->IsDoneWithTraversal());
181 return DataObjectTreeIteratorReference{ this->Iterator };
182 }
183
184 mutable SmartIterator Iterator;
185};
186
187//------------------------------------------------------------------------------
188// DataObjectTree range proxy.
190{
191private:
194
195public:
196 using size_type = int;
202
205 : DataObjectTree(cds)
206 , Options(opts)
207 {
208 assert(this->DataObjectTree);
209 }
210
211 vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
212
213 DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
214
215 // This is O(N), since the size requires traversal due to various options.
217 {
218 size_type result = 0;
219 auto iter = this->NewIterator();
220 iter->InitTraversal();
221 while (!iter->IsDoneWithTraversal())
222 {
223 ++result;
224 iter->GoToNextItem();
225 }
226 return result;
227 }
228
229 iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
230
231 iterator end() const { return DataObjectTreeIterator{}; }
232
233 // Note: These return mutable objects because const vtkObject are unusable.
234 const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
235
236 // Note: These return mutable objects because const vtkObjects are unusable.
238
239private:
240 SmartIterator NewIterator() const
241 {
242 using Opts = vtk::DataObjectTreeOptions;
243
244 auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
245 result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
246 result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
247 result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
248 result->InitTraversal();
249 return result;
250 }
251
252 mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
253 DataObjectTreeOptions Options;
254};
255
256VTK_ABI_NAMESPACE_END
257}
258} // end namespace vtk::detail
259
260#endif // vtkDataObjectTreeRange_h
261
262// VTK-HeaderTest-Exclude: vtkDataObjectTreeRange.h
virtual void SetDataSet(vtkCompositeDataSet *ds)
Set the composite dataset this iterator is iterating over.
virtual void InitTraversal()
Begin iterating over the composite dataset structure.
virtual void SetSkipEmptyNodes(vtkTypeBool)
If SkipEmptyNodes is true, then nullptr datasets will be skipped.
superclass for composite data iterators
int IsDoneWithTraversal() override
Test whether the iterator is finished with the traversal.
virtual void SetTraverseSubTree(vtkTypeBool)
If TraverseSubTree is set to true, the iterator will visit the entire tree structure,...
void GoToNextItem() override
Move the iterator to the next item in the collection.
unsigned int GetCurrentFlatIndex() override
Flat index is an index obtained by traversing the tree in preorder.
virtual void SetVisitOnlyLeaves(vtkTypeBool)
If VisitOnlyLeaves is true, the iterator will only visit nodes (sub-datasets) that are not composite.
provides implementation for most abstract methods in the superclass vtkCompositeDataSet
virtual vtkDataObjectTreeIterator * NewTreeIterator()
Return a new iterator (the iterator has to be deleted by user).
general representation of visualization data
static vtkSmartPointer< InternalIterator > Take(InternalIterator *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
vtk::CompositeDataSetNodeReference< vtkDataObjectTreeIterator, DataObjectTreeIterator > DataObjectTreeIteratorReference
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
DataObjectTreeIterator(const DataObjectTreeIterator &o)
DataObjectTreeIterator(DataObjectTreeIterator &&) noexcept=default
DataObjectTreeIterator(SmartIterator &&iter) noexcept
friend bool operator!=(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
std::forward_iterator_tag iterator_category
friend bool operator==(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
friend void swap(DataObjectTreeIterator &lhs, DataObjectTreeIterator &rhs) noexcept
vtkDataObjectTree * GetDataObjectTree() const noexcept
DataObjectTreeOptions GetOptions() const noexcept
DataObjectTreeRange(vtkDataObjectTree *cds, DataObjectTreeOptions opts=DataObjectTreeOptions::None)
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
This file contains a variety of metaprogramming constructs for working with vtk types.