VTK  9.3.20240721
vtkCompositeDataSetRange.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 vtkCompositeDataSetRange_h
5#define vtkCompositeDataSetRange_h
6
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 CompositeDataSetOptions : unsigned int
22{
23 None = 0,
24 SkipEmptyNodes = 1 << 1 // Skip null datasets.
25};
26
27VTK_ABI_NAMESPACE_END
28} // end namespace vtk (for bitflag op definition)
29
30VTK_ABI_NAMESPACE_BEGIN
31VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
32VTK_ABI_NAMESPACE_END
33
34namespace vtk
35{
36namespace detail
37{
38VTK_ABI_NAMESPACE_BEGIN
39
40struct CompositeDataSetRange;
41struct CompositeDataSetIterator;
42
45
46//------------------------------------------------------------------------------
47// vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
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 CompositeDataSetIterator 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
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
118 {
119 return !(lhs == rhs); // let the compiler handle this one =)
120 }
121
123 {
124 using std::swap;
125 swap(lhs.Iterator, rhs.Iterator);
126 }
127
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->InitTraversal();
154 // XXX(empty iteration): This assert fires for some iterator
155 // implementations if iterating over an empty dataset (because in this
156 // case, `begin() == end()`. This assert needs work.
157 // assert(!source->IsDoneWithTraversal());
158 this->AdvanceTo(source->GetCurrentFlatIndex());
159 }
160 }
161
162 void AdvanceTo(const unsigned int flatIdx)
163 {
164 assert(this->Iterator != nullptr);
165 assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
166 while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
167 {
168 this->Increment();
169 }
170 }
171
172 void Increment()
173 {
174 assert(this->Iterator != nullptr);
175 assert(!this->Iterator->IsDoneWithTraversal());
176 this->Iterator->GoToNextItem();
177 }
178
180 {
181 assert(this->Iterator != nullptr);
182 assert(!this->Iterator->IsDoneWithTraversal());
183 return CompositeDataSetIteratorReference{ this->Iterator };
184 }
185
186 mutable SmartIterator Iterator;
187};
188
189//------------------------------------------------------------------------------
190// CompositeDataSet range proxy.
191// The const_iterators/references are the same as the non-const versions, since
192// vtkObjects marked const are unusable.
194{
195private:
198
199public:
200 using size_type = int;
206
209 : CompositeDataSet(cds)
210 , Options(opts)
211 {
212 assert(this->CompositeDataSet);
213 }
214
215 vtkCompositeDataSet* GetCompositeDataSet() const noexcept { return this->CompositeDataSet; }
216
217 CompositeDataSetOptions GetOptions() const noexcept { return this->Options; }
218
219 // This is O(N), since the size requires traversal due to various options.
221 {
222 size_type result = 0;
223 auto iter = this->NewIterator();
224 iter->InitTraversal();
225 while (!iter->IsDoneWithTraversal())
226 {
227 ++result;
228 iter->GoToNextItem();
229 }
230 return result;
231 }
232
233 iterator begin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
234
236
237 // Note: These return mutable objects because const vtkObject are unusable.
238 const_iterator cbegin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
239
240 // Note: These return mutable objects because const vtkObjects are unusable.
242
243private:
244 SmartIterator NewIterator() const
245 {
246 using Opts = vtk::CompositeDataSetOptions;
247
248 auto result = SmartIterator::Take(this->CompositeDataSet->NewIterator());
249 result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
250 result->InitTraversal();
251 return result;
252 }
253
254 mutable vtkSmartPointer<vtkCompositeDataSet> CompositeDataSet;
256};
257
258VTK_ABI_NAMESPACE_END
259}
260} // end namespace vtk::detail
261
262#endif // vtkCompositeDataSetRange_h
263
264// VTK-HeaderTest-Exclude: vtkCompositeDataSetRange.h
superclass for composite data iterators
virtual void SetDataSet(vtkCompositeDataSet *ds)
Set the composite dataset this iterator is iterating over.
virtual int IsDoneWithTraversal()=0
Test whether the iterator is finished with the traversal.
virtual void InitTraversal()
Begin iterating over the composite dataset structure.
virtual void SetSkipEmptyNodes(vtkTypeBool)
If SkipEmptyNodes is true, then nullptr datasets will be skipped.
virtual void GoToNextItem()=0
Move the iterator to the next item in the collection.
virtual unsigned int GetCurrentFlatIndex()=0
Flat index is an index to identify the data in a composite data structure.
abstract superclass for composite (multi-block or AMR) datasets
virtual vtkCompositeDataIterator * NewIterator()=0
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< vtkCompositeDataIterator, CompositeDataSetIterator > CompositeDataSetIteratorReference
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
CompositeDataSetIterator(CompositeDataSetIterator &&) noexcept=default
friend bool operator!=(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)
friend void swap(CompositeDataSetIterator &lhs, CompositeDataSetIterator &rhs) noexcept
CompositeDataSetIterator(SmartIterator &&iter) noexcept
CompositeDataSetIterator(const CompositeDataSetIterator &o)
friend bool operator==(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)
CompositeDataSetOptions GetOptions() const noexcept
vtkCompositeDataSet * GetCompositeDataSet() const noexcept
CompositeDataSetRange(vtkCompositeDataSet *cds, CompositeDataSetOptions opts=CompositeDataSetOptions::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.