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 
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  : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
58  CompositeDataSetIteratorReference, CompositeDataSetIteratorReference>
59 {
60 private:
61  using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
62  CompositeDataSetIteratorReference, CompositeDataSetIteratorReference>;
65 
66 public:
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 
134  friend void swap(CompositeDataSetIterator& lhs, CompositeDataSetIterator& rhs) noexcept
135  {
136  using std::swap;
137  swap(lhs.Iterator, rhs.Iterator);
138  }
139 
140  friend struct CompositeDataSetRange;
141 
142 protected:
143  // Note: This takes ownership of iter and manages its lifetime.
144  // Iter should not be used past this point by the caller.
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 
157 private:
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 
191  CompositeDataSetIteratorReference GetData() const
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 {
207 private:
210 
211 public:
212  using size_type = int;
217  using value_type = vtkDataObject*;
218 
220  vtkCompositeDataSet* cds, CompositeDataSetOptions opts = CompositeDataSetOptions::None)
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.
232  size_type size() const
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 
247  iterator end() const { return CompositeDataSetIterator{}; }
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 
255 private:
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;
267  CompositeDataSetOptions Options;
268 };
269 
270 }
271 } // end namespace vtk::detail
272 
273 #endif // vtkCompositeDataSetRange_h
274 
275 // VTK-HeaderTest-Exclude: vtkCompositeDataSetRange.h
vtk::CompositeDataSetNodeReference< vtkCompositeDataIterator, CompositeDataSetIterator > CompositeDataSetIteratorReference
virtual int IsDoneWithTraversal()=0
Test whether the iterator is finished with the traversal.
CompositeDataSetIterator operator++(int)
typename Superclass::iterator_category iterator_category
CompositeDataSetRange(vtkCompositeDataSet *cds, CompositeDataSetOptions opts=CompositeDataSetOptions::None)
CompositeDataSetOptions GetOptions() const noexcept
CompositeDataSetIterator(const CompositeDataSetIterator &o)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
This file contains a variety of metaprogramming constructs for working with vtk types.
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
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
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.
CompositeDataSetIterator(SmartIterator &&iter) noexcept
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
typename Superclass::difference_type difference_type
general representation of visualization data
Definition: vtkDataObject.h:65
virtual unsigned int GetCurrentFlatIndex()=0
Flat index is an index to identify the data in a composite data structure.
typename Superclass::reference reference
friend bool operator!=(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)