VTK  9.6.20260402
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
357
358#undef VTK_REF_OP_OVERLOADS
359
360 friend struct ConstComponentReference<ArrayType, TupleSize>;
361 friend struct ComponentIterator<ArrayType, TupleSize>;
362
363protected:
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;
374 NumCompsType NumComps;
377};
378
379//------------------------------------------------------------------------------
380// Const component iterator
381template <typename ArrayType, ComponentIdType TupleSize>
383{
384private:
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
390public:
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;
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
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
556private:
557 mutable ArrayType* Array;
558 NumCompsType NumComps;
559 TupleIdType TupleId;
560 ComponentIdType ComponentId;
561};
562
563//------------------------------------------------------------------------------
564// Component iterator
565template <typename ArrayType, ComponentIdType TupleSize>
567{
568private:
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
575public:
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
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
739protected:
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
755template <typename ArrayType, ComponentIdType TupleSize>
757{
758private:
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
765public:
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;
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);
815 if constexpr (std::is_same<ArrayType, vtkDataArray>::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);
831 if constexpr (std::is_same<ArrayType, vtkDataArray>::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
944protected:
945 // Intentionally hidden:
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;
966 NumCompsType NumComps;
968};
969
970//------------------------------------------------------------------------------
971// Tuple reference
972template <typename ArrayType, ComponentIdType TupleSize>
974{
975private:
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
982public:
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
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);
1025 if constexpr (std::is_same<ArrayType, vtkDataArray>::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);
1041 if constexpr (std::is_same<ArrayType, vtkDataArray>::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);
1062 if constexpr (std::is_same<ArrayType, vtkDataArray>::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);
1078 if constexpr (std::is_same<ArrayType, vtkDataArray>::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
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
1322protected:
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;
1347 NumCompsType NumComps;
1349};
1350
1351//------------------------------------------------------------------------------
1352// Const tuple iterator
1353template <typename ArrayType, ComponentIdType TupleSize>
1355{
1356private:
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
1362public:
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
1518private:
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
1537template <typename ArrayType, ComponentIdType TupleSize>
1539{
1540private:
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
1546public:
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
1700protected:
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
1719template <typename ArrayTypeT, ComponentIdType TupleSize>
1721{
1722 using ArrayType = ArrayTypeT;
1725
1726private:
1727 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1728 static_assert(IsVtkArray<ArrayTypeT>::value, "Invalid array type.");
1729
1730 using NumCompsType = GenericTupleSize<TupleSize>;
1731
1732public:
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());
1765 }
1766
1768 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1769 {
1770 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1771 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1772
1773 return TupleRange{ this->Array, realBegin, realEnd };
1774 }
1775
1777 ArrayType* GetArray() const noexcept { return this->Array; }
1779 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1781 TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1783 TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1784
1786 size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1787
1789 iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1791 iterator end() noexcept { return this->NewIter(this->EndTuple); }
1792
1794 const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1796 const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1797
1799 const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1801 const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1802
1805 {
1806 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1807 }
1808
1811 {
1812 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1813 }
1814
1815 void VTK_ITER_INLINE GetTuple(size_type i, ValueType* tuple) const noexcept
1816 {
1817 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1818 {
1819 this->Array->GetTuple(this->BeginTuple + i, tuple);
1820 }
1821 else
1822 {
1823 this->Array->GetTypedTuple(this->BeginTuple + i, tuple);
1824 }
1825 }
1826
1827 template <typename VT = APIType>
1828 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE GetTuple(
1829 size_type i, double* tuple) const noexcept
1830 {
1831 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1832 {
1833 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1834 {
1835 tuple[comp] = static_cast<double>(this->Array->GetComponent(i, comp));
1836 }
1837 }
1838 else
1839 {
1840 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1841 {
1842 tuple[comp] = static_cast<double>(this->Array->GetTypedComponent(i, comp));
1843 }
1844 }
1845 }
1846
1847 void VTK_ITER_INLINE SetTuple(size_type i, const ValueType* tuple) noexcept
1848 {
1849 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1850 {
1851 this->Array->SetTuple(this->BeginTuple + i, tuple);
1852 }
1853 else
1854 {
1855 this->Array->SetTypedTuple(this->BeginTuple + i, tuple);
1856 }
1857 }
1858
1859 template <typename VT = APIType>
1860 typename std::enable_if_t<!std::is_same_v<VT, double>> VTK_ITER_INLINE SetTuple(
1861 size_type i, const double* tuple) noexcept
1862 {
1863 if constexpr (std::is_same<ArrayType, vtkDataArray>::value)
1864 {
1865 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1866 {
1867 this->Array->SetComponent(this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1868 }
1869 }
1870 else
1871 {
1872 for (ComponentIdType comp = 0; comp < this->NumComps.value; ++comp)
1873 {
1874 this->Array->SetTypedComponent(
1875 this->BeginTuple + i, comp, static_cast<ValueType>(tuple[comp]));
1876 }
1877 }
1878 }
1879
1880private:
1882 iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1883
1885 const_iterator NewCIter(TupleIdType t) const
1886 {
1887 return const_iterator{ this->Array, this->NumComps, t };
1888 }
1889
1890 mutable ArrayType* Array{ nullptr };
1891 NumCompsType NumComps{};
1892 TupleIdType BeginTuple{ 0 };
1893 TupleIdType EndTuple{ 0 };
1894};
1895
1896// Unimplemented, only used inside decltype in SelectTupleRange:
1897template <typename ArrayType, ComponentIdType TupleSize>
1899
1900VTK_ABI_NAMESPACE_END
1901} // end namespace detail
1902} // end namespace vtk
1903
1905
1906#endif // __VTK_WRAP__
1907
1908// 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)