VTK  9.2.6
vtkCompositeDataSetRange.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkCompositeDataSetRange.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14=========================================================================*/
15
16#ifndef vtkCompositeDataSetRange_h
17#define vtkCompositeDataSetRange_h
18
20#include "vtkCompositeDataSet.h"
22#include "vtkMeta.h"
23#include "vtkRange.h"
24#include "vtkSmartPointer.h"
25
26#include <cassert>
27
28namespace vtk
29{
30
31// Pass these to vtk::Range(cds, options):
32enum class CompositeDataSetOptions : unsigned int
33{
34 None = 0,
35 SkipEmptyNodes = 1 << 1 // Skip null datasets.
36};
37
38} // end namespace vtk (for bitflag op definition)
39
40VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
41
42namespace vtk
43{
44
45namespace detail
46{
47
50
53
54//------------------------------------------------------------------------------
55// vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
57 : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
58 CompositeDataSetIteratorReference, CompositeDataSetIteratorReference>
59{
60private:
61 using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
63 using InternalIterator = vtkCompositeDataIterator;
64 using SmartIterator = vtkSmartPointer<InternalIterator>;
65
66public:
67 using iterator_category = typename Superclass::iterator_category;
68 using value_type = typename Superclass::value_type;
69 using difference_type = typename Superclass::difference_type;
70 using pointer = typename Superclass::pointer;
71 using reference = typename Superclass::reference;
72
74 : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
75 {
76 this->CopyState(o.Iterator);
77 }
78
80
82 {
83 this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
84 this->CopyState(o.Iterator);
85 return *this;
86 }
87
89 {
90 this->Increment();
91 return *this;
92 }
93
95 {
96 CompositeDataSetIterator other(*this);
97 this->Increment();
98 return other;
99 }
100
101 reference operator*() const { return this->GetData(); }
102
103 pointer operator->() const { return this->GetData(); }
104
106 {
107 // A null internal iterator means it is an 'end' sentinal.
108 InternalIterator* l = lhs.Iterator;
109 InternalIterator* r = rhs.Iterator;
110
111 if (!r && !l)
112 { // end == end
113 return true;
114 }
115 else if (!r)
116 { // right is end
117 return l->IsDoneWithTraversal() != 0;
118 }
119 else if (!l)
120 { // left is end
121 return r->IsDoneWithTraversal() != 0;
122 }
123 else
124 { // Both iterators are valid, check unique idx:
125 return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
126 }
127 }
128
130 {
131 return !(lhs == rhs); // let the compiler handle this one =)
132 }
133
135 {
136 using std::swap;
137 swap(lhs.Iterator, rhs.Iterator);
138 }
139
141
142protected:
143 // Note: This takes ownership of iter and manages its lifetime.
144 // Iter should not be used past this point by the caller.
145 CompositeDataSetIterator(SmartIterator&& iter) noexcept
146 : Iterator(std::move(iter))
147 {
148 }
149
150 // Note: Iterators constructed using this ctor will be considered
151 // 'end' iterators via a sentinal pattern.
153 : Iterator(nullptr)
154 {
155 }
156
157private:
158 void CopyState(InternalIterator* source)
159 {
160 if (source)
161 {
162 assert(this->Iterator != nullptr);
163 this->Iterator->SetDataSet(source->GetDataSet());
164 this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
165 this->Iterator->InitTraversal();
166 // XXX(empty iteration): This assert fires for some iterator
167 // implementations if iterating over an empty dataset (because in this
168 // case, `begin() == end()`. This assert needs work.
169 // assert(!source->IsDoneWithTraversal());
170 this->AdvanceTo(source->GetCurrentFlatIndex());
171 }
172 }
173
174 void AdvanceTo(const unsigned int flatIdx)
175 {
176 assert(this->Iterator != nullptr);
177 assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
178 while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
179 {
180 this->Increment();
181 }
182 }
183
184 void Increment()
185 {
186 assert(this->Iterator != nullptr);
187 assert(!this->Iterator->IsDoneWithTraversal());
188 this->Iterator->GoToNextItem();
189 }
190
192 {
193 assert(this->Iterator != nullptr);
194 assert(!this->Iterator->IsDoneWithTraversal());
195 return CompositeDataSetIteratorReference{ this->Iterator };
196 }
197
198 mutable SmartIterator Iterator;
199};
200
201//------------------------------------------------------------------------------
202// CompositeDataSet range proxy.
203// The const_iterators/references are the same as the non-const versions, since
204// vtkObjects marked const are unusable.
206{
207private:
208 using InternalIterator = vtkCompositeDataIterator;
209 using SmartIterator = vtkSmartPointer<InternalIterator>;
210
211public:
212 using size_type = int;
218
221 : CompositeDataSet(cds)
222 , Options(opts)
223 {
224 assert(this->CompositeDataSet);
225 }
226
227 vtkCompositeDataSet* GetCompositeDataSet() const noexcept { return this->CompositeDataSet; }
228
229 CompositeDataSetOptions GetOptions() const noexcept { return this->Options; }
230
231 // This is O(N), since the size requires traversal due to various options.
233 {
234 size_type result = 0;
235 auto iter = this->NewIterator();
236 iter->InitTraversal();
237 while (!iter->IsDoneWithTraversal())
238 {
239 ++result;
240 iter->GoToNextItem();
241 }
242 return result;
243 }
244
245 iterator begin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
246
248
249 // Note: These return mutable objects because const vtkObject are unusable.
250 const_iterator cbegin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
251
252 // Note: These return mutable objects because const vtkObjects are unusable.
254
255private:
256 SmartIterator NewIterator() const
257 {
258 using Opts = vtk::CompositeDataSetOptions;
259
260 auto result = SmartIterator::Take(this->CompositeDataSet->NewIterator());
261 result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
262 result->InitTraversal();
263 return result;
264 }
265
266 mutable vtkSmartPointer<vtkCompositeDataSet> CompositeDataSet;
268};
269
270}
271} // end namespace vtk::detail
272
273#endif // vtkCompositeDataSetRange_h
274
275// 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 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
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< InternalIterator > Take(InternalIterator *t)
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
typename Superclass::difference_type difference_type
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)
typename Superclass::iterator_category iterator_category
typename Superclass::value_type value_type
CompositeDataSetOptions GetOptions() const noexcept
vtkCompositeDataSet * GetCompositeDataSet() const noexcept
const CompositeDataSetIteratorReference const_reference
CompositeDataSetIteratorReference reference
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.