VTK  9.6.20260220
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
7
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
21namespace vtk
22{
23namespace detail
24{
25VTK_ABI_NAMESPACE_BEGIN
26
27// Forward decs for friends/args
28template <typename ArrayType, ComponentIdType>
30template <typename ArrayType, ComponentIdType>
32template <typename ArrayType, ComponentIdType>
34template <typename ArrayType, ComponentIdType>
36template <typename ArrayType, ComponentIdType>
38template <typename ArrayType, ComponentIdType>
39struct TupleReference;
40template <typename ArrayType, ComponentIdType>
42template <typename ArrayType, ComponentIdType>
43struct TupleIterator;
44template <typename ArrayType, ComponentIdType>
45struct TupleRange;
46
47//------------------------------------------------------------------------------
48// Const component reference
49template <typename ArrayType, ComponentIdType TupleSize>
51{
52private:
53 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
54 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
55
56 using NumCompsType = GenericTupleSize<TupleSize>;
57 using APIType = GetAPIType<ArrayType>;
58
59public:
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
95
98
101
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);
128 if constexpr (std::is_same<ArrayType, vtkDataArray>::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
138protected:
139 mutable ArrayType* Array;
140 NumCompsType NumComps;
143};
144
145//------------------------------------------------------------------------------
146// Component reference
147template <typename ArrayType, ComponentIdType TupleSize>
149{
150private:
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
157public:
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
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);
237 if constexpr (std::is_same<ArrayType, vtkDataArray>::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);
251 if constexpr (std::is_same<ArrayType, vtkDataArray>::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>
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
354
355#undef VTK_REF_OP_OVERLOADS
356
357 friend struct ConstComponentReference<ArrayType, TupleSize>;
358 friend struct ComponentIterator<ArrayType, TupleSize>;
359
360protected:
362 void CopyReference(const ComponentReference& o) noexcept
363 {
364 this->Array = o.Array;
365 this->NumComps = o.NumComps;
366 this->TupleId = o.TupleId;
367 this->ComponentId = o.ComponentId;
368 }
369
370 mutable ArrayType* Array;
371 NumCompsType NumComps;
374};
375
376//------------------------------------------------------------------------------
377// Const component iterator
378template <typename ArrayType, ComponentIdType TupleSize>
380{
381private:
382 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
383 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
384
385 using NumCompsType = GenericTupleSize<TupleSize>;
386
387public:
388 using iterator_category = std::random_access_iterator_tag;
391 using pointer = void;
393
396 : Array{ nullptr }
397 , TupleId{ 0 }
398 , ComponentId{ 0 }
399 {
400 }
401
404 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
405 : Array(array)
406 , NumComps(numComps)
407 , TupleId(tupleId)
408 , ComponentId(comp)
409 {
410 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
411 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
412 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
413 "Const component iterator at invalid tuple id.");
414 VTK_ITER_ASSERT(comp >= 0 && comp <= this->NumComps.value,
415 "Const component iterator at invalid component id.");
416 }
417
420 : Array{ o.GetArray() }
421 , NumComps{ o.GetNumComps() }
422 , TupleId{ o.GetTupleId() }
423 , ComponentId{ o.GetComponentId() }
424 {
425 }
426
428 ConstComponentIterator(const ConstComponentIterator& o) noexcept = default;
431
433 ConstComponentIterator& operator++() noexcept // prefix
434 {
435 ++this->ComponentId;
436 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
437 "Const component iterator at invalid component id.");
438 return *this;
439 }
440
442 ConstComponentIterator operator++(int) noexcept // postfix
443 {
444 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
445 this->ComponentId++ };
446 }
447
449 ConstComponentIterator& operator--() noexcept // prefix
450 {
451 --this->ComponentId;
452 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
453 "Const component iterator at invalid component id.");
454 return *this;
455 }
456
458 ConstComponentIterator operator--(int) noexcept // postfix
459 {
460 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
461 this->ComponentId-- };
462 }
463
466 {
467 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
468 }
469
471 reference operator*() const noexcept
472 {
473 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
474 }
475
476#define VTK_TMP_MAKE_OPERATOR(OP) \
477 friend VTK_ITER_INLINE bool operator OP( \
478 const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
479 { \
480 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
481 VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
482 VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
483 VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
484 return lhs.ComponentId OP rhs.ComponentId; \
485 }
486
493
494#undef VTK_TMP_MAKE_OPERATOR
495
498 {
499 this->ComponentId += offset;
500 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
501 "Const component iterator at invalid component id.");
502 return *this;
503 }
504
506 const ConstComponentIterator& it, difference_type offset) noexcept
507 {
508 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
509 }
510
512 difference_type offset, const ConstComponentIterator& it) noexcept
513 {
514 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
515 }
516
519 {
520 this->ComponentId -= offset;
521 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
522 "Const component iterator at invalid component id.");
523 return *this;
524 }
525
527 const ConstComponentIterator& it, difference_type offset) noexcept
528 {
529 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId - offset };
530 }
531
533 const ConstComponentIterator& it1, const ConstComponentIterator& it2) noexcept
534 {
535 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
536 VTK_ITER_ASSERT(it1.TupleId == it2.TupleId,
537 "Cannot do math with component iterators from different "
538 "tuples.");
539 return it1.ComponentId - it2.ComponentId;
540 }
541
544 {
545 // Different arrays may use different iterator implementations.
546 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
547
548 using std::swap;
549 swap(lhs.TupleId, rhs.TupleId);
550 swap(lhs.ComponentId, rhs.ComponentId);
551 }
552
553private:
554 mutable ArrayType* Array;
555 NumCompsType NumComps;
556 TupleIdType TupleId;
557 ComponentIdType ComponentId;
558};
559
560//------------------------------------------------------------------------------
561// Component iterator
562template <typename ArrayType, ComponentIdType TupleSize>
564{
565private:
566 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
567 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
568
569 using NumCompsType = GenericTupleSize<TupleSize>;
570 using APIType = GetAPIType<ArrayType>;
571
572public:
573 using iterator_category = std::random_access_iterator_tag;
574 using value_type = APIType;
578
580 ComponentIterator() noexcept = default;
581
584 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
585 : Ref(array, numComps, tupleId, comp)
586 {
587 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
588 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
589 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
590 "Component iterator at invalid tuple id.");
592 comp >= 0 && comp <= numComps.value, "Component iterator at invalid component id.");
593 }
594
596 ComponentIterator(const ComponentIterator& o) noexcept = default;
597
600 {
601 this->Ref.CopyReference(o.Ref);
602 return *this;
603 }
604
606 ComponentIterator& operator++() noexcept // prefix
607 {
608 ++this->Ref.ComponentId;
609 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
610 "Component iterator at invalid component id.");
611 return *this;
612 }
613
615 ComponentIterator operator++(int) noexcept // postfix
616 {
617 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
618 this->Ref.ComponentId++ };
619 }
620
622 ComponentIterator& operator--() noexcept // prefix
623 {
624 --this->Ref.ComponentId;
625 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
626 "Component iterator at invalid component id.");
627 return *this;
628 }
629
631 ComponentIterator operator--(int) noexcept // postfix
632 {
633 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
634 this->Ref.ComponentId-- };
635 }
636
639 {
640 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
641 this->Ref.ComponentId + i };
642 }
643
645 reference operator*() const noexcept { return this->Ref; }
646
648 const pointer& operator->() const noexcept { return this->Ref; }
649
650#define VTK_TMP_MAKE_OPERATOR(OP) \
651 friend VTK_ITER_INLINE bool operator OP( \
652 const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
653 { \
654 VTK_ITER_ASSERT( \
655 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
656 VTK_ITER_ASSERT( \
657 lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
658 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
659 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
660 return lhs.GetComponentId() OP rhs.GetComponentId(); \
661 }
662
669
670#undef VTK_TMP_MAKE_OPERATOR
671
674 {
675 this->Ref.ComponentId += offset;
676 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
677 "Component iterator at invalid component id.");
678 return *this;
679 }
680
682 const ComponentIterator& it, difference_type offset) noexcept
683 {
684 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
685 it.GetComponentId() + offset };
686 }
687
689 difference_type offset, const ComponentIterator& it) noexcept
690 {
691 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
692 it.GetComponentId() + offset };
693 }
694
697 {
698 this->Ref.ComponentId -= offset;
699 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
700 "Component iterator at invalid component id.");
701 return *this;
702 }
703
705 const ComponentIterator& it, difference_type offset) noexcept
706 {
707 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
708 it.GetComponentId() - offset };
709 }
710
712 const ComponentIterator& it1, const ComponentIterator& it2) noexcept
713 {
714 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
715 "Cannot do math with component iterators from different "
716 "arrays.");
717 VTK_ITER_ASSERT(it1.GetTupleId() == it2.GetTupleId(),
718 "Cannot do math with component iterators from different "
719 "tuples.");
720 return it1.GetComponentId() - it2.GetComponentId();
721 }
722
724 {
725 // Different arrays may use different iterator implementations.
727 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
728
729 using std::swap;
730 swap(lhs.GetTupleId(), rhs.GetTupleId());
731 swap(lhs.GetComponentId(), rhs.GetComponentId());
732 }
733
734 friend struct ConstComponentIterator<ArrayType, TupleSize>;
735
736protected:
737 // Needed for access from friend functions. We could just store the array
738 // and ID here instead of the ref, but meh.
739 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
740 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
741 const TupleIdType& GetTupleId() const noexcept { return this->Ref.TupleId; }
742 ComponentIdType& GetComponentId() noexcept { return this->Ref.ComponentId; }
743 const ComponentIdType& GetComponentId() const noexcept { return this->Ref.ComponentId; }
744 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
745 const NumCompsType& GetNumComps() const noexcept { return this->Ref.NumComps; }
746
748};
749
750//------------------------------------------------------------------------------
751// Const tuple reference
752template <typename ArrayType, ComponentIdType TupleSize>
754{
755private:
756 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
757 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
758
759 using NumCompsType = GenericTupleSize<TupleSize>;
760 using APIType = GetAPIType<ArrayType>;
761
762public:
764 using value_type = APIType;
768
771 : Array(nullptr)
772 , TupleId(0)
773 {
774 }
775
777 ConstTupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
778 : Array(array)
779 , NumComps(numComps)
780 , TupleId(tupleId)
781 {
782 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
783 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
784 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
785 "Const tuple reference at invalid tuple id.");
786 }
787
790 : Array{ o.Array }
791 , NumComps{ o.NumComps }
792 , TupleId{ o.TupleId }
793 {
794 }
795
797 ConstTupleReference(const ConstTupleReference&) noexcept = default;
800
801 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
803 ConstTupleReference* operator->() noexcept { return this; }
805 const ConstTupleReference* operator->() const noexcept { return this; }
806
807 // Caller must ensure that there are size() elements in array.
808 VTK_ITER_INLINE void GetTuple(APIType* tuple) const noexcept
809 {
810 VTK_ITER_ASSUME(this->NumComps.value > 0);
811 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
812 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
813 {
814 this->Array->GetTuple(this->TupleId, tuple);
815 }
816 else
817 {
818 this->Array->GetTypedTuple(this->TupleId, tuple);
819 }
820 }
821
822 template <typename VT = APIType>
823 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
824 double* tuple) const noexcept
825 {
826 VTK_ITER_ASSUME(this->NumComps.value > 0);
827 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
828 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
829 {
830 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
831 {
832 tuple[comp] = static_cast<double>(this->Array->GetComponent(this->TupleId, comp));
833 }
834 }
835 else
836 {
837 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
838 {
839 tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(this->TupleId, comp));
840 }
841 }
842 }
843
844 // skips some runtime checks when both sizes are fixed:
845 template <typename OArrayType, ComponentIdType OSize>
847 const TupleReference<OArrayType, OSize>& other) const noexcept
848 {
849 // Check that types are convertible:
850 using OAPIType = GetAPIType<OArrayType>;
851 static_assert(
852 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
853
854 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
855 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
856
857 return std::equal(this->cbegin(), this->cend(), other.cbegin());
858 }
859
860 // Needs a runtime check:
861 template <typename OArrayType, ComponentIdType OSize>
863 const TupleReference<OArrayType, OSize>& other) const noexcept
864 {
865 // Check that types are convertible:
866 using OAPIType = GetAPIType<OArrayType>;
867 static_assert(
868 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
869
871 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
872
873 return std::equal(this->cbegin(), this->cend(), other.cbegin());
874 }
875
876 // skips some runtime checks when both sizes are fixed:
877 template <typename OArrayType, ComponentIdType OSize>
879 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
880 {
881 // Check that types are convertible:
882 using OAPIType = GetAPIType<OArrayType>;
883 static_assert(
884 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
885
886 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
887 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
888
889 return std::equal(this->cbegin(), this->cend(), other.cbegin());
890 }
891
892 // Needs a runtime check:
893 template <typename OArrayType, ComponentIdType OSize>
895 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
896 {
897 // Check that types are convertible:
898 using OAPIType = GetAPIType<OArrayType>;
899 static_assert(
900 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
901
903 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
904
905 return std::equal(this->cbegin(), this->cend(), other.cbegin());
906 }
907
908 template <typename OArrayType, ComponentIdType OSize>
910 {
911 return !(*this == o);
912 }
913
914 template <typename OArrayT, ComponentIdType OSize>
916 {
917 return !(*this == o);
918 }
919
922 {
923 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
924 }
925
927 size_type size() const noexcept { return this->NumComps.value; }
928
930 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
932 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
933
935 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
937 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
938
939 friend struct ConstTupleIterator<ArrayType, TupleSize>;
940
941protected:
942 // Intentionally hidden:
945
948 {
949 VTK_ITER_ASSUME(this->NumComps.value > 0);
950 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
951 }
952
954 void CopyReference(const ConstTupleReference& o) noexcept
955 {
956 // Must use same array, other array types may use different implementations.
957 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
958 this->NumComps = o.NumComps;
959 this->TupleId = o.TupleId;
960 }
961
962 mutable ArrayType* Array;
963 NumCompsType NumComps;
965};
966
967//------------------------------------------------------------------------------
968// Tuple reference
969template <typename ArrayType, ComponentIdType TupleSize>
971{
972private:
973 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
974 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
975
976 using NumCompsType = GenericTupleSize<TupleSize>;
977 using APIType = GetAPIType<ArrayType>;
978
979public:
981 using value_type = APIType;
986
988 TupleReference() noexcept
989 : Array(nullptr)
990 , TupleId(0)
991 {
992 }
993
995 TupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
996 : Array(array)
997 , NumComps(numComps)
998 , TupleId(tupleId)
999 {
1000 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1001 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1002 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1003 "Tuple reference at invalid tuple id.");
1004 }
1005
1009 TupleReference(TupleReference&&) noexcept = default;
1010
1011 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
1013 TupleReference* operator->() noexcept { return this; }
1015 const TupleReference* operator->() const noexcept { return this; }
1016
1017 // Caller must ensure that there are size() elements in array.
1018 VTK_ITER_INLINE void GetTuple(APIType* tuple) const noexcept
1019 {
1020 VTK_ITER_ASSUME(this->NumComps.value > 0);
1021 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1022 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1023 {
1024 this->Array->GetTuple(this->TupleId, tuple);
1025 }
1026 else
1027 {
1028 this->Array->GetTypedTuple(this->TupleId, tuple);
1029 }
1030 }
1031
1032 template <typename VT = APIType>
1033 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
1034 double* tuple) const noexcept
1035 {
1036 VTK_ITER_ASSUME(this->NumComps.value > 0);
1037 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1038 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1039 {
1040 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1041 {
1042 tuple[comp] = static_cast<double>(this->Array->GetComponent(this->TupleId, comp));
1043 }
1044 }
1045 else
1046 {
1047 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1048 {
1049 tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(this->TupleId, comp));
1050 }
1051 }
1052 }
1053
1054 // Caller must ensure that there are size() elements in array.
1055 VTK_ITER_INLINE void SetTuple(const APIType* tuple) noexcept
1056 {
1057 VTK_ITER_ASSUME(this->NumComps.value > 0);
1058 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1059 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1060 {
1061 this->Array->SetTuple(this->TupleId, tuple);
1062 }
1063 else
1064 {
1065 this->Array->SetTypedTuple(this->TupleId, tuple);
1066 }
1067 }
1068
1069 template <typename VT = APIType>
1070 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE SetTuple(
1071 const double* tuple) noexcept
1072 {
1073 VTK_ITER_ASSUME(this->NumComps.value > 0);
1074 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1075 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1076 {
1077 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1078 {
1079 this->Array->SetComponent(this->TupleId, comp, static_cast<APIType>(tuple[comp]));
1080 }
1081 }
1082 else
1083 {
1084 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1085 {
1086 this->Array->SetTypedComponent(this->TupleId, comp, static_cast<APIType>(tuple[comp]));
1087 }
1088 }
1089 }
1090
1093 {
1094 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1095 return *this;
1096 }
1097
1098 // skips some runtime checks when both sizes are fixed:
1099 template <typename OArrayType, ComponentIdType OSize>
1101 const TupleReference<OArrayType, OSize>& other) noexcept
1102 {
1103 // Check that types are convertible:
1104 using OAPIType = GetAPIType<OArrayType>;
1105 static_assert(
1106 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1107
1108 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1109 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1110
1111 std::copy_n(other.cbegin(), OSize, this->begin());
1112 return *this;
1113 }
1114
1115 // Needs a runtime check:
1116 template <typename OArrayType, ComponentIdType OSize>
1118 const TupleReference<OArrayType, OSize>& other) noexcept
1119 {
1120 // Check that types are convertible:
1121 using OAPIType = GetAPIType<OArrayType>;
1122 static_assert(
1123 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1124
1126 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1127
1128 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1129 return *this;
1130 }
1131
1132 // skips some runtime checks when both sizes are fixed:
1133 template <typename OArrayType, ComponentIdType OSize>
1135 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1136 {
1137 // Check that types are convertible:
1138 using OAPIType = GetAPIType<OArrayType>;
1139 static_assert(
1140 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1141
1142 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1143 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1144
1145 std::copy_n(other.cbegin(), OSize, this->begin());
1146 return *this;
1147 }
1148
1149 // Needs a runtime check:
1150 template <typename OArrayType, ComponentIdType OSize>
1152 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1153 {
1154 // Check that types are convertible:
1155 using OAPIType = GetAPIType<OArrayType>;
1156 static_assert(
1157 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1158
1160 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1161
1162 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1163 return *this;
1164 }
1165
1166 // skips some runtime checks when both sizes are fixed:
1167 template <typename OArrayType, ComponentIdType OSize>
1169 const TupleReference<OArrayType, OSize>& other) const noexcept
1170 {
1171 // Check that types are convertible:
1172 using OAPIType = GetAPIType<OArrayType>;
1173 static_assert(
1174 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1175
1176 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1177 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1178
1179 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1180 }
1181
1182 // Needs a runtime check:
1183 template <typename OArrayType, ComponentIdType OSize>
1185 const TupleReference<OArrayType, OSize>& other) const noexcept
1186 {
1187 // Check that types are convertible:
1188 using OAPIType = GetAPIType<OArrayType>;
1189 static_assert(
1190 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1191
1193 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1194
1195 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1196 }
1197
1198 // skips some runtime checks when both sizes are fixed:
1199 template <typename OArrayType, ComponentIdType OSize>
1201 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1202 {
1203 // Check that types are convertible:
1204 using OAPIType = GetAPIType<OArrayType>;
1205 static_assert(
1206 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1207
1208 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1209 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1210
1211 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1212 }
1213
1214 // Needs a runtime check:
1215 template <typename OArrayType, ComponentIdType OSize>
1217 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1218 {
1219 // Check that types are convertible:
1220 using OAPIType = GetAPIType<OArrayType>;
1221 static_assert(
1222 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1223
1225 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1226
1227 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1228 }
1229
1230 template <typename OArrayType, ComponentIdType OSize>
1232 {
1233 return !(*this == o);
1234 }
1235
1236 template <typename OArray, ComponentIdType OSize>
1238 {
1239 return !(*this == o);
1240 }
1241
1242 // skips some runtime checks:
1243 template <typename OArrayType, ComponentIdType OSize>
1245 TupleReference<OArrayType, OSize> other) noexcept
1246 {
1247 // Check that types are convertible:
1248 using OAPIType = GetAPIType<OArrayType>;
1249 static_assert(
1250 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1251
1252 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1253 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
1254
1255 std::swap_ranges(this->begin(), this->end(), other.begin());
1256 }
1257
1258 // Needs a runtime check:
1259 template <typename OArrayType, ComponentIdType OSize>
1261 TupleReference<OArrayType, OSize> other) noexcept
1262 {
1263 // Check that types are convertible:
1264 using OAPIType = GetAPIType<OArrayType>;
1265 static_assert(
1266 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1267
1269 other.size() == this->NumComps.value, "Cannot swap tuples with different sizes.");
1270
1271 std::swap_ranges(this->begin(), this->end(), other.begin());
1272 }
1273
1274 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
1275
1276 template <typename OArray, ComponentIdType OSize>
1278 {
1279 a.swap(b);
1280 }
1281
1284 {
1285 return reference{ this->Array, this->NumComps, this->TupleId, i };
1286 }
1287
1290 {
1291 // Let the reference type do the lookup during implicit conversion.
1292 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
1293 }
1294
1296 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
1297
1299 size_type size() const noexcept { return this->NumComps.value; }
1300
1302 iterator begin() noexcept { return this->NewIterator(0); }
1304 iterator end() noexcept { return this->NewIterator(this->NumComps.value); }
1305
1307 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
1309 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1310
1312 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
1314 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1315
1316 friend struct ConstTupleReference<ArrayType, TupleSize>;
1317 friend struct TupleIterator<ArrayType, TupleSize>;
1318
1319protected:
1322 {
1323 VTK_ITER_ASSUME(this->NumComps.value > 0);
1324 return iterator{ this->Array, this->NumComps, this->TupleId, comp };
1325 }
1326
1329 {
1330 VTK_ITER_ASSUME(this->NumComps.value > 0);
1331 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
1332 }
1333
1335 void CopyReference(const TupleReference& o) noexcept
1336 {
1337 // Must use same array, other array types may use different implementations.
1338 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
1339 this->NumComps = o.NumComps;
1340 this->TupleId = o.TupleId;
1341 }
1342
1343 mutable ArrayType* Array;
1344 NumCompsType NumComps;
1346};
1347
1348//------------------------------------------------------------------------------
1349// Const tuple iterator
1350template <typename ArrayType, ComponentIdType TupleSize>
1352{
1353private:
1354 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1355 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
1356
1357 using NumCompsType = GenericTupleSize<TupleSize>;
1358
1359public:
1360 using iterator_category = std::random_access_iterator_tag;
1365
1367 ConstTupleIterator() noexcept = default;
1368
1370 ConstTupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1371 : Ref(array, numComps, tupleId)
1372 {
1373 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1374 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1375 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1376 "Const tuple iterator at invalid tuple id.");
1377 }
1378
1381 : Ref{ o.Ref }
1382 {
1383 }
1384
1386 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
1389 {
1390 this->Ref.CopyReference(o.Ref);
1391 return *this;
1392 }
1393
1395 ConstTupleIterator& operator++() noexcept // prefix
1396 {
1397 ++this->Ref.TupleId;
1399 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1400 "Const tuple iterator at invalid component id.");
1401 return *this;
1402 }
1403
1405 ConstTupleIterator operator++(int) noexcept // postfix
1406 {
1407 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1408 }
1409
1411 ConstTupleIterator& operator--() noexcept // prefix
1412 {
1413 --this->Ref.TupleId;
1415 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1416 "Const tuple iterator at invalid component id.");
1417 return *this;
1418 }
1419
1421 ConstTupleIterator operator--(int) noexcept // postfix
1422 {
1423 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1424 }
1425
1428 {
1429 return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1430 }
1431
1433 reference operator*() noexcept { return this->Ref; }
1434
1436 pointer operator->() noexcept { return this->Ref; }
1437
1438#define VTK_TMP_MAKE_OPERATOR(OP) \
1439 friend VTK_ITER_INLINE bool operator OP( \
1440 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1441 { \
1442 VTK_ITER_ASSERT( \
1443 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1444 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1445 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1446 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1447 }
1448
1455
1456#undef VTK_TMP_MAKE_OPERATOR
1457
1460 {
1461 this->Ref.TupleId += offset;
1463 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1464 "Const tuple iterator at invalid component id.");
1465 return *this;
1466 }
1467
1469 const ConstTupleIterator& it, difference_type offset) noexcept
1470 {
1471 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1472 }
1473
1475 difference_type offset, const ConstTupleIterator& it) noexcept
1476 {
1477 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1478 }
1479
1482 {
1483 this->Ref.TupleId -= offset;
1485 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1486 "Const tuple iterator at invalid component id.");
1487 return *this;
1488 }
1489
1491 const ConstTupleIterator& it, difference_type offset) noexcept
1492 {
1493 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1494 }
1495
1497 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
1498 {
1499 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1500 "Cannot do math with tuple iterators from different "
1501 "arrays.");
1502 return it1.GetTupleId() - it2.GetTupleId();
1503 }
1504
1506 {
1507 // Different arrays may use different iterator implementations.
1509 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1510
1511 using std::swap;
1512 swap(lhs.GetTupleId(), rhs.GetTupleId());
1513 }
1514
1515private:
1517 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1519 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1521 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1523 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1525 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1527 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1528
1529 ConstTupleReference<ArrayType, TupleSize> Ref;
1530};
1531
1532//------------------------------------------------------------------------------
1533// Tuple iterator
1534template <typename ArrayType, ComponentIdType TupleSize>
1536{
1537private:
1538 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1539 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
1540
1541 using NumCompsType = GenericTupleSize<TupleSize>;
1542
1543public:
1544 using iterator_category = std::random_access_iterator_tag;
1549
1551 TupleIterator() noexcept = default;
1552
1554 TupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1555 : Ref(array, numComps, tupleId)
1556 {
1557 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1558 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1560 tupleId >= 0 && tupleId <= array->GetNumberOfTuples(), "Tuple iterator at invalid tuple id.");
1561 }
1562
1564 TupleIterator(const TupleIterator& o) noexcept = default;
1565
1568 {
1569 this->Ref.CopyReference(o.Ref);
1570 return *this;
1571 }
1572
1574 TupleIterator& operator++() noexcept // prefix
1575 {
1576 ++this->Ref.TupleId;
1578 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1579 "Tuple iterator at invalid component id.");
1580 return *this;
1581 }
1582
1584 TupleIterator operator++(int) noexcept // postfix
1585 {
1586 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1587 }
1588
1590 TupleIterator& operator--() noexcept // prefix
1591 {
1592 --this->Ref.TupleId;
1594 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1595 "Tuple iterator at invalid component id.");
1596 return *this;
1597 }
1598
1600 TupleIterator operator--(int) noexcept // postfix
1601 {
1602 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1603 }
1604
1607 {
1608 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId + i };
1609 }
1610
1612 reference operator*() noexcept { return this->Ref; }
1613
1615 pointer& operator->() noexcept { return this->Ref; }
1616
1617#define VTK_TMP_MAKE_OPERATOR(OP) \
1618 friend VTK_ITER_INLINE bool operator OP( \
1619 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1620 { \
1621 VTK_ITER_ASSERT( \
1622 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1623 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1624 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1625 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1626 }
1627
1634
1635#undef VTK_TMP_MAKE_OPERATOR
1636
1639 {
1640 this->Ref.TupleId += offset;
1642 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1643 "Tuple iterator at invalid component id.");
1644 return *this;
1645 }
1646
1648 const TupleIterator& it, difference_type offset) noexcept
1649 {
1650 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1651 }
1652
1654 difference_type offset, const TupleIterator& it) noexcept
1655 {
1656 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1657 }
1658
1661 {
1662 this->Ref.TupleId -= offset;
1664 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1665 "Tuple iterator at invalid component id.");
1666 return *this;
1667 }
1668
1670 const TupleIterator& it, difference_type offset) noexcept
1671 {
1672 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1673 }
1674
1676 const TupleIterator& it1, const TupleIterator& it2) noexcept
1677 {
1678 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1679 "Cannot do math with tuple iterators from different "
1680 "arrays.");
1681 return it1.GetTupleId() - it2.GetTupleId();
1682 }
1683
1684 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
1685 {
1686 // Different arrays may use different iterator implementations.
1688 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1689
1690 using std::swap;
1691 swap(lhs.GetTupleId(), rhs.GetTupleId());
1692 }
1693
1694 friend struct ConstTupleIterator<ArrayType, TupleSize>;
1695 friend struct ConstTupleReference<ArrayType, TupleSize>;
1696
1697protected:
1699 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1701 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1703 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1705 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1707 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1709 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1710
1712};
1713
1714//------------------------------------------------------------------------------
1715// Tuple range
1716template <typename ArrayTypeT, ComponentIdType TupleSize>
1718{
1719 using ArrayType = ArrayTypeT;
1722
1723private:
1724 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1725 static_assert(IsVtkArray<ArrayTypeT>::value, "Invalid array type.");
1726
1727 using NumCompsType = GenericTupleSize<TupleSize>;
1728
1729public:
1739
1740 // May be DynamicTupleSize, or the actual tuple size.
1741 constexpr static ComponentIdType TupleSizeTag = TupleSize;
1742
1748
1750 TupleRange() noexcept = default;
1751
1753 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
1754 : Array(arr)
1755 , NumComps(arr)
1756 , BeginTuple(beginTuple)
1757 , EndTuple(endTuple)
1758 {
1759 assert(this->Array);
1760 assert(beginTuple >= 0 && beginTuple <= endTuple);
1761 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1762 }
1763
1765 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1766 {
1767 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1768 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1769
1770 return TupleRange{ this->Array, realBegin, realEnd };
1771 }
1772
1774 ArrayType* GetArray() const noexcept { return this->Array; }
1776 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1778 TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1780 TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1781
1783 size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1784
1786 iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1788 iterator end() noexcept { return this->NewIter(this->EndTuple); }
1789
1791 const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1793 const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1794
1796 const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1798 const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1799
1802 {
1803 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1804 }
1805
1808 {
1809 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1810 }
1811
1812 void VTK_ITER_INLINE GetTuple(size_type i, ValueType* tuple) const noexcept
1813 {
1814 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1815 {
1816 this->Array->GetTuple(this->BeginTuple + i, tuple);
1817 }
1818 else
1819 {
1820 this->Array->GetTypedTuple(this->BeginTuple + i, tuple);
1821 }
1822 }
1823
1824 template <typename VT = APIType>
1825 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
1826 size_type i, double* tuple) const noexcept
1827 {
1828 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1829 {
1830 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1831 {
1832 tuple[comp] = static_cast<double>(this->Array->GetComponent(i, comp));
1833 }
1834 }
1835 else
1836 {
1837 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1838 {
1839 tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(i, comp));
1840 }
1841 }
1842 }
1843
1844 void VTK_ITER_INLINE SetTuple(size_type i, const ValueType* tuple) noexcept
1845 {
1846 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1847 {
1848 this->Array->SetTuple(this->BeginTuple + i, tuple);
1849 }
1850 else
1851 {
1852 this->Array->SetTypedTuple(this->BeginTuple + i, tuple);
1853 }
1854 }
1855
1856 template <typename VT = APIType>
1857 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE SetTuple(
1858 size_type i, const double* tuple) noexcept
1859 {
1860 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1861 {
1862 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1863 {
1864 this->Array->SetComponent(this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1865 }
1866 }
1867 else
1868 {
1869 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1870 {
1871 this->Array->SetTypedComponent(
1872 this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1873 }
1874 }
1875 }
1876
1877private:
1879 iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1880
1882 const_iterator NewCIter(TupleIdType t) const
1883 {
1884 return const_iterator{ this->Array, this->NumComps, t };
1885 }
1886
1887 mutable ArrayType* Array{ nullptr };
1888 NumCompsType NumComps{};
1889 TupleIdType BeginTuple{ 0 };
1890 TupleIdType EndTuple{ 0 };
1891};
1892
1893// Unimplemented, only used inside decltype in SelectTupleRange:
1894template <typename ArrayType, ComponentIdType TupleSize>
1896
1897VTK_ABI_NAMESPACE_END
1898} // end namespace detail
1899} // end namespace vtk
1900
1902
1903#endif // __VTK_WRAP__
1904
1905// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_Generic.h
Abstract superclass for all arrays.
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
std::enable_if_t< IsEitherTupleSizeDynamic< S1, S2 >::value, T > EnableIfEitherTupleSizeIsDynamic
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType, ForceValueTypeForVtkDataArray >::APIType GetAPIType
vtkIdType TupleIdType
int ComponentIdType
const ComponentIdType & GetComponentId() const noexcept
ComponentReference< ArrayType, TupleSize > Ref
VTK_ITER_INLINE ComponentIterator(const ComponentIterator &o) noexcept=default
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
ComponentReference< ArrayType, TupleSize > pointer
friend VTK_ITER_INLINE difference_type operator-(const ComponentIterator &it1, const ComponentIterator &it2) noexcept
VTK_ITER_INLINE ComponentIterator operator++(int) noexcept
VTK_ITER_INLINE const pointer & operator->() const noexcept
VTK_ITER_INLINE ComponentIterator & operator+=(difference_type offset) noexcept
friend VTK_ITER_INLINE void swap(ComponentIterator &lhs, ComponentIterator &rhs) noexcept
VTK_ITER_INLINE ComponentIterator operator--(int) noexcept
std::random_access_iterator_tag iterator_category
friend VTK_ITER_INLINE ComponentIterator operator+(const ComponentIterator &it, difference_type offset) noexcept
const TupleIdType & GetTupleId() const noexcept
VTK_ITER_INLINE ComponentIterator() noexcept=default
VTK_ITER_INLINE ComponentIterator & operator--() noexcept
VTK_ITER_INLINE ComponentIterator & operator=(const ComponentIterator &o) noexcept
VTK_ITER_INLINE ComponentIterator & operator-=(difference_type offset) noexcept
ComponentReference< ArrayType, TupleSize > reference
VTK_ITER_INLINE reference operator*() const noexcept
const NumCompsType & GetNumComps() const noexcept
VTK_ITER_INLINE ComponentIterator & operator++() noexcept
friend VTK_ITER_INLINE ComponentIterator operator+(difference_type offset, const ComponentIterator &it) noexcept
friend VTK_ITER_INLINE ComponentIterator operator-(const ComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ComponentReference operator++() noexcept
VTK_ITER_INLINE ComponentReference(ComponentReference &&o) noexcept=default
VTK_ITER_INLINE ComponentReference operator=(ComponentReference &&o) noexcept
VTK_ITER_INLINE APIType operator++(int) noexcept
VTK_ITER_INLINE ComponentReference operator--() noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, ComponentReference rhs) noexcept
VTK_ITER_INLINE ComponentReference(const ComponentReference &o) noexcept=default
friend VTK_ITER_INLINE void swap(APIType &lhs, ComponentReference rhs) noexcept
VTK_ITER_INLINE ComponentReference operator=(APIType val) noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, ComponentReference< OArray, OSize > rhs) noexcept
VTK_ITER_INLINE ComponentReference(ArrayType *array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
VTK_ITER_INLINE ComponentReference operator=(const ComponentReference< OArray, OSize > &o) noexcept
friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType &rhs) noexcept
VTK_ITER_INLINE ComponentReference operator=(const ComponentReference &o) noexcept
VTK_ITER_INLINE void CopyReference(const ComponentReference &o) noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator+(difference_type offset, const ConstComponentIterator &it) noexcept
VTK_ITER_INLINE ConstComponentIterator & operator--() noexcept
VTK_ITER_INLINE ConstComponentIterator & operator=(const ConstComponentIterator &o) noexcept=default
VTK_ITER_INLINE ConstComponentIterator(const ConstComponentIterator &o) noexcept=default
friend VTK_ITER_INLINE difference_type operator-(const ConstComponentIterator &it1, const ConstComponentIterator &it2) noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE reference operator*() const noexcept
VTK_ITER_INLINE ConstComponentIterator operator--(int) noexcept
VTK_ITER_INLINE ConstComponentIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE ConstComponentIterator & operator++() noexcept
ConstComponentReference< ArrayType, TupleSize > reference
friend VTK_ITER_INLINE void swap(ConstComponentIterator &lhs, ConstComponentIterator &rhs) noexcept
VTK_ITER_INLINE ConstComponentIterator(const ComponentIterator< ArrayType, TupleSize > &o) noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator-(const ConstComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstComponentIterator(ArrayType *array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
VTK_ITER_INLINE ConstComponentIterator operator++(int) noexcept
friend VTK_ITER_INLINE ConstComponentIterator operator+(const ConstComponentIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
VTK_ITER_INLINE ConstComponentIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE ConstComponentReference(const ConstComponentReference &o) noexcept=default
VTK_ITER_INLINE ConstComponentReference & operator=(ConstComponentReference &&o) noexcept
VTK_ITER_INLINE ConstComponentReference(const ComponentReference< ArrayType, TupleSize > &o)
VTK_ITER_INLINE ConstComponentReference & operator=(const ConstComponentReference &o) noexcept
VTK_ITER_INLINE ConstComponentReference(ArrayType *array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
VTK_ITER_INLINE ConstComponentReference(ConstComponentReference &&o) noexcept=default
VTK_ITER_INLINE ConstTupleIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator=(const ConstTupleIterator &o) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator++() noexcept
friend VTK_ITER_INLINE void swap(ConstTupleIterator &lhs, ConstTupleIterator &rhs) noexcept
VTK_ITER_INLINE ConstTupleIterator operator--(int) noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator+(difference_type offset, const ConstTupleIterator &it) noexcept
VTK_ITER_INLINE reference operator*() noexcept
VTK_ITER_INLINE ConstTupleIterator() noexcept=default
VTK_ITER_INLINE pointer operator->() noexcept
std::random_access_iterator_tag iterator_category
friend VTK_ITER_INLINE ConstTupleIterator operator+(const ConstTupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) noexcept
ConstTupleReference< ArrayType, TupleSize > value_type
friend VTK_ITER_INLINE ConstTupleIterator operator-(const ConstTupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstTupleIterator(const ConstTupleIterator &o) noexcept=default
VTK_ITER_INLINE ConstTupleIterator(const TupleIterator< ArrayType, TupleSize > &o) noexcept
ConstTupleReference< ArrayType, TupleSize > reference
VTK_ITER_INLINE ConstTupleIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstTupleIterator &it1, const ConstTupleIterator &it2) noexcept
VTK_ITER_INLINE ConstTupleIterator operator++(int) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator--() noexcept
ConstTupleReference< ArrayType, TupleSize > pointer
ConstComponentIterator< ArrayType, TupleSize > const_iterator
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE const ConstTupleReference * operator->() const noexcept
VTK_ITER_INLINE ConstTupleReference(ConstTupleReference &&) noexcept=default
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
ConstComponentIterator< ArrayType, TupleSize > iterator
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const_iterator begin() const noexcept
VTK_ITER_INLINE void CopyReference(const ConstTupleReference &o) noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(double *tuple) const noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE ConstTupleReference(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
VTK_ITER_INLINE ConstTupleReference(const ConstTupleReference &) noexcept=default
VTK_ITER_INLINE void GetTuple(APIType *tuple) const noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArrayT, OSize > &o) const noexcept
VTK_ITER_INLINE const_iterator NewConstIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE ConstTupleReference(const TupleReference< ArrayType, TupleSize > &o) noexcept
ConstComponentReference< ArrayType, TupleSize > const_reference
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ConstTupleReference & operator=(const ConstTupleReference &) noexcept=default
static constexpr bool value
TupleReference< ArrayType, TupleSize > pointer
TupleReference< ArrayType, TupleSize > value_type
VTK_ITER_INLINE TupleIterator & operator=(const TupleIterator &o) noexcept
VTK_ITER_INLINE ArrayType *& GetArray() noexcept
friend VTK_ITER_INLINE TupleIterator operator+(const TupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE TupleIdType & GetTupleId() noexcept
TupleReference< ArrayType, TupleSize > reference
friend VTK_ITER_INLINE void swap(TupleIterator &lhs, TupleIterator &rhs) noexcept
VTK_ITER_INLINE NumCompsType GetNumComps() const noexcept
VTK_ITER_INLINE TupleIterator(const TupleIterator &o) noexcept=default
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE TupleIterator & operator++() noexcept
VTK_ITER_INLINE TupleIterator & operator--() noexcept
VTK_ITER_INLINE NumCompsType & GetNumComps() noexcept
VTK_ITER_INLINE pointer & operator->() noexcept
friend VTK_ITER_INLINE TupleIterator operator-(const TupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE TupleIdType GetTupleId() const noexcept
VTK_ITER_INLINE TupleIterator & operator+=(difference_type offset) noexcept
TupleReference< ArrayType, TupleSize > Ref
VTK_ITER_INLINE reference operator[](difference_type i) noexcept
friend VTK_ITER_INLINE TupleIterator operator+(difference_type offset, const TupleIterator &it) noexcept
VTK_ITER_INLINE reference operator*() noexcept
VTK_ITER_INLINE TupleIterator operator++(int) noexcept
VTK_ITER_INLINE TupleIterator operator--(int) noexcept
VTK_ITER_INLINE TupleIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE difference_type operator-(const TupleIterator &it1, const TupleIterator &it2) noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE TupleIterator() noexcept=default
ConstComponentReference< ArrayType, TupleSize > ConstComponentReferenceType
VTK_ITER_INLINE const_iterator begin() const noexcept
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE TupleIdType GetBeginTupleId() const noexcept
VTK_ITER_INLINE TupleIdType GetEndTupleId() const noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(size_type i, double *tuple) const noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE SetTuple(size_type i, const double *tuple) noexcept
static constexpr ComponentIdType TupleSizeTag
TupleIterator< ArrayType, TupleSize > TupleIteratorType
VTK_ITER_INLINE TupleRange() noexcept=default
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE size_type size() const noexcept
ConstTupleIterator< ArrayType, TupleSize > ConstTupleIteratorType
ConstComponentIterator< ArrayType, TupleSize > ConstComponentIteratorType
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
TupleReference< ArrayType, TupleSize > TupleReferenceType
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
ComponentReference< ArrayType, TupleSize > ComponentReferenceType
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE iterator end() noexcept
ConstTupleReference< ArrayType, TupleSize > ConstTupleReferenceType
void VTK_ITER_INLINE GetTuple(size_type i, ValueType *tuple) const noexcept
ComponentIterator< ArrayType, TupleSize > ComponentIteratorType
VTK_ITER_INLINE TupleRange GetSubRange(TupleIdType beginTuple=0, TupleIdType endTuple=-1) const noexcept
VTK_ITER_INLINE iterator begin() noexcept
void VTK_ITER_INLINE SetTuple(size_type i, const ValueType *tuple) noexcept
VTK_ITER_INLINE void SetTuple(const APIType *tuple) noexcept
VTK_ITER_INLINE const_iterator begin() const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const TupleReference * operator->() const noexcept
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE TupleReference(const TupleReference &)=default
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
ComponentIterator< ArrayType, TupleSize > iterator
VTK_ITER_INLINE void GetTuple(APIType *tuple) const noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE TupleReference(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
VTK_ITER_INLINE TupleReference & operator=(const TupleReference &other) noexcept
VTK_ITER_INLINE TupleReference(TupleReference &&) noexcept=default
ComponentReference< ArrayType, TupleSize > reference
VTK_ITER_INLINE iterator NewIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE void CopyReference(const TupleReference &o) noexcept
VTK_ITER_INLINE iterator begin() noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
ConstComponentIterator< ArrayType, TupleSize > const_iterator
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE iterator end() noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE SetTuple(const double *tuple) noexcept
VTK_ITER_INLINE void fill(const value_type &v) noexcept
std::enable_if_t<!std::is_same_v< VT, double > > VTK_ITER_INLINE GetTuple(double *tuple) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
ConstComponentReference< ArrayType, TupleSize > const_reference
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE const_iterator NewConstIterator(ComponentIdType comp) const noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArray, OSize > &o) const noexcept
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference< OArray, OSize > b) noexcept
This file contains a variety of metaprogramming constructs for working with vtkDataArrays.
#define VTK_ITER_OPTIMIZE_START
#define VTK_ITER_INLINE
#define VTK_ITER_OPTIMIZE_END
#define VTK_ITER_ASSERT(x, msg)
#define VTK_ITER_ASSUME
#define VTK_TMP_MAKE_OPERATOR(OP)
#define VTK_REF_OP_OVERLOADS(Op, ImplOp)