VTK  9.1.0
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
32#ifndef __VTK_WRAP__
33
35
36namespace vtk
37{
38
39namespace detail
40{
41
42// Forward decs for friends/args
43template <typename ArrayType, ComponentIdType>
44struct ConstComponentReference;
45template <typename ArrayType, ComponentIdType>
46struct ComponentReference;
47template <typename ArrayType, ComponentIdType>
48struct ConstComponentIterator;
49template <typename ArrayType, ComponentIdType>
50struct ComponentIterator;
51template <typename ArrayType, ComponentIdType>
52struct ConstTupleReference;
53template <typename ArrayType, ComponentIdType>
54struct TupleReference;
55template <typename ArrayType, ComponentIdType>
56struct ConstTupleIterator;
57template <typename ArrayType, ComponentIdType>
58struct TupleIterator;
59template <typename ArrayType, ComponentIdType>
60struct TupleRange;
61
62//------------------------------------------------------------------------------
63// Const component reference
64template <typename ArrayType, ComponentIdType TupleSize>
66{
67private:
68 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
69 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
70
72 using APIType = GetAPIType<ArrayType>;
73
74public:
75 using value_type = APIType;
76
79 : Array{ nullptr }
80 , NumComps{}
81 , TupleId{ 0 }
82 , ComponentId{ 0 }
83 {
84 }
85
88 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
89 : Array{ array }
90 , NumComps{ numComps }
91 , TupleId{ tuple }
92 , ComponentId{ comp }
93 {
94 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
95 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
97 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
98 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
99 "Invalid component accessed by iterator.");
100 }
101
104 : Array{ o.Array }
105 , NumComps{ o.NumComps }
106 , TupleId{ o.TupleId }
108 {
109 }
110
113
116
119 {
120 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
121 // Initialize the reference.
122 this->Array = o.Array;
123 this->NumComps = o.NumComps;
124 this->TupleId = o.TupleId;
125 this->ComponentId = o.ComponentId;
126 }
127
130 {
131 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
132 // Initialize the reference.
133 this->Array = std::move(o.Array);
134 this->NumComps = std::move(o.NumComps);
135 this->TupleId = std::move(o.TupleId);
136 this->ComponentId = std::move(o.ComponentId);
137 }
138
140 operator APIType() const noexcept
141 {
142 VTK_ITER_ASSUME(this->NumComps.value > 0);
143 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
145 return acc.Get(this->TupleId, this->ComponentId);
146 }
147
148protected:
149 mutable ArrayType* Array;
153};
154
155//------------------------------------------------------------------------------
156// Component reference
157template <typename ArrayType, ComponentIdType TupleSize>
159{
160private:
161 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
162 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
163
165 using APIType = GetAPIType<ArrayType>;
166
167public:
168 using value_type = APIType;
169
172 : Array{ nullptr }
173 , NumComps{}
174 , TupleId{ 0 }
175 , ComponentId{ 0 }
176 {
177 }
178
181 ArrayType* array, NumCompsType numComps, TupleIdType tuple, ComponentIdType comp) noexcept
182 : Array{ array }
183 , NumComps{ numComps }
184 , TupleId{ tuple }
185 , ComponentId{ comp }
186 {
187 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
188 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
190 tuple >= 0 && tuple <= array->GetNumberOfTuples(), "Invalid tuple accessed by iterator.");
191 VTK_ITER_ASSERT(comp >= 0 && comp <= array->GetNumberOfComponents(),
192 "Invalid component accessed by iterator.");
193 }
194
196 ComponentReference(const ComponentReference& o) noexcept = default;
198 ComponentReference(ComponentReference&& o) noexcept = default;
199
202 {
203 if (this->Array)
204 { // Already initialized. Assign the value, not the reference
205 return *this = static_cast<APIType>(o);
206 }
207 else
208 { // Initialize the reference.
209 this->Array = o.Array;
210 this->NumComps = o.NumComps;
211 this->TupleId = o.TupleId;
212 this->ComponentId = o.ComponentId;
213
214 return *this;
215 }
216 }
217
220 {
221 if (this->Array)
222 { // Already initialized. Assign the value, not the reference
223 return *this = std::move(static_cast<APIType>(o));
224 }
225 else
226 { // Initialize the reference.
227 this->Array = std::move(o.Array);
228 this->NumComps = std::move(o.NumComps);
229 this->TupleId = std::move(o.TupleId);
230 this->ComponentId = std::move(o.ComponentId);
231
232 return *this;
233 }
234 }
235
236 template <typename OArray, ComponentIdType OSize>
238 { // Always copy the value for different reference types:
239 const APIType tmp = o;
240 return *this = std::move(tmp);
241 }
242
244 operator APIType() const noexcept
245 {
246 VTK_ITER_ASSUME(this->NumComps.value > 0);
247 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
249 return acc.Get(this->TupleId, this->ComponentId);
250 }
251
253 ComponentReference operator=(APIType val) noexcept
254 {
255 VTK_ITER_ASSUME(this->NumComps.value > 0);
256 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
258 acc.Set(this->TupleId, this->ComponentId, val);
259 return *this;
260 }
261
263 { // Swap values, not references:
264 APIType tmp = std::move(static_cast<APIType>(lhs));
265 lhs = std::move(static_cast<APIType>(rhs));
266 rhs = std::move(tmp);
267 }
268
269 template <typename OArray, ComponentIdType OSize>
272 { // Swap values, not references:
273 using OAPIType = GetAPIType<OArray>;
274 static_assert(
275 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
276
277 APIType tmp = std::move(static_cast<APIType>(lhs));
278 lhs = std::move(static_cast<APIType>(rhs));
279 rhs = std::move(tmp);
280 }
281
282 friend VTK_ITER_INLINE void swap(ComponentReference lhs, APIType& rhs) noexcept
283 {
284 APIType tmp = std::move(static_cast<APIType>(lhs));
285 lhs = std::move(rhs);
286 rhs = std::move(tmp);
287 }
288
289 friend VTK_ITER_INLINE void swap(APIType& lhs, ComponentReference rhs) noexcept
290 {
291 APIType tmp = std::move(lhs);
292 lhs = std::move(static_cast<APIType>(rhs));
293 rhs = std::move(tmp);
294 }
295
297 ComponentReference operator++() noexcept // prefix
298 {
299 const APIType newVal = *this + 1;
300 *this = newVal;
301 return *this;
302 }
303
305 APIType operator++(int) noexcept // postfix
306 {
307 const APIType retVal = *this;
308 *this = *this + 1;
309 return retVal;
310 }
311
313 ComponentReference operator--() noexcept // prefix
314 {
315 const APIType newVal = *this - 1;
316 *this = newVal;
317 return *this;
318 }
319
321 APIType operator--(int) noexcept // postfix
322 {
323 const APIType retVal = *this;
324 *this = *this - 1;
325 return retVal;
326 }
327
328#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
329 friend VTK_ITER_INLINE ComponentReference operator Op( \
330 ComponentReference lhs, APIType val) noexcept \
331 { \
332 const APIType newVal = lhs ImplOp val; \
333 lhs = newVal; \
334 return lhs; \
335 } \
336 friend VTK_ITER_INLINE ComponentReference operator Op( \
337 ComponentReference lhs, ComponentReference val) noexcept \
338 { \
339 const APIType newVal = lhs ImplOp val; \
340 lhs = newVal; \
341 return lhs; \
342 } \
343 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ComponentReference val) noexcept \
344 { \
345 const APIType newVal = lhs ImplOp val; \
346 lhs = newVal; \
347 return lhs; \
348 }
349
354
355#undef VTK_REF_OP_OVERLOADS
356
357 friend struct ConstComponentReference<ArrayType, TupleSize>;
358 friend struct ComponentIterator<ArrayType, TupleSize>;
359
360protected:
362 void CopyReference(const ComponentReference& o) noexcept
363 {
364 this->Array = o.Array;
365 this->NumComps = o.NumComps;
366 this->TupleId = o.TupleId;
367 this->ComponentId = o.ComponentId;
368 }
369
370 mutable ArrayType* Array;
374};
375
376//------------------------------------------------------------------------------
377// Const component iterator
378template <typename ArrayType, ComponentIdType TupleSize>
380{
381private:
382 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
383 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
384
386
387public:
388 using iterator_category = std::random_access_iterator_tag;
391 using pointer = void;
393
396 : Array{ nullptr }
397 , TupleId{ 0 }
398 , ComponentId{ 0 }
399 {
400 }
401
404 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
405 : Array(array)
406 , NumComps(numComps)
407 , TupleId(tupleId)
408 , ComponentId(comp)
409 {
410 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
411 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
412 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
413 "Const component iterator at invalid tuple id.");
414 VTK_ITER_ASSERT(comp >= 0 && comp <= this->NumComps.value,
415 "Const component iterator at invalid component id.");
416 }
417
420 : Array{ o.GetArray() }
421 , NumComps{ o.GetNumComps() }
422 , TupleId{ o.GetTupleId() }
423 , ComponentId{ o.GetComponentId() }
424 {
425 }
426
428 ConstComponentIterator(const ConstComponentIterator& o) noexcept = default;
431
433 ConstComponentIterator& operator++() noexcept // prefix
434 {
435 ++this->ComponentId;
436 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
437 "Const component iterator at invalid component id.");
438 return *this;
439 }
440
442 ConstComponentIterator operator++(int) noexcept // postfix
443 {
444 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
445 this->ComponentId++ };
446 }
447
449 ConstComponentIterator& operator--() noexcept // prefix
450 {
451 --this->ComponentId;
452 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
453 "Const component iterator at invalid component id.");
454 return *this;
455 }
456
458 ConstComponentIterator operator--(int) noexcept // postfix
459 {
460 return ConstComponentIterator{ this->Array, this->NumComps, this->TupleId,
461 this->ComponentId-- };
462 }
463
466 {
467 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
468 }
469
471 reference operator*() const noexcept
472 {
473 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
474 }
475
476#define VTK_TMP_MAKE_OPERATOR(OP) \
477 friend VTK_ITER_INLINE bool operator OP( \
478 const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
479 { \
480 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
481 VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
482 VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
483 VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
484 return lhs.ComponentId OP rhs.ComponentId; \
485 }
486
493
494#undef VTK_TMP_MAKE_OPERATOR
495
498 {
499 this->ComponentId += offset;
500 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
501 "Const component iterator at invalid component id.");
502 return *this;
503 }
504
507 {
508 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
509 }
510
513 {
514 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId + offset };
515 }
516
519 {
520 this->ComponentId -= offset;
521 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
522 "Const component iterator at invalid component id.");
523 return *this;
524 }
525
528 {
529 return ConstComponentIterator{ it.Array, it.NumComps, it.TupleId, it.ComponentId - offset };
530 }
531
533 const ConstComponentIterator& it1, const ConstComponentIterator& it2) noexcept
534 {
535 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
536 VTK_ITER_ASSERT(it1.TupleId == it2.TupleId,
537 "Cannot do math with component iterators from different "
538 "tuples.");
539 return it1.ComponentId - it2.ComponentId;
540 }
541
544 {
545 // Different arrays may use different iterator implementations.
546 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
547
548 using std::swap;
549 swap(lhs.TupleId, rhs.TupleId);
550 swap(lhs.ComponentId, rhs.ComponentId);
551 }
552
553private:
554 mutable ArrayType* Array;
555 NumCompsType NumComps;
556 TupleIdType TupleId;
557 ComponentIdType ComponentId;
558};
559
560//------------------------------------------------------------------------------
561// Component iterator
562template <typename ArrayType, ComponentIdType TupleSize>
564{
565private:
566 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
567 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
568
570 using APIType = GetAPIType<ArrayType>;
571
572public:
573 using iterator_category = std::random_access_iterator_tag;
574 using value_type = APIType;
578
580 ComponentIterator() noexcept = default;
581
584 ArrayType* array, NumCompsType numComps, TupleIdType tupleId, ComponentIdType comp) noexcept
585 : Ref(array, numComps, tupleId, comp)
586 {
587 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
588 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
589 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
590 "Component iterator at invalid tuple id.");
592 comp >= 0 && comp <= numComps.value, "Component iterator at invalid component id.");
593 }
594
596 ComponentIterator(const ComponentIterator& o) noexcept = default;
597
600 {
601 this->Ref.CopyReference(o.Ref);
602 return *this;
603 }
604
606 ComponentIterator& operator++() noexcept // prefix
607 {
608 ++this->Ref.ComponentId;
609 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
610 "Component iterator at invalid component id.");
611 return *this;
612 }
613
615 ComponentIterator operator++(int) noexcept // postfix
616 {
617 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
618 this->Ref.ComponentId++ };
619 }
620
622 ComponentIterator& operator--() noexcept // prefix
623 {
624 --this->Ref.ComponentId;
625 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
626 "Component iterator at invalid component id.");
627 return *this;
628 }
629
631 ComponentIterator operator--(int) noexcept // postfix
632 {
633 return ComponentIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
634 this->Ref.ComponentId-- };
635 }
636
639 {
640 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId,
641 this->Ref.ComponentId + i };
642 }
643
645 reference operator*() const noexcept { return this->Ref; }
646
648 const pointer& operator->() const noexcept { return this->Ref; }
649
650#define VTK_TMP_MAKE_OPERATOR(OP) \
651 friend VTK_ITER_INLINE bool operator OP( \
652 const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
653 { \
654 VTK_ITER_ASSERT( \
655 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
656 VTK_ITER_ASSERT( \
657 lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
658 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
659 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
660 return lhs.GetComponentId() OP rhs.GetComponentId(); \
661 }
662
669
670#undef VTK_TMP_MAKE_OPERATOR
671
674 {
675 this->Ref.ComponentId += offset;
676 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
677 "Component iterator at invalid component id.");
678 return *this;
679 }
680
682 const ComponentIterator& it, difference_type offset) noexcept
683 {
684 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
685 it.GetComponentId() + offset };
686 }
687
689 difference_type offset, const ComponentIterator& it) noexcept
690 {
691 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
692 it.GetComponentId() + offset };
693 }
694
697 {
698 this->Ref.ComponentId -= offset;
699 VTK_ITER_ASSERT(this->Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
700 "Component iterator at invalid component id.");
701 return *this;
702 }
703
705 const ComponentIterator& it, difference_type offset) noexcept
706 {
707 return ComponentIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId(),
708 it.GetComponentId() - offset };
709 }
710
712 const ComponentIterator& it1, const ComponentIterator& it2) noexcept
713 {
714 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
715 "Cannot do math with component iterators from different "
716 "arrays.");
717 VTK_ITER_ASSERT(it1.GetTupleId() == it2.GetTupleId(),
718 "Cannot do math with component iterators from different "
719 "tuples.");
720 return it1.GetComponentId() - it2.GetComponentId();
721 }
722
724 {
725 // Different arrays may use different iterator implementations.
727 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
728
729 using std::swap;
730 swap(lhs.GetTupleId(), rhs.GetTupleId());
731 swap(lhs.GetComponentId(), rhs.GetComponentId());
732 }
733
734 friend struct ConstComponentIterator<ArrayType, TupleSize>;
735
736protected:
737 // Needed for access from friend functions. We could just store the array
738 // and ID here instead of the ref, but meh.
739 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
740 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
741 const TupleIdType& GetTupleId() const noexcept { return this->Ref.TupleId; }
742 ComponentIdType& GetComponentId() noexcept { return this->Ref.ComponentId; }
743 const ComponentIdType& GetComponentId() const noexcept { return this->Ref.ComponentId; }
744 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
745 const NumCompsType& GetNumComps() const noexcept { return this->Ref.NumComps; }
746
748};
749
750//------------------------------------------------------------------------------
751// Const tuple reference
752template <typename ArrayType, ComponentIdType TupleSize>
754{
755private:
756 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
757 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
758
760 using APIType = GetAPIType<ArrayType>;
761
762public:
764 using value_type = APIType;
768
771 : Array(nullptr)
772 , TupleId(0)
773 {
774 }
775
777 ConstTupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
778 : Array(array)
779 , NumComps(numComps)
780 , TupleId(tupleId)
781 {
782 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
783 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
784 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
785 "Const tuple reference at invalid tuple id.");
786 }
787
790 : Array{ o.Array }
791 , NumComps{ o.NumComps }
792 , TupleId{ o.TupleId }
793 {
794 }
795
797 ConstTupleReference(const ConstTupleReference&) noexcept = default;
800
801 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
803 ConstTupleReference* operator->() noexcept { return this; }
805 const ConstTupleReference* operator->() const noexcept { return this; }
806
807 // Caller must ensure that there are size() elements in array.
809 void GetTuple(APIType* tuple) const noexcept
810 {
811 VTK_ITER_ASSUME(this->NumComps.value > 0);
812 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
814 acc.Get(this->TupleId, tuple);
815 }
816
817 // skips some runtime checks when both sizes are fixed:
818 template <typename OArrayType, ComponentIdType OSize>
820 const TupleReference<OArrayType, OSize>& other) const noexcept
821 {
822 // Check that types are convertible:
823 using OAPIType = GetAPIType<OArrayType>;
824 static_assert(
825 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
826
827 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
828 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
829
830 return std::equal(this->cbegin(), this->cend(), other.cbegin());
831 }
832
833 // Needs a runtime check:
834 template <typename OArrayType, ComponentIdType OSize>
836 const TupleReference<OArrayType, OSize>& other) const noexcept
837 {
838 // Check that types are convertible:
839 using OAPIType = GetAPIType<OArrayType>;
840 static_assert(
841 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
842
844 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
845
846 return std::equal(this->cbegin(), this->cend(), other.cbegin());
847 }
848
849 // skips some runtime checks when both sizes are fixed:
850 template <typename OArrayType, ComponentIdType OSize>
852 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
853 {
854 // Check that types are convertible:
855 using OAPIType = GetAPIType<OArrayType>;
856 static_assert(
857 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
858
859 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
860 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
861
862 return std::equal(this->cbegin(), this->cend(), other.cbegin());
863 }
864
865 // Needs a runtime check:
866 template <typename OArrayType, ComponentIdType OSize>
868 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
869 {
870 // Check that types are convertible:
871 using OAPIType = GetAPIType<OArrayType>;
872 static_assert(
873 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
874
876 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
877
878 return std::equal(this->cbegin(), this->cend(), other.cbegin());
879 }
880
881 template <typename OArrayType, ComponentIdType OSize>
883 {
884 return !(*this == o);
885 }
886
887 template <typename OArrayT, ComponentIdType OSize>
889 {
890 return !(*this == o);
891 }
892
895 {
896 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
897 }
898
900 size_type size() const noexcept { return this->NumComps.value; }
901
903 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
905 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
906
908 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
910 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
911
912 friend struct ConstTupleIterator<ArrayType, TupleSize>;
913
914protected:
915 // Intentionally hidden:
918
921 {
922 VTK_ITER_ASSUME(this->NumComps.value > 0);
923 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
924 }
925
927 void CopyReference(const ConstTupleReference& o) noexcept
928 {
929 // Must use same array, other array types may use different implementations.
930 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
931 this->NumComps = o.NumComps;
932 this->TupleId = o.TupleId;
933 }
934
935 mutable ArrayType* Array;
938};
939
940//------------------------------------------------------------------------------
941// Tuple reference
942template <typename ArrayType, ComponentIdType TupleSize>
944{
945private:
946 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
947 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
948
950 using APIType = GetAPIType<ArrayType>;
951
952public:
954 using value_type = APIType;
959
961 TupleReference() noexcept
962 : Array(nullptr)
963 , TupleId(0)
964 {
965 }
966
968 TupleReference(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
969 : Array(array)
970 , NumComps(numComps)
971 , TupleId(tupleId)
972 {
973 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
974 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
975 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
976 "Tuple reference at invalid tuple id.");
977 }
978
983
984 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
986 TupleReference* operator->() noexcept { return this; }
988 const TupleReference* operator->() const noexcept { return this; }
989
990 // Caller must ensure that there are size() elements in array.
992 void GetTuple(APIType* tuple) const noexcept
993 {
994 VTK_ITER_ASSUME(this->NumComps.value > 0);
995 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
997 acc.Get(this->TupleId, tuple);
998 }
999
1000 // Caller must ensure that there are size() elements in array.
1002 void SetTuple(const APIType* tuple) noexcept
1003 {
1004 VTK_ITER_ASSUME(this->NumComps.value > 0);
1005 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->NumComps.value);
1007 acc.Set(this->TupleId, tuple);
1008 }
1009
1012 {
1013 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1014 return *this;
1015 }
1016
1017 // skips some runtime checks when both sizes are fixed:
1018 template <typename OArrayType, ComponentIdType OSize>
1020 const TupleReference<OArrayType, OSize>& other) noexcept
1021 {
1022 // Check that types are convertible:
1023 using OAPIType = GetAPIType<OArrayType>;
1024 static_assert(
1025 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1026
1027 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1028 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1029
1030 std::copy_n(other.cbegin(), OSize, this->begin());
1031 return *this;
1032 }
1033
1034 // Needs a runtime check:
1035 template <typename OArrayType, ComponentIdType OSize>
1037 const TupleReference<OArrayType, OSize>& other) noexcept
1038 {
1039 // Check that types are convertible:
1040 using OAPIType = GetAPIType<OArrayType>;
1041 static_assert(
1042 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1043
1045 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1046
1047 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1048 return *this;
1049 }
1050
1051 // skips some runtime checks when both sizes are fixed:
1052 template <typename OArrayType, ComponentIdType OSize>
1054 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1055 {
1056 // Check that types are convertible:
1057 using OAPIType = GetAPIType<OArrayType>;
1058 static_assert(
1059 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1060
1061 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1062 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
1063
1064 std::copy_n(other.cbegin(), OSize, this->begin());
1065 return *this;
1066 }
1067
1068 // Needs a runtime check:
1069 template <typename OArrayType, ComponentIdType OSize>
1071 const ConstTupleReference<OArrayType, OSize>& other) noexcept
1072 {
1073 // Check that types are convertible:
1074 using OAPIType = GetAPIType<OArrayType>;
1075 static_assert(
1076 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
1077
1079 other.size() == this->NumComps.value, "Cannot assign tuples with different sizes.");
1080
1081 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1082 return *this;
1083 }
1084
1085 // skips some runtime checks when both sizes are fixed:
1086 template <typename OArrayType, ComponentIdType OSize>
1088 const TupleReference<OArrayType, OSize>& other) const noexcept
1089 {
1090 // Check that types are convertible:
1091 using OAPIType = GetAPIType<OArrayType>;
1092 static_assert(
1093 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1094
1095 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1096 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1097
1098 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1099 }
1100
1101 // Needs a runtime check:
1102 template <typename OArrayType, ComponentIdType OSize>
1104 const TupleReference<OArrayType, OSize>& other) const noexcept
1105 {
1106 // Check that types are convertible:
1107 using OAPIType = GetAPIType<OArrayType>;
1108 static_assert(
1109 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1110
1112 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1113
1114 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1115 }
1116
1117 // skips some runtime checks when both sizes are fixed:
1118 template <typename OArrayType, ComponentIdType OSize>
1120 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1121 {
1122 // Check that types are convertible:
1123 using OAPIType = GetAPIType<OArrayType>;
1124 static_assert(
1125 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1126
1127 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1128 static_assert(TupleSize == OSize, "Cannot compare tuples with different sizes.");
1129
1130 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1131 }
1132
1133 // Needs a runtime check:
1134 template <typename OArrayType, ComponentIdType OSize>
1136 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
1137 {
1138 // Check that types are convertible:
1139 using OAPIType = GetAPIType<OArrayType>;
1140 static_assert(
1141 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when comparing tuples.");
1142
1144 other.size() == this->NumComps.value, "Cannot compare tuples with different sizes.");
1145
1146 return std::equal(this->cbegin(), this->cend(), other.cbegin());
1147 }
1148
1149 template <typename OArrayType, ComponentIdType OSize>
1151 {
1152 return !(*this == o);
1153 }
1154
1155 template <typename OArray, ComponentIdType OSize>
1157 {
1158 return !(*this == o);
1159 }
1160
1161 // skips some runtime checks:
1162 template <typename OArrayType, ComponentIdType OSize>
1164 TupleReference<OArrayType, OSize> other) noexcept
1165 {
1166 // Check that types are convertible:
1167 using OAPIType = GetAPIType<OArrayType>;
1168 static_assert(
1169 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1170
1171 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
1172 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
1173
1174 std::swap_ranges(this->begin(), this->end(), other.begin());
1175 }
1176
1177 // Needs a runtime check:
1178 template <typename OArrayType, ComponentIdType OSize>
1180 TupleReference<OArrayType, OSize> other) noexcept
1181 {
1182 // Check that types are convertible:
1183 using OAPIType = GetAPIType<OArrayType>;
1184 static_assert(
1185 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
1186
1188 other.size() == this->NumComps.value, "Cannot swap tuples with different sizes.");
1189
1190 std::swap_ranges(this->begin(), this->end(), other.begin());
1191 }
1192
1193 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
1194
1195 template <typename OArray, ComponentIdType OSize>
1197 {
1198 a.swap(b);
1199 }
1200
1203 {
1204 return reference{ this->Array, this->NumComps, this->TupleId, i };
1205 }
1206
1209 {
1210 // Let the reference type do the lookup during implicit conversion.
1211 return const_reference{ this->Array, this->NumComps, this->TupleId, i };
1212 }
1213
1215 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
1216
1218 size_type size() const noexcept { return this->NumComps.value; }
1219
1221 iterator begin() noexcept { return this->NewIterator(0); }
1223 iterator end() noexcept { return this->NewIterator(this->NumComps.value); }
1224
1226 const_iterator begin() const noexcept { return this->NewConstIterator(0); }
1228 const_iterator end() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1229
1231 const_iterator cbegin() const noexcept { return this->NewConstIterator(0); }
1233 const_iterator cend() const noexcept { return this->NewConstIterator(this->NumComps.value); }
1234
1235 friend struct ConstTupleReference<ArrayType, TupleSize>;
1236 friend struct TupleIterator<ArrayType, TupleSize>;
1237
1238protected:
1241 {
1242 VTK_ITER_ASSUME(this->NumComps.value > 0);
1243 return iterator{ this->Array, this->NumComps, this->TupleId, comp };
1244 }
1245
1248 {
1249 VTK_ITER_ASSUME(this->NumComps.value > 0);
1250 return const_iterator{ this->Array, this->NumComps, this->TupleId, comp };
1251 }
1252
1254 void CopyReference(const TupleReference& o) noexcept
1255 {
1256 // Must use same array, other array types may use different implementations.
1257 VTK_ITER_ASSERT(this->Array == o.Array, "Cannot copy reference objects between arrays.");
1258 this->NumComps = o.NumComps;
1259 this->TupleId = o.TupleId;
1260 }
1261
1262 mutable ArrayType* Array;
1265};
1266
1267//------------------------------------------------------------------------------
1268// Const tuple iterator
1269template <typename ArrayType, ComponentIdType TupleSize>
1271{
1272private:
1273 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1274 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1275
1277
1278public:
1279 using iterator_category = std::random_access_iterator_tag;
1284
1286 ConstTupleIterator() noexcept = default;
1287
1289 ConstTupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1290 : Ref(array, numComps, tupleId)
1291 {
1292 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1293 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1294 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1295 "Const tuple iterator at invalid tuple id.");
1296 }
1297
1300 : Ref{ o.Ref }
1301 {
1302 }
1303
1305 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
1308 {
1309 this->Ref.CopyReference(o.Ref);
1310 return *this;
1311 }
1312
1314 ConstTupleIterator& operator++() noexcept // prefix
1315 {
1316 ++this->Ref.TupleId;
1318 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1319 "Const tuple iterator at invalid component id.");
1320 return *this;
1321 }
1322
1324 ConstTupleIterator operator++(int) noexcept // postfix
1325 {
1326 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1327 }
1328
1330 ConstTupleIterator& operator--() noexcept // prefix
1331 {
1332 --this->Ref.TupleId;
1334 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1335 "Const tuple iterator at invalid component id.");
1336 return *this;
1337 }
1338
1340 ConstTupleIterator operator--(int) noexcept // postfix
1341 {
1342 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1343 }
1344
1347 {
1348 return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1349 }
1350
1352 reference operator*() noexcept { return this->Ref; }
1353
1355 pointer operator->() noexcept { return this->Ref; }
1356
1357#define VTK_TMP_MAKE_OPERATOR(OP) \
1358 friend VTK_ITER_INLINE bool operator OP( \
1359 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1360 { \
1361 VTK_ITER_ASSERT( \
1362 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1363 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1364 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1365 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1366 }
1367
1374
1375#undef VTK_TMP_MAKE_OPERATOR
1376
1379 {
1380 this->Ref.TupleId += offset;
1382 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1383 "Const tuple iterator at invalid component id.");
1384 return *this;
1385 }
1386
1388 const ConstTupleIterator& it, difference_type offset) noexcept
1389 {
1390 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1391 }
1392
1394 difference_type offset, const ConstTupleIterator& it) noexcept
1395 {
1396 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1397 }
1398
1401 {
1402 this->Ref.TupleId -= offset;
1404 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1405 "Const tuple iterator at invalid component id.");
1406 return *this;
1407 }
1408
1410 const ConstTupleIterator& it, difference_type offset) noexcept
1411 {
1412 return ConstTupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1413 }
1414
1416 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
1417 {
1418 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1419 "Cannot do math with tuple iterators from different "
1420 "arrays.");
1421 return it1.GetTupleId() - it2.GetTupleId();
1422 }
1423
1425 {
1426 // Different arrays may use different iterator implementations.
1428 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1429
1430 using std::swap;
1431 swap(lhs.GetTupleId(), rhs.GetTupleId());
1432 }
1433
1434private:
1436 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1438 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1440 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1442 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1444 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1446 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1447
1448 ConstTupleReference<ArrayType, TupleSize> Ref;
1449};
1450
1451//------------------------------------------------------------------------------
1452// Tuple iterator
1453template <typename ArrayType, ComponentIdType TupleSize>
1455{
1456private:
1457 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1458 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
1459
1461
1462public:
1463 using iterator_category = std::random_access_iterator_tag;
1468
1470 TupleIterator() noexcept = default;
1471
1473 TupleIterator(ArrayType* array, NumCompsType numComps, TupleIdType tupleId) noexcept
1474 : Ref(array, numComps, tupleId)
1475 {
1476 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
1477 VTK_ITER_ASSERT(numComps.value > 0, "Invalid number of components.");
1479 tupleId >= 0 && tupleId <= array->GetNumberOfTuples(), "Tuple iterator at invalid tuple id.");
1480 }
1481
1483 TupleIterator(const TupleIterator& o) noexcept = default;
1484
1487 {
1488 this->Ref.CopyReference(o.Ref);
1489 return *this;
1490 }
1491
1493 TupleIterator& operator++() noexcept // prefix
1494 {
1495 ++this->Ref.TupleId;
1497 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1498 "Tuple iterator at invalid component id.");
1499 return *this;
1500 }
1501
1503 TupleIterator operator++(int) noexcept // postfix
1504 {
1505 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1506 }
1507
1509 TupleIterator& operator--() noexcept // prefix
1510 {
1511 --this->Ref.TupleId;
1513 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1514 "Tuple iterator at invalid component id.");
1515 return *this;
1516 }
1517
1519 TupleIterator operator--(int) noexcept // postfix
1520 {
1521 return TupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1522 }
1523
1526 {
1527 return reference{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId + i };
1528 }
1529
1531 reference operator*() noexcept { return this->Ref; }
1532
1534 pointer& operator->() noexcept { return this->Ref; }
1535
1536#define VTK_TMP_MAKE_OPERATOR(OP) \
1537 friend VTK_ITER_INLINE bool operator OP( \
1538 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1539 { \
1540 VTK_ITER_ASSERT( \
1541 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1542 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1543 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1544 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1545 }
1546
1553
1554#undef VTK_TMP_MAKE_OPERATOR
1555
1558 {
1559 this->Ref.TupleId += offset;
1561 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1562 "Tuple iterator at invalid component id.");
1563 return *this;
1564 }
1565
1567 const TupleIterator& it, difference_type offset) noexcept
1568 {
1569 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1570 }
1571
1573 difference_type offset, const TupleIterator& it) noexcept
1574 {
1575 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() + offset };
1576 }
1577
1580 {
1581 this->Ref.TupleId -= offset;
1583 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1584 "Tuple iterator at invalid component id.");
1585 return *this;
1586 }
1587
1589 const TupleIterator& it, difference_type offset) noexcept
1590 {
1591 return TupleIterator{ it.GetArray(), it.GetNumComps(), it.GetTupleId() - offset };
1592 }
1593
1595 const TupleIterator& it1, const TupleIterator& it2) noexcept
1596 {
1597 VTK_ITER_ASSERT(it1.GetArray() == it2.GetArray(),
1598 "Cannot do math with tuple iterators from different "
1599 "arrays.");
1600 return it1.GetTupleId() - it2.GetTupleId();
1601 }
1602
1603 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
1604 {
1605 // Different arrays may use different iterator implementations.
1607 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
1608
1609 using std::swap;
1610 swap(lhs.GetTupleId(), rhs.GetTupleId());
1611 }
1612
1613 friend struct ConstTupleIterator<ArrayType, TupleSize>;
1614 friend struct ConstTupleReference<ArrayType, TupleSize>;
1615
1616protected:
1618 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
1620 ArrayType*& GetArray() noexcept { return this->Ref.Array; }
1622 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
1624 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
1626 TupleIdType GetTupleId() const noexcept { return this->Ref.TupleId; }
1628 TupleIdType& GetTupleId() noexcept { return this->Ref.TupleId; }
1629
1631};
1632
1633//------------------------------------------------------------------------------
1634// Tuple range
1635template <typename ArrayTypeT, ComponentIdType TupleSize>
1637{
1638private:
1640 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
1641 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
1642
1643public:
1644 using ArrayType = ArrayTypeT;
1655
1656 // May be DynamicTupleSize, or the actual tuple size.
1657 constexpr static ComponentIdType TupleSizeTag = TupleSize;
1658
1664
1666 TupleRange() noexcept = default;
1667
1669 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
1670 : Array(arr)
1671 , NumComps(arr)
1672 , BeginTuple(beginTuple)
1673 , EndTuple(endTuple)
1674 {
1675 assert(this->Array);
1676 assert(beginTuple >= 0 && beginTuple <= endTuple);
1677 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1678 }
1679
1681 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
1682 {
1683 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1684 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1685
1686 return TupleRange{ this->Array, realBegin, realEnd };
1687 }
1688
1690 ArrayType* GetArray() const noexcept { return this->Array; }
1692 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
1694 TupleIdType GetBeginTupleId() const noexcept { return this->BeginTuple; }
1696 TupleIdType GetEndTupleId() const noexcept { return this->EndTuple; }
1697
1699 size_type size() const noexcept { return this->EndTuple - this->BeginTuple; }
1700
1702 iterator begin() noexcept { return this->NewIter(this->BeginTuple); }
1704 iterator end() noexcept { return this->NewIter(this->EndTuple); }
1705
1707 const_iterator begin() const noexcept { return this->NewCIter(this->BeginTuple); }
1709 const_iterator end() const noexcept { return this->NewCIter(this->EndTuple); }
1710
1712 const_iterator cbegin() const noexcept { return this->NewCIter(this->BeginTuple); }
1714 const_iterator cend() const noexcept { return this->NewCIter(this->EndTuple); }
1715
1718 {
1719 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1720 }
1721
1724 {
1725 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1726 }
1727
1728private:
1730 iterator NewIter(TupleIdType t) const { return iterator{ this->Array, this->NumComps, t }; }
1731
1733 const_iterator NewCIter(TupleIdType t) const
1734 {
1735 return const_iterator{ this->Array, this->NumComps, t };
1736 }
1737
1738 mutable ArrayType* Array{ nullptr };
1739 NumCompsType NumComps{};
1740 TupleIdType BeginTuple{ 0 };
1741 TupleIdType EndTuple{ 0 };
1742};
1743
1744// Unimplemented, only used inside decltype in SelectTupleRange:
1745template <typename ArrayType, ComponentIdType TupleSize>
1747
1748} // end namespace detail
1749} // end namespace vtk
1750
1752
1753#endif // __VTK_WRAP__
1754#endif // vtkDataArrayTupleRange_Generic_h
1755
1756// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_Generic.h
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:159
@ value
Definition: vtkX3D.h:226
@ offset
Definition: vtkX3D.h:444
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.
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
ComponentIdType & GetComponentId() 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 TupleReference() 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)