VTK  9.1.0
vtkDataArrayValueRange_Generic.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataArrayValueRange_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 vtkDataArrayValueRange_Generic_h
21#define vtkDataArrayValueRange_Generic_h
22
24#include "vtkDataArrayMeta.h"
25
26#include <algorithm>
27#include <cassert>
28#include <iterator>
29#include <tuple>
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 ValueReference;
45template <typename ArrayType, ComponentIdType>
46struct ConstValueReference;
47template <typename ArrayType, ComponentIdType>
48struct ValueIterator;
49template <typename ArrayType, ComponentIdType>
50struct ConstValueIterator;
51template <typename ArrayType, ComponentIdType>
52struct ValueRange;
53
54//------------------------------------------------------------------------------
55// Helper that converts ValueId <--> { TupleId, ComponentId }
56// This class stores both representations. Profiling and assembly inspection
57// show that ValueId is much more efficient for comparing Ids, while Tuple/Comp
58// ids are much faster for looking up elements (especially when considering
59// SOA arrays). The overhead of maintaining both is low, and this class is
60// transparent enough that the compiler will produce efficient ASM with
61// simple optimizations enabled.
62template <ComponentIdType TupleSize>
64{
66
68 IdStorage() noexcept
69 : ValueId(0)
70 , TupleId(0)
71 , ComponentId(0)
72 {
73 }
74
76 IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
77 : ValueId(valueId)
78 , TupleId(static_cast<TupleIdType>(valueId) / static_cast<TupleIdType>(numComps.value))
79 , ComponentId(static_cast<ComponentIdType>(valueId % static_cast<ValueIdType>(numComps.value)))
80 , NumComps(numComps)
81 {
82 }
83
85 IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
86 : ValueId(tupleId * numComps.value + comp)
87 , TupleId(tupleId)
88 , ComponentId(comp)
89 , NumComps(numComps)
90 {
91 }
92
95 ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
96 : ValueId(valueId)
97 , TupleId(tupleId)
98 , ComponentId(comp)
99 , NumComps(numComps)
100 {
101 }
102
103 template <typename ArrayType>
104 VTK_ITER_INLINE void DebugAsserts(ArrayType* array) const noexcept
105 {
106 (void)array;
107 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
108 VTK_ITER_ASSERT(this->ValueId == this->TupleId * this->GetTupleSize() + this->ComponentId,
109 "Inconsistent internal state in IdStorage.");
110 VTK_ITER_ASSERT(this->GetTupleSize() > 0, "Invalid number of components.");
112 this->ValueId >= 0 && this->ValueId <= array->GetNumberOfValues(), "Invalid value id.");
113 VTK_ITER_ASSERT(this->GetTupleId() >= 0 && this->GetTupleId() <= array->GetNumberOfTuples(),
114 "Invalid tuple id.");
115 VTK_ITER_ASSERT(this->GetComponentId() >= 0 &&
116 (this->GetComponentId() < this->GetTupleSize() ||
117 (this->GetComponentId() == this->GetTupleSize() &&
118 this->GetTupleId() == array->GetNumberOfTuples())),
119 "Invalid component id.");
120 VTK_ITER_ASSERT(this->GetValueId() >= 0 && this->GetValueId() <= array->GetNumberOfValues(),
121 "Invalid value id.");
122 }
123
125 IdStorage& operator++() noexcept // prefix
126 {
127 ++this->ValueId;
128 ++this->ComponentId;
129 if (this->ComponentId == this->GetTupleSize())
130 {
131 this->ComponentId = 0;
132 ++this->TupleId;
133 }
134 return *this;
135 }
136
138 IdStorage operator++(int) noexcept // postfix
139 {
140 auto v = this->ValueId++;
141 auto t = this->TupleId;
142 auto c = this->ComponentId++;
143 if (this->ComponentId == this->GetTupleSize())
144 {
145 this->ComponentId = 0;
146 ++this->TupleId;
147 }
148 return IdStorage{ v, t, c, this->NumComps };
149 }
150
151 friend VTK_ITER_INLINE IdStorage operator+(const IdStorage& id, ValueIdType offset) noexcept
152 {
153 IdStorage res = id;
154 res.AddOffset(offset);
155 return res;
156 }
157
159 IdStorage& operator--() noexcept // prefix
160 {
161 --this->ValueId;
162 --this->ComponentId;
163 if (this->ComponentId < 0)
164 {
165 this->ComponentId = this->GetTupleSize() - 1;
166 --this->TupleId;
167 }
168 return *this;
169 }
170
172 IdStorage operator--(int) noexcept // postfix
173 {
174 auto v = this->ValueId--;
175 auto t = this->TupleId;
176 auto c = this->ComponentId--;
177 if (this->ComponentId < 0)
178 {
179 this->ComponentId = this->GetTupleSize() - 1;
180 --this->TupleId;
181 }
182 return IdStorage{ v, t, c, this->NumComps };
183 }
184
186 ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
187 {
188 return static_cast<ValueIdType>(tuple) * this->NumComps.value + comp;
189 }
190
192 std::pair<TupleIdType, ComponentIdType> Convert(ValueIdType value) const noexcept
193 {
194 return std::make_pair(static_cast<TupleIdType>(value / this->NumComps.value),
195 static_cast<ComponentIdType>(value % this->NumComps.value));
196 }
197
199 void AddOffset(ValueIdType offset) noexcept
200 {
201 this->ValueId += offset;
202 std::tie(this->TupleId, this->ComponentId) = this->Convert(this->ValueId);
203 }
204
206 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
207
209 TupleIdType GetTupleId() const noexcept { return this->TupleId; }
210
212 ComponentIdType GetComponentId() const noexcept { return this->ComponentId; }
213
215 ValueIdType GetValueId() const noexcept { return this->ValueId; }
216
217 friend VTK_ITER_INLINE void swap(IdStorage& lhs, IdStorage& rhs) noexcept
218 {
219 using std::swap;
220 swap(lhs.ValueId, rhs.ValueId);
221 swap(lhs.TupleId, rhs.TupleId);
222 swap(lhs.ComponentId, rhs.ComponentId);
223 }
224
225private:
226 vtk::ValueIdType ValueId;
227 vtk::TupleIdType TupleId;
228 vtk::ComponentIdType ComponentId;
229 NumCompsType NumComps;
230};
231
232//------------------------------------------------------------------------------
233// Value reference
234template <typename ArrayType, ComponentIdType TupleSize>
236{
237private:
238 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
239 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
240
242 using APIType = GetAPIType<ArrayType>;
243
244public:
245 using value_type = APIType;
246
249 : Array{ nullptr }
250 , Id{}
251 {
252 }
253
255 ConstValueReference(ArrayType* array, IdStorageType id) noexcept
256 : Array{ array }
257 , Id{ id }
258 {
259 this->Id.DebugAsserts(array);
260 }
261
264 : Array{ o.Array }
265 , Id{ o.Id }
266 {
267 }
268
270 ConstValueReference(const ConstValueReference& o) noexcept = default;
271
274
277 {
278 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
279 // Initialize the reference.
280 this->Array = o.Array;
281 this->Id = o.Id;
282 return *this;
283 }
284
287 {
288 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
289 // Initialize the reference.
290 this->Array = std::move(o.Array);
291 this->Id = std::move(o.Id);
292 return *this;
293 }
294
296 operator APIType() const noexcept
297 {
298 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
299 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
301 return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
302 }
303
304protected:
305 mutable ArrayType* Array;
307};
308
309//------------------------------------------------------------------------------
310// Value reference
311template <typename ArrayType, ComponentIdType TupleSize>
313{
314private:
315 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
316 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
317
318 using APIType = GetAPIType<ArrayType>;
320
321public:
322 using value_type = APIType;
323
325 ValueReference() noexcept
326 : Array{ nullptr }
327 , Id{}
328 {
329 }
330
332 ValueReference(ArrayType* array, IdStorageType id) noexcept
333 : Array{ array }
334 , Id{ id }
335 {
336 this->Id.DebugAsserts(this->Array);
337 }
338
340 ValueReference(const ValueReference& o) noexcept = default;
342 ValueReference(ValueReference&& o) noexcept = default;
343
346 {
347 if (this->Array)
348 { // Already initialized. Assign the value, not the reference:
349 return *this = static_cast<APIType>(o);
350 }
351 else
352 { // Initialize the reference:
353 this->Array = o.Array;
354 this->Id = o.Id;
355 return *this;
356 }
357 }
358
361 {
362 if (this->Array)
363 { // Already initialized. Assign the value, not the reference:
364 return *this = static_cast<APIType>(o);
365 }
366 else
367 { // Initialize the reference:
368 this->Array = std::move(o.Array);
369 this->Id = std::move(o.Id);
370 return *this;
371 }
372 }
373
374 template <typename OArray, ComponentIdType OSize>
376 { // Always copy the value for different reference types:
377 const APIType tmp = o;
378 return *this = std::move(tmp);
379 }
380
382 operator APIType() const noexcept
383 {
384 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
385 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
387 return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
388 }
389
391 ValueReference operator=(APIType val) noexcept
392 {
393 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
394 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
396 acc.Set(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
397 return *this;
398 }
399
400 friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
401 { // Swap values, not references:
402 APIType tmp = std::move(static_cast<APIType>(lhs));
403 lhs = std::move(static_cast<APIType>(rhs));
404 rhs = std::move(tmp);
405 }
406
407 template <typename OArray, ComponentIdType OSize>
409 { // Swap values, not references:
410 using OAPIType = typename ValueReference<OArray, OSize>::value_type;
411 static_assert(
412 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
413
414 APIType tmp = std::move(static_cast<APIType>(lhs));
415 lhs = std::move(static_cast<APIType>(rhs));
416 rhs = std::move(tmp);
417 }
418
419 friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
420 {
421 APIType tmp = std::move(static_cast<APIType>(lhs));
422 lhs = std::move(rhs);
423 rhs = std::move(tmp);
424 }
425
426 friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
427 {
428 APIType tmp = std::move(lhs);
429 lhs = std::move(static_cast<APIType>(rhs));
430 rhs = std::move(tmp);
431 }
432
434 ValueReference operator++() noexcept // prefix
435 {
436 const APIType newVal = *this + 1;
437 *this = newVal;
438 return *this;
439 }
440
442 APIType operator++(int) noexcept // postfix
443 {
444 const APIType retVal = *this;
445 *this = *this + 1;
446 return retVal;
447 }
448
450 ValueReference operator--() noexcept // prefix
451 {
452 const APIType newVal = *this - 1;
453 *this = newVal;
454 return *this;
455 }
456
458 APIType operator--(int) noexcept // postfix
459 {
460 const APIType retVal = *this;
461 *this = *this - 1;
462 return retVal;
463 }
464
465#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
466 friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
467 { \
468 const APIType newVal = lhs ImplOp val; \
469 lhs = newVal; \
470 return lhs; \
471 } \
472 friend VTK_ITER_INLINE ValueReference operator Op( \
473 ValueReference lhs, ValueReference val) noexcept \
474 { \
475 const APIType newVal = lhs ImplOp val; \
476 lhs = newVal; \
477 return lhs; \
478 } \
479 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
480 { \
481 const APIType newVal = lhs ImplOp val; \
482 lhs = newVal; \
483 return lhs; \
484 }
485
490
491#undef VTK_REF_OP_OVERLOADS
492
493 friend struct ConstValueReference<ArrayType, TupleSize>;
494 friend struct ValueIterator<ArrayType, TupleSize>;
495
496protected:
497 void CopyReference(const ValueReference& o) noexcept
498 {
499 this->Array = o.Array;
500 this->Id = o.Id;
501 }
502
503 mutable ArrayType* Array;
505};
506
507//------------------------------------------------------------------------------
508// Const value iterator
509template <typename ArrayType, ComponentIdType TupleSize>
511{
512private:
513 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
514 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
515
516 using APIType = GetAPIType<ArrayType>;
518
519public:
520 using iterator_category = std::random_access_iterator_tag;
521 using value_type = APIType;
523 using pointer = void;
525
528 : Array(nullptr)
529 , Id()
530 {
531 }
532
534 ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
535 : Array(array)
536 , Id(id)
537 {
538 this->Id.DebugAsserts(this->Array);
539 }
540
543 : Array{ o.GetArray() }
544 , Id{ o.GetId() }
545 {
546 }
547
549 ConstValueIterator(const ConstValueIterator& o) noexcept = default;
551 ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
552
554 ConstValueIterator& operator++() noexcept // prefix
555 {
556 ++this->Id;
557 this->Id.DebugAsserts(this->Array);
558 return *this;
559 }
560
562 ConstValueIterator operator++(int) noexcept // postfix
563 {
564 auto ret = this->Id++;
565 this->Id.DebugAsserts(this->Array);
566 return ConstValueIterator{ this->Array, ret };
567 }
568
570 ConstValueIterator& operator--() noexcept // prefix
571 {
572 --this->Id;
573 this->Id.DebugAsserts(this->Array);
574 return *this;
575 }
576
578 ConstValueIterator operator--(int) noexcept // postfix
579 {
580 auto ret = this->Id--;
581 this->Id.DebugAsserts(this->Array);
582 return ConstValueIterator{ this->Array, ret };
583 }
584
587 {
588 return reference{ this->Array, this->Id + i };
589 }
590
592 reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
593
594 // Using GetValueType here makes iteration 50% faster by reducing comparisons
595 // and jumps (instead of comparing std::tie(tupleId, compId)).
596#define VTK_TMP_MAKE_OPERATOR(OP) \
597 friend VTK_ITER_INLINE bool operator OP( \
598 const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
599 { \
600 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
601 return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
602 }
603
610
611#undef VTK_TMP_MAKE_OPERATOR
612
615 {
616 this->Id.AddOffset(offset);
617 this->Id.DebugAsserts(this->Array);
618 return *this;
619 }
620
622 const ConstValueIterator& it, difference_type offset) noexcept
623 {
624 return ConstValueIterator{ it.Array, it.Id + offset };
625 }
626
628 difference_type offset, const ConstValueIterator& it) noexcept
629 {
630 return ConstValueIterator{ it.Array, it.Id + offset };
631 }
632
635 {
636 this->Id.AddOffset(-offset);
637 this->Id.DebugAsserts(this->Array);
638 return *this;
639 }
640
642 const ConstValueIterator& it, difference_type offset) noexcept
643 {
644 return ConstValueIterator{ it.Array, it.Id + (-offset) };
645 }
646
648 const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
649 {
650 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
651 return it1.Id.GetValueId() - it2.Id.GetValueId();
652 }
653
655 {
656 // Different arrays may use different iterator implementations.
657 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
658
659 using std::swap;
660 swap(lhs.Id, rhs.Id);
661 }
662
663private:
664 mutable ArrayType* Array;
665 IdStorageType Id;
666};
667
668//------------------------------------------------------------------------------
669// Component iterator
670template <typename ArrayType, ComponentIdType TupleSize>
672{
673private:
674 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
675 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
676
677 using APIType = GetAPIType<ArrayType>;
679
680public:
681 using iterator_category = std::random_access_iterator_tag;
686
688 ValueIterator() noexcept = default;
689
691 ValueIterator(ArrayType* array, IdStorageType id) noexcept
692 : Ref{ array, id }
693 {
694 this->DebugIdAsserts();
695 }
696
698 ValueIterator(const ValueIterator& o) noexcept = default;
699
702 {
703 this->Ref.CopyReference(o.Ref);
704 this->DebugIdAsserts();
705 return *this;
706 }
707
709 ValueIterator& operator++() noexcept // prefix
710 {
711 ++this->Ref.Id;
712 this->DebugIdAsserts();
713 return *this;
714 }
715
717 ValueIterator operator++(int) noexcept // postfix
718 {
719 auto ret = this->Ref.Id++;
720 this->DebugIdAsserts();
721 return ValueIterator{ this->Ref.Array, ret };
722 }
723
725 ValueIterator& operator--() noexcept // prefix
726 {
727 --this->Ref.Id;
728 this->DebugIdAsserts();
729 return *this;
730 }
731
733 ValueIterator operator--(int) noexcept // postfix
734 {
735 auto ret = this->Ref.Id--;
736 this->DebugIdAsserts();
737 return ValueIterator{ this->Ref.Array, ret };
738 }
739
742 {
743 return reference{ this->Ref.Array, this->Ref.Id + i };
744 }
745
747 reference operator*() const noexcept { return this->Ref; }
748
750 const pointer& operator->() const noexcept { return this->Ref; }
751
752#define VTK_TMP_MAKE_OPERATOR(OP) \
753 friend VTK_ITER_INLINE bool operator OP( \
754 const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
755 { \
756 VTK_ITER_ASSERT( \
757 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
758 return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
759 }
760
767
768#undef VTK_TMP_MAKE_OPERATOR
769
772 {
773 this->Ref.Id.AddOffset(offset);
774 this->DebugIdAsserts();
775 return *this;
776 }
777
779 const ValueIterator& it, difference_type offset) noexcept
780 {
781 return ValueIterator{ it.GetArray(), it.GetId() + offset };
782 }
783
785 difference_type offset, const ValueIterator& it) noexcept
786 {
787 return ValueIterator{ it.GetArray(), it.GetId() + offset };
788 }
789
792 {
793 this->Ref.Id.AddOffset(-offset);
794 this->Ref.Id.DebugAsserts(this->Ref.Array);
795 return *this;
796 }
797
799 const ValueIterator& it, difference_type offset) noexcept
800 {
801 return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
802 }
803
805 const ValueIterator& it1, const ValueIterator& it2) noexcept
806 {
808 it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
809 return it1.GetId().GetValueId() - it2.GetId().GetValueId();
810 }
811
812 friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
813 {
814 // Different arrays may use different iterator implementations.
816 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
817
818 using std::swap;
819 swap(lhs.GetId(), rhs.GetId());
820 }
821
822 friend struct ConstValueIterator<ArrayType, TupleSize>;
823
824protected:
826 void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
827
828 // Needed for access from friend functions. We could just store the array
829 // and ID here instead of the ref, but meh.
830 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
831 IdStorageType& GetId() noexcept { return this->Ref.Id; }
832 const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
833
835};
836
837//------------------------------------------------------------------------------
838// ValueRange
839template <typename ArrayTypeT, ComponentIdType TupleSize>
841{
842private:
843 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
844 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
845
848
849public:
850 using ArrayType = ArrayTypeT;
852
857
858 // May be DynamicTupleSize, or the actual tuple size.
859 constexpr static ComponentIdType TupleSizeTag = TupleSize;
860
861 // STL-compat
868
870 ValueRange() noexcept = default;
871
873 ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
874 : Array(arr)
875 , NumComps(arr)
876 , BeginValue(beginValue, this->NumComps)
877 , EndValue(endValue, this->NumComps)
878 {
879 assert(this->Array);
880 assert(beginValue >= 0 && beginValue <= endValue);
881 assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
882 }
883
885 ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
886 {
887 const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
888 const ValueIdType realEnd =
889 endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
890
891 return ValueRange{ this->Array, realBegin, realEnd };
892 }
893
895 ArrayType* GetArray() const noexcept { return this->Array; }
897 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
898
900 ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
901
903 ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
904
906 size_type size() const noexcept
907 {
908 return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
909 }
910
912 iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
914 iterator end() noexcept { return this->NewIterator(this->EndValue); }
915
917 const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
919 const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
920
922 const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
924 const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
925
928 {
929 return reference{ this->Array, this->BeginValue + i };
930 }
933 {
934 return const_reference{ this->Array, this->BeginValue + i };
935 }
936
937private:
939 iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
940
942 const_iterator NewConstIterator(IdStorageType id) const noexcept
943 {
944 return const_iterator{ this->Array, id };
945 }
946
947 mutable ArrayType* Array{ nullptr };
948 NumCompsType NumComps{};
949 IdStorageType BeginValue{};
950 IdStorageType EndValue{};
951};
952
953// Unimplemented, only used inside decltype in SelectValueRange:
954template <typename ArrayType, ComponentIdType TupleSize>
956
957} // end namespace detail
958} // end namespace vtk
959
961
962#endif // __VTK_WRAP__
963#endif // vtkDataArrayValueRange_Generic_h
964
965// VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:159
ValueRange< AOSArrayType, TupleSize > DeclareValueRangeSpecialization(ArrayType *)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType >::APIType GetAPIType
vtkIdType ValueIdType
vtkIdType TupleIdType
int ComponentIdType
Efficient templated access to vtkDataArray.
VTK_ITER_INLINE ConstValueIterator & operator--() noexcept
friend VTK_ITER_INLINE void swap(ConstValueIterator &lhs, ConstValueIterator &rhs) noexcept
VTK_ITER_INLINE ConstValueIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE ConstValueIterator operator-(const ConstValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator(const ConstValueIterator &o) noexcept=default
VTK_ITER_INLINE ConstValueIterator(ArrayType *array, IdStorageType id) noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstValueIterator &it1, const ConstValueIterator &it2) noexcept
VTK_ITER_INLINE ConstValueIterator(const ValueIterator< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE ConstValueIterator operator++(int) noexcept
VTK_ITER_INLINE ConstValueIterator & operator=(const ConstValueIterator &o) noexcept=default
friend VTK_ITER_INLINE ConstValueIterator operator+(const ConstValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator operator--(int) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
VTK_ITER_INLINE ConstValueIterator & operator++() noexcept
VTK_ITER_INLINE reference operator*() const noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE ConstValueIterator & operator+=(difference_type offset) noexcept
friend VTK_ITER_INLINE ConstValueIterator operator+(difference_type offset, const ConstValueIterator &it) noexcept
VTK_ITER_INLINE ConstValueReference(const ValueReference< ArrayType, TupleSize > &o)
VTK_ITER_INLINE ConstValueReference operator=(const ConstValueReference &o) noexcept
VTK_ITER_INLINE ConstValueReference(ConstValueReference &&o) noexcept=default
VTK_ITER_INLINE ConstValueReference(ArrayType *array, IdStorageType id) noexcept
VTK_ITER_INLINE ConstValueReference(const ConstValueReference &o) noexcept=default
VTK_ITER_INLINE ConstValueReference operator=(ConstValueReference &&o) noexcept
GenericTupleSize< TupleSize > NumCompsType
VTK_ITER_INLINE ComponentIdType GetComponentId() const noexcept
VTK_ITER_INLINE IdStorage operator--(int) noexcept
VTK_ITER_INLINE IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
VTK_ITER_INLINE IdStorage & operator++() noexcept
VTK_ITER_INLINE std::pair< TupleIdType, ComponentIdType > Convert(ValueIdType value) const noexcept
VTK_ITER_INLINE void DebugAsserts(ArrayType *array) const noexcept
VTK_ITER_INLINE void AddOffset(ValueIdType offset) noexcept
VTK_ITER_INLINE IdStorage operator++(int) noexcept
VTK_ITER_INLINE IdStorage & operator--() noexcept
VTK_ITER_INLINE IdStorage() noexcept
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
friend VTK_ITER_INLINE void swap(IdStorage &lhs, IdStorage &rhs) noexcept
friend VTK_ITER_INLINE IdStorage operator+(const IdStorage &id, ValueIdType offset) noexcept
VTK_ITER_INLINE ValueIdType GetValueId() const noexcept
VTK_ITER_INLINE IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
VTK_ITER_INLINE ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
VTK_ITER_INLINE TupleIdType GetTupleId() const noexcept
VTK_ITER_INLINE IdStorage(ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
friend VTK_ITER_INLINE ValueIterator operator+(const ValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE reference operator*() const noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
VTK_ITER_INLINE ValueIterator & operator--() noexcept
VTK_ITER_INLINE ValueIterator operator--(int) noexcept
VTK_ITER_INLINE ValueIterator(const ValueIterator &o) noexcept=default
VTK_ITER_INLINE ValueIterator & operator=(const ValueIterator &o) noexcept
VTK_ITER_INLINE ValueIterator() noexcept=default
VTK_ITER_INLINE ValueIterator operator++(int) noexcept
const IdStorageType & GetId() const noexcept
VTK_ITER_INLINE void DebugIdAsserts() const
VTK_ITER_INLINE ValueIterator & operator+=(difference_type offset) noexcept
friend VTK_ITER_INLINE ValueIterator operator+(difference_type offset, const ValueIterator &it) noexcept
ArrayType * GetArray() const noexcept
VTK_ITER_INLINE const pointer & operator->() const noexcept
VTK_ITER_INLINE ValueIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE ValueIterator operator-(const ValueIterator &it, difference_type offset) noexcept
ValueReference< ArrayType, TupleSize > Ref
friend VTK_ITER_INLINE void swap(ValueIterator &lhs, ValueIterator &rhs) noexcept
std::random_access_iterator_tag iterator_category
friend VTK_ITER_INLINE difference_type operator-(const ValueIterator &it1, const ValueIterator &it2) noexcept
VTK_ITER_INLINE ValueIterator & operator++() noexcept
VTK_ITER_INLINE ValueRange() noexcept=default
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE iterator end() noexcept
ConstValueReference< ArrayType, TupleSize > ConstReferenceType
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
VTK_ITER_INLINE const_iterator begin() const noexcept
ValueIterator< ArrayType, TupleSize > IteratorType
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ValueIdType GetEndValueId() const noexcept
VTK_ITER_INLINE ValueIdType GetBeginValueId() const noexcept
VTK_ITER_INLINE ValueRange GetSubRange(ValueIdType beginValue=0, ValueIdType endValue=-1) const noexcept
ValueReference< ArrayType, TupleSize > ReferenceType
VTK_ITER_INLINE iterator begin() noexcept
static constexpr ComponentIdType TupleSizeTag
VTK_ITER_INLINE const_iterator end() const noexcept
ConstValueIterator< ArrayType, TupleSize > ConstIteratorType
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE ValueReference() noexcept
VTK_ITER_INLINE ValueReference(ArrayType *array, IdStorageType id) noexcept
VTK_ITER_INLINE ValueReference operator=(ValueReference &&o) noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference &o) noexcept
friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType &rhs) noexcept
friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference< OArray, OSize > rhs) noexcept
VTK_ITER_INLINE ValueReference(const ValueReference &o) noexcept=default
friend VTK_ITER_INLINE void swap(APIType &lhs, ValueReference rhs) noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference< OArray, OSize > &o) noexcept
void CopyReference(const ValueReference &o) noexcept
VTK_ITER_INLINE ValueReference operator=(APIType val) noexcept
VTK_ITER_INLINE ValueReference operator++() noexcept
VTK_ITER_INLINE APIType operator++(int) noexcept
VTK_ITER_INLINE ValueReference operator--() noexcept
VTK_ITER_INLINE ValueReference(ValueReference &&o) noexcept=default
friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) 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)