VTK  9.3.1
vtkCompositeDataSetRange.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 
4 #ifndef vtkCompositeDataSetRange_h
5 #define vtkCompositeDataSetRange_h
6 
8 #include "vtkCompositeDataSet.h"
10 #include "vtkMeta.h"
11 #include "vtkRange.h"
12 #include "vtkSmartPointer.h"
13 
14 #include <cassert>
15 
16 namespace vtk
17 {
18 VTK_ABI_NAMESPACE_BEGIN
19 
20 // Pass these to vtk::Range(cds, options):
21 enum class CompositeDataSetOptions : unsigned int
22 {
23  None = 0,
24  SkipEmptyNodes = 1 << 1 // Skip null datasets.
25 };
26 
27 VTK_ABI_NAMESPACE_END
28 } // end namespace vtk (for bitflag op definition)
29 
30 VTK_ABI_NAMESPACE_BEGIN
31 VTK_GENERATE_BITFLAG_OPS(vtk::CompositeDataSetOptions)
32 VTK_ABI_NAMESPACE_END
33 
34 namespace vtk
35 {
36 namespace detail
37 {
38 VTK_ABI_NAMESPACE_BEGIN
39 
40 struct CompositeDataSetRange;
41 struct CompositeDataSetIterator;
42 
45 
46 //------------------------------------------------------------------------------
47 // vtkCompositeDataSet iterator. Returns vtk::CompositeDataSetNodeReference.
49 {
50 private:
53 
54 public:
55  using iterator_category = std::forward_iterator_tag;
57  using difference_type = int;
60 
62  : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
63  {
64  this->CopyState(o.Iterator);
65  }
66 
68 
70  {
71  this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
72  this->CopyState(o.Iterator);
73  return *this;
74  }
75 
77  {
78  this->Increment();
79  return *this;
80  }
81 
83  {
84  CompositeDataSetIterator other(*this);
85  this->Increment();
86  return other;
87  }
88 
89  reference operator*() const { return this->GetData(); }
90 
91  pointer operator->() const { return this->GetData(); }
92 
93  friend bool operator==(const CompositeDataSetIterator& lhs, const CompositeDataSetIterator& rhs)
94  {
95  // A null internal iterator means it is an 'end' sentinal.
96  InternalIterator* l = lhs.Iterator;
97  InternalIterator* r = rhs.Iterator;
98 
99  if (!r && !l)
100  { // end == end
101  return true;
102  }
103  else if (!r)
104  { // right is end
105  return l->IsDoneWithTraversal() != 0;
106  }
107  else if (!l)
108  { // left is end
109  return r->IsDoneWithTraversal() != 0;
110  }
111  else
112  { // Both iterators are valid, check unique idx:
113  return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
114  }
115  }
116 
118  {
119  return !(lhs == rhs); // let the compiler handle this one =)
120  }
121 
122  friend void swap(CompositeDataSetIterator& lhs, CompositeDataSetIterator& rhs) noexcept
123  {
124  using std::swap;
125  swap(lhs.Iterator, rhs.Iterator);
126  }
127 
128  friend struct CompositeDataSetRange;
129 
130 protected:
131  // Note: This takes ownership of iter and manages its lifetime.
132  // Iter should not be used past this point by the caller.
134  : Iterator(std::move(iter))
135  {
136  }
137 
138  // Note: Iterators constructed using this ctor will be considered
139  // 'end' iterators via a sentinal pattern.
141  : Iterator(nullptr)
142  {
143  }
144 
145 private:
146  void CopyState(InternalIterator* source)
147  {
148  if (source)
149  {
150  assert(this->Iterator != nullptr);
151  this->Iterator->SetDataSet(source->GetDataSet());
152  this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
153  this->Iterator->InitTraversal();
154  // XXX(empty iteration): This assert fires for some iterator
155  // implementations if iterating over an empty dataset (because in this
156  // case, `begin() == end()`. This assert needs work.
157  // assert(!source->IsDoneWithTraversal());
158  this->AdvanceTo(source->GetCurrentFlatIndex());
159  }
160  }
161 
162  void AdvanceTo(const unsigned int flatIdx)
163  {
164  assert(this->Iterator != nullptr);
165  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
166  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
167  {
168  this->Increment();
169  }
170  }
171 
172  void Increment()
173  {
174  assert(this->Iterator != nullptr);
175  assert(!this->Iterator->IsDoneWithTraversal());
176  this->Iterator->GoToNextItem();
177  }
178 
179  CompositeDataSetIteratorReference GetData() const
180  {
181  assert(this->Iterator != nullptr);
182  assert(!this->Iterator->IsDoneWithTraversal());
183  return CompositeDataSetIteratorReference{ this->Iterator };
184  }
185 
186  mutable SmartIterator Iterator;
187 };
188 
189 //------------------------------------------------------------------------------
190 // CompositeDataSet range proxy.
191 // The const_iterators/references are the same as the non-const versions, since
192 // vtkObjects marked const are unusable.
194 {
195 private:
198 
199 public:
200  using size_type = int;
206 
208  vtkCompositeDataSet* cds, CompositeDataSetOptions opts = CompositeDataSetOptions::None)
209  : CompositeDataSet(cds)
210  , Options(opts)
211  {
212  assert(this->CompositeDataSet);
213  }
214 
215  vtkCompositeDataSet* GetCompositeDataSet() const noexcept { return this->CompositeDataSet; }
216 
217  CompositeDataSetOptions GetOptions() const noexcept { return this->Options; }
218 
219  // This is O(N), since the size requires traversal due to various options.
220  size_type size() const
221  {
222  size_type result = 0;
223  auto iter = this->NewIterator();
224  iter->InitTraversal();
225  while (!iter->IsDoneWithTraversal())
226  {
227  ++result;
228  iter->GoToNextItem();
229  }
230  return result;
231  }
232 
233  iterator begin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
234 
235  iterator end() const { return CompositeDataSetIterator{}; }
236 
237  // Note: These return mutable objects because const vtkObject are unusable.
238  const_iterator cbegin() const { return CompositeDataSetIterator{ this->NewIterator() }; }
239 
240  // Note: These return mutable objects because const vtkObjects are unusable.
242 
243 private:
244  SmartIterator NewIterator() const
245  {
246  using Opts = vtk::CompositeDataSetOptions;
247 
248  auto result = SmartIterator::Take(this->CompositeDataSet->NewIterator());
249  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
250  result->InitTraversal();
251  return result;
252  }
253 
254  mutable vtkSmartPointer<vtkCompositeDataSet> CompositeDataSet;
255  CompositeDataSetOptions Options;
256 };
257 
258 VTK_ABI_NAMESPACE_END
259 }
260 } // end namespace vtk::detail
261 
262 #endif // vtkCompositeDataSetRange_h
263 
264 // 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)
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
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...
general representation of visualization data
Definition: vtkDataObject.h:54
virtual unsigned int GetCurrentFlatIndex()=0
Flat index is an index to identify the data in a composite data structure.
friend bool operator!=(const CompositeDataSetIterator &lhs, const CompositeDataSetIterator &rhs)