VTK  9.3.20231205
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' sentinel.
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 sentinel 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 
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 
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
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.