VTK  9.2.6
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
33
34namespace vtk
35{
36
37namespace detail
38{
39
40// Forward decs for friends/args
41template <typename ArrayType, ComponentIdType>
42struct ValueReference;
43template <typename ArrayType, ComponentIdType>
44struct ConstValueReference;
45template <typename ArrayType, ComponentIdType>
46struct ValueIterator;
47template <typename ArrayType, ComponentIdType>
48struct ConstValueIterator;
49template <typename ArrayType, ComponentIdType>
50struct ValueRange;
51
52//------------------------------------------------------------------------------
53// Helper that converts ValueId <--> { TupleId, ComponentId }
54// This class stores both representations. Profiling and assembly inspection
55// show that ValueId is much more efficient for comparing Ids, while Tuple/Comp
56// ids are much faster for looking up elements (especially when considering
57// SOA arrays). The overhead of maintaining both is low, and this class is
58// transparent enough that the compiler will produce efficient ASM with
59// simple optimizations enabled.
60template <ComponentIdType TupleSize>
62{
64
66 IdStorage() noexcept
67 : ValueId(0)
68 , TupleId(0)
69 , ComponentId(0)
70 {
71 }
72
74 IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
75 : ValueId(valueId)
76 , TupleId(static_cast<TupleIdType>(valueId) / static_cast<TupleIdType>(numComps.value))
77 , ComponentId(static_cast<ComponentIdType>(valueId % static_cast<ValueIdType>(numComps.value)))
78 , NumComps(numComps)
79 {
80 }
81
83 IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
84 : ValueId(tupleId * numComps.value + comp)
85 , TupleId(tupleId)
86 , ComponentId(comp)
87 , NumComps(numComps)
88 {
89 }
90
93 ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
94 : ValueId(valueId)
95 , TupleId(tupleId)
96 , ComponentId(comp)
97 , NumComps(numComps)
98 {
99 }
100
101 template <typename ArrayType>
102 VTK_ITER_INLINE void DebugAsserts(ArrayType* array) const noexcept
103 {
104 (void)array;
105 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
106 VTK_ITER_ASSERT(this->ValueId == this->TupleId * this->GetTupleSize() + this->ComponentId,
107 "Inconsistent internal state in IdStorage.");
108 VTK_ITER_ASSERT(this->GetTupleSize() > 0, "Invalid number of components.");
110 this->ValueId >= 0 && this->ValueId <= array->GetNumberOfValues(), "Invalid value id.");
111 VTK_ITER_ASSERT(this->GetTupleId() >= 0 && this->GetTupleId() <= array->GetNumberOfTuples(),
112 "Invalid tuple id.");
113 VTK_ITER_ASSERT(this->GetComponentId() >= 0 &&
114 (this->GetComponentId() < this->GetTupleSize() ||
115 (this->GetComponentId() == this->GetTupleSize() &&
116 this->GetTupleId() == array->GetNumberOfTuples())),
117 "Invalid component id.");
118 VTK_ITER_ASSERT(this->GetValueId() >= 0 && this->GetValueId() <= array->GetNumberOfValues(),
119 "Invalid value id.");
120 }
121
123 IdStorage& operator++() noexcept // prefix
124 {
125 ++this->ValueId;
126 ++this->ComponentId;
127 if (this->ComponentId == this->GetTupleSize())
128 {
129 this->ComponentId = 0;
130 ++this->TupleId;
131 }
132 return *this;
133 }
134
136 IdStorage operator++(int) noexcept // postfix
137 {
138 auto v = this->ValueId++;
139 auto t = this->TupleId;
140 auto c = this->ComponentId++;
141 if (this->ComponentId == this->GetTupleSize())
142 {
143 this->ComponentId = 0;
144 ++this->TupleId;
145 }
146 return IdStorage{ v, t, c, this->NumComps };
147 }
148
149 friend VTK_ITER_INLINE IdStorage operator+(const IdStorage& id, ValueIdType offset) noexcept
150 {
151 IdStorage res = id;
152 res.AddOffset(offset);
153 return res;
154 }
155
157 IdStorage& operator--() noexcept // prefix
158 {
159 --this->ValueId;
160 --this->ComponentId;
161 if (this->ComponentId < 0)
162 {
163 this->ComponentId = this->GetTupleSize() - 1;
164 --this->TupleId;
165 }
166 return *this;
167 }
168
170 IdStorage operator--(int) noexcept // postfix
171 {
172 auto v = this->ValueId--;
173 auto t = this->TupleId;
174 auto c = this->ComponentId--;
175 if (this->ComponentId < 0)
176 {
177 this->ComponentId = this->GetTupleSize() - 1;
178 --this->TupleId;
179 }
180 return IdStorage{ v, t, c, this->NumComps };
181 }
182
184 ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
185 {
186 return static_cast<ValueIdType>(tuple) * this->NumComps.value + comp;
187 }
188
190 std::pair<TupleIdType, ComponentIdType> Convert(ValueIdType value) const noexcept
191 {
192 return std::make_pair(static_cast<TupleIdType>(value / this->NumComps.value),
193 static_cast<ComponentIdType>(value % this->NumComps.value));
194 }
195
197 void AddOffset(ValueIdType offset) noexcept
198 {
199 this->ValueId += offset;
200 std::tie(this->TupleId, this->ComponentId) = this->Convert(this->ValueId);
201 }
202
204 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
205
207 TupleIdType GetTupleId() const noexcept { return this->TupleId; }
208
210 ComponentIdType GetComponentId() const noexcept { return this->ComponentId; }
211
213 ValueIdType GetValueId() const noexcept { return this->ValueId; }
214
215 friend VTK_ITER_INLINE void swap(IdStorage& lhs, IdStorage& rhs) noexcept
216 {
217 using std::swap;
218 swap(lhs.ValueId, rhs.ValueId);
219 swap(lhs.TupleId, rhs.TupleId);
220 swap(lhs.ComponentId, rhs.ComponentId);
221 }
222
223private:
224 vtk::ValueIdType ValueId;
225 vtk::TupleIdType TupleId;
226 vtk::ComponentIdType ComponentId;
227 NumCompsType NumComps;
228};
229
230//------------------------------------------------------------------------------
231// Value reference
232template <typename ArrayType, ComponentIdType TupleSize>
234{
235private:
236 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
237 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
238
240 using APIType = GetAPIType<ArrayType>;
241
242public:
243 using value_type = APIType;
244
247 : Array{ nullptr }
248 , Id{}
249 {
250 }
251
253 ConstValueReference(ArrayType* array, IdStorageType id) noexcept
254 : Array{ array }
255 , Id{ id }
256 {
257 this->Id.DebugAsserts(array);
258 }
259
262 : Array{ o.Array }
263 , Id{ o.Id }
264 {
265 }
266
268 ConstValueReference(const ConstValueReference& o) noexcept = default;
269
272
275 {
276 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
277 // Initialize the reference.
278 this->Array = o.Array;
279 this->Id = o.Id;
280 return *this;
281 }
282
285 {
286 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
287 // Initialize the reference.
288 this->Array = std::move(o.Array);
289 this->Id = std::move(o.Id);
290 return *this;
291 }
292
294 operator APIType() const noexcept
295 {
296 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
297 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
299 return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
300 }
301
302protected:
303 mutable ArrayType* Array;
305};
306
307//------------------------------------------------------------------------------
308// Value reference
309template <typename ArrayType, ComponentIdType TupleSize>
311{
312private:
313 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
314 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
315
316 using APIType = GetAPIType<ArrayType>;
318
319public:
320 using value_type = APIType;
321
323 ValueReference() noexcept
324 : Array{ nullptr }
325 , Id{}
326 {
327 }
328
330 ValueReference(ArrayType* array, IdStorageType id) noexcept
331 : Array{ array }
332 , Id{ id }
333 {
334 this->Id.DebugAsserts(this->Array);
335 }
336
338 ValueReference(const ValueReference& o) noexcept = default;
340 ValueReference(ValueReference&& o) noexcept = default;
341
344 {
345 if (this->Array)
346 { // Already initialized. Assign the value, not the reference:
347 return *this = static_cast<APIType>(o);
348 }
349 else
350 { // Initialize the reference:
351 this->Array = o.Array;
352 this->Id = o.Id;
353 return *this;
354 }
355 }
356
359 {
360 if (this->Array)
361 { // Already initialized. Assign the value, not the reference:
362 return *this = static_cast<APIType>(o);
363 }
364 else
365 { // Initialize the reference:
366 this->Array = std::move(o.Array);
367 this->Id = std::move(o.Id);
368 return *this;
369 }
370 }
371
372 template <typename OArray, ComponentIdType OSize>
374 { // Always copy the value for different reference types:
375 const APIType tmp = o;
376 return *this = std::move(tmp);
377 }
378
380 operator APIType() const noexcept
381 {
382 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
383 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
385 return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
386 }
387
389 ValueReference operator=(APIType val) noexcept
390 {
391 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
392 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
394 acc.Set(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
395 return *this;
396 }
397
398 friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
399 { // Swap values, not references:
400 APIType tmp = std::move(static_cast<APIType>(lhs));
401 lhs = std::move(static_cast<APIType>(rhs));
402 rhs = std::move(tmp);
403 }
404
405 template <typename OArray, ComponentIdType OSize>
407 { // Swap values, not references:
408 using OAPIType = typename ValueReference<OArray, OSize>::value_type;
409 static_assert(
410 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
411
412 APIType tmp = std::move(static_cast<APIType>(lhs));
413 lhs = std::move(static_cast<APIType>(rhs));
414 rhs = std::move(tmp);
415 }
416
417 friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
418 {
419 APIType tmp = std::move(static_cast<APIType>(lhs));
420 lhs = std::move(rhs);
421 rhs = std::move(tmp);
422 }
423
424 friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
425 {
426 APIType tmp = std::move(lhs);
427 lhs = std::move(static_cast<APIType>(rhs));
428 rhs = std::move(tmp);
429 }
430
432 ValueReference operator++() noexcept // prefix
433 {
434 const APIType newVal = *this + 1;
435 *this = newVal;
436 return *this;
437 }
438
440 APIType operator++(int) noexcept // postfix
441 {
442 const APIType retVal = *this;
443 *this = *this + 1;
444 return retVal;
445 }
446
448 ValueReference operator--() noexcept // prefix
449 {
450 const APIType newVal = *this - 1;
451 *this = newVal;
452 return *this;
453 }
454
456 APIType operator--(int) noexcept // postfix
457 {
458 const APIType retVal = *this;
459 *this = *this - 1;
460 return retVal;
461 }
462
463#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
464 friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
465 { \
466 const APIType newVal = lhs ImplOp val; \
467 lhs = newVal; \
468 return lhs; \
469 } \
470 friend VTK_ITER_INLINE ValueReference operator Op( \
471 ValueReference lhs, ValueReference val) noexcept \
472 { \
473 const APIType newVal = lhs ImplOp val; \
474 lhs = newVal; \
475 return lhs; \
476 } \
477 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
478 { \
479 const APIType newVal = lhs ImplOp val; \
480 lhs = newVal; \
481 return lhs; \
482 }
483
488
489#undef VTK_REF_OP_OVERLOADS
490
491 friend struct ConstValueReference<ArrayType, TupleSize>;
492 friend struct ValueIterator<ArrayType, TupleSize>;
493
494protected:
495 void CopyReference(const ValueReference& o) noexcept
496 {
497 this->Array = o.Array;
498 this->Id = o.Id;
499 }
500
501 mutable ArrayType* Array;
503};
504
505//------------------------------------------------------------------------------
506// Const value iterator
507template <typename ArrayType, ComponentIdType TupleSize>
509{
510private:
511 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
512 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
513
514 using APIType = GetAPIType<ArrayType>;
516
517public:
518 using iterator_category = std::random_access_iterator_tag;
519 using value_type = APIType;
521 using pointer = void;
523
526 : Array(nullptr)
527 , Id()
528 {
529 }
530
532 ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
533 : Array(array)
534 , Id(id)
535 {
536 this->Id.DebugAsserts(this->Array);
537 }
538
541 : Array{ o.GetArray() }
542 , Id{ o.GetId() }
543 {
544 }
545
547 ConstValueIterator(const ConstValueIterator& o) noexcept = default;
549 ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
550
552 ConstValueIterator& operator++() noexcept // prefix
553 {
554 ++this->Id;
555 this->Id.DebugAsserts(this->Array);
556 return *this;
557 }
558
560 ConstValueIterator operator++(int) noexcept // postfix
561 {
562 auto ret = this->Id++;
563 this->Id.DebugAsserts(this->Array);
564 return ConstValueIterator{ this->Array, ret };
565 }
566
568 ConstValueIterator& operator--() noexcept // prefix
569 {
570 --this->Id;
571 this->Id.DebugAsserts(this->Array);
572 return *this;
573 }
574
576 ConstValueIterator operator--(int) noexcept // postfix
577 {
578 auto ret = this->Id--;
579 this->Id.DebugAsserts(this->Array);
580 return ConstValueIterator{ this->Array, ret };
581 }
582
585 {
586 return reference{ this->Array, this->Id + i };
587 }
588
590 reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
591
592 // Using GetValueType here makes iteration 50% faster by reducing comparisons
593 // and jumps (instead of comparing std::tie(tupleId, compId)).
594#define VTK_TMP_MAKE_OPERATOR(OP) \
595 friend VTK_ITER_INLINE bool operator OP( \
596 const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
597 { \
598 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
599 return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
600 }
601
608
609#undef VTK_TMP_MAKE_OPERATOR
610
613 {
614 this->Id.AddOffset(offset);
615 this->Id.DebugAsserts(this->Array);
616 return *this;
617 }
618
620 const ConstValueIterator& it, difference_type offset) noexcept
621 {
622 return ConstValueIterator{ it.Array, it.Id + offset };
623 }
624
626 difference_type offset, const ConstValueIterator& it) noexcept
627 {
628 return ConstValueIterator{ it.Array, it.Id + offset };
629 }
630
633 {
634 this->Id.AddOffset(-offset);
635 this->Id.DebugAsserts(this->Array);
636 return *this;
637 }
638
640 const ConstValueIterator& it, difference_type offset) noexcept
641 {
642 return ConstValueIterator{ it.Array, it.Id + (-offset) };
643 }
644
646 const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
647 {
648 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
649 return it1.Id.GetValueId() - it2.Id.GetValueId();
650 }
651
653 {
654 // Different arrays may use different iterator implementations.
655 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
656
657 using std::swap;
658 swap(lhs.Id, rhs.Id);
659 }
660
661private:
662 mutable ArrayType* Array;
663 IdStorageType Id;
664};
665
666//------------------------------------------------------------------------------
667// Component iterator
668template <typename ArrayType, ComponentIdType TupleSize>
670{
671private:
672 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
673 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
674
675 using APIType = GetAPIType<ArrayType>;
677
678public:
679 using iterator_category = std::random_access_iterator_tag;
684
686 ValueIterator() noexcept = default;
687
689 ValueIterator(ArrayType* array, IdStorageType id) noexcept
690 : Ref{ array, id }
691 {
692 this->DebugIdAsserts();
693 }
694
696 ValueIterator(const ValueIterator& o) noexcept = default;
697
700 {
701 this->Ref.CopyReference(o.Ref);
702 this->DebugIdAsserts();
703 return *this;
704 }
705
707 ValueIterator& operator++() noexcept // prefix
708 {
709 ++this->Ref.Id;
710 this->DebugIdAsserts();
711 return *this;
712 }
713
715 ValueIterator operator++(int) noexcept // postfix
716 {
717 auto ret = this->Ref.Id++;
718 this->DebugIdAsserts();
719 return ValueIterator{ this->Ref.Array, ret };
720 }
721
723 ValueIterator& operator--() noexcept // prefix
724 {
725 --this->Ref.Id;
726 this->DebugIdAsserts();
727 return *this;
728 }
729
731 ValueIterator operator--(int) noexcept // postfix
732 {
733 auto ret = this->Ref.Id--;
734 this->DebugIdAsserts();
735 return ValueIterator{ this->Ref.Array, ret };
736 }
737
740 {
741 return reference{ this->Ref.Array, this->Ref.Id + i };
742 }
743
745 reference operator*() const noexcept { return this->Ref; }
746
748 const pointer& operator->() const noexcept { return this->Ref; }
749
750#define VTK_TMP_MAKE_OPERATOR(OP) \
751 friend VTK_ITER_INLINE bool operator OP( \
752 const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
753 { \
754 VTK_ITER_ASSERT( \
755 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
756 return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
757 }
758
765
766#undef VTK_TMP_MAKE_OPERATOR
767
770 {
771 this->Ref.Id.AddOffset(offset);
772 this->DebugIdAsserts();
773 return *this;
774 }
775
777 const ValueIterator& it, difference_type offset) noexcept
778 {
779 return ValueIterator{ it.GetArray(), it.GetId() + offset };
780 }
781
783 difference_type offset, const ValueIterator& it) noexcept
784 {
785 return ValueIterator{ it.GetArray(), it.GetId() + offset };
786 }
787
790 {
791 this->Ref.Id.AddOffset(-offset);
792 this->Ref.Id.DebugAsserts(this->Ref.Array);
793 return *this;
794 }
795
797 const ValueIterator& it, difference_type offset) noexcept
798 {
799 return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
800 }
801
803 const ValueIterator& it1, const ValueIterator& it2) noexcept
804 {
806 it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
807 return it1.GetId().GetValueId() - it2.GetId().GetValueId();
808 }
809
810 friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
811 {
812 // Different arrays may use different iterator implementations.
814 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
815
816 using std::swap;
817 swap(lhs.GetId(), rhs.GetId());
818 }
819
820 friend struct ConstValueIterator<ArrayType, TupleSize>;
821
822protected:
824 void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
825
826 // Needed for access from friend functions. We could just store the array
827 // and ID here instead of the ref, but meh.
828 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
829 IdStorageType& GetId() noexcept { return this->Ref.Id; }
830 const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
831
833};
834
835//------------------------------------------------------------------------------
836// ValueRange
837template <typename ArrayTypeT, ComponentIdType TupleSize>
839{
840private:
841 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
842 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
843
846
847public:
848 using ArrayType = ArrayTypeT;
850
855
856 // May be DynamicTupleSize, or the actual tuple size.
857 constexpr static ComponentIdType TupleSizeTag = TupleSize;
858
859 // STL-compat
866
868 ValueRange() noexcept = default;
869
871 ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
872 : Array(arr)
873 , NumComps(arr)
874 , BeginValue(beginValue, this->NumComps)
875 , EndValue(endValue, this->NumComps)
876 {
877 assert(this->Array);
878 assert(beginValue >= 0 && beginValue <= endValue);
879 assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
880 }
881
883 ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
884 {
885 const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
886 const ValueIdType realEnd =
887 endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
888
889 return ValueRange{ this->Array, realBegin, realEnd };
890 }
891
893 ArrayType* GetArray() const noexcept { return this->Array; }
895 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
896
898 ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
899
901 ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
902
904 size_type size() const noexcept
905 {
906 return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
907 }
908
910 iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
912 iterator end() noexcept { return this->NewIterator(this->EndValue); }
913
915 const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
917 const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
918
920 const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
922 const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
923
926 {
927 return reference{ this->Array, this->BeginValue + i };
928 }
931 {
932 return const_reference{ this->Array, this->BeginValue + i };
933 }
934
935private:
937 iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
938
940 const_iterator NewConstIterator(IdStorageType id) const noexcept
941 {
942 return const_iterator{ this->Array, id };
943 }
944
945 mutable ArrayType* Array{ nullptr };
946 NumCompsType NumComps{};
947 IdStorageType BeginValue{};
948 IdStorageType EndValue{};
949};
950
951// Unimplemented, only used inside decltype in SelectValueRange:
952template <typename ArrayType, ComponentIdType TupleSize>
954
955} // end namespace detail
956} // end namespace vtk
957
959
960#endif // vtkDataArrayValueRange_Generic_h
961
962// VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
abstract superclass for arrays of numeric data
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_ALWAYS_INLINE APIType Get(vtkIdType tupleIdx, int compIdx) const
VTK_ALWAYS_INLINE void Set(vtkIdType tupleIdx, int compIdx, APIType val) const
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(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)