VTK  9.2.6
vtkDataArrayTupleRange_Generic.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataArrayTupleRange_Generic.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14=========================================================================*/
20#ifndef vtkDataArrayTupleRange_Generic_h
21#define vtkDataArrayTupleRange_Generic_h
22
23#include "vtkAssume.h"
25#include "vtkDataArrayMeta.h"
26
27#include <algorithm>
28#include <cassert>
29#include <iterator>
30#include <type_traits>
31
33
34namespace vtk
35{
36
37namespace detail
38{
39
40// Forward decs for friends/args
41template <typename ArrayType, ComponentIdType>
42struct ConstComponentReference;
43template <typename ArrayType, ComponentIdType>
44struct ComponentReference;
45template <typename ArrayType, ComponentIdType>
46struct ConstComponentIterator;
47template <typename ArrayType, ComponentIdType>
48struct ComponentIterator;
49template <typename ArrayType, ComponentIdType>
50struct ConstTupleReference;
51template <typename ArrayType, ComponentIdType>
52struct TupleReference;
53template <typename ArrayType, ComponentIdType>
54struct ConstTupleIterator;
55template <typename ArrayType, ComponentIdType>
56struct TupleIterator;
57template <typename ArrayType, ComponentIdType>
58struct TupleRange;
59
60//------------------------------------------------------------------------------
61// Const component reference
62template <typename ArrayType, ComponentIdType TupleSize>
64{
65private:
66 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
67 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
68
70 using APIType = GetAPIType<ArrayType>;
71
72public:
73 using value_type = APIType;
74
77 : Array{ nullptr }
78 , NumComps{}
79 , TupleId{ 0 }
80 , ComponentId{ 0 }
81 {
82 }
83
86 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
87 : Array{ array }
88 , NumComps{ numComps }
89 , TupleId{ tuple }
90 , ComponentId{ comp }
91 {
92 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
93 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
95 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
96 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
97 "Invalid component accessed by iterator.");
98 }
99
108
111
114
117 {
118 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
119 // Initialize the reference.
120 this->Array = o.Array;
121 this->NumComps = o.NumComps;
122 this->TupleId = o.TupleId;
123 this->ComponentId = o.ComponentId;
124 }
125
128 {
129 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
130 // Initialize the reference.
131 this->Array = std::move(o.Array);
132 this->NumComps = std::move(o.NumComps);
133 this->TupleId = std::move(o.TupleId);
134 this->ComponentId = std::move(o.ComponentId);
135 }
136
138 operator APIType() const noexcept
139 {
140 VTK_ITER_ASSUME(this->NumComps.value > 0);
141 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
143 return acc.Get(this->TupleId, this->ComponentId);
144 }
145
146protected:
147 mutable ArrayType* Array;
151};
152
153//------------------------------------------------------------------------------
154// Component reference
155template <typename ArrayType, ComponentIdType TupleSize>
157{
158private:
159 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
160 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
161
163 using APIType = GetAPIType<ArrayType>;
164
165public:
166 using value_type = APIType;
167
170 : Array{ nullptr }
171 , NumComps{}
172 , TupleId{ 0 }
173 , ComponentId{ 0 }
174 {
175 }
176
179 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
180 : Array{ array }
181 , NumComps{ numComps }
182 , TupleId{ tuple }
183 , ComponentId{ comp }
184 {
185 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
186 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
188 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
189 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
190 "Invalid component accessed by iterator.");
191 }
192
194 ComponentReference(const ComponentReference& o) noexcept = default;
196 ComponentReference(ComponentReference&& o) noexcept = default;
197
200 {
201 if (this->Array)
202 { // Already initialized. Assign the value, not the reference
203 return *this = static_cast<APIType>(o);
204 }
205 else
206 { // Initialize the reference.
207 this->Array = o.Array;
208 this->NumComps = o.NumComps;
209 this->TupleId = o.TupleId;
210 this->ComponentId = o.ComponentId;
211
212 return *this;
213 }
214 }
215
218 {
219 if (this->Array)
220 { // Already initialized. Assign the value, not the reference
221 return *this = std::move(static_cast<APIType>(o));
222 }
223 else
224 { // Initialize the reference.
225 this->Array = std::move(o.Array);
226 this->NumComps = std::move(o.NumComps);
227 this->TupleId = std::move(o.TupleId);
228 this->ComponentId = std::move(o.ComponentId);
229
230 return *this;
231 }
232 }
233
234 template <typename OArray, ComponentIdType OSize>
236 { // Always copy the value for different reference types:
237 const APIType tmp = o;
238 return *this = std::move(tmp);
239 }
240
242 operator APIType() const noexcept
243 {
244 VTK_ITER_ASSUME(this->NumComps.value > 0);
245 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
247 return acc.Get(this->TupleId, this->ComponentId);
248 }
249
251 ComponentReference operator=(APIType val) noexcept
252 {
253 VTK_ITER_ASSUME(this->NumComps.value > 0);
254 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
256 acc.Set(this->TupleId, this->ComponentId, val);
257 return *this;
258 }
259
261 { // Swap values, not references:
262 APIType tmp = std::move(static_cast<APIType>(lhs));
263 lhs = std::move(static_cast<APIType>(rhs));
264 rhs = std::move(tmp);
265 }
266
267 template <typename OArray, ComponentIdType OSize>
270 { // Swap values, not references:
271 using OAPIType = GetAPIType<OArray>;
272 static_assert(
273 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
274
275 APIType tmp = std::move(static_cast<APIType>(lhs));
276 lhs = std::move(static_cast<APIType>(rhs));
277 rhs = std::move(tmp);
278 }
279
280 friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType& rhs) noexcept
281 {
282 APIType tmp = std::move(static_cast<APIType>(lhs));
283 lhs = std::move(rhs);
284 rhs = std::move(tmp);
285 }
286
287 friend VTK_ITER_INLINE void swap(APIType& lhs, ComponentReference rhs) noexcept
288 {
289 APIType tmp = std::move(lhs);
290 lhs = std::move(static_cast<APIType>(rhs));
291 rhs = std::move(tmp);
292 }
293
295 ComponentReference operator++() noexcept // prefix
296 {
297 const APIType newVal = *this + 1;
298 *this = newVal;
299 return *this;
300 }
301
303 APIType operator++(int) noexcept // postfix
304 {
305 const APIType retVal = *this;
306 *this = *this + 1;
307 return retVal;
308 }
309
311 ComponentReference operator--() noexcept // prefix
312 {
313 const APIType newVal = *this - 1;
314 *this = newVal;
315 return *this;
316 }
317
319 APIType operator--(int) noexcept // postfix
320 {
321 const APIType retVal = *this;
322 *this = *this - 1;
323 return retVal;
324 }
325
326#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
327 friend VTK_ITER_INLINE ComponentReference operator Op( \
328 ComponentReference lhs, APIType val) noexcept \
329 { \
330 const APIType newVal = lhs ImplOp val; \
331 lhs = newVal; \
332 return lhs; \
333 } \
334 friend VTK_ITER_INLINE ComponentReference operator Op( \
335 ComponentReference lhs, ComponentReference val) noexcept \
336 { \
337 const APIType newVal = lhs ImplOp val; \
338 lhs = newVal; \
339 return lhs; \
340 } \
341 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ComponentReference val) noexcept \
342 { \
343 const APIType newVal = lhs ImplOp val; \
344 lhs = newVal; \
345 return lhs; \
346 }
347
352
353#undef VTK_REF_OP_OVERLOADS
354
355 friend struct ConstComponentReference<ArrayType, TupleSize>;
356 friend struct ComponentIterator<ArrayType, TupleSize>;
357
358protected:
360 void CopyReference(const ComponentReference& o) noexcept
361 {
362 this->Array = o.Array;
363 this->NumComps = o.NumComps;
364 this->TupleId = o.TupleId;
365 this->ComponentId = o.ComponentId;
366 }
367
368 mutable ArrayType* Array;
372};
373
374//------------------------------------------------------------------------------
375// Const component iterator
376template <typename ArrayType, ComponentIdType TupleSize>
378{
379private:
380 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
381 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
382
384
385public:
386 using iterator_category = std::random_access_iterator_tag;
389 using pointer = void;
391
394 : Array{ nullptr }
395 , TupleId{ 0 }
396 , ComponentId{ 0 }
397 {
398 }
399
402 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
403 : Array(array)
404 , NumComps(numComps)
405 , TupleId(tupleId)
406 , ComponentId(comp)
407 {
408 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
409 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
410 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
411 "Const component iterator at invalid tuple id.");
412 VTK_ITER_ASSERT(comp >= 0 && comp <= this->NumComps.value,
413 "Const component iterator at invalid component id.");
414 }
415
418 : Array{ o.GetArray() }
419 , NumComps{ o.GetNumComps() }
420 , TupleId{ o.GetTupleId() }
421 , ComponentId{ o.GetComponentId() }
422 {
423 }
424
426 ConstComponentIterator(const ConstComponentIterator& o) noexcept = default;
429
431 ConstComponentIterator& operator++() noexcept // prefix
432 {
433 ++this->ComponentId;
434 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
435 "Const component iterator at invalid component id.");
436 return *this;
437 }
438
440 ConstComponentIterator operator++(int) noexcept // postfix
441 {
442 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
443 this->ComponentId++ };
444 }
445
447 ConstComponentIterator& operator--() noexcept // prefix
448 {
449 --this->ComponentId;
450 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
451 "Const component iterator at invalid component id.");
452 return *this;
453 }
454
456 ConstComponentIterator operator--(int) noexcept // postfix
457 {
458 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
459 this->ComponentId-- };
460 }
461
464 {
465 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
466 }
467
469 reference operator*() const noexcept
470 {
471 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
472 }
473
474#define VTK_TMP_MAKE_OPERATOR(OP) \
475 friend VTK_ITER_INLINE bool operator OP( \
476 const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
477 { \
478 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
479 VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
480 VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
481 VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
482 return lhs.ComponentId OP rhs.ComponentId; \
483 }
484
491
492#undef VTK_TMP_MAKE_OPERATOR
493
496 {
497 this->ComponentId += offset;
498 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
499 "Const component iterator at invalid component id.");
500 return *this;
501 }
502
504 const ConstComponentIterator& it, difference_type offset) noexcept
505 {
506 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
507 }
508
510 difference_type offset, const ConstComponentIterator& it) noexcept
511 {
512 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
513 }
514
517 {
518 this->ComponentId -= offset;
519 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
520 "Const component iterator at invalid component id.");
521 return *this;
522 }
523
525 const ConstComponentIterator& it, difference_type offset) noexcept
526 {
527 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId - offset };
528 }
529
531 const ConstComponentIterator& it1, const ConstComponentIterator& it2) noexcept
532 {
533 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
534 VTK_ITER_ASSERT(it1.TupleId == it2.TupleId,
535 "Cannot do math with component iterators from different "
536 "tuples.");
537 return it1.ComponentId - it2.ComponentId;
538 }
539
542 {
543 // Different arrays may use different iterator implementations.
544 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
545
546 using std::swap;
547 swap(lhs.TupleId, rhs.TupleId);
548 swap(lhs.ComponentId, rhs.ComponentId);
549 }
550
551private:
552 mutable ArrayType* Array;
553 NumCompsType NumComps;
554 TupleIdType TupleId;
555 ComponentIdType ComponentId;
556};
557
558//------------------------------------------------------------------------------
559// Component iterator
560template <typename ArrayType, ComponentIdType TupleSize>
562{
563private:
564 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
565 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
566
568 using APIType = GetAPIType<ArrayType>;
569
570public:
571 using iterator_category = std::random_access_iterator_tag;
572 using value_type = APIType;
576
578 ComponentIterator() noexcept = default;
579
582 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
583 : Ref(array, numComps, tupleId, comp)
584 {
585 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
586 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
587 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
588 "Component iterator at invalid tuple id.");
590 comp >= 0 && comp <= numComps.value, "Component iterator at invalid component id.");
591 }
592
594 ComponentIterator(const ComponentIterator& o) noexcept = default;
595
598 {
599 this->Ref.CopyReference(o.Ref);
600 return *this;
601 }
602
604 ComponentIterator& operator++() noexcept // prefix
605 {
606 ++this->Ref.ComponentId;
607 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
608 "Component iterator at invalid component id.");
609 return *this;
610 }
611
613 ComponentIterator operator++(int) noexcept // postfix
614 {
615 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
616 this->Ref.ComponentId++ };
617 }
618
620 ComponentIterator& operator--() noexcept // prefix
621 {
622 --this->Ref.ComponentId;
623 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
624 "Component iterator at invalid component id.");
625 return *this;
626 }
627
629 ComponentIterator operator--(int) noexcept // postfix
630 {
631 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
632 this->Ref.ComponentId-- };
633 }
634
637 {
638 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
639 this->Ref.ComponentId + i };
640 }
641
643 reference operator*() const noexcept { return this->Ref; }
644
646 const pointer& operator->() const noexcept { return this->Ref; }
647
648#define VTK_TMP_MAKE_OPERATOR(OP) \
649 friend VTK_ITER_INLINE bool operator OP( \
650 const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
651 { \
652 VTK_ITER_ASSERT( \
653 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
654 VTK_ITER_ASSERT( \
655 lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
656 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
657 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
658 return lhs.GetComponentId() OP rhs.GetComponentId(); \
659 }
660
667
668#undef VTK_TMP_MAKE_OPERATOR
669
672 {
673 this->Ref.ComponentId += offset;
674 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
675 "Component iterator at invalid component id.");
676 return *this;
677 }
678
680 const ComponentIterator& it, difference_type offset) noexcept
681 {
682 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
683 it.GetComponentId() + offset };
684 }
685
687 difference_type offset, const ComponentIterator& it) noexcept
688 {
689 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
690 it.GetComponentId() + offset };
691 }
692
695 {
696 this->Ref.ComponentId -= offset;
697 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
698 "Component iterator at invalid component id.");
699 return *this;
700 }
701
703 const ComponentIterator& it, difference_type offset) noexcept
704 {
705 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
706 it.GetComponentId() - offset };
707 }
708
710 const ComponentIterator& it1, const ComponentIterator& it2) noexcept
711 {
712 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
713 "Cannot do math with component iterators from different "
714 "arrays.");
715 VTK_ITER_ASSERT(it1.GetTupleId() == it2.GetTupleId(),
716 "Cannot do math with component iterators from different "
717 "tuples.");
718 return it1.GetComponentId() - it2.GetComponentId();
719 }
720
722 {
723 // Different arrays may use different iterator implementations.
725 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
726
727 using std::swap;
728 swap(lhs.GetTupleId(), rhs.GetTupleId());
729 swap(lhs.GetComponentId(), rhs.GetComponentId());
730 }
731
732 friend struct ConstComponentIterator<ArrayType, TupleSize>;
733
734protected:
735 // Needed for access from friend functions. We could just store the array
736 // and ID here instead of the ref, but meh.
737 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
738 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
739 const TupleIdType& GetTupleId() const noexcept { return this->Ref.TupleId; }
740 ComponentIdType& GetComponentId() noexcept { return this->Ref.ComponentId; }
741 const ComponentIdType& GetComponentId() const noexcept { return this->Ref.ComponentId; }
742 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
743 const NumCompsType& GetNumComps() const noexcept { return this->Ref.NumComps; }
744
746};
747
748//------------------------------------------------------------------------------
749// Const tuple reference
750template <typename ArrayType, ComponentIdType TupleSize>
752{
753private:
754 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
755 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
756
758 using APIType = GetAPIType<ArrayType>;
759
760public:
762 using value_type = APIType;
766
769 : Array(nullptr)
770 , TupleId(0)
771 {
772 }
773
775 ConstTupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
776 : Array(array)
777 , NumComps(numComps)
778 , TupleId(tupleId)
779 {
780 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
781 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
782 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
783 "Const tuple reference at invalid tuple id.");
784 }
785
788 : Array{ o.Array }
789 , NumComps{ o.NumComps }
790 , TupleId{ o.TupleId }
791 {
792 }
793
795 ConstTupleReference(const ConstTupleReference&) noexcept = default;
798
799 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
801 ConstTupleReference* operator->() noexcept { return this; }
803 const ConstTupleReference* operator->() const noexcept { return this; }
804
805 // Caller must ensure that there are size() elements in array.
807 void GetTuple(APIType* tuple) const noexcept
808 {
809 VTK_ITER_ASSUME(this->NumComps.value > 0);
810 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
812 acc.Get(this->TupleId, tuple);
813 }
814
815 // skips some runtime checks when both sizes are fixed:
816 template <typename OArrayType, ComponentIdType OSize>
818 const TupleReference<OArrayType, OSize>& other) const noexcept
819 {
820 // Check that types are convertible:
821 using OAPIType = GetAPIType<OArrayType>;
822 static_assert(
823 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
824
825 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
826 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
827
828 return std::equal(this->cbegin(), this->cend(), other.cbegin());
829 }
830
831 // Needs a runtime check:
832 template <typename OArrayType, ComponentIdType OSize>
834 const TupleReference<OArrayType, OSize>& other) const noexcept
835 {
836 // Check that types are convertible:
837 using OAPIType = GetAPIType<OArrayType>;
838 static_assert(
839 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
840
842 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
843
844 return std::equal(this->cbegin(), this->cend(), other.cbegin());
845 }
846
847 // skips some runtime checks when both sizes are fixed:
848 template <typename OArrayType, ComponentIdType OSize>
850 const ConstTupleReference<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 ConstTupleReference<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 template <typename OArrayType, ComponentIdType OSize>
881 {
882 return !(*this == o);
883 }
884
885 template <typename OArrayT, ComponentIdType OSize>
887 {
888 return !(*this == o);
889 }
890
893 {
894 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
895 }
896
898 size_type size() const noexcept { return this->NumComps.value; }
899
901 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
903 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
904
906 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
908 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
909
910 friend struct ConstTupleIterator<ArrayType, TupleSize>;
911
912protected:
913 // Intentionally hidden:
916
919 {
920 VTK_ITER_ASSUME(this->NumComps.value > 0);
921 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
922 }
923
925 void CopyReference(const ConstTupleReference& o) noexcept
926 {
927 // Must use same array, other array types may use different implementations.
928 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
929 this->NumComps = o.NumComps;
930 this->TupleId = o.TupleId;
931 }
932
933 mutable ArrayType* Array;
936};
937
938//------------------------------------------------------------------------------
939// Tuple reference
940template <typename ArrayType, ComponentIdType TupleSize>
942{
943private:
944 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
945 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
946
948 using APIType = GetAPIType<ArrayType>;
949
950public:
952 using value_type = APIType;
957
959 TupleReference() noexcept
960 : Array(nullptr)
961 , TupleId(0)
962 {
963 }
964
966 TupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
967 : Array(array)
968 , NumComps(numComps)
969 , TupleId(tupleId)
970 {
971 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
972 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
973 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
974 "Tuple reference at invalid tuple id.");
975 }
976
981
982 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
984 TupleReference* operator->() noexcept { return this; }
986 const TupleReference* operator->() const noexcept { return this; }
987
988 // Caller must ensure that there are size() elements in array.
990 void GetTuple(APIType* tuple) const noexcept
991 {
992 VTK_ITER_ASSUME(this->NumComps.value > 0);
993 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
995 acc.Get(this->TupleId, tuple);
996 }
997
998 // Caller must ensure that there are size() elements in array.
1000 void SetTuple(const APIType* tuple) noexcept
1001 {
1002 VTK_ITER_ASSUME(this->NumComps.value > 0);
1003 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1005 acc.Set(this->TupleId, tuple);
1006 }
1007
1010 {
1011 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1012 return *this;
1013 }
1014
1015 // skips some runtime checks when both sizes are fixed:
1016 template <typename OArrayType, ComponentIdType OSize>
1018 const TupleReference<OArrayType, OSize>& other) noexcept
1019 {
1020 // Check that types are convertible:
1021 using OAPIType = GetAPIType<OArrayType>;
1022 static_assert(
1023 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1024
1025 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1026 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1027
1028 std::copy_n(other.cbegin(), OSize, this->begin());
1029 return *this;
1030 }
1031
1032 // Needs a runtime check:
1033 template <typename OArrayType, ComponentIdType OSize>
1035 const TupleReference<OArrayType, OSize>& other) noexcept
1036 {
1037 // Check that types are convertible:
1038 using OAPIType = GetAPIType<OArrayType>;
1039 static_assert(
1040 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1041
1043 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1044
1045 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1046 return *this;
1047 }
1048
1049 // skips some runtime checks when both sizes are fixed:
1050 template <typename OArrayType, ComponentIdType OSize>
1052 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1053 {
1054 // Check that types are convertible:
1055 using OAPIType = GetAPIType<OArrayType>;
1056 static_assert(
1057 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1058
1059 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1060 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1061
1062 std::copy_n(other.cbegin(), OSize, this->begin());
1063 return *this;
1064 }
1065
1066 // Needs a runtime check:
1067 template <typename OArrayType, ComponentIdType OSize>
1069 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1070 {
1071 // Check that types are convertible:
1072 using OAPIType = GetAPIType<OArrayType>;
1073 static_assert(
1074 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1075
1077 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1078
1079 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1080 return *this;
1081 }
1082
1083 // skips some runtime checks when both sizes are fixed:
1084 template <typename OArrayType, ComponentIdType OSize>
1086 const TupleReference<OArrayType, OSize>& other) const noexcept
1087 {
1088 // Check that types are convertible:
1089 using OAPIType = GetAPIType<OArrayType>;
1090 static_assert(
1091 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1092
1093 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1094 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1095
1096 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1097 }
1098
1099 // Needs a runtime check:
1100 template <typename OArrayType, ComponentIdType OSize>
1102 const TupleReference<OArrayType, OSize>& other) const noexcept
1103 {
1104 // Check that types are convertible:
1105 using OAPIType = GetAPIType<OArrayType>;
1106 static_assert(
1107 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1108
1110 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1111
1112 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1113 }
1114
1115 // skips some runtime checks when both sizes are fixed:
1116 template <typename OArrayType, ComponentIdType OSize>
1118 const ConstTupleReference<OArrayType, OSize>& other) const 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 comparing tuples.");
1124
1125 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1126 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1127
1128 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1129 }
1130
1131 // Needs a runtime check:
1132 template <typename OArrayType, ComponentIdType OSize>
1134 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1135 {
1136 // Check that types are convertible:
1137 using OAPIType = GetAPIType<OArrayType>;
1138 static_assert(
1139 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1140
1142 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1143
1144 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1145 }
1146
1147 template <typename OArrayType, ComponentIdType OSize>
1149 {
1150 return !(*this == o);
1151 }
1152
1153 template <typename OArray, ComponentIdType OSize>
1155 {
1156 return !(*this == o);
1157 }
1158
1159 // skips some runtime checks:
1160 template <typename OArrayType, ComponentIdType OSize>
1162 TupleReference<OArrayType, OSize> other) noexcept
1163 {
1164 // Check that types are convertible:
1165 using OAPIType = GetAPIType<OArrayType>;
1166 static_assert(
1167 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1168
1169 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1170 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
1171
1172 std::swap_ranges(this->begin(), this->end(), other.begin());
1173 }
1174
1175 // Needs a runtime check:
1176 template <typename OArrayType, ComponentIdType OSize>
1178 TupleReference<OArrayType, OSize> other) noexcept
1179 {
1180 // Check that types are convertible:
1181 using OAPIType = GetAPIType<OArrayType>;
1182 static_assert(
1183 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1184
1186 other.size() == this->NumComps.value, "Cannot swap tuples with different sizes.");
1187
1188 std::swap_ranges(this->begin(), this->end(), other.begin());
1189 }
1190
1191 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
1192
1193 template <typename OArray, ComponentIdType OSize>
1195 {
1196 a.swap(b);
1197 }
1198
1201 {
1202 return reference{ this->Array, this->NumComps, this->TupleId, i };
1203 }
1204
1207 {
1208 // Let the reference type do the lookup during implicit conversion.
1209 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
1210 }
1211
1213 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
1214
1216 size_type size() const noexcept { return this->NumComps.value; }
1217
1219 iterator begin() noexcept { return this->NewIterator(0); }
1221 iterator end() noexcept { return this->NewIterator(this->NumComps.value); }
1222
1224 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
1226 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1227
1229 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
1231 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1232
1233 friend struct ConstTupleReference<ArrayType, TupleSize>;
1234 friend struct TupleIterator<ArrayType, TupleSize>;
1235
1236protected:
1239 {
1240 VTK_ITER_ASSUME(this->NumComps.value > 0);
1241 return iterator{ this->Array, this->NumComps, this->TupleId, comp };
1242 }
1243
1246 {
1247 VTK_ITER_ASSUME(this->NumComps.value > 0);
1248 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
1249 }
1250
1252 void CopyReference(const TupleReference& o) noexcept
1253 {
1254 // Must use same array, other array types may use different implementations.
1255 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
1256 this->NumComps = o.NumComps;
1257 this->TupleId = o.TupleId;
1258 }
1259
1260 mutable ArrayType* Array;
1263};
1264
1265//------------------------------------------------------------------------------
1266// Const tuple iterator
1267template <typename ArrayType, ComponentIdType TupleSize>
1269{
1270private:
1271 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1272 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1273
1275
1276public:
1277 using iterator_category = std::random_access_iterator_tag;
1282
1284 ConstTupleIterator() noexcept = default;
1285
1287 ConstTupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1288 : Ref(array, numComps, tupleId)
1289 {
1290 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1291 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1292 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1293 "Const tuple iterator at invalid tuple id.");
1294 }
1295
1298 : Ref{ o.Ref }
1299 {
1300 }
1301
1303 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
1306 {
1307 this->Ref.CopyReference(o.Ref);
1308 return *this;
1309 }
1310
1312 ConstTupleIterator& operator++() noexcept // prefix
1313 {
1314 ++this->Ref.TupleId;
1316 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1317 "Const tuple iterator at invalid component id.");
1318 return *this;
1319 }
1320
1322 ConstTupleIterator operator++(int) noexcept // postfix
1323 {
1324 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1325 }
1326
1328 ConstTupleIterator& operator--() noexcept // prefix
1329 {
1330 --this->Ref.TupleId;
1332 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1333 "Const tuple iterator at invalid component id.");
1334 return *this;
1335 }
1336
1338 ConstTupleIterator operator--(int) noexcept // postfix
1339 {
1340 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1341 }
1342
1345 {
1346 return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1347 }
1348
1350 reference operator*() noexcept { return this->Ref; }
1351
1353 pointer operator->() noexcept { return this->Ref; }
1354
1355#define VTK_TMP_MAKE_OPERATOR(OP) \
1356 friend VTK_ITER_INLINE bool operator OP( \
1357 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1358 { \
1359 VTK_ITER_ASSERT( \
1360 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1361 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1362 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1363 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1364 }
1365
1372
1373#undef VTK_TMP_MAKE_OPERATOR
1374
1377 {
1378 this->Ref.TupleId += offset;
1380 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1381 "Const tuple iterator at invalid component id.");
1382 return *this;
1383 }
1384
1386 const ConstTupleIterator& it, difference_type offset) noexcept
1387 {
1388 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1389 }
1390
1392 difference_type offset, const ConstTupleIterator& it) noexcept
1393 {
1394 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1395 }
1396
1399 {
1400 this->Ref.TupleId -= offset;
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 const ConstTupleIterator& it, difference_type offset) noexcept
1409 {
1410 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1411 }
1412
1414 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
1415 {
1416 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1417 "Cannot do math with tuple iterators from different "
1418 "arrays.");
1419 return it1.GetTupleId() - it2.GetTupleId();
1420 }
1421
1423 {
1424 // Different arrays may use different iterator implementations.
1426 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1427
1428 using std::swap;
1429 swap(lhs.GetTupleId(), rhs.GetTupleId());
1430 }
1431
1432private:
1434 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1436 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1438 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1440 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1442 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1444 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1445
1446 ConstTupleReference<ArrayType, TupleSize> Ref;
1447};
1448
1449//------------------------------------------------------------------------------
1450// Tuple iterator
1451template <typename ArrayType, ComponentIdType TupleSize>
1453{
1454private:
1455 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1456 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1457
1459
1460public:
1461 using iterator_category = std::random_access_iterator_tag;
1466
1468 TupleIterator() noexcept = default;
1469
1471 TupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1472 : Ref(array, numComps, tupleId)
1473 {
1474 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1475 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1477 tupleId >= 0 && tupleId <= array->GetNumberOfTuples(), "Tuple iterator at invalid tuple id.");
1478 }
1479
1481 TupleIterator(const TupleIterator& o) noexcept = default;
1482
1485 {
1486 this->Ref.CopyReference(o.Ref);
1487 return *this;
1488 }
1489
1491 TupleIterator& operator++() noexcept // prefix
1492 {
1493 ++this->Ref.TupleId;
1495 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1496 "Tuple iterator at invalid component id.");
1497 return *this;
1498 }
1499
1501 TupleIterator operator++(int) noexcept // postfix
1502 {
1503 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1504 }
1505
1507 TupleIterator& operator--() noexcept // prefix
1508 {
1509 --this->Ref.TupleId;
1511 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1512 "Tuple iterator at invalid component id.");
1513 return *this;
1514 }
1515
1517 TupleIterator operator--(int) noexcept // postfix
1518 {
1519 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1520 }
1521
1524 {
1525 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId + i };
1526 }
1527
1529 reference operator*() noexcept { return this->Ref; }
1530
1532 pointer& operator->() noexcept { return this->Ref; }
1533
1534#define VTK_TMP_MAKE_OPERATOR(OP) \
1535 friend VTK_ITER_INLINE bool operator OP( \
1536 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1537 { \
1538 VTK_ITER_ASSERT( \
1539 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1540 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1541 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1542 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1543 }
1544
1551
1552#undef VTK_TMP_MAKE_OPERATOR
1553
1556 {
1557 this->Ref.TupleId += offset;
1559 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1560 "Tuple iterator at invalid component id.");
1561 return *this;
1562 }
1563
1565 const TupleIterator& it, difference_type offset) noexcept
1566 {
1567 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1568 }
1569
1571 difference_type offset, const TupleIterator& it) noexcept
1572 {
1573 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1574 }
1575
1578 {
1579 this->Ref.TupleId -= offset;
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 const TupleIterator& it, difference_type offset) noexcept
1588 {
1589 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1590 }
1591
1593 const TupleIterator& it1, const TupleIterator& it2) noexcept
1594 {
1595 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1596 "Cannot do math with tuple iterators from different "
1597 "arrays.");
1598 return it1.GetTupleId() - it2.GetTupleId();
1599 }
1600
1601 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
1602 {
1603 // Different arrays may use different iterator implementations.
1605 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1606
1607 using std::swap;
1608 swap(lhs.GetTupleId(), rhs.GetTupleId());
1609 }
1610
1611 friend struct ConstTupleIterator<ArrayType, TupleSize>;
1612 friend struct ConstTupleReference<ArrayType, TupleSize>;
1613
1614protected:
1616 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1618 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1620 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1622 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1624 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1626 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1627
1629};
1630
1631//------------------------------------------------------------------------------
1632// Tuple range
1633template <typename ArrayTypeT, ComponentIdType TupleSize>
1635{
1636private:
1638 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1639 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
1640
1641public:
1642 using ArrayType = ArrayTypeT;
1653
1654 // May be DynamicTupleSize, or the actual tuple size.
1655 constexpr static ComponentIdType TupleSizeTag = TupleSize;
1656
1662
1664 TupleRange() noexcept = default;
1665
1667 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
1668 : Array(arr)
1669 , NumComps(arr)
1670 , BeginTuple(beginTuple)
1671 , EndTuple(endTuple)
1672 {
1673 assert(this->Array);
1674 assert(beginTuple >= 0 && beginTuple <= endTuple);
1675 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1676 }
1677
1679 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1680 {
1681 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1682 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1683
1684 return TupleRange{ this->Array, realBegin, realEnd };
1685 }
1686
1688 ArrayType* GetArray() const noexcept { return this->Array; }
1690 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1692 TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1694 TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1695
1697 size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1698
1700 iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1702 iterator end() noexcept { return this->NewIter(this->EndTuple); }
1703
1705 const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1707 const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1708
1710 const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1712 const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1713
1716 {
1717 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1718 }
1719
1722 {
1723 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1724 }
1725
1726private:
1728 iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1729
1731 const_iterator NewCIter(TupleIdType t) const
1732 {
1733 return const_iterator{ this->Array, this->NumComps, t };
1734 }
1735
1736 mutable ArrayType* Array{ nullptr };
1737 NumCompsType NumComps{};
1738 TupleIdType BeginTuple{ 0 };
1739 TupleIdType EndTuple{ 0 };
1740};
1741
1742// Unimplemented, only used inside decltype in SelectTupleRange:
1743template <typename ArrayType, ComponentIdType TupleSize>
1745
1746} // end namespace detail
1747} // end namespace vtk
1748
1750
1751#endif // __VTK_WRAP__
1752
1753// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_Generic.h
abstract superclass for arrays of numeric data
typename std::enable_if< IsEitherTupleSizeDynamic< S1, S2 >::value, T >::type EnableIfEitherTupleSizeIsDynamic
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType >::APIType GetAPIType
vtkIdType TupleIdType
int ComponentIdType
Efficient templated access to vtkDataArray.
VTK_ALWAYS_INLINE APIType Get(vtkIdType tupleIdx, int compIdx) const
VTK_ALWAYS_INLINE void Set(vtkIdType tupleIdx, int compIdx, APIType val) const
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
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
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
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
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
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
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
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
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
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ConstTupleReference & operator=(const ConstTupleReference &) noexcept=default
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
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
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
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
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
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE iterator end() noexcept
ConstTupleReference< ArrayType, TupleSize > ConstTupleReferenceType
VTK_ITER_INLINE TupleRange GetSubRange(TupleIdType beginTuple=0, TupleIdType endTuple=-1) const noexcept
VTK_ITER_INLINE iterator begin() 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
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 * operator->() noexcept
VTK_ITER_INLINE TupleReference(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
VTK_ITER_INLINE TupleReference & operator=(const TupleReference &other) noexcept
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
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 TupleReference(TupleReference &&)=default
VTK_ITER_INLINE iterator end() noexcept
VTK_ITER_INLINE void fill(const value_type &v) 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
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)