VTK  9.7.1
vtkDataArrayTupleRange_Generic.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
8 #ifndef vtkDataArrayTupleRange_Generic_h
9 #define vtkDataArrayTupleRange_Generic_h
10 
11 #include "vtkAssume.h"
12 #include "vtkDataArrayMeta.h"
13 
14 #include <algorithm>
15 #include <cassert>
16 #include <iterator>
17 #include <type_traits>
18 
20 
21 namespace vtk
22 {
23 namespace detail
24 {
25 VTK_ABI_NAMESPACE_BEGIN
26 
27 // Forward decs for friends/args
28 template <typename ArrayType, ComponentIdType>
30 template <typename ArrayType, ComponentIdType>
32 template <typename ArrayType, ComponentIdType>
34 template <typename ArrayType, ComponentIdType>
36 template <typename ArrayType, ComponentIdType>
37 struct ConstTupleReference;
38 template <typename ArrayType, ComponentIdType>
39 struct TupleReference;
40 template <typename ArrayType, ComponentIdType>
41 struct ConstTupleIterator;
42 template <typename ArrayType, ComponentIdType>
43 struct TupleIterator;
44 template <typename ArrayType, ComponentIdType>
45 struct TupleRange;
46 
47 //------------------------------------------------------------------------------
48 // Const component reference
49 template <typename ArrayType, ComponentIdType TupleSize>
51 {
52 private:
53  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
54  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
55 
57  using APIType = GetAPIType<ArrayType>;
58 
59 public:
60  using value_type = APIType;
61 
64  : Array{ nullptr }
65  , NumComps{}
66  , TupleId{ 0 }
67  , ComponentId{ 0 }
68  {
69  }
70 
73  ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
74  : Array{ array }
75  , NumComps{ numComps }
76  , TupleId{ tuple }
77  , ComponentId{ comp }
78  {
79  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
80  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
82  tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
83  VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
84  "Invalid component accessed by iterator.");
85  }
86 
89  : Array{ o.Array }
90  , NumComps{ o.NumComps }
91  , TupleId{ o.TupleId }
92  , ComponentId{ o.ComponentId }
93  {
94  }
95 
97  ConstComponentReference(const ConstComponentReference& o) noexcept = default;
98 
100  ConstComponentReference(ConstComponentReference&& o) noexcept = default;
101 
103  ConstComponentReference& operator=(const ConstComponentReference& o) noexcept
104  {
105  VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
106  // Initialize the reference.
107  this->Array = o.Array;
108  this->NumComps = o.NumComps;
109  this->TupleId = o.TupleId;
110  this->ComponentId = o.ComponentId;
111  }
112 
115  {
116  VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
117  // Initialize the reference.
118  this->Array = std::move(o.Array);
119  this->NumComps = std::move(o.NumComps);
120  this->TupleId = o.TupleId;
121  this->ComponentId = o.ComponentId;
122  }
123 
124  VTK_ITER_INLINE operator APIType() const noexcept
125  {
126  VTK_ITER_ASSUME(this->NumComps.value > 0);
127  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
129  {
130  return this->Array->GetComponent(this->TupleId, this->ComponentId);
131  }
132  else
133  {
134  return this->Array->GetTypedComponent(this->TupleId, this->ComponentId);
135  }
136  }
137 
138 protected:
139  mutable ArrayType* Array;
143 };
144 
145 //------------------------------------------------------------------------------
146 // Component reference
147 template <typename ArrayType, ComponentIdType TupleSize>
148 struct ComponentReference
149 {
150 private:
151  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
152  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
153 
154  using NumCompsType = GenericTupleSize<TupleSize>;
155  using APIType = GetAPIType<ArrayType>;
156 
157 public:
158  using value_type = APIType;
159 
162  : Array{ nullptr }
163  , NumComps{}
164  , TupleId{ 0 }
165  , ComponentId{ 0 }
166  {
167  }
168 
171  ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
172  : Array{ array }
173  , NumComps{ numComps }
174  , TupleId{ tuple }
175  , ComponentId{ comp }
176  {
177  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
178  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
180  tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
181  VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
182  "Invalid component accessed by iterator.");
183  }
184 
186  ComponentReference(const ComponentReference& o) noexcept = default;
188  ComponentReference(ComponentReference&& o) noexcept = default;
189 
191  ComponentReference operator=(const ComponentReference& o) noexcept
192  {
193  if (this->Array)
194  { // Already initialized. Assign the value, not the reference
195  return *this = static_cast<APIType>(o);
196  }
197  else
198  { // Initialize the reference.
199  this->Array = o.Array;
200  this->NumComps = o.NumComps;
201  this->TupleId = o.TupleId;
202  this->ComponentId = o.ComponentId;
203 
204  return *this;
205  }
206  }
207 
210  {
211  if (this->Array)
212  { // Already initialized. Assign the value, not the reference
213  return *this = std::move(static_cast<APIType>(o));
214  }
215  else
216  { // Initialize the reference.
217  this->Array = std::move(o.Array);
218  this->NumComps = std::move(o.NumComps);
219  this->TupleId = o.TupleId;
220  this->ComponentId = o.ComponentId;
221 
222  return *this;
223  }
224  }
225 
226  template <typename OArray, ComponentIdType OSize>
228  { // Always copy the value for different reference types:
229  const APIType tmp = o;
230  return *this = std::move(tmp);
231  }
232 
233  VTK_ITER_INLINE operator APIType() const noexcept
234  {
235  VTK_ITER_ASSUME(this->NumComps.value > 0);
236  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
238  {
239  return this->Array->GetComponent(this->TupleId, this->ComponentId);
240  }
241  else
242  {
243  return this->Array->GetTypedComponent(this->TupleId, this->ComponentId);
244  }
245  }
246 
248  {
249  VTK_ITER_ASSUME(this->NumComps.value > 0);
250  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
252  {
253  this->Array->SetComponent(this->TupleId, this->ComponentId, val);
254  }
255  else
256  {
257  this->Array->SetTypedComponent(this->TupleId, this->ComponentId, val);
258  }
259  return *this;
260  }
261 
263  { // Swap values, not references:
264  APIType tmp = static_cast<APIType>(lhs);
265  lhs = static_cast<APIType>(rhs);
266  rhs = std::move(tmp);
267  }
268 
269  template <typename OArray, ComponentIdType OSize>
270  friend VTK_ITER_INLINE void swap(
272  { // Swap values, not references:
273  using OAPIType = GetAPIType<OArray>;
274  static_assert(
275  std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
276 
277  APIType tmp = static_cast<APIType>(lhs);
278  lhs = static_cast<APIType>(rhs);
279  rhs = std::move(tmp);
280  }
281 
282  friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType& rhs) noexcept
283  {
284  APIType tmp = static_cast<APIType>(lhs);
285  lhs = std::move(rhs);
286  rhs = std::move(tmp);
287  }
288 
289  friend VTK_ITER_INLINE void swap(APIType& lhs, ComponentReference rhs) noexcept
290  {
291  APIType tmp = std::move(lhs);
292  lhs = static_cast<APIType>(rhs);
293  rhs = std::move(tmp);
294  }
295 
297  ComponentReference operator++() noexcept // prefix
298  {
299  const APIType newVal = *this + 1;
300  *this = newVal;
301  return *this;
302  }
303 
305  APIType operator++(int) noexcept // postfix
306  {
307  const APIType retVal = *this;
308  *this = *this + 1;
309  return retVal;
310  }
311 
313  ComponentReference operator--() noexcept // prefix
314  {
315  const APIType newVal = *this - 1;
316  *this = newVal;
317  return *this;
318  }
319 
321  APIType operator--(int) noexcept // postfix
322  {
323  const APIType retVal = *this;
324  *this = *this - 1;
325  return retVal;
326  }
327 
328 #define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
329  friend VTK_ITER_INLINE ComponentReference operator Op( \
330  ComponentReference lhs, APIType val) noexcept \
331  { \
332  const APIType newVal = lhs ImplOp val; \
333  lhs = newVal; \
334  return lhs; \
335  } \
336  friend VTK_ITER_INLINE ComponentReference operator Op( \
337  ComponentReference lhs, ComponentReference val) noexcept \
338  { \
339  const APIType newVal = lhs ImplOp val; \
340  lhs = newVal; \
341  return lhs; \
342  } \
343  friend VTK_ITER_INLINE APIType& operator Op(APIType & lhs, ComponentReference val) noexcept \
344  { \
345  const APIType newVal = lhs ImplOp val; \
346  lhs = newVal; \
347  return lhs; \
348  }
349 
350  VTK_REF_OP_OVERLOADS(+=, +)
351  VTK_REF_OP_OVERLOADS(-=, -)
352  VTK_REF_OP_OVERLOADS(*=, *)
353  VTK_REF_OP_OVERLOADS(/=, /)
354  VTK_REF_OP_OVERLOADS(|=, |)
355  VTK_REF_OP_OVERLOADS(&=, &)
356  VTK_REF_OP_OVERLOADS(^=, ^)
357 
358 #undef VTK_REF_OP_OVERLOADS
359 
360  friend struct ConstComponentReference<ArrayType, TupleSize>;
361  friend struct ComponentIterator<ArrayType, TupleSize>;
362 
363 protected:
365  void CopyReference(const ComponentReference& o) noexcept
366  {
367  this->Array = o.Array;
368  this->NumComps = o.NumComps;
369  this->TupleId = o.TupleId;
370  this->ComponentId = o.ComponentId;
371  }
372 
373  mutable ArrayType* Array;
377 };
378 
379 //------------------------------------------------------------------------------
380 // Const component iterator
381 template <typename ArrayType, ComponentIdType TupleSize>
383 {
384 private:
385  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
386  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
387 
388  using NumCompsType = GenericTupleSize<TupleSize>;
389 
390 public:
391  using iterator_category = std::random_access_iterator_tag;
394  using pointer = void;
396 
399  : Array{ nullptr }
400  , TupleId{ 0 }
401  , ComponentId{ 0 }
402  {
403  }
404 
407  ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
408  : Array(array)
409  , NumComps(numComps)
410  , TupleId(tupleId)
411  , ComponentId(comp)
412  {
413  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
414  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
415  VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
416  "Const component iterator at invalid tuple id.");
417  VTK_ITER_ASSERT(comp >= 0 && comp <= this->NumComps.value,
418  "Const component iterator at invalid component id.");
419  }
420 
423  : Array{ o.GetArray() }
424  , NumComps{ o.GetNumComps() }
425  , TupleId{ o.GetTupleId() }
426  , ComponentId{ o.GetComponentId() }
427  {
428  }
429 
431  ConstComponentIterator(const ConstComponentIterator& o) noexcept = default;
433  ConstComponentIterator& operator=(const ConstComponentIterator& o) noexcept = default;
434 
436  ConstComponentIterator& operator++() noexcept // prefix
437  {
438  ++this->ComponentId;
439  VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
440  "Const component iterator at invalid component id.");
441  return *this;
442  }
443 
445  ConstComponentIterator operator++(int) noexcept // postfix
446  {
447  return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
448  this->ComponentId++ };
449  }
450 
452  ConstComponentIterator& operator--() noexcept // prefix
453  {
454  --this->ComponentId;
455  VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
456  "Const component iterator at invalid component id.");
457  return *this;
458  }
459 
461  ConstComponentIterator operator--(int) noexcept // postfix
462  {
463  return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
464  this->ComponentId-- };
465  }
466 
469  {
470  return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
471  }
472 
474  reference operator*() const noexcept
475  {
476  return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
477  }
478 
479 #define VTK_TMP_MAKE_OPERATOR(OP) \
480  friend VTK_ITER_INLINE bool operator OP( \
481  const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
482  { \
483  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
484  VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
485  VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
486  VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
487  return lhs.ComponentId OP rhs.ComponentId; \
488  }
489 
496 
497 #undef VTK_TMP_MAKE_OPERATOR
498 
501  {
502  this->ComponentId += offset;
503  VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
504  "Const component iterator at invalid component id.");
505  return *this;
506  }
507 
509  const ConstComponentIterator& it, difference_type offset) noexcept
510  {
511  return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
512  }
513 
515  difference_type offset, const ConstComponentIterator& it) noexcept
516  {
517  return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
518  }
519 
522  {
523  this->ComponentId -= offset;
524  VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
525  "Const component iterator at invalid component id.");
526  return *this;
527  }
528 
530  const ConstComponentIterator& it, difference_type offset) noexcept
531  {
532  return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId - offset };
533  }
534 
536  const ConstComponentIterator& it1, const ConstComponentIterator& it2) noexcept
537  {
538  VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
539  VTK_ITER_ASSERT(it1.TupleId == it2.TupleId,
540  "Cannot do math with component iterators from different "
541  "tuples.");
542  return it1.ComponentId - it2.ComponentId;
543  }
544 
545  friend VTK_ITER_INLINE void swap(
547  {
548  // Different arrays may use different iterator implementations.
549  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
550 
551  using std::swap;
552  swap(lhs.TupleId, rhs.TupleId);
553  swap(lhs.ComponentId, rhs.ComponentId);
554  }
555 
556 private:
557  mutable ArrayType* Array;
558  NumCompsType NumComps;
559  TupleIdType TupleId;
560  ComponentIdType ComponentId;
561 };
562 
563 //------------------------------------------------------------------------------
564 // Component iterator
565 template <typename ArrayType, ComponentIdType TupleSize>
566 struct ComponentIterator
567 {
568 private:
569  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
570  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
571 
572  using NumCompsType = GenericTupleSize<TupleSize>;
573  using APIType = GetAPIType<ArrayType>;
574 
575 public:
576  using iterator_category = std::random_access_iterator_tag;
577  using value_type = APIType;
581 
583  ComponentIterator() noexcept = default;
584 
587  ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
588  : Ref(array, numComps, tupleId, comp)
589  {
590  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
591  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
592  VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
593  "Component iterator at invalid tuple id.");
595  comp >= 0 && comp <= numComps.value, "Component iterator at invalid component id.");
596  }
597 
599  ComponentIterator(const ComponentIterator& o) noexcept = default;
600 
603  {
604  this->Ref.CopyReference(o.Ref);
605  return *this;
606  }
607 
609  ComponentIterator& operator++() noexcept // prefix
610  {
611  ++this->Ref.ComponentId;
612  VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
613  "Component iterator at invalid component id.");
614  return *this;
615  }
616 
618  ComponentIterator operator++(int) noexcept // postfix
619  {
620  return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
621  this->Ref.ComponentId++ };
622  }
623 
625  ComponentIterator& operator--() noexcept // prefix
626  {
627  --this->Ref.ComponentId;
628  VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
629  "Component iterator at invalid component id.");
630  return *this;
631  }
632 
634  ComponentIterator operator--(int) noexcept // postfix
635  {
636  return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
637  this->Ref.ComponentId-- };
638  }
639 
642  {
643  return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
644  this->Ref.ComponentId + i };
645  }
646 
648  reference operator*() const noexcept { return this->Ref; }
649 
651  const pointer& operator->() const noexcept { return this->Ref; }
652 
653 #define VTK_TMP_MAKE_OPERATOR(OP) \
654  friend VTK_ITER_INLINE bool operator OP( \
655  const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
656  { \
657  VTK_ITER_ASSERT( \
658  lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
659  VTK_ITER_ASSERT( \
660  lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
661  VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
662  VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
663  return lhs.GetComponentId() OP rhs.GetComponentId(); \
664  }
665 
672 
673 #undef VTK_TMP_MAKE_OPERATOR
674 
677  {
678  this->Ref.ComponentId += offset;
679  VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
680  "Component iterator at invalid component id.");
681  return *this;
682  }
683 
685  const ComponentIterator& it, difference_type offset) noexcept
686  {
687  return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
688  it.GetComponentId() + offset };
689  }
690 
692  difference_type offset, const ComponentIterator& it) noexcept
693  {
694  return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
695  it.GetComponentId() + offset };
696  }
697 
700  {
701  this->Ref.ComponentId -= offset;
702  VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
703  "Component iterator at invalid component id.");
704  return *this;
705  }
706 
708  const ComponentIterator& it, difference_type offset) noexcept
709  {
710  return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
711  it.GetComponentId() - offset };
712  }
713 
715  const ComponentIterator& it1, const ComponentIterator& it2) noexcept
716  {
717  VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
718  "Cannot do math with component iterators from different "
719  "arrays.");
720  VTK_ITER_ASSERT(it1.GetTupleId() == it2.GetTupleId(),
721  "Cannot do math with component iterators from different "
722  "tuples.");
723  return it1.GetComponentId() - it2.GetComponentId();
724  }
725 
726  friend VTK_ITER_INLINE void swap(ComponentIterator& lhs, ComponentIterator& rhs) noexcept
727  {
728  // Different arrays may use different iterator implementations.
730  lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
731 
732  using std::swap;
733  swap(lhs.GetTupleId(), rhs.GetTupleId());
734  swap(lhs.GetComponentId(), rhs.GetComponentId());
735  }
736 
737  friend struct ConstComponentIterator<ArrayType, TupleSize>;
738 
739 protected:
740  // Needed for access from friend functions. We could just store the array
741  // and ID here instead of the ref, but meh.
742  ArrayType* GetArray() const noexcept { return this->Ref.Array; }
743  TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
744  const TupleIdType& GetTupleId() const noexcept { return this->Ref.TupleId; }
745  ComponentIdType& GetComponentId() noexcept { return this->Ref.ComponentId; }
746  const ComponentIdType& GetComponentId() const noexcept { return this->Ref.ComponentId; }
747  NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
748  const NumCompsType& GetNumComps() const noexcept { return this->Ref.NumComps; }
749 
751 };
752 
753 //------------------------------------------------------------------------------
754 // Const tuple reference
755 template <typename ArrayType, ComponentIdType TupleSize>
756 struct ConstTupleReference
757 {
758 private:
759  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
760  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
761 
762  using NumCompsType = GenericTupleSize<TupleSize>;
763  using APIType = GetAPIType<ArrayType>;
764 
765 public:
767  using value_type = APIType;
771 
774  : Array(nullptr)
775  , TupleId(0)
776  {
777  }
778 
780  ConstTupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
781  : Array(array)
782  , NumComps(numComps)
783  , TupleId(tupleId)
784  {
785  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
786  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
787  VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
788  "Const tuple reference at invalid tuple id.");
789  }
790 
793  : Array{ o.Array }
794  , NumComps{ o.NumComps }
795  , TupleId{ o.TupleId }
796  {
797  }
798 
800  ConstTupleReference(const ConstTupleReference&) noexcept = default;
802  ConstTupleReference(ConstTupleReference&&) noexcept = default;
803 
804  // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
806  ConstTupleReference* operator->() noexcept { return this; }
808  const ConstTupleReference* operator->() const noexcept { return this; }
809 
810  // Caller must ensure that there are size() elements in array.
811  VTK_ITER_INLINE void GetTuple(APIType* tuple) const noexcept
812  {
813  VTK_ITER_ASSUME(this->NumComps.value > 0);
814  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
816  {
817  this->Array->GetTuple(this->TupleId, tuple);
818  }
819  else
820  {
821  this->Array->GetTypedTuple(this->TupleId, tuple);
822  }
823  }
824 
825  template <typename VT = APIType>
826  typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
827  double* tuple) const noexcept
828  {
829  VTK_ITER_ASSUME(this->NumComps.value > 0);
830  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
832  {
833  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
834  {
835  tuple[comp] = static_cast<double>(this->Array->GetComponent(this->TupleId, comp));
836  }
837  }
838  else
839  {
840  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
841  {
842  tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(this->TupleId, comp));
843  }
844  }
845  }
846 
847  // skips some runtime checks when both sizes are fixed:
848  template <typename OArrayType, ComponentIdType OSize>
850  const TupleReference<OArrayType, OSize>& other) const noexcept
851  {
852  // Check that types are convertible:
853  using OAPIType = GetAPIType<OArrayType>;
854  static_assert(
855  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
856 
857  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
858  static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
859 
860  return std::equal(this->cbegin(), this->cend(), other.cbegin());
861  }
862 
863  // Needs a runtime check:
864  template <typename OArrayType, ComponentIdType OSize>
866  const TupleReference<OArrayType, OSize>& other) const noexcept
867  {
868  // Check that types are convertible:
869  using OAPIType = GetAPIType<OArrayType>;
870  static_assert(
871  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
872 
874  other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
875 
876  return std::equal(this->cbegin(), this->cend(), other.cbegin());
877  }
878 
879  // skips some runtime checks when both sizes are fixed:
880  template <typename OArrayType, ComponentIdType OSize>
882  const ConstTupleReference<OArrayType, OSize>& other) const noexcept
883  {
884  // Check that types are convertible:
885  using OAPIType = GetAPIType<OArrayType>;
886  static_assert(
887  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
888 
889  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
890  static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
891 
892  return std::equal(this->cbegin(), this->cend(), other.cbegin());
893  }
894 
895  // Needs a runtime check:
896  template <typename OArrayType, ComponentIdType OSize>
898  const ConstTupleReference<OArrayType, OSize>& other) const noexcept
899  {
900  // Check that types are convertible:
901  using OAPIType = GetAPIType<OArrayType>;
902  static_assert(
903  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
904 
906  other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
907 
908  return std::equal(this->cbegin(), this->cend(), other.cbegin());
909  }
910 
911  template <typename OArrayType, ComponentIdType OSize>
913  {
914  return !(*this == o);
915  }
916 
917  template <typename OArrayT, ComponentIdType OSize>
919  {
920  return !(*this == o);
921  }
922 
925  {
926  return const_reference{ this->Array, this->NumComps, this->TupleId, i };
927  }
928 
930  size_type size() const noexcept { return this->NumComps.value; }
931 
933  const_iterator begin() const noexcept { return this->NewConstIterator(0); }
935  const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
936 
938  const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
940  const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
941 
942  friend struct ConstTupleIterator<ArrayType, TupleSize>;
943 
944 protected:
945  // Intentionally hidden:
947  ConstTupleReference& operator=(const ConstTupleReference&) noexcept = default;
948 
951  {
952  VTK_ITER_ASSUME(this->NumComps.value > 0);
953  return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
954  }
955 
957  void CopyReference(const ConstTupleReference& o) noexcept
958  {
959  // Must use same array, other array types may use different implementations.
960  VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
961  this->NumComps = o.NumComps;
962  this->TupleId = o.TupleId;
963  }
964 
965  mutable ArrayType* Array;
968 };
969 
970 //------------------------------------------------------------------------------
971 // Tuple reference
972 template <typename ArrayType, ComponentIdType TupleSize>
973 struct TupleReference
974 {
975 private:
976  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
977  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
978 
979  using NumCompsType = GenericTupleSize<TupleSize>;
980  using APIType = GetAPIType<ArrayType>;
981 
982 public:
984  using value_type = APIType;
989 
991  TupleReference() noexcept
992  : Array(nullptr)
993  , TupleId(0)
994  {
995  }
996 
998  TupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
999  : Array(array)
1000  , NumComps(numComps)
1001  , TupleId(tupleId)
1002  {
1003  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1004  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1005  VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1006  "Tuple reference at invalid tuple id.");
1007  }
1008 
1010  TupleReference(const TupleReference&) = default;
1012  TupleReference(TupleReference&&) noexcept = default;
1013 
1014  // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
1016  TupleReference* operator->() noexcept { return this; }
1018  const TupleReference* operator->() const noexcept { return this; }
1019 
1020  // Caller must ensure that there are size() elements in array.
1021  VTK_ITER_INLINE void GetTuple(APIType* tuple) const noexcept
1022  {
1023  VTK_ITER_ASSUME(this->NumComps.value > 0);
1024  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1026  {
1027  this->Array->GetTuple(this->TupleId, tuple);
1028  }
1029  else
1030  {
1031  this->Array->GetTypedTuple(this->TupleId, tuple);
1032  }
1033  }
1034 
1035  template <typename VT = APIType>
1036  typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
1037  double* tuple) const noexcept
1038  {
1039  VTK_ITER_ASSUME(this->NumComps.value > 0);
1040  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1042  {
1043  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1044  {
1045  tuple[comp] = static_cast<double>(this->Array->GetComponent(this->TupleId, comp));
1046  }
1047  }
1048  else
1049  {
1050  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1051  {
1052  tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(this->TupleId, comp));
1053  }
1054  }
1055  }
1056 
1057  // Caller must ensure that there are size() elements in array.
1058  VTK_ITER_INLINE void SetTuple(const APIType* tuple) noexcept
1059  {
1060  VTK_ITER_ASSUME(this->NumComps.value > 0);
1061  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1063  {
1064  this->Array->SetTuple(this->TupleId, tuple);
1065  }
1066  else
1067  {
1068  this->Array->SetTypedTuple(this->TupleId, tuple);
1069  }
1070  }
1071 
1072  template <typename VT = APIType>
1073  typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE SetTuple(
1074  const double* tuple) noexcept
1075  {
1076  VTK_ITER_ASSUME(this->NumComps.value > 0);
1077  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1079  {
1080  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1081  {
1082  this->Array->SetComponent(this->TupleId, comp, static_cast<APIType>(tuple[comp]));
1083  }
1084  }
1085  else
1086  {
1087  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1088  {
1089  this->Array->SetTypedComponent(this->TupleId, comp, static_cast<APIType>(tuple[comp]));
1090  }
1091  }
1092  }
1093 
1095  TupleReference& operator=(const TupleReference& other) noexcept
1096  {
1097  std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1098  return *this;
1099  }
1100 
1101  // skips some runtime checks when both sizes are fixed:
1102  template <typename OArrayType, ComponentIdType OSize>
1104  const TupleReference<OArrayType, OSize>& other) noexcept
1105  {
1106  // Check that types are convertible:
1107  using OAPIType = GetAPIType<OArrayType>;
1108  static_assert(
1109  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1110 
1111  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1112  static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1113 
1114  std::copy_n(other.cbegin(), OSize, this->begin());
1115  return *this;
1116  }
1117 
1118  // Needs a runtime check:
1119  template <typename OArrayType, ComponentIdType OSize>
1121  const TupleReference<OArrayType, OSize>& other) noexcept
1122  {
1123  // Check that types are convertible:
1124  using OAPIType = GetAPIType<OArrayType>;
1125  static_assert(
1126  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1127 
1129  other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1130 
1131  std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1132  return *this;
1133  }
1134 
1135  // skips some runtime checks when both sizes are fixed:
1136  template <typename OArrayType, ComponentIdType OSize>
1138  const ConstTupleReference<OArrayType, OSize>& other) noexcept
1139  {
1140  // Check that types are convertible:
1141  using OAPIType = GetAPIType<OArrayType>;
1142  static_assert(
1143  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1144 
1145  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1146  static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1147 
1148  std::copy_n(other.cbegin(), OSize, this->begin());
1149  return *this;
1150  }
1151 
1152  // Needs a runtime check:
1153  template <typename OArrayType, ComponentIdType OSize>
1155  const ConstTupleReference<OArrayType, OSize>& other) noexcept
1156  {
1157  // Check that types are convertible:
1158  using OAPIType = GetAPIType<OArrayType>;
1159  static_assert(
1160  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1161 
1163  other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1164 
1165  std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1166  return *this;
1167  }
1168 
1169  // skips some runtime checks when both sizes are fixed:
1170  template <typename OArrayType, ComponentIdType OSize>
1172  const TupleReference<OArrayType, OSize>& other) const noexcept
1173  {
1174  // Check that types are convertible:
1175  using OAPIType = GetAPIType<OArrayType>;
1176  static_assert(
1177  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1178 
1179  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1180  static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1181 
1182  return std::equal(this->cbegin(), this->cend(), other.cbegin());
1183  }
1184 
1185  // Needs a runtime check:
1186  template <typename OArrayType, ComponentIdType OSize>
1188  const TupleReference<OArrayType, OSize>& other) const noexcept
1189  {
1190  // Check that types are convertible:
1191  using OAPIType = GetAPIType<OArrayType>;
1192  static_assert(
1193  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1194 
1196  other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1197 
1198  return std::equal(this->cbegin(), this->cend(), other.cbegin());
1199  }
1200 
1201  // skips some runtime checks when both sizes are fixed:
1202  template <typename OArrayType, ComponentIdType OSize>
1204  const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1205  {
1206  // Check that types are convertible:
1207  using OAPIType = GetAPIType<OArrayType>;
1208  static_assert(
1209  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1210 
1211  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1212  static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1213 
1214  return std::equal(this->cbegin(), this->cend(), other.cbegin());
1215  }
1216 
1217  // Needs a runtime check:
1218  template <typename OArrayType, ComponentIdType OSize>
1220  const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1221  {
1222  // Check that types are convertible:
1223  using OAPIType = GetAPIType<OArrayType>;
1224  static_assert(
1225  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1226 
1228  other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1229 
1230  return std::equal(this->cbegin(), this->cend(), other.cbegin());
1231  }
1232 
1233  template <typename OArrayType, ComponentIdType OSize>
1235  {
1236  return !(*this == o);
1237  }
1238 
1239  template <typename OArray, ComponentIdType OSize>
1241  {
1242  return !(*this == o);
1243  }
1244 
1245  // skips some runtime checks:
1246  template <typename OArrayType, ComponentIdType OSize>
1248  TupleReference<OArrayType, OSize> other) noexcept
1249  {
1250  // Check that types are convertible:
1251  using OAPIType = GetAPIType<OArrayType>;
1252  static_assert(
1253  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1254 
1255  // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1256  static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
1257 
1258  std::swap_ranges(this->begin(), this->end(), other.begin());
1259  }
1260 
1261  // Needs a runtime check:
1262  template <typename OArrayType, ComponentIdType OSize>
1264  TupleReference<OArrayType, OSize> other) noexcept
1265  {
1266  // Check that types are convertible:
1267  using OAPIType = GetAPIType<OArrayType>;
1268  static_assert(
1269  (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1270 
1272  other.size() == this->NumComps.value, "Cannot swap tuples with different sizes.");
1273 
1274  std::swap_ranges(this->begin(), this->end(), other.begin());
1275  }
1276 
1277  friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
1278 
1279  template <typename OArray, ComponentIdType OSize>
1281  {
1282  a.swap(b);
1283  }
1284 
1287  {
1288  return reference{ this->Array, this->NumComps, this->TupleId, i };
1289  }
1290 
1293  {
1294  // Let the reference type do the lookup during implicit conversion.
1295  return const_reference{ this->Array, this->NumComps, this->TupleId, i };
1296  }
1297 
1299  void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
1300 
1302  size_type size() const noexcept { return this->NumComps.value; }
1303 
1305  iterator begin() noexcept { return this->NewIterator(0); }
1307  iterator end() noexcept { return this->NewIterator(this->NumComps.value); }
1308 
1310  const_iterator begin() const noexcept { return this->NewConstIterator(0); }
1312  const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1313 
1315  const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
1317  const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1318 
1319  friend struct ConstTupleReference<ArrayType, TupleSize>;
1320  friend struct TupleIterator<ArrayType, TupleSize>;
1321 
1322 protected:
1324  iterator NewIterator(ComponentIdType comp) const noexcept
1325  {
1326  VTK_ITER_ASSUME(this->NumComps.value > 0);
1327  return iterator{ this->Array, this->NumComps, this->TupleId, comp };
1328  }
1329 
1332  {
1333  VTK_ITER_ASSUME(this->NumComps.value > 0);
1334  return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
1335  }
1336 
1338  void CopyReference(const TupleReference& o) noexcept
1339  {
1340  // Must use same array, other array types may use different implementations.
1341  VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
1342  this->NumComps = o.NumComps;
1343  this->TupleId = o.TupleId;
1344  }
1345 
1346  mutable ArrayType* Array;
1349 };
1350 
1351 //------------------------------------------------------------------------------
1352 // Const tuple iterator
1353 template <typename ArrayType, ComponentIdType TupleSize>
1354 struct ConstTupleIterator
1355 {
1356 private:
1357  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1358  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
1359 
1360  using NumCompsType = GenericTupleSize<TupleSize>;
1361 
1362 public:
1363  using iterator_category = std::random_access_iterator_tag;
1368 
1370  ConstTupleIterator() noexcept = default;
1371 
1373  ConstTupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1374  : Ref(array, numComps, tupleId)
1375  {
1376  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1377  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1378  VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1379  "Const tuple iterator at invalid tuple id.");
1380  }
1381 
1384  : Ref{ o.Ref }
1385  {
1386  }
1387 
1389  ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
1392  {
1393  this->Ref.CopyReference(o.Ref);
1394  return *this;
1395  }
1396 
1398  ConstTupleIterator& operator++() noexcept // prefix
1399  {
1400  ++this->Ref.TupleId;
1402  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1403  "Const tuple iterator at invalid component id.");
1404  return *this;
1405  }
1406 
1408  ConstTupleIterator operator++(int) noexcept // postfix
1409  {
1410  return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1411  }
1412 
1414  ConstTupleIterator& operator--() noexcept // prefix
1415  {
1416  --this->Ref.TupleId;
1418  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1419  "Const tuple iterator at invalid component id.");
1420  return *this;
1421  }
1422 
1424  ConstTupleIterator operator--(int) noexcept // postfix
1425  {
1426  return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1427  }
1428 
1431  {
1432  return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1433  }
1434 
1436  reference operator*() noexcept { return this->Ref; }
1437 
1439  pointer operator->() noexcept { return this->Ref; }
1440 
1441 #define VTK_TMP_MAKE_OPERATOR(OP) \
1442  friend VTK_ITER_INLINE bool operator OP( \
1443  const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1444  { \
1445  VTK_ITER_ASSERT( \
1446  lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1447  VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1448  VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1449  return lhs.GetTupleId() OP rhs.GetTupleId(); \
1450  }
1451 
1458 
1459 #undef VTK_TMP_MAKE_OPERATOR
1460 
1463  {
1464  this->Ref.TupleId += offset;
1466  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1467  "Const tuple iterator at invalid component id.");
1468  return *this;
1469  }
1470 
1472  const ConstTupleIterator& it, difference_type offset) noexcept
1473  {
1474  return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1475  }
1476 
1478  difference_type offset, const ConstTupleIterator& it) noexcept
1479  {
1480  return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1481  }
1482 
1485  {
1486  this->Ref.TupleId -= offset;
1488  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1489  "Const tuple iterator at invalid component id.");
1490  return *this;
1491  }
1492 
1494  const ConstTupleIterator& it, difference_type offset) noexcept
1495  {
1496  return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1497  }
1498 
1500  const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
1501  {
1502  VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1503  "Cannot do math with tuple iterators from different "
1504  "arrays.");
1505  return it1.GetTupleId() - it2.GetTupleId();
1506  }
1507 
1509  {
1510  // Different arrays may use different iterator implementations.
1512  lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1513 
1514  using std::swap;
1515  swap(lhs.GetTupleId(), rhs.GetTupleId());
1516  }
1517 
1518 private:
1520  ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1522  ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1524  NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1526  NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1528  TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1530  TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1531 
1532  ConstTupleReference<ArrayType, TupleSize> Ref;
1533 };
1534 
1535 //------------------------------------------------------------------------------
1536 // Tuple iterator
1537 template <typename ArrayType, ComponentIdType TupleSize>
1538 struct TupleIterator
1539 {
1540 private:
1541  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1542  static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
1543 
1544  using NumCompsType = GenericTupleSize<TupleSize>;
1545 
1546 public:
1547  using iterator_category = std::random_access_iterator_tag;
1552 
1554  TupleIterator() noexcept = default;
1555 
1557  TupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1558  : Ref(array, numComps, tupleId)
1559  {
1560  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1561  VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1563  tupleId >= 0 && tupleId <= array->GetNumberOfTuples(), "Tuple iterator at invalid tuple id.");
1564  }
1565 
1567  TupleIterator(const TupleIterator& o) noexcept = default;
1568 
1571  {
1572  this->Ref.CopyReference(o.Ref);
1573  return *this;
1574  }
1575 
1577  TupleIterator& operator++() noexcept // prefix
1578  {
1579  ++this->Ref.TupleId;
1581  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1582  "Tuple iterator at invalid component id.");
1583  return *this;
1584  }
1585 
1587  TupleIterator operator++(int) noexcept // postfix
1588  {
1589  return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1590  }
1591 
1593  TupleIterator& operator--() noexcept // prefix
1594  {
1595  --this->Ref.TupleId;
1597  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1598  "Tuple iterator at invalid component id.");
1599  return *this;
1600  }
1601 
1603  TupleIterator operator--(int) noexcept // postfix
1604  {
1605  return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1606  }
1607 
1610  {
1611  return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId + i };
1612  }
1613 
1615  reference operator*() noexcept { return this->Ref; }
1616 
1618  pointer& operator->() noexcept { return this->Ref; }
1619 
1620 #define VTK_TMP_MAKE_OPERATOR(OP) \
1621  friend VTK_ITER_INLINE bool operator OP( \
1622  const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1623  { \
1624  VTK_ITER_ASSERT( \
1625  lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1626  VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1627  VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1628  return lhs.GetTupleId() OP rhs.GetTupleId(); \
1629  }
1630 
1637 
1638 #undef VTK_TMP_MAKE_OPERATOR
1639 
1642  {
1643  this->Ref.TupleId += offset;
1645  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1646  "Tuple iterator at invalid component id.");
1647  return *this;
1648  }
1649 
1651  const TupleIterator& it, difference_type offset) noexcept
1652  {
1653  return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1654  }
1655 
1657  difference_type offset, const TupleIterator& it) noexcept
1658  {
1659  return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1660  }
1661 
1664  {
1665  this->Ref.TupleId -= offset;
1667  this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1668  "Tuple iterator at invalid component id.");
1669  return *this;
1670  }
1671 
1673  const TupleIterator& it, difference_type offset) noexcept
1674  {
1675  return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1676  }
1677 
1679  const TupleIterator& it1, const TupleIterator& it2) noexcept
1680  {
1681  VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1682  "Cannot do math with tuple iterators from different "
1683  "arrays.");
1684  return it1.GetTupleId() - it2.GetTupleId();
1685  }
1686 
1687  friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
1688  {
1689  // Different arrays may use different iterator implementations.
1691  lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1692 
1693  using std::swap;
1694  swap(lhs.GetTupleId(), rhs.GetTupleId());
1695  }
1696 
1697  friend struct ConstTupleIterator<ArrayType, TupleSize>;
1698  friend struct ConstTupleReference<ArrayType, TupleSize>;
1699 
1700 protected:
1702  ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1704  ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1706  NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1708  NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1710  TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1712  TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1713 
1715 };
1716 
1717 //------------------------------------------------------------------------------
1718 // Tuple range
1719 template <typename ArrayTypeT, ComponentIdType TupleSize>
1720 struct TupleRange
1721 {
1722  using ArrayType = ArrayTypeT;
1725 
1726 private:
1727  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1728  static_assert(IsVtkArray<ArrayTypeT>::value, "Invalid array type.");
1729 
1731 
1732 public:
1742 
1743  // May be DynamicTupleSize, or the actual tuple size.
1744  constexpr static ComponentIdType TupleSizeTag = TupleSize;
1745 
1751 
1753  TupleRange() noexcept = default;
1754 
1756  TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
1757  : Array(arr)
1758  , NumComps(arr)
1759  , BeginTuple(beginTuple)
1760  , EndTuple(endTuple)
1761  {
1762  assert(this->Array);
1763  assert(beginTuple >= 0 && beginTuple <= endTuple);
1764  assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1766  {
1767  assert(arr->GetNumberOfComponents() == TupleSize);
1768  }
1769  }
1770 
1772  TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1773  {
1774  const TupleIdType realBegin = this->BeginTuple + beginTuple;
1775  const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1776 
1777  return TupleRange{ this->Array, realBegin, realEnd };
1778  }
1779 
1781  ArrayType* GetArray() const noexcept { return this->Array; }
1783  ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1785  TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1787  TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1788 
1790  size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1791 
1793  iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1795  iterator end() noexcept { return this->NewIter(this->EndTuple); }
1796 
1798  const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1800  const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1801 
1803  const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1805  const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1806 
1809  {
1810  return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1811  }
1812 
1815  {
1816  return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1817  }
1818 
1819  void VTK_ITER_INLINE GetTuple(size_type i, ValueType* tuple) const noexcept
1820  {
1822  {
1823  this->Array->GetTuple(this->BeginTuple + i, tuple);
1824  }
1825  else
1826  {
1827  this->Array->GetTypedTuple(this->BeginTuple + i, tuple);
1828  }
1829  }
1830 
1831  template <typename VT = APIType>
1832  typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
1833  size_type i, double* tuple) const noexcept
1834  {
1836  {
1837  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1838  {
1839  tuple[comp] = static_cast<double>(this->Array->GetComponent(i, comp));
1840  }
1841  }
1842  else
1843  {
1844  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1845  {
1846  tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(i, comp));
1847  }
1848  }
1849  }
1850 
1851  void VTK_ITER_INLINE SetTuple(size_type i, const ValueType* tuple) noexcept
1852  {
1854  {
1855  this->Array->SetTuple(this->BeginTuple + i, tuple);
1856  }
1857  else
1858  {
1859  this->Array->SetTypedTuple(this->BeginTuple + i, tuple);
1860  }
1861  }
1862 
1863  template <typename VT = APIType>
1864  typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE SetTuple(
1865  size_type i, const double* tuple) noexcept
1866  {
1868  {
1869  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1870  {
1871  this->Array->SetComponent(this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1872  }
1873  }
1874  else
1875  {
1876  for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1877  {
1878  this->Array->SetTypedComponent(
1879  this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1880  }
1881  }
1882  }
1883 
1884 private:
1886  iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1887 
1889  const_iterator NewCIter(TupleIdType t) const
1890  {
1891  return const_iterator{ this->Array, this->NumComps, t };
1892  }
1893 
1894  mutable ArrayType* Array{ nullptr };
1895  NumCompsType NumComps{};
1896  TupleIdType BeginTuple{ 0 };
1897  TupleIdType EndTuple{ 0 };
1898 };
1899 
1900 // Unimplemented, only used inside decltype in SelectTupleRange:
1901 template <typename ArrayType, ComponentIdType TupleSize>
1902 TupleRange<ArrayType, TupleSize> DeclareTupleRangeSpecialization(vtkAbstractArray*);
1903 
1904 VTK_ABI_NAMESPACE_END
1905 } // end namespace detail
1906 } // end namespace vtk
1907 
1909 
1910 #endif // __VTK_WRAP__
1911 
1912 // VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_Generic.h
const NumCompsType & GetNumComps() const noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, ComponentReference rhs) noexcept
VTK_ITER_INLINE APIType operator--(int) noexcept
VTK_ITER_INLINE void CopyReference(const TupleReference &o) noexcept
friend VTK_ITER_INLINE void swap(ComponentIterator &lhs, ComponentIterator &rhs) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
TupleReference< ArrayType, TupleSize > TupleReferenceType
VTK_ITER_INLINE TupleReference() noexcept
friend VTK_ITER_INLINE ComponentIterator operator+(const ComponentIterator &it, difference_type offset) noexcept
friend VTK_ITER_INLINE void swap(ConstComponentIterator &lhs, ConstComponentIterator &rhs) noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator+(difference_type offset, const ConstComponentIterator &it) noexcept
void VTK_ITER_INLINE GetTuple(size_type i, ValueType *tuple) const noexcept
VTK_ITER_INLINE iterator end() noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator-(const ConstTupleIterator &it, difference_type offset) noexcept
const TupleIdType & GetTupleId() const noexcept
VTK_ITER_INLINE const pointer & operator->() const noexcept
vtkIdType TupleIdType
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
VTK_ITER_INLINE ConstComponentIterator(ArrayType *array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
int ComponentIdType
friend VTK_ITER_INLINE ComponentIterator operator+(difference_type offset, const ComponentIterator &it) noexcept
VTK_ITER_INLINE APIType operator++(int) noexcept
VTK_ITER_INLINE reference operator*() const noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator+(const ConstComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE pointer & operator->() noexcept
std::enable_if_t< IsEitherTupleSizeDynamic< S1, S2 >::value, T > EnableIfEitherTupleSizeIsDynamic
VTK_ITER_INLINE TupleIterator & operator--() noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(size_type i, double *tuple) const noexcept
TupleReference< ArrayType, TupleSize > Ref
friend VTK_ITER_INLINE ConstTupleIterator operator+(difference_type offset, const ConstTupleIterator &it) noexcept
friend VTK_ITER_INLINE TupleIterator operator-(const TupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE TupleRange() noexcept=default
VTK_ITER_INLINE void CopyReference(const ComponentReference &o) noexcept
VTK_ITER_INLINE NumCompsType GetNumComps() const noexcept
Abstract superclass for all arrays.
VTK_ITER_INLINE const_iterator begin() const noexcept
friend VTK_ITER_INLINE void swap(TupleIterator &lhs, TupleIterator &rhs) noexcept
VTK_ITER_INLINE void GetTuple(APIType *tuple) const noexcept
typename detail::GetAPITypeImpl< ArrayType, ForceValueTypeForVtkDataArray >::APIType GetAPIType
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE iterator NewIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE ConstTupleReference(const TupleReference< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE ConstComponentIterator operator--(int) noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE ComponentReference operator--() noexcept
VTK_ITER_INLINE ConstTupleIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
friend VTK_ITER_INLINE TupleIterator operator+(const TupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE TupleReference & operator=(const TupleReference &other) noexcept
VTK_ITER_INLINE ConstTupleIterator(const TupleIterator< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE ConstComponentReference(const ComponentReference< ArrayType, TupleSize > &o)
VTK_ITER_INLINE ComponentReference(ArrayType *array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE ConstTupleIterator() noexcept=default
friend VTK_ITER_INLINE TupleIterator operator+(difference_type offset, const TupleIterator &it) noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
friend VTK_ITER_INLINE difference_type operator-(const TupleIterator &it1, const TupleIterator &it2) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator=(const ConstTupleIterator &o) noexcept
VTK_ITER_INLINE iterator begin() noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstTupleIterator &it1, const ConstTupleIterator &it2) noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE TupleRange GetSubRange(TupleIdType beginTuple=0, TupleIdType endTuple=-1) const noexcept
VTK_ITER_INLINE ConstComponentIterator & operator--() noexcept
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE const_iterator NewConstIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE TupleIdType & GetTupleId() noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator+(const ConstTupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE NumCompsType & GetNumComps() noexcept
VTK_ITER_INLINE ConstComponentIterator operator++(int) noexcept
VTK_ITER_INLINE ComponentReference operator=(const ComponentReference< OArray, OSize > &o) noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArrayT, OSize > &o) const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
This file contains a variety of metaprogramming constructs for working with vtkDataArrays.
friend VTK_ITER_INLINE void swap(APIType &lhs, ComponentReference rhs) noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
#define VTK_ITER_INLINE
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE ArrayType *& GetArray() noexcept
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference< OArray, OSize > b) noexcept
VTK_ITER_INLINE ConstTupleIterator operator--(int) noexcept
const ComponentIdType & GetComponentId() const noexcept
VTK_ITER_INLINE reference operator*() const noexcept
VTK_ITER_INLINE ConstComponentReference(ArrayType *array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE SetTuple(size_type i, const double *tuple) noexcept
friend VTK_ITER_INLINE ComponentIterator operator-(const ComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE TupleIterator operator--(int) noexcept
VTK_ITER_INLINE pointer operator->() noexcept
VTK_ITER_INLINE ComponentIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE TupleIdType GetTupleId() const noexcept
#define VTK_ITER_ASSUME
VTK_ITER_INLINE const TupleReference * operator->() const noexcept
VTK_ITER_INLINE ConstTupleIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE ComponentIterator operator++(int) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) noexcept
VTK_ITER_INLINE TupleIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE TupleReference(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
void VTK_ITER_INLINE SetTuple(size_type i, const ValueType *tuple) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
#define VTK_ITER_OPTIMIZE_END
static constexpr ComponentIdType TupleSizeTag
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(double *tuple) const noexcept
friend VTK_ITER_INLINE void swap(ConstTupleIterator &lhs, ConstTupleIterator &rhs) noexcept
TupleIterator< ArrayType, TupleSize > TupleIteratorType
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE ConstComponentIterator & operator=(const ConstComponentIterator &o) noexcept=default
VTK_ITER_INLINE iterator end() noexcept
VTK_ITER_INLINE const_iterator NewConstIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE void GetTuple(APIType *tuple) const noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE const_iterator begin() const noexcept
VTK_ITER_INLINE ConstComponentIterator & operator+=(difference_type offset) noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator-(const ConstComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE void SetTuple(const APIType *tuple) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ConstComponentReference & operator=(ConstComponentReference &&o) noexcept
VTK_ITER_INLINE TupleIterator() noexcept=default
ComponentIdType & GetComponentId() noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE const_iterator begin() const noexcept
VTK_ITER_INLINE ConstComponentIterator(const ComponentIterator< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) noexcept
VTK_ITER_INLINE ComponentReference operator=(APIType val) noexcept
VTK_ITER_INLINE ComponentReference operator++() noexcept
ComponentReference< ArrayType, TupleSize > Ref
VTK_ITER_INLINE ComponentIterator() noexcept=default
VTK_ITER_INLINE ConstTupleIterator & operator++() noexcept
VTK_ITER_INLINE ConstTupleReference(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE ConstTupleIterator operator++(int) noexcept
VTK_ITER_INLINE reference operator*() noexcept
VTK_ITER_INLINE size_type size() const noexcept
#define VTK_ITER_ASSERT(x, msg)
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
ConstTupleIterator< ArrayType, TupleSize > ConstTupleIteratorType
VTK_ITER_INLINE ConstTupleIterator & operator--() noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE TupleIterator & operator=(const TupleIterator &o) noexcept
VTK_ITER_INLINE ConstComponentIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
#define VTK_TMP_MAKE_OPERATOR(OP)
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE TupleIterator & operator++() noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const ConstTupleReference * operator->() const noexcept
VTK_ITER_INLINE void CopyReference(const ConstTupleReference &o) noexcept
VTK_ITER_INLINE void fill(const value_type &v) noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE TupleIdType GetEndTupleId() const noexcept
VTK_ITER_INLINE iterator begin() noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstComponentIterator &it1, const ConstComponentIterator &it2) noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, ComponentReference< OArray, OSize > rhs) noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE SetTuple(const double *tuple) noexcept
VTK_ITER_INLINE TupleIterator operator++(int) noexcept
VTK_ITER_INLINE ComponentIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE difference_type operator-(const ComponentIterator &it1, const ComponentIterator &it2) noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
std::random_access_iterator_tag iterator_category
ConstTupleReference< ArrayType, TupleSize > ConstTupleReferenceType
VTK_ITER_INLINE ComponentIterator operator--(int) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
Compiler hint macros for assumptions and branch prediction.
VTK_ITER_INLINE TupleIterator & operator+=(difference_type offset) noexcept
#define VTK_ITER_OPTIMIZE_START
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(double *tuple) const noexcept
VTK_ITER_INLINE ConstTupleReference & operator=(const ConstTupleReference &) noexcept=default
VTK_ITER_INLINE ConstComponentIterator & operator++() noexcept
VTK_ITER_INLINE ComponentIterator & operator=(const ComponentIterator &o) noexcept
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept
VTK_ITER_INLINE TupleIdType GetBeginTupleId() const noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType &rhs) noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
#define VTK_REF_OP_OVERLOADS(Op, ImplOp)
VTK_ITER_INLINE reference operator*() noexcept
VTK_ITER_INLINE ComponentIterator & operator--() noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE ComponentIterator & operator++() noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArray, OSize > &o) const noexcept
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
VTK_ITER_INLINE ComponentReference operator=(ComponentReference &&o) noexcept