VTK  9.3.1
vtkDataObjectTreeRange.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 vtkDataObjectTreeRange_h
5 #define vtkDataObjectTreeRange_h
6 
8 #include "vtkDataObjectTree.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 DataObjectTreeOptions : unsigned int
22 {
23  None = 0,
24  SkipEmptyNodes = 1 << 1, // Skip null datasets.
25  VisitOnlyLeaves = 1 << 2, // Skip child composite datasets.
26  TraverseSubTree = 1 << 3, // Descend into child composite datasets.
27 };
28 
29 VTK_ABI_NAMESPACE_END
30 } // end namespace vtk (for bitflag op definition)
31 
32 VTK_ABI_NAMESPACE_BEGIN
33 VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
34 VTK_ABI_NAMESPACE_END
35 
36 namespace vtk
37 {
38 namespace detail
39 {
40 VTK_ABI_NAMESPACE_BEGIN
41 
42 struct DataObjectTreeRange;
43 struct DataObjectTreeIterator;
44 
47 
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 
67  DataObjectTreeIterator(DataObjectTreeIterator&&) noexcept = default;
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  DataObjectTreeIterator 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 DataObjectTreeIterator& lhs, const DataObjectTreeIterator& 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 
117  friend bool operator!=(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
118  {
119  return !(lhs == rhs); // let the compiler handle this one =)
120  }
121 
122  friend void swap(DataObjectTreeIterator& lhs, DataObjectTreeIterator& rhs) noexcept
123  {
124  using std::swap;
125  swap(lhs.Iterator, rhs.Iterator);
126  }
127 
128  friend struct DataObjectTreeRange;
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->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
154  this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
155  this->Iterator->InitTraversal();
156  this->AdvanceTo(source->GetCurrentFlatIndex());
157  }
158  }
159 
160  void AdvanceTo(const unsigned int flatIdx)
161  {
162  assert(this->Iterator != nullptr);
163  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
164  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
165  {
166  this->Increment();
167  }
168  }
169 
170  void Increment()
171  {
172  assert(this->Iterator != nullptr);
173  assert(!this->Iterator->IsDoneWithTraversal());
174  this->Iterator->GoToNextItem();
175  }
176 
177  DataObjectTreeIteratorReference GetData() const
178  {
179  assert(this->Iterator != nullptr);
180  assert(!this->Iterator->IsDoneWithTraversal());
181  return DataObjectTreeIteratorReference{ this->Iterator };
182  }
183 
184  mutable SmartIterator Iterator;
185 };
186 
187 //------------------------------------------------------------------------------
188 // DataObjectTree range proxy.
190 {
191 private:
194 
195 public:
196  using size_type = int;
202 
204  vtkDataObjectTree* cds, DataObjectTreeOptions opts = DataObjectTreeOptions::None)
205  : DataObjectTree(cds)
206  , Options(opts)
207  {
208  assert(this->DataObjectTree);
209  }
210 
211  vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
212 
213  DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
214 
215  // This is O(N), since the size requires traversal due to various options.
216  size_type size() const
217  {
218  size_type result = 0;
219  auto iter = this->NewIterator();
220  iter->InitTraversal();
221  while (!iter->IsDoneWithTraversal())
222  {
223  ++result;
224  iter->GoToNextItem();
225  }
226  return result;
227  }
228 
229  iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
230 
231  iterator end() const { return DataObjectTreeIterator{}; }
232 
233  // Note: These return mutable objects because const vtkObject are unusable.
234  const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
235 
236  // Note: These return mutable objects because const vtkObjects are unusable.
238 
239 private:
240  SmartIterator NewIterator() const
241  {
242  using Opts = vtk::DataObjectTreeOptions;
243 
244  auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
245  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
246  result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
247  result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
248  result->InitTraversal();
249  return result;
250  }
251 
252  mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
253  DataObjectTreeOptions Options;
254 };
255 
256 VTK_ABI_NAMESPACE_END
257 }
258 } // end namespace vtk::detail
259 
260 #endif // vtkDataObjectTreeRange_h
261 
262 // VTK-HeaderTest-Exclude: vtkDataObjectTreeRange.h
std::forward_iterator_tag iterator_category
vtkDataObjectTree * GetDataObjectTree() const noexcept
provides implementation for most abstract methods in the superclass vtkCompositeDataSet ...
vtk::CompositeDataSetNodeReference< vtkDataObjectTreeIterator, DataObjectTreeIterator > DataObjectTreeIteratorReference
DataObjectTreeIterator operator++(int)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
DataObjectTreeOptions GetOptions() const noexcept
DataObjectTreeIterator(const DataObjectTreeIterator &o)
This file contains a variety of metaprogramming constructs for working with vtk types.
int IsDoneWithTraversal() override
Test whether the iterator is finished with the traversal.
friend bool operator==(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
friend bool operator!=(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
DataObjectTreeRange(vtkDataObjectTree *cds, DataObjectTreeOptions opts=DataObjectTreeOptions::None)
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
unsigned int GetCurrentFlatIndex() override
Flat index is an index obtained by traversing the tree in preorder.
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.
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
superclass for composite data iterators
friend void swap(DataObjectTreeIterator &lhs, DataObjectTreeIterator &rhs) noexcept
DataObjectTreeIterator(SmartIterator &&iter) noexcept
general representation of visualization data
Definition: vtkDataObject.h:54