VTK  9.2.20220811
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 namespace vtk
29 {
30 
31 // Pass these to vtk::Range(cds, options):
32 enum 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 
40 VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
41 
42 namespace vtk
43 {
44 
45 namespace detail
46 {
47 
48 struct CompositeDataSetRange;
49 struct CompositeDataSetIterator;
50 
53 
54 //------------------------------------------------------------------------------
55 // vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
57 {
58 private:
61 
62 public:
63  using iterator_category = std::forward_iterator_tag;
65  using difference_type = int;
68 
70  : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
71  {
72  this->CopyState(o.Iterator);
73  }
74 
76 
78  {
79  this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
80  this->CopyState(o.Iterator);
81  return *this;
82  }
83 
85  {
86  this->Increment();
87  return *this;
88  }
89 
91  {
92  CompositeDataSetIterator other(*this);
93  this->Increment();
94  return other;
95  }
96 
97  reference operator*() const { return this->GetData(); }
98 
99  pointer operator->() const { return this->GetData(); }
100 
102  {
103  // A null internal iterator means it is an 'end' sentinal.
104  InternalIterator* l = lhs.Iterator;
105  InternalIterator* r = rhs.Iterator;
106 
107  if (!r && !l)
108  { // end == end
109  return true;
110  }
111  else if (!r)
112  { // right is end
113  return l->IsDoneWithTraversal() != 0;
114  }
115  else if (!l)
116  { // left is end
117  return r->IsDoneWithTraversal() != 0;
118  }
119  else
120  { // Both iterators are valid, check unique idx:
121  return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
122  }
123  }
124 
126  {
127  return !(lhs == rhs); // let the compiler handle this one =)
128  }
129 
130  friend void swap(CompositeDataSetIterator& lhs, CompositeDataSetIterator& rhs) noexcept
131  {
132  using std::swap;
133  swap(lhs.Iterator, rhs.Iterator);
134  }
135 
136  friend struct CompositeDataSetRange;
137 
138 protected:
139  // Note: This takes ownership of iter and manages its lifetime.
140  // Iter should not be used past this point by the caller.
142  : Iterator(std::move(iter))
143  {
144  }
145 
146  // Note: Iterators constructed using this ctor will be considered
147  // 'end' iterators via a sentinal pattern.
149  : Iterator(nullptr)
150  {
151  }
152 
153 private:
154  void CopyState(InternalIterator* source)
155  {
156  if (source)
157  {
158  assert(this->Iterator != nullptr);
159  this->Iterator->SetDataSet(source->GetDataSet());
160  this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
161  this->Iterator->InitTraversal();
162  // XXX(empty iteration): This assert fires for some iterator
163  // implementations if iterating over an empty dataset (because in this
164  // case, `begin() == end()`. This assert needs work.
165  // assert(!source->IsDoneWithTraversal());
166  this->AdvanceTo(source->GetCurrentFlatIndex());
167  }
168  }
169 
170  void AdvanceTo(const unsigned int flatIdx)
171  {
172  assert(this->Iterator != nullptr);
173  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
174  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
175  {
176  this->Increment();
177  }
178  }
179 
180  void Increment()
181  {
182  assert(this->Iterator != nullptr);
183  assert(!this->Iterator->IsDoneWithTraversal());
184  this->Iterator->GoToNextItem();
185  }
186 
188  {
189  assert(this->Iterator != nullptr);
190  assert(!this->Iterator->IsDoneWithTraversal());
191  return CompositeDataSetIteratorReference{ this->Iterator };
192  }
193 
194  mutable SmartIterator Iterator;
195 };
196 
197 //------------------------------------------------------------------------------
198 // CompositeDataSet range proxy.
199 // The const_iterators/references are the same as the non-const versions, since
200 // vtkObjects marked const are unusable.
202 {
203 private:
206 
207 public:
208  using size_type = int;
214 
217  : CompositeDataSet(cds)
218  , Options(opts)
219  {
220  assert(this->CompositeDataSet);
221  }
222 
223  vtkCompositeDataSet* GetCompositeDataSet() const noexcept { return this->CompositeDataSet; }
224 
225  CompositeDataSetOptions GetOptions() const noexcept { return this->Options; }
226 
227  // This is O(N), since the size requires traversal due to various options.
228  size_type size() const
229  {
230  size_type result = 0;
231  auto iter = this->NewIterator();
232  iter->InitTraversal();
233  while (!iter->IsDoneWithTraversal())
234  {
235  ++result;
236  iter->GoToNextItem();
237  }
238  return result;
239  }
240 
241  iterator begin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
242 
243  iterator end() const { return CompositeDataSetIterator{}; }
244 
245  // Note: These return mutable objects because const vtkObject are unusable.
246  const_iterator cbegin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
247 
248  // Note: These return mutable objects because const vtkObjects are unusable.
250 
251 private:
252  SmartIterator NewIterator() const
253  {
254  using Opts = vtk::CompositeDataSetOptions;
255 
256  auto result = SmartIterator::Take(this->CompositeDataSet->NewIterator());
257  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
258  result->InitTraversal();
259  return result;
260  }
261 
262  mutable vtkSmartPointer<vtkCompositeDataSet> CompositeDataSet;
263  CompositeDataSetOptions Options;
264 };
265 
266 }
267 } // end namespace vtk::detail
268 
269 #endif // vtkCompositeDataSetRange_h
270 
271 // 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...
vtkSmartPointer< vtkDataArray > GetData(const Ioss::GroupingEntity *entity, const std::string &fieldname, Ioss::Transform *transform=nullptr, Cache *cache=nullptr, const std::string &cachekey=std::string())
Returns a VTK array for a given field (fieldname) on the chosen block (or set) entity.
vtk::CompositeDataSetNodeReference< vtkCompositeDataIterator, CompositeDataSetIterator > CompositeDataSetIteratorReference
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
CompositeDataSetIterator operator++(int)
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)
vtkCompositeDataSet * GetCompositeDataSet() const noexcept
CompositeDataSetOptions GetOptions() 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.