VTK  9.2.20230324
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 VTK_ABI_NAMESPACE_BEGIN
31 
32 // Pass these to vtk::Range(cds, options):
33 enum class CompositeDataSetOptions : unsigned int
34 {
35  None = 0,
36  SkipEmptyNodes = 1 << 1 // Skip null datasets.
37 };
38 
39 VTK_ABI_NAMESPACE_END
40 } // end namespace vtk (for bitflag op definition)
41 
42 VTK_ABI_NAMESPACE_BEGIN
43 VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
44 VTK_ABI_NAMESPACE_END
45 
46 namespace vtk
47 {
48 namespace detail
49 {
50 VTK_ABI_NAMESPACE_BEGIN
51 
52 struct CompositeDataSetRange;
53 struct CompositeDataSetIterator;
54 
57 
58 //------------------------------------------------------------------------------
59 // vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
61 {
62 private:
65 
66 public:
67  using iterator_category = std::forward_iterator_tag;
69  using difference_type = int;
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 
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;
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.
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 VTK_ABI_NAMESPACE_END
271 }
272 } // end namespace vtk::detail
273 
274 #endif // vtkCompositeDataSetRange_h
275 
276 // 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.