VTK
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 
28 #ifndef __VTK_WRAP__
29 
30 namespace vtk
31 {
32 
33 // Pass these to vtk::Range(cds, options):
34 enum class CompositeDataSetOptions : unsigned int
35 {
36  None = 0,
37  SkipEmptyNodes = 1 << 1 // Skip null datasets.
38 };
39 
40 } // end namespace vtk (for bitflag op definition)
41 
42 VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
43 
44 namespace vtk
45 {
46 
47 namespace detail
48 {
49 
50 struct CompositeDataSetRange;
51 struct CompositeDataSetIterator;
52 
56 
57 //------------------------------------------------------------------------------
58 // vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
60  public std::iterator<std::forward_iterator_tag,
61  vtkDataObject*,
62  int,
63  CompositeDataSetIteratorReference,
64  CompositeDataSetIteratorReference>
65 {
66 private:
67  using Superclass = std::iterator<std::forward_iterator_tag,
69  int,
71  CompositeDataSetIteratorReference>;
72  using InternalIterator = vtkCompositeDataIterator;
74 
75 public:
76  using iterator_category = typename Superclass::iterator_category;
77  using value_type = typename Superclass::value_type;
78  using difference_type = typename Superclass::difference_type;
79  using pointer = typename Superclass::pointer;
80  using reference = typename Superclass::reference;
81 
83  : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance())
84  : nullptr)
85  {
86  this->CopyState(o.Iterator);
87  }
88 
90 
92  {
93  this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance())
94  : nullptr;
95  this->CopyState(o.Iterator);
96  return *this;
97  }
98 
100  {
101  this->Increment();
102  return *this;
103  }
104 
106  {
107  CompositeDataSetIterator other(*this);
108  this->Increment();
109  return other;
110  }
111 
113  {
114  return this->GetData();
115  }
116 
118  {
119  return this->GetData();
120  }
121 
122  friend bool operator==(const CompositeDataSetIterator& lhs,
123  const CompositeDataSetIterator& rhs)
124  {
125  // A null internal iterator means it is an 'end' sentinal.
126  InternalIterator *l = lhs.Iterator;
127  InternalIterator *r = rhs.Iterator;
128 
129  if (!r && !l)
130  { // end == end
131  return true;
132  }
133  else if (!r)
134  { // right is end
135  return l->IsDoneWithTraversal() != 0;
136  }
137  else if (!l)
138  { // left is end
139  return r->IsDoneWithTraversal() != 0;
140  }
141  else
142  { // Both iterators are valid, check unique idx:
143  return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
144  }
145  }
146 
147  friend bool operator!=(const CompositeDataSetIterator& lhs,
148  const CompositeDataSetIterator& rhs)
149  {
150  return !(lhs == rhs); // let the compiler handle this one =)
151  }
152 
153  friend void swap(CompositeDataSetIterator& lhs,
154  CompositeDataSetIterator& rhs) noexcept
155  {
156  using std::swap;
157  swap(lhs.Iterator, rhs.Iterator);
158  }
159 
160  friend struct CompositeDataSetRange;
161 
162 protected:
163  // Note: This takes ownership of iter and manages its lifetime.
164  // Iter should not be used past this point by the caller.
166  : Iterator(std::move(iter))
167  {
168  }
169 
170  // Note: Iterators constructed using this ctor will be considered
171  // 'end' iterators via a sentinal pattern.
172  CompositeDataSetIterator() noexcept : Iterator(nullptr) {}
173 
174 private:
175  void CopyState(InternalIterator *source)
176  {
177  if (source)
178  {
179  assert(this->Iterator != nullptr);
180  this->Iterator->SetDataSet(source->GetDataSet());
181  this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
182  this->Iterator->InitTraversal();
183  this->AdvanceTo(source->GetCurrentFlatIndex());
184  }
185  }
186 
187  void AdvanceTo(const unsigned int flatIdx)
188  {
189  assert(this->Iterator != nullptr);
190  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
191  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
192  {
193  this->Increment();
194  }
195  }
196 
197  void Increment()
198  {
199  assert(this->Iterator != nullptr);
200  assert(!this->Iterator->IsDoneWithTraversal());
201  this->Iterator->GoToNextItem();
202  }
203 
204  CompositeDataSetIteratorReference GetData() const
205  {
206  assert(this->Iterator != nullptr);
207  assert(!this->Iterator->IsDoneWithTraversal());
208  return CompositeDataSetIteratorReference{this->Iterator};
209  }
210 
211  mutable SmartIterator Iterator;
212 };
213 
214 //------------------------------------------------------------------------------
215 // CompositeDataSet range proxy.
216 // The const_iterators/references are the same as the non-const versions, since
217 // vtkObjects marked const are unusable.
219 {
220 private:
221  using InternalIterator = vtkCompositeDataIterator;
223 
224 public:
225  using size_type = int;
231 
234  : CompositeDataSet(cds)
235  , Options(opts)
236  {
237  assert(this->CompositeDataSet);
238  }
239 
241  {
242  return this->CompositeDataSet;
243  }
244 
246  {
247  return this->Options;
248  }
249 
250  // This is O(N), since the size requires traversal due to various options.
251  size_type size() const
252  {
253  size_type result = 0;
254  auto iter = this->NewIterator();
255  iter->InitTraversal();
256  while (!iter->IsDoneWithTraversal())
257  {
258  ++result;
259  iter->GoToNextItem();
260  }
261  return result;
262  }
263 
264  iterator begin() const
265  {
266  return CompositeDataSetIterator{this->NewIterator()};
267  }
268 
269  iterator end() const
270  {
271  return CompositeDataSetIterator{};
272  }
273 
274  // Note: These return mutable objects because const vtkObject are unusable.
276  {
277  return CompositeDataSetIterator{this->NewIterator()};
278  }
279 
280  // Note: These return mutable objects because const vtkObjects are unusable.
282  {
283  return CompositeDataSetIterator{};
284  }
285 
286 private:
287  SmartIterator NewIterator() const
288  {
289  using Opts = vtk::CompositeDataSetOptions;
290 
291  auto result = SmartIterator::Take(this->CompositeDataSet->NewIterator());
292  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
293  result->InitTraversal();
294  return result;
295  }
296 
297  mutable vtkSmartPointer<vtkCompositeDataSet> CompositeDataSet;
298  CompositeDataSetOptions Options;
299 };
300 
301 }
302 } // end namespace vtk::detail
303 
304 #endif // __VTK_WRAP__
305 
306 #endif // vtkCompositeDataSetRange_h
307 
308 // VTK-HeaderTest-Exclude: vtkCompositeDataSetRange.h
vtk::CompositeDataSetNodeReference< vtkCompositeDataIterator, CompositeDataSetIterator > CompositeDataSetIteratorReference
virtual int IsDoneWithTraversal()=0
Test whether the iterator is finished with the traversal.
typename Superclass::iterator_category iterator_category
CompositeDataSetOptions GetOptions() const noexcept
static vtkSmartPointer< T > NewInstance(T *t)
Create a new instance of the given VTK object.
CompositeDataSetRange(vtkCompositeDataSet *cds, CompositeDataSetOptions opts=CompositeDataSetOptions::None)
CompositeDataSetIterator(const CompositeDataSetIterator &o)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
superclass for composite data iterators
friend bool operator==(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)
abstract superclass for composite (multi-block or AMR) datasets
friend void swap(CompositeDataSetIterator &lhs, CompositeDataSetIterator &rhs) noexcept
vtkCompositeDataSet * GetCompositeDataSet() const noexcept
typename Superclass::value_type value_type
CompositeDataSetIterator & operator=(const CompositeDataSetIterator &o)
CompositeDataSetIterator(SmartIterator &&iter) noexcept
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
typename Superclass::difference_type difference_type
virtual vtkTypeBool GetSkipEmptyNodes()
If SkipEmptyNodes is true, then nullptr datasets will be skipped.
general representation of visualization data
Definition: vtkDataObject.h:64
virtual unsigned int GetCurrentFlatIndex()=0
Flat index is an index to identify the data in a composite data structure.
virtual vtkCompositeDataSet * GetDataSet()
Set the composite dataset this iterator is iterating over.
typename Superclass::reference reference
friend bool operator!=(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)