VTK  9.3.0
vtkDataArrayTupleRange_Generic.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
8#ifndef vtkDataArrayTupleRange_Generic_h
9#define vtkDataArrayTupleRange_Generic_h
10
11#include "vtkAssume.h"
13#include "vtkDataArrayMeta.h"
14
15#include <algorithm>
16#include <cassert>
17#include <iterator>
18#include <type_traits>
19
21
22namespace vtk
23{
24namespace detail
25{
26VTK_ABI_NAMESPACE_BEGIN
27
28// Forward decs for friends/args
29template <typename ArrayType, ComponentIdType>
30struct ConstComponentReference;
31template <typename ArrayType, ComponentIdType>
32struct ComponentReference;
33template <typename ArrayType, ComponentIdType>
34struct ConstComponentIterator;
35template <typename ArrayType, ComponentIdType>
36struct ComponentIterator;
37template <typename ArrayType, ComponentIdType>
38struct ConstTupleReference;
39template <typename ArrayType, ComponentIdType>
40struct TupleReference;
41template <typename ArrayType, ComponentIdType>
42struct ConstTupleIterator;
43template <typename ArrayType, ComponentIdType>
44struct TupleIterator;
45template <typename ArrayType, ComponentIdType>
46struct TupleRange;
47
48//------------------------------------------------------------------------------
49// Const component reference
50template <typename ArrayType, ComponentIdType TupleSize>
52{
53private:
54 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
55 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
56
58 using APIType = GetAPIType<ArrayType>;
59
60public:
61 using value_type = APIType;
62
65 : Array{ nullptr }
66 , NumComps{}
67 , TupleId{ 0 }
68 , ComponentId{ 0 }
69 {
70 }
71
74 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
75 : Array{ array }
76 , NumComps{ numComps }
77 , TupleId{ tuple }
78 , ComponentId{ comp }
79 {
80 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
81 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
83 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
84 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
85 "Invalid component accessed by iterator.");
86 }
87
90 : Array{ o.Array }
91 , NumComps{ o.NumComps }
92 , TupleId{ o.TupleId }
94 {
95 }
96
99
102
105 {
106 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
107 // Initialize the reference.
108 this->Array = o.Array;
109 this->NumComps = o.NumComps;
110 this->TupleId = o.TupleId;
111 this->ComponentId = o.ComponentId;
112 }
113
116 {
117 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
118 // Initialize the reference.
119 this->Array = std::move(o.Array);
120 this->NumComps = std::move(o.NumComps);
121 this->TupleId = std::move(o.TupleId);
122 this->ComponentId = std::move(o.ComponentId);
123 }
124
126 operator APIType() const noexcept
127 {
128 VTK_ITER_ASSUME(this->NumComps.value > 0);
129 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
131 return acc.Get(this->TupleId, this->ComponentId);
132 }
133
134protected:
135 mutable ArrayType* Array;
139};
140
141//------------------------------------------------------------------------------
142// Component reference
143template <typename ArrayType, ComponentIdType TupleSize>
145{
146private:
147 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
148 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
149
151 using APIType = GetAPIType<ArrayType>;
152
153public:
154 using value_type = APIType;
155
158 : Array{ nullptr }
159 , NumComps{}
160 , TupleId{ 0 }
161 , ComponentId{ 0 }
162 {
163 }
164
167 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
168 : Array{ array }
169 , NumComps{ numComps }
170 , TupleId{ tuple }
171 , ComponentId{ comp }
172 {
173 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
174 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
176 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
177 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
178 "Invalid component accessed by iterator.");
179 }
180
182 ComponentReference(const ComponentReference& o) noexcept = default;
184 ComponentReference(ComponentReference&& o) noexcept = default;
185
188 {
189 if (this->Array)
190 { // Already initialized. Assign the value, not the reference
191 return *this = static_cast<APIType>(o);
192 }
193 else
194 { // Initialize the reference.
195 this->Array = o.Array;
196 this->NumComps = o.NumComps;
197 this->TupleId = o.TupleId;
198 this->ComponentId = o.ComponentId;
199
200 return *this;
201 }
202 }
203
206 {
207 if (this->Array)
208 { // Already initialized. Assign the value, not the reference
209 return *this = std::move(static_cast<APIType>(o));
210 }
211 else
212 { // Initialize the reference.
213 this->Array = std::move(o.Array);
214 this->NumComps = std::move(o.NumComps);
215 this->TupleId = std::move(o.TupleId);
216 this->ComponentId = std::move(o.ComponentId);
217
218 return *this;
219 }
220 }
221
222 template <typename OArray, ComponentIdType OSize>
224 { // Always copy the value for different reference types:
225 const APIType tmp = o;
226 return *this = std::move(tmp);
227 }
228
230 operator APIType() const noexcept
231 {
232 VTK_ITER_ASSUME(this->NumComps.value > 0);
233 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
235 return acc.Get(this->TupleId, this->ComponentId);
236 }
237
239 ComponentReference operator=(APIType val) noexcept
240 {
241 VTK_ITER_ASSUME(this->NumComps.value > 0);
242 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
244 acc.Set(this->TupleId, this->ComponentId, val);
245 return *this;
246 }
247
249 { // Swap values, not references:
250 APIType tmp = std::move(static_cast<APIType>(lhs));
251 lhs = std::move(static_cast<APIType>(rhs));
252 rhs = std::move(tmp);
253 }
254
255 template <typename OArray, ComponentIdType OSize>
258 { // Swap values, not references:
259 using OAPIType = GetAPIType<OArray>;
260 static_assert(
261 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
262
263 APIType tmp = std::move(static_cast<APIType>(lhs));
264 lhs = std::move(static_cast<APIType>(rhs));
265 rhs = std::move(tmp);
266 }
267
268 friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType& rhs) noexcept
269 {
270 APIType tmp = std::move(static_cast<APIType>(lhs));
271 lhs = std::move(rhs);
272 rhs = std::move(tmp);
273 }
274
275 friend VTK_ITER_INLINE void swap(APIType& lhs, ComponentReference rhs) noexcept
276 {
277 APIType tmp = std::move(lhs);
278 lhs = std::move(static_cast<APIType>(rhs));
279 rhs = std::move(tmp);
280 }
281
283 ComponentReference operator++() noexcept // prefix
284 {
285 const APIType newVal = *this + 1;
286 *this = newVal;
287 return *this;
288 }
289
291 APIType operator++(int) noexcept // postfix
292 {
293 const APIType retVal = *this;
294 *this = *this + 1;
295 return retVal;
296 }
297
299 ComponentReference operator--() noexcept // prefix
300 {
301 const APIType newVal = *this - 1;
302 *this = newVal;
303 return *this;
304 }
305
307 APIType operator--(int) noexcept // postfix
308 {
309 const APIType retVal = *this;
310 *this = *this - 1;
311 return retVal;
312 }
313
314#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
315 friend VTK_ITER_INLINE ComponentReference operator Op( \
316 ComponentReference lhs, APIType val) noexcept \
317 { \
318 const APIType newVal = lhs ImplOp val; \
319 lhs = newVal; \
320 return lhs; \
321 } \
322 friend VTK_ITER_INLINE ComponentReference operator Op( \
323 ComponentReference lhs, ComponentReference val) noexcept \
324 { \
325 const APIType newVal = lhs ImplOp val; \
326 lhs = newVal; \
327 return lhs; \
328 } \
329 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ComponentReference val) noexcept \
330 { \
331 const APIType newVal = lhs ImplOp val; \
332 lhs = newVal; \
333 return lhs; \
334 }
335
340
341#undef VTK_REF_OP_OVERLOADS
342
343 friend struct ConstComponentReference<ArrayType, TupleSize>;
344 friend struct ComponentIterator<ArrayType, TupleSize>;
345
346protected:
348 void CopyReference(const ComponentReference& o) noexcept
349 {
350 this->Array = o.Array;
351 this->NumComps = o.NumComps;
352 this->TupleId = o.TupleId;
353 this->ComponentId = o.ComponentId;
354 }
355
356 mutable ArrayType* Array;
360};
361
362//------------------------------------------------------------------------------
363// Const component iterator
364template <typename ArrayType, ComponentIdType TupleSize>
366{
367private:
368 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
369 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
370
372
373public:
374 using iterator_category = std::random_access_iterator_tag;
377 using pointer = void;
379
382 : Array{ nullptr }
383 , TupleId{ 0 }
384 , ComponentId{ 0 }
385 {
386 }
387
390 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
391 : Array(array)
392 , NumComps(numComps)
393 , TupleId(tupleId)
394 , ComponentId(comp)
395 {
396 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
397 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
398 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
399 "Const component iterator at invalid tuple id.");
400 VTK_ITER_ASSERT(comp >= 0 && comp <= this->NumComps.value,
401 "Const component iterator at invalid component id.");
402 }
403
406 : Array{ o.GetArray() }
407 , NumComps{ o.GetNumComps() }
408 , TupleId{ o.GetTupleId() }
409 , ComponentId{ o.GetComponentId() }
410 {
411 }
412
414 ConstComponentIterator(const ConstComponentIterator& o) noexcept = default;
417
419 ConstComponentIterator& operator++() noexcept // prefix
420 {
421 ++this->ComponentId;
422 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
423 "Const component iterator at invalid component id.");
424 return *this;
425 }
426
428 ConstComponentIterator operator++(int) noexcept // postfix
429 {
430 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
431 this->ComponentId++ };
432 }
433
435 ConstComponentIterator& operator--() noexcept // prefix
436 {
437 --this->ComponentId;
438 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
439 "Const component iterator at invalid component id.");
440 return *this;
441 }
442
444 ConstComponentIterator operator--(int) noexcept // postfix
445 {
446 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
447 this->ComponentId-- };
448 }
449
452 {
453 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
454 }
455
457 reference operator*() const noexcept
458 {
459 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
460 }
461
462#define VTK_TMP_MAKE_OPERATOR(OP) \
463 friend VTK_ITER_INLINE bool operator OP( \
464 const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
465 { \
466 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
467 VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
468 VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
469 VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
470 return lhs.ComponentId OP rhs.ComponentId; \
471 }
472
479
480#undef VTK_TMP_MAKE_OPERATOR
481
484 {
485 this->ComponentId += offset;
486 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
487 "Const component iterator at invalid component id.");
488 return *this;
489 }
490
492 const ConstComponentIterator& it, difference_type offset) noexcept
493 {
494 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
495 }
496
498 difference_type offset, const ConstComponentIterator& it) noexcept
499 {
500 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
501 }
502
505 {
506 this->ComponentId -= offset;
507 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
508 "Const component iterator at invalid component id.");
509 return *this;
510 }
511
513 const ConstComponentIterator& it, difference_type offset) noexcept
514 {
515 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId - offset };
516 }
517
519 const ConstComponentIterator& it1, const ConstComponentIterator& it2) noexcept
520 {
521 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
522 VTK_ITER_ASSERT(it1.TupleId == it2.TupleId,
523 "Cannot do math with component iterators from different "
524 "tuples.");
525 return it1.ComponentId - it2.ComponentId;
526 }
527
530 {
531 // Different arrays may use different iterator implementations.
532 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
533
534 using std::swap;
535 swap(lhs.TupleId, rhs.TupleId);
536 swap(lhs.ComponentId, rhs.ComponentId);
537 }
538
539private:
540 mutable ArrayType* Array;
541 NumCompsType NumComps;
542 TupleIdType TupleId;
543 ComponentIdType ComponentId;
544};
545
546//------------------------------------------------------------------------------
547// Component iterator
548template <typename ArrayType, ComponentIdType TupleSize>
550{
551private:
552 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
553 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
554
556 using APIType = GetAPIType<ArrayType>;
557
558public:
559 using iterator_category = std::random_access_iterator_tag;
560 using value_type = APIType;
564
566 ComponentIterator() noexcept = default;
567
570 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
571 : Ref(array, numComps, tupleId, comp)
572 {
573 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
574 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
575 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
576 "Component iterator at invalid tuple id.");
578 comp >= 0 && comp <= numComps.value, "Component iterator at invalid component id.");
579 }
580
582 ComponentIterator(const ComponentIterator& o) noexcept = default;
583
586 {
587 this->Ref.CopyReference(o.Ref);
588 return *this;
589 }
590
592 ComponentIterator& operator++() noexcept // prefix
593 {
594 ++this->Ref.ComponentId;
595 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
596 "Component iterator at invalid component id.");
597 return *this;
598 }
599
601 ComponentIterator operator++(int) noexcept // postfix
602 {
603 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
604 this->Ref.ComponentId++ };
605 }
606
608 ComponentIterator& operator--() noexcept // prefix
609 {
610 --this->Ref.ComponentId;
611 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
612 "Component iterator at invalid component id.");
613 return *this;
614 }
615
617 ComponentIterator operator--(int) noexcept // postfix
618 {
619 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
620 this->Ref.ComponentId-- };
621 }
622
625 {
626 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
627 this->Ref.ComponentId + i };
628 }
629
631 reference operator*() const noexcept { return this->Ref; }
632
634 const pointer& operator->() const noexcept { return this->Ref; }
635
636#define VTK_TMP_MAKE_OPERATOR(OP) \
637 friend VTK_ITER_INLINE bool operator OP( \
638 const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
639 { \
640 VTK_ITER_ASSERT( \
641 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
642 VTK_ITER_ASSERT( \
643 lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
644 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
645 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
646 return lhs.GetComponentId() OP rhs.GetComponentId(); \
647 }
648
655
656#undef VTK_TMP_MAKE_OPERATOR
657
660 {
661 this->Ref.ComponentId += offset;
662 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
663 "Component iterator at invalid component id.");
664 return *this;
665 }
666
668 const ComponentIterator& it, difference_type offset) noexcept
669 {
670 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
671 it.GetComponentId() + offset };
672 }
673
675 difference_type offset, const ComponentIterator& it) noexcept
676 {
677 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
678 it.GetComponentId() + offset };
679 }
680
683 {
684 this->Ref.ComponentId -= offset;
685 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
686 "Component iterator at invalid component id.");
687 return *this;
688 }
689
691 const ComponentIterator& it, difference_type offset) noexcept
692 {
693 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
694 it.GetComponentId() - offset };
695 }
696
698 const ComponentIterator& it1, const ComponentIterator& it2) noexcept
699 {
700 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
701 "Cannot do math with component iterators from different "
702 "arrays.");
703 VTK_ITER_ASSERT(it1.GetTupleId() == it2.GetTupleId(),
704 "Cannot do math with component iterators from different "
705 "tuples.");
706 return it1.GetComponentId() - it2.GetComponentId();
707 }
708
710 {
711 // Different arrays may use different iterator implementations.
713 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
714
715 using std::swap;
716 swap(lhs.GetTupleId(), rhs.GetTupleId());
717 swap(lhs.GetComponentId(), rhs.GetComponentId());
718 }
719
720 friend struct ConstComponentIterator<ArrayType, TupleSize>;
721
722protected:
723 // Needed for access from friend functions. We could just store the array
724 // and ID here instead of the ref, but meh.
725 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
726 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
727 const TupleIdType& GetTupleId() const noexcept { return this->Ref.TupleId; }
728 ComponentIdType& GetComponentId() noexcept { return this->Ref.ComponentId; }
729 const ComponentIdType& GetComponentId() const noexcept { return this->Ref.ComponentId; }
730 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
731 const NumCompsType& GetNumComps() const noexcept { return this->Ref.NumComps; }
732
734};
735
736//------------------------------------------------------------------------------
737// Const tuple reference
738template <typename ArrayType, ComponentIdType TupleSize>
740{
741private:
742 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
743 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
744
746 using APIType = GetAPIType<ArrayType>;
747
748public:
750 using value_type = APIType;
754
757 : Array(nullptr)
758 , TupleId(0)
759 {
760 }
761
763 ConstTupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
764 : Array(array)
765 , NumComps(numComps)
766 , TupleId(tupleId)
767 {
768 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
769 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
770 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
771 "Const tuple reference at invalid tuple id.");
772 }
773
776 : Array{ o.Array }
777 , NumComps{ o.NumComps }
778 , TupleId{ o.TupleId }
779 {
780 }
781
783 ConstTupleReference(const ConstTupleReference&) noexcept = default;
786
787 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
789 ConstTupleReference* operator->() noexcept { return this; }
791 const ConstTupleReference* operator->() const noexcept { return this; }
792
793 // Caller must ensure that there are size() elements in array.
795 void GetTuple(APIType* tuple) const noexcept
796 {
797 VTK_ITER_ASSUME(this->NumComps.value > 0);
798 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
800 acc.Get(this->TupleId, tuple);
801 }
802
803 // skips some runtime checks when both sizes are fixed:
804 template <typename OArrayType, ComponentIdType OSize>
806 const TupleReference<OArrayType, OSize>& other) const noexcept
807 {
808 // Check that types are convertible:
809 using OAPIType = GetAPIType<OArrayType>;
810 static_assert(
811 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
812
813 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
814 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
815
816 return std::equal(this->cbegin(), this->cend(), other.cbegin());
817 }
818
819 // Needs a runtime check:
820 template <typename OArrayType, ComponentIdType OSize>
822 const TupleReference<OArrayType, OSize>& other) const noexcept
823 {
824 // Check that types are convertible:
825 using OAPIType = GetAPIType<OArrayType>;
826 static_assert(
827 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
828
830 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
831
832 return std::equal(this->cbegin(), this->cend(), other.cbegin());
833 }
834
835 // skips some runtime checks when both sizes are fixed:
836 template <typename OArrayType, ComponentIdType OSize>
838 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
839 {
840 // Check that types are convertible:
841 using OAPIType = GetAPIType<OArrayType>;
842 static_assert(
843 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
844
845 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
846 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
847
848 return std::equal(this->cbegin(), this->cend(), other.cbegin());
849 }
850
851 // Needs a runtime check:
852 template <typename OArrayType, ComponentIdType OSize>
854 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
855 {
856 // Check that types are convertible:
857 using OAPIType = GetAPIType<OArrayType>;
858 static_assert(
859 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
860
862 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
863
864 return std::equal(this->cbegin(), this->cend(), other.cbegin());
865 }
866
867 template <typename OArrayType, ComponentIdType OSize>
869 {
870 return !(*this == o);
871 }
872
873 template <typename OArrayT, ComponentIdType OSize>
875 {
876 return !(*this == o);
877 }
878
881 {
882 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
883 }
884
886 size_type size() const noexcept { return this->NumComps.value; }
887
889 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
891 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
892
894 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
896 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
897
898 friend struct ConstTupleIterator<ArrayType, TupleSize>;
899
900protected:
901 // Intentionally hidden:
904
907 {
908 VTK_ITER_ASSUME(this->NumComps.value > 0);
909 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
910 }
911
913 void CopyReference(const ConstTupleReference& o) noexcept
914 {
915 // Must use same array, other array types may use different implementations.
916 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
917 this->NumComps = o.NumComps;
918 this->TupleId = o.TupleId;
919 }
920
921 mutable ArrayType* Array;
924};
925
926//------------------------------------------------------------------------------
927// Tuple reference
928template <typename ArrayType, ComponentIdType TupleSize>
930{
931private:
932 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
933 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
934
936 using APIType = GetAPIType<ArrayType>;
937
938public:
940 using value_type = APIType;
945
947 TupleReference() noexcept
948 : Array(nullptr)
949 , TupleId(0)
950 {
951 }
952
954 TupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
955 : Array(array)
956 , NumComps(numComps)
957 , TupleId(tupleId)
958 {
959 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
960 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
961 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
962 "Tuple reference at invalid tuple id.");
963 }
964
968 TupleReference(TupleReference&&) noexcept = default;
969
970 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
972 TupleReference* operator->() noexcept { return this; }
974 const TupleReference* operator->() const noexcept { return this; }
975
976 // Caller must ensure that there are size() elements in array.
978 void GetTuple(APIType* tuple) const noexcept
979 {
980 VTK_ITER_ASSUME(this->NumComps.value > 0);
981 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
983 acc.Get(this->TupleId, tuple);
984 }
985
986 // Caller must ensure that there are size() elements in array.
988 void SetTuple(const APIType* tuple) noexcept
989 {
990 VTK_ITER_ASSUME(this->NumComps.value > 0);
991 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
993 acc.Set(this->TupleId, tuple);
994 }
995
998 {
999 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1000 return *this;
1001 }
1002
1003 // skips some runtime checks when both sizes are fixed:
1004 template <typename OArrayType, ComponentIdType OSize>
1006 const TupleReference<OArrayType, OSize>& other) noexcept
1007 {
1008 // Check that types are convertible:
1009 using OAPIType = GetAPIType<OArrayType>;
1010 static_assert(
1011 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1012
1013 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1014 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1015
1016 std::copy_n(other.cbegin(), OSize, this->begin());
1017 return *this;
1018 }
1019
1020 // Needs a runtime check:
1021 template <typename OArrayType, ComponentIdType OSize>
1023 const TupleReference<OArrayType, OSize>& other) noexcept
1024 {
1025 // Check that types are convertible:
1026 using OAPIType = GetAPIType<OArrayType>;
1027 static_assert(
1028 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1029
1031 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1032
1033 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1034 return *this;
1035 }
1036
1037 // skips some runtime checks when both sizes are fixed:
1038 template <typename OArrayType, ComponentIdType OSize>
1040 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1041 {
1042 // Check that types are convertible:
1043 using OAPIType = GetAPIType<OArrayType>;
1044 static_assert(
1045 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1046
1047 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1048 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1049
1050 std::copy_n(other.cbegin(), OSize, this->begin());
1051 return *this;
1052 }
1053
1054 // Needs a runtime check:
1055 template <typename OArrayType, ComponentIdType OSize>
1057 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1058 {
1059 // Check that types are convertible:
1060 using OAPIType = GetAPIType<OArrayType>;
1061 static_assert(
1062 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1063
1065 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1066
1067 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1068 return *this;
1069 }
1070
1071 // skips some runtime checks when both sizes are fixed:
1072 template <typename OArrayType, ComponentIdType OSize>
1074 const TupleReference<OArrayType, OSize>& other) const noexcept
1075 {
1076 // Check that types are convertible:
1077 using OAPIType = GetAPIType<OArrayType>;
1078 static_assert(
1079 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1080
1081 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1082 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1083
1084 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1085 }
1086
1087 // Needs a runtime check:
1088 template <typename OArrayType, ComponentIdType OSize>
1090 const TupleReference<OArrayType, OSize>& other) const noexcept
1091 {
1092 // Check that types are convertible:
1093 using OAPIType = GetAPIType<OArrayType>;
1094 static_assert(
1095 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1096
1098 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1099
1100 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1101 }
1102
1103 // skips some runtime checks when both sizes are fixed:
1104 template <typename OArrayType, ComponentIdType OSize>
1106 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1107 {
1108 // Check that types are convertible:
1109 using OAPIType = GetAPIType<OArrayType>;
1110 static_assert(
1111 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1112
1113 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1114 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1115
1116 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1117 }
1118
1119 // Needs a runtime check:
1120 template <typename OArrayType, ComponentIdType OSize>
1122 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1123 {
1124 // Check that types are convertible:
1125 using OAPIType = GetAPIType<OArrayType>;
1126 static_assert(
1127 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1128
1130 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1131
1132 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1133 }
1134
1135 template <typename OArrayType, ComponentIdType OSize>
1137 {
1138 return !(*this == o);
1139 }
1140
1141 template <typename OArray, ComponentIdType OSize>
1143 {
1144 return !(*this == o);
1145 }
1146
1147 // skips some runtime checks:
1148 template <typename OArrayType, ComponentIdType OSize>
1150 TupleReference<OArrayType, OSize> other) noexcept
1151 {
1152 // Check that types are convertible:
1153 using OAPIType = GetAPIType<OArrayType>;
1154 static_assert(
1155 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1156
1157 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1158 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
1159
1160 std::swap_ranges(this->begin(), this->end(), other.begin());
1161 }
1162
1163 // Needs a runtime check:
1164 template <typename OArrayType, ComponentIdType OSize>
1166 TupleReference<OArrayType, OSize> other) noexcept
1167 {
1168 // Check that types are convertible:
1169 using OAPIType = GetAPIType<OArrayType>;
1170 static_assert(
1171 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1172
1174 other.size() == this->NumComps.value, "Cannot swap tuples with different sizes.");
1175
1176 std::swap_ranges(this->begin(), this->end(), other.begin());
1177 }
1178
1179 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
1180
1181 template <typename OArray, ComponentIdType OSize>
1183 {
1184 a.swap(b);
1185 }
1186
1189 {
1190 return reference{ this->Array, this->NumComps, this->TupleId, i };
1191 }
1192
1195 {
1196 // Let the reference type do the lookup during implicit conversion.
1197 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
1198 }
1199
1201 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
1202
1204 size_type size() const noexcept { return this->NumComps.value; }
1205
1207 iterator begin() noexcept { return this->NewIterator(0); }
1209 iterator end() noexcept { return this->NewIterator(this->NumComps.value); }
1210
1212 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
1214 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1215
1217 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
1219 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1220
1221 friend struct ConstTupleReference<ArrayType, TupleSize>;
1222 friend struct TupleIterator<ArrayType, TupleSize>;
1223
1224protected:
1227 {
1228 VTK_ITER_ASSUME(this->NumComps.value > 0);
1229 return iterator{ this->Array, this->NumComps, this->TupleId, comp };
1230 }
1231
1234 {
1235 VTK_ITER_ASSUME(this->NumComps.value > 0);
1236 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
1237 }
1238
1240 void CopyReference(const TupleReference& o) noexcept
1241 {
1242 // Must use same array, other array types may use different implementations.
1243 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
1244 this->NumComps = o.NumComps;
1245 this->TupleId = o.TupleId;
1246 }
1247
1248 mutable ArrayType* Array;
1251};
1252
1253//------------------------------------------------------------------------------
1254// Const tuple iterator
1255template <typename ArrayType, ComponentIdType TupleSize>
1257{
1258private:
1259 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1260 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1261
1263
1264public:
1265 using iterator_category = std::random_access_iterator_tag;
1270
1272 ConstTupleIterator() noexcept = default;
1273
1275 ConstTupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1276 : Ref(array, numComps, tupleId)
1277 {
1278 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1279 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1280 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1281 "Const tuple iterator at invalid tuple id.");
1282 }
1283
1286 : Ref{ o.Ref }
1287 {
1288 }
1289
1291 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
1294 {
1295 this->Ref.CopyReference(o.Ref);
1296 return *this;
1297 }
1298
1300 ConstTupleIterator& operator++() noexcept // prefix
1301 {
1302 ++this->Ref.TupleId;
1304 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1305 "Const tuple iterator at invalid component id.");
1306 return *this;
1307 }
1308
1310 ConstTupleIterator operator++(int) noexcept // postfix
1311 {
1312 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1313 }
1314
1316 ConstTupleIterator& operator--() noexcept // prefix
1317 {
1318 --this->Ref.TupleId;
1320 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1321 "Const tuple iterator at invalid component id.");
1322 return *this;
1323 }
1324
1326 ConstTupleIterator operator--(int) noexcept // postfix
1327 {
1328 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1329 }
1330
1333 {
1334 return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1335 }
1336
1338 reference operator*() noexcept { return this->Ref; }
1339
1341 pointer operator->() noexcept { return this->Ref; }
1342
1343#define VTK_TMP_MAKE_OPERATOR(OP) \
1344 friend VTK_ITER_INLINE bool operator OP( \
1345 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1346 { \
1347 VTK_ITER_ASSERT( \
1348 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1349 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1350 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1351 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1352 }
1353
1360
1361#undef VTK_TMP_MAKE_OPERATOR
1362
1365 {
1366 this->Ref.TupleId += offset;
1368 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1369 "Const tuple iterator at invalid component id.");
1370 return *this;
1371 }
1372
1374 const ConstTupleIterator& it, difference_type offset) noexcept
1375 {
1376 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1377 }
1378
1380 difference_type offset, const ConstTupleIterator& it) noexcept
1381 {
1382 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1383 }
1384
1387 {
1388 this->Ref.TupleId -= offset;
1390 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1391 "Const tuple iterator at invalid component id.");
1392 return *this;
1393 }
1394
1396 const ConstTupleIterator& it, difference_type offset) noexcept
1397 {
1398 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1399 }
1400
1402 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
1403 {
1404 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1405 "Cannot do math with tuple iterators from different "
1406 "arrays.");
1407 return it1.GetTupleId() - it2.GetTupleId();
1408 }
1409
1411 {
1412 // Different arrays may use different iterator implementations.
1414 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1415
1416 using std::swap;
1417 swap(lhs.GetTupleId(), rhs.GetTupleId());
1418 }
1419
1420private:
1422 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1424 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1426 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1428 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1430 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1432 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1433
1434 ConstTupleReference<ArrayType, TupleSize> Ref;
1435};
1436
1437//------------------------------------------------------------------------------
1438// Tuple iterator
1439template <typename ArrayType, ComponentIdType TupleSize>
1441{
1442private:
1443 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1444 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1445
1447
1448public:
1449 using iterator_category = std::random_access_iterator_tag;
1454
1456 TupleIterator() noexcept = default;
1457
1459 TupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1460 : Ref(array, numComps, tupleId)
1461 {
1462 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1463 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1465 tupleId >= 0 && tupleId <= array->GetNumberOfTuples(), "Tuple iterator at invalid tuple id.");
1466 }
1467
1469 TupleIterator(const TupleIterator& o) noexcept = default;
1470
1473 {
1474 this->Ref.CopyReference(o.Ref);
1475 return *this;
1476 }
1477
1479 TupleIterator& operator++() noexcept // prefix
1480 {
1481 ++this->Ref.TupleId;
1483 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1484 "Tuple iterator at invalid component id.");
1485 return *this;
1486 }
1487
1489 TupleIterator operator++(int) noexcept // postfix
1490 {
1491 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1492 }
1493
1495 TupleIterator& operator--() noexcept // prefix
1496 {
1497 --this->Ref.TupleId;
1499 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1500 "Tuple iterator at invalid component id.");
1501 return *this;
1502 }
1503
1505 TupleIterator operator--(int) noexcept // postfix
1506 {
1507 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1508 }
1509
1512 {
1513 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId + i };
1514 }
1515
1517 reference operator*() noexcept { return this->Ref; }
1518
1520 pointer& operator->() noexcept { return this->Ref; }
1521
1522#define VTK_TMP_MAKE_OPERATOR(OP) \
1523 friend VTK_ITER_INLINE bool operator OP( \
1524 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1525 { \
1526 VTK_ITER_ASSERT( \
1527 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1528 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1529 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1530 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1531 }
1532
1539
1540#undef VTK_TMP_MAKE_OPERATOR
1541
1544 {
1545 this->Ref.TupleId += offset;
1547 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1548 "Tuple iterator at invalid component id.");
1549 return *this;
1550 }
1551
1553 const TupleIterator& it, difference_type offset) noexcept
1554 {
1555 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1556 }
1557
1559 difference_type offset, const TupleIterator& it) noexcept
1560 {
1561 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1562 }
1563
1566 {
1567 this->Ref.TupleId -= offset;
1569 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1570 "Tuple iterator at invalid component id.");
1571 return *this;
1572 }
1573
1575 const TupleIterator& it, difference_type offset) noexcept
1576 {
1577 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1578 }
1579
1581 const TupleIterator& it1, const TupleIterator& it2) noexcept
1582 {
1583 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1584 "Cannot do math with tuple iterators from different "
1585 "arrays.");
1586 return it1.GetTupleId() - it2.GetTupleId();
1587 }
1588
1589 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
1590 {
1591 // Different arrays may use different iterator implementations.
1593 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1594
1595 using std::swap;
1596 swap(lhs.GetTupleId(), rhs.GetTupleId());
1597 }
1598
1599 friend struct ConstTupleIterator<ArrayType, TupleSize>;
1600 friend struct ConstTupleReference<ArrayType, TupleSize>;
1601
1602protected:
1604 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1606 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1608 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1610 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1612 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1614 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1615
1617};
1618
1619//------------------------------------------------------------------------------
1620// Tuple range
1621template <typename ArrayTypeT, ComponentIdType TupleSize>
1623{
1624private:
1626 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1627 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
1628
1629public:
1630 using ArrayType = ArrayTypeT;
1641
1642 // May be DynamicTupleSize, or the actual tuple size.
1643 constexpr static ComponentIdType TupleSizeTag = TupleSize;
1644
1650
1652 TupleRange() noexcept = default;
1653
1655 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
1656 : Array(arr)
1657 , NumComps(arr)
1658 , BeginTuple(beginTuple)
1659 , EndTuple(endTuple)
1660 {
1661 assert(this->Array);
1662 assert(beginTuple >= 0 && beginTuple <= endTuple);
1663 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1664 }
1665
1667 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1668 {
1669 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1670 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1671
1672 return TupleRange{ this->Array, realBegin, realEnd };
1673 }
1674
1676 ArrayType* GetArray() const noexcept { return this->Array; }
1678 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1680 TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1682 TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1683
1685 size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1686
1688 iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1690 iterator end() noexcept { return this->NewIter(this->EndTuple); }
1691
1693 const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1695 const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1696
1698 const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1700 const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1701
1704 {
1705 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1706 }
1707
1710 {
1711 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1712 }
1713
1714private:
1716 iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1717
1719 const_iterator NewCIter(TupleIdType t) const
1720 {
1721 return const_iterator{ this->Array, this->NumComps, t };
1722 }
1723
1724 mutable ArrayType* Array{ nullptr };
1725 NumCompsType NumComps{};
1726 TupleIdType BeginTuple{ 0 };
1727 TupleIdType EndTuple{ 0 };
1728};
1729
1730// Unimplemented, only used inside decltype in SelectTupleRange:
1731template <typename ArrayType, ComponentIdType TupleSize>
1733
1734VTK_ABI_NAMESPACE_END
1735} // end namespace detail
1736} // end namespace vtk
1737
1739
1740#endif // __VTK_WRAP__
1741
1742// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_Generic.h
abstract superclass for arrays of numeric data
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
typename std::enable_if< IsEitherTupleSizeDynamic< S1, S2 >::value, T >::type EnableIfEitherTupleSizeIsDynamic
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(ArrayType *array, NumCompsType numComps, TupleIdType tupleId) noexcept
VTK_ITER_INLINE TupleReference & operator=(const TupleReference &other) noexcept
VTK_ITER_INLINE TupleReference(TupleReference &&) noexcept=default
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 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)