VTK  9.6.20260227
vtkDataArrayValueRange_Generic.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
7
8#ifndef vtkDataArrayValueRange_Generic_h
9#define vtkDataArrayValueRange_Generic_h
10
11#include "vtkDataArrayMeta.h"
12
13#include <algorithm>
14#include <cassert>
15#include <iterator>
16#include <tuple>
17#include <type_traits>
18
20
21namespace vtk
22{
23namespace detail
24{
25VTK_ABI_NAMESPACE_BEGIN
26
27// Forward decs for friends/args
28template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
29struct ValueReference;
30template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
32template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
33struct ValueIterator;
34template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
36template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
37struct ValueRange;
38
39//------------------------------------------------------------------------------
40// Helper that converts ValueId <--> { TupleId, ComponentId }
41// This class stores both representations. Profiling and assembly inspection
42// show that ValueId is much more efficient for comparing Ids, while Tuple/Comp
43// ids are much faster for looking up elements (especially when considering
44// SOA arrays). The overhead of maintaining both is low, and this class is
45// transparent enough that the compiler will produce efficient ASM with
46// simple optimizations enabled.
47template <ComponentIdType TupleSize>
49{
51
53 IdStorage() noexcept
54 : ValueId(0)
55 , TupleId(0)
56 , ComponentId(0)
57 {
58 }
59
61 IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
62 : ValueId(valueId)
63 , TupleId(static_cast<TupleIdType>(valueId) / static_cast<TupleIdType>(numComps.value))
64 , ComponentId(static_cast<ComponentIdType>(valueId % static_cast<ValueIdType>(numComps.value)))
65 , NumComps(numComps)
66 {
67 }
68
70 IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
71 : ValueId(tupleId * numComps.value + comp)
72 , TupleId(tupleId)
73 , ComponentId(comp)
74 , NumComps(numComps)
75 {
76 }
77
80 ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
81 : ValueId(valueId)
82 , TupleId(tupleId)
83 , ComponentId(comp)
84 , NumComps(numComps)
85 {
86 }
87
88 template <typename ArrayType>
89 VTK_ITER_INLINE void DebugAsserts(ArrayType* array) const noexcept
90 {
91 (void)array;
92 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
93 VTK_ITER_ASSERT(this->ValueId == this->TupleId * this->GetTupleSize() + this->ComponentId,
94 "Inconsistent internal state in IdStorage.");
95 VTK_ITER_ASSERT(this->GetTupleSize() > 0, "Invalid number of components.");
97 this->ValueId >= 0 && this->ValueId <= array->GetNumberOfValues(), "Invalid value id.");
98 VTK_ITER_ASSERT(this->GetTupleId() >= 0 && this->GetTupleId() <= array->GetNumberOfTuples(),
99 "Invalid tuple id.");
100 VTK_ITER_ASSERT(this->GetComponentId() >= 0 &&
101 (this->GetComponentId() < this->GetTupleSize() ||
102 (this->GetComponentId() == this->GetTupleSize() &&
103 this->GetTupleId() == array->GetNumberOfTuples())),
104 "Invalid component id.");
105 VTK_ITER_ASSERT(this->GetValueId() >= 0 && this->GetValueId() <= array->GetNumberOfValues(),
106 "Invalid value id.");
107 }
108
110 IdStorage& operator++() noexcept // prefix
111 {
112 ++this->ValueId;
113 ++this->ComponentId;
114 if (this->ComponentId == this->GetTupleSize())
115 {
116 this->ComponentId = 0;
117 ++this->TupleId;
118 }
119 return *this;
120 }
121
123 IdStorage operator++(int) noexcept // postfix
124 {
125 auto v = this->ValueId++;
126 auto t = this->TupleId;
127 auto c = this->ComponentId++;
128 if (this->ComponentId == this->GetTupleSize())
129 {
130 this->ComponentId = 0;
131 ++this->TupleId;
132 }
133 return IdStorage{ v, t, c, this->NumComps };
134 }
135
136 friend VTK_ITER_INLINE IdStorage operator+(const IdStorage& id, ValueIdType offset) noexcept
137 {
138 IdStorage res = id;
139 res.AddOffset(offset);
140 return res;
141 }
142
144 IdStorage& operator--() noexcept // prefix
145 {
146 --this->ValueId;
147 --this->ComponentId;
148 if (this->ComponentId < 0)
149 {
150 this->ComponentId = this->GetTupleSize() - 1;
151 --this->TupleId;
152 }
153 return *this;
154 }
155
157 IdStorage operator--(int) noexcept // postfix
158 {
159 auto v = this->ValueId--;
160 auto t = this->TupleId;
161 auto c = this->ComponentId--;
162 if (this->ComponentId < 0)
163 {
164 this->ComponentId = this->GetTupleSize() - 1;
165 --this->TupleId;
166 }
167 return IdStorage{ v, t, c, this->NumComps };
168 }
169
171 ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
172 {
173 return static_cast<ValueIdType>(tuple) * this->NumComps.value + comp;
174 }
175
177 std::pair<TupleIdType, ComponentIdType> Convert(ValueIdType value) const noexcept
178 {
179 return std::make_pair(static_cast<TupleIdType>(value / this->NumComps.value),
180 static_cast<ComponentIdType>(value % this->NumComps.value));
181 }
182
184 void AddOffset(ValueIdType offset) noexcept
185 {
186 this->ValueId += offset;
187 std::tie(this->TupleId, this->ComponentId) = this->Convert(this->ValueId);
188 }
189
191 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
192
194 TupleIdType GetTupleId() const noexcept { return this->TupleId; }
195
197 ComponentIdType GetComponentId() const noexcept { return this->ComponentId; }
198
200 ValueIdType GetValueId() const noexcept { return this->ValueId; }
201
202 friend VTK_ITER_INLINE void swap(IdStorage& lhs, IdStorage& rhs) noexcept
203 {
204 using std::swap;
205 swap(lhs.ValueId, rhs.ValueId);
206 swap(lhs.TupleId, rhs.TupleId);
207 swap(lhs.ComponentId, rhs.ComponentId);
208 }
209
210private:
211 vtk::ValueIdType ValueId;
212 vtk::TupleIdType TupleId;
213 vtk::ComponentIdType ComponentId;
214 NumCompsType NumComps;
215};
216
217//------------------------------------------------------------------------------
218// Value reference
219template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
221{
222private:
223 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
224 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
225
226 using IdStorageType = IdStorage<TupleSize>;
228
229public:
230 using value_type = APIType;
231
234 : Array{ nullptr }
235 , Id{}
236 {
237 }
238
240 ConstValueReference(ArrayType* array, IdStorageType id) noexcept
241 : Array{ array }
242 , Id{ id }
243 {
244 this->Id.DebugAsserts(array);
245 }
246
253
255 ConstValueReference(const ConstValueReference& o) noexcept = default;
256
259
262 {
263 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
264 // Initialize the reference.
265 this->Array = o.Array;
266 this->Id = o.Id;
267 return *this;
268 }
269
272 {
273 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
274 // Initialize the reference.
275 this->Array = std::move(o.Array);
276 this->Id = std::move(o.Id);
277 return *this;
278 }
279
280 VTK_ITER_INLINE operator APIType() const noexcept
281 {
282 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
283 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
284 if constexpr (std::is_same_v<ArrayType, vtkDataArray>)
285 {
286 return this->Array->GetComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
287 }
288 else if constexpr (TupleSize == 1)
289 {
290 return this->Array->GetValue(this->Id.GetValueId());
291 }
292 else
293 {
294 return this->Array->GetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
295 }
296 }
297
298 mutable ArrayType* Array;
299 IdStorageType Id;
300};
301
302//------------------------------------------------------------------------------
303// Value reference
304template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
306{
307private:
308 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
309 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
310
312 using IdStorageType = IdStorage<TupleSize>;
313
314public:
315 using value_type = APIType;
316
318 ValueReference() noexcept
319 : Array{ nullptr }
320 , Id{}
321 {
322 }
323
325 ValueReference(ArrayType* array, IdStorageType id) noexcept
326 : Array{ array }
327 , Id{ id }
328 {
329 this->Id.DebugAsserts(this->Array);
330 }
331
333 ValueReference(const ValueReference& o) noexcept = default;
335 ValueReference(ValueReference&& o) noexcept = default;
336
339 {
340 if (this->Array)
341 { // Already initialized. Assign the value, not the reference:
342 return *this = static_cast<APIType>(o);
343 }
344 else
345 { // Initialize the reference:
346 this->Array = o.Array;
347 this->Id = o.Id;
348 return *this;
349 }
350 }
351
354 {
355 if (this->Array)
356 { // Already initialized. Assign the value, not the reference:
357 return *this = static_cast<APIType>(o);
358 }
359 else
360 { // Initialize the reference:
361 this->Array = std::move(o.Array);
362 this->Id = std::move(o.Id);
363 return *this;
364 }
365 }
366
367 template <typename OArray, ComponentIdType OSize>
370 { // Always copy the value for different reference types:
371 const APIType tmp = o;
372 return *this = std::move(tmp);
373 }
374
375 VTK_ITER_INLINE operator APIType() const noexcept
376 {
377 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
378 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
379 if constexpr (std::is_same_v<ArrayType, vtkDataArray>)
380 {
381 return this->Array->GetComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
382 }
383 else if constexpr (TupleSize == 1)
384 {
385 return this->Array->GetValue(this->Id.GetValueId());
386 }
387 else
388 {
389 return this->Array->GetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
390 }
391 }
392
394 {
395 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
396 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
397 if constexpr (std::is_same_v<ArrayType, vtkDataArray>)
398 {
399 this->Array->SetComponent(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
400 }
401 else if constexpr (TupleSize == 1)
402 {
403 this->Array->SetValue(this->Id.GetValueId(), val);
404 }
405 else
406 {
407 this->Array->SetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
408 }
409 return *this;
410 }
411
412 friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
413 { // Swap values, not references:
414 APIType tmp = static_cast<APIType>(lhs);
415 lhs = static_cast<APIType>(rhs);
416 rhs = std::move(tmp);
417 }
418
419 template <typename OArray, ComponentIdType OSize>
422 { // Swap values, not references:
423 using OAPIType =
425 static_assert(
426 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
427
428 APIType tmp = static_cast<APIType>(lhs);
429 lhs = static_cast<APIType>(rhs);
430 rhs = std::move(tmp);
431 }
432
433 friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
434 {
435 APIType tmp = static_cast<APIType>(lhs);
436 lhs = std::move(rhs);
437 rhs = std::move(tmp);
438 }
439
440 friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
441 {
442 APIType tmp = std::move(lhs);
443 lhs = static_cast<APIType>(rhs);
444 rhs = std::move(tmp);
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
464 ValueReference operator--() noexcept // prefix
465 {
466 const APIType newVal = *this - 1;
467 *this = newVal;
468 return *this;
469 }
470
472 APIType operator--(int) noexcept // postfix
473 {
474 const APIType retVal = *this;
475 *this = *this - 1;
476 return retVal;
477 }
478
479#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
480 friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
481 { \
482 const APIType newVal = lhs ImplOp val; \
483 lhs = newVal; \
484 return lhs; \
485 } \
486 friend VTK_ITER_INLINE ValueReference operator Op( \
487 ValueReference lhs, ValueReference val) noexcept \
488 { \
489 const APIType newVal = lhs ImplOp val; \
490 lhs = newVal; \
491 return lhs; \
492 } \
493 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
494 { \
495 const APIType newVal = lhs ImplOp val; \
496 lhs = newVal; \
497 return lhs; \
498 }
499
504
505#undef VTK_REF_OP_OVERLOADS
506
507 friend struct ConstValueReference<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
508 friend struct ValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
509
510protected:
511 void CopyReference(const ValueReference& o) noexcept
512 {
513 this->Array = o.Array;
514 this->Id = o.Id;
515 }
516
517 mutable ArrayType* Array;
518 IdStorageType Id;
519};
520
521//------------------------------------------------------------------------------
522// Const value iterator
523template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
525{
526private:
527 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
528 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
529
531 using IdStorageType = IdStorage<TupleSize>;
532
533public:
534 using iterator_category = std::random_access_iterator_tag;
535 using value_type = APIType;
537 using pointer = void;
539
542 : Array(nullptr)
543 , Id()
544 {
545 }
546
548 ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
549 : Array(array)
550 , Id(id)
551 {
552 this->Id.DebugAsserts(this->Array);
553 }
554
558 : Array{ o.GetArray() }
559 , Id{ o.GetId() }
560 {
561 }
562
564 ConstValueIterator(const ConstValueIterator& o) noexcept = default;
566 ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
567
569 ConstValueIterator& operator++() noexcept // prefix
570 {
571 ++this->Id;
572 this->Id.DebugAsserts(this->Array);
573 return *this;
574 }
575
577 ConstValueIterator operator++(int) noexcept // postfix
578 {
579 auto ret = this->Id++;
580 this->Id.DebugAsserts(this->Array);
581 return ConstValueIterator{ this->Array, ret };
582 }
583
585 ConstValueIterator& operator--() noexcept // prefix
586 {
587 --this->Id;
588 this->Id.DebugAsserts(this->Array);
589 return *this;
590 }
591
593 ConstValueIterator operator--(int) noexcept // postfix
594 {
595 auto ret = this->Id--;
596 this->Id.DebugAsserts(this->Array);
597 return ConstValueIterator{ this->Array, ret };
598 }
599
602 {
603 return reference{ this->Array, this->Id + i };
604 }
605
607 reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
608
609 // Using GetValueType here makes iteration 50% faster by reducing comparisons
610 // and jumps (instead of comparing std::tie(tupleId, compId)).
611#define VTK_TMP_MAKE_OPERATOR(OP) \
612 friend VTK_ITER_INLINE bool operator OP( \
613 const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
614 { \
615 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
616 return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
617 }
618
625
626#undef VTK_TMP_MAKE_OPERATOR
627
630 {
631 this->Id.AddOffset(offset);
632 this->Id.DebugAsserts(this->Array);
633 return *this;
634 }
635
637 const ConstValueIterator& it, difference_type offset) noexcept
638 {
639 return ConstValueIterator{ it.Array, it.Id + offset };
640 }
641
643 difference_type offset, const ConstValueIterator& it) noexcept
644 {
645 return ConstValueIterator{ it.Array, it.Id + offset };
646 }
647
650 {
651 this->Id.AddOffset(-offset);
652 this->Id.DebugAsserts(this->Array);
653 return *this;
654 }
655
657 const ConstValueIterator& it, difference_type offset) noexcept
658 {
659 return ConstValueIterator{ it.Array, it.Id + (-offset) };
660 }
661
663 const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
664 {
665 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
666 return it1.Id.GetValueId() - it2.Id.GetValueId();
667 }
668
670 {
671 // Different arrays may use different iterator implementations.
672 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
673
674 using std::swap;
675 swap(lhs.Id, rhs.Id);
676 }
677
678private:
679 mutable ArrayType* Array;
680 IdStorageType Id;
681};
682
683//------------------------------------------------------------------------------
684// Component iterator
685template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
687{
688private:
689 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
690 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
691
693 using IdStorageType = IdStorage<TupleSize>;
694
695public:
696 using iterator_category = std::random_access_iterator_tag;
701
703 ValueIterator() noexcept = default;
704
706 ValueIterator(ArrayType* array, IdStorageType id) noexcept
707 : Ref{ array, id }
708 {
709 this->DebugIdAsserts();
710 }
711
713 ValueIterator(const ValueIterator& o) noexcept = default;
714
717 {
718 this->Ref.CopyReference(o.Ref);
719 this->DebugIdAsserts();
720 return *this;
721 }
722
724 ValueIterator& operator++() noexcept // prefix
725 {
726 ++this->Ref.Id;
727 this->DebugIdAsserts();
728 return *this;
729 }
730
732 ValueIterator operator++(int) noexcept // postfix
733 {
734 auto ret = this->Ref.Id++;
735 this->DebugIdAsserts();
736 return ValueIterator{ this->Ref.Array, ret };
737 }
738
740 ValueIterator& operator--() noexcept // prefix
741 {
742 --this->Ref.Id;
743 this->DebugIdAsserts();
744 return *this;
745 }
746
748 ValueIterator operator--(int) noexcept // postfix
749 {
750 auto ret = this->Ref.Id--;
751 this->DebugIdAsserts();
752 return ValueIterator{ this->Ref.Array, ret };
753 }
754
757 {
758 return reference{ this->Ref.Array, this->Ref.Id + i };
759 }
760
762 reference operator*() const noexcept { return this->Ref; }
763
765 const pointer& operator->() const noexcept { return this->Ref; }
766
767#define VTK_TMP_MAKE_OPERATOR(OP) \
768 friend VTK_ITER_INLINE bool operator OP( \
769 const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
770 { \
771 VTK_ITER_ASSERT( \
772 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
773 return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
774 }
775
782
783#undef VTK_TMP_MAKE_OPERATOR
784
787 {
788 this->Ref.Id.AddOffset(offset);
789 this->DebugIdAsserts();
790 return *this;
791 }
792
794 const ValueIterator& it, difference_type offset) noexcept
795 {
796 return ValueIterator{ it.GetArray(), it.GetId() + offset };
797 }
798
800 difference_type offset, const ValueIterator& it) noexcept
801 {
802 return ValueIterator{ it.GetArray(), it.GetId() + offset };
803 }
804
807 {
808 this->Ref.Id.AddOffset(-offset);
809 this->Ref.Id.DebugAsserts(this->Ref.Array);
810 return *this;
811 }
812
814 const ValueIterator& it, difference_type offset) noexcept
815 {
816 return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
817 }
818
820 const ValueIterator& it1, const ValueIterator& it2) noexcept
821 {
823 it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
824 return it1.GetId().GetValueId() - it2.GetId().GetValueId();
825 }
826
827 friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
828 {
829 // Different arrays may use different iterator implementations.
831 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
832
833 using std::swap;
834 swap(lhs.GetId(), rhs.GetId());
835 }
836
837 friend struct ConstValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
838
839protected:
841 void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
842
843 // Needed for access from friend functions. We could just store the array
844 // and ID here instead of the ref, but meh.
845 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
846 IdStorageType& GetId() noexcept { return this->Ref.Id; }
847 const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
848
850};
851
852//------------------------------------------------------------------------------
853// ValueRange
854template <typename ArrayTypeT, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
856{
857private:
858 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
859 static_assert(IsVtkArray<ArrayTypeT>::value, "Invalid array type.");
860
861 using IdStorageType = IdStorage<TupleSize>;
862 using NumCompsType = GenericTupleSize<TupleSize>;
863
864public:
865 using ArrayType = ArrayTypeT;
867
873
874 // May be DynamicTupleSize, or the actual tuple size.
875 constexpr static ComponentIdType TupleSizeTag = TupleSize;
876
877 // STL-compat
884
886 ValueRange() noexcept = default;
887
889 ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
890 : Array(arr)
891 , NumComps(arr)
892 , BeginValue(beginValue, this->NumComps)
893 , EndValue(endValue, this->NumComps)
894 {
895 assert(this->Array);
896 assert(beginValue >= 0 && beginValue <= endValue);
897 assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
898 }
899
901 ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
902 {
903 const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
904 const ValueIdType realEnd =
905 endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
906
907 return ValueRange{ this->Array, realBegin, realEnd };
908 }
909
911 ArrayType* GetArray() const noexcept { return this->Array; }
913 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
914
916 ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
917
919 ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
920
922 size_type size() const noexcept
923 {
924 return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
925 }
926
928 iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
930 iterator end() noexcept { return this->NewIterator(this->EndValue); }
931
933 const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
935 const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
936
938 const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
940 const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
941
944 {
945 return reference{ this->Array, this->BeginValue + i };
946 }
949 {
950 return const_reference{ this->Array, this->BeginValue + i };
951 }
952
954
961 VTK_DEPRECATED_IN_9_6_0("Use iterators instead.")
962 value_type* data() noexcept
963 {
964 // NOLINTNEXTLINE(bugprone-unsafe-functions)
965 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
966 }
967 VTK_DEPRECATED_IN_9_6_0("Use iterators instead.")
968 value_type* data() const noexcept
969 {
970 // NOLINTNEXTLINE(bugprone-unsafe-functions)
971 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
972 }
973
974
975private:
977 iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
978
980 const_iterator NewConstIterator(IdStorageType id) const noexcept
981 {
982 return const_iterator{ this->Array, id };
983 }
984
985 mutable ArrayType* Array{ nullptr };
986 NumCompsType NumComps{};
987 IdStorageType BeginValue{};
988 IdStorageType EndValue{};
989};
990
991// Unimplemented, only used inside decltype in SelectValueRange:
992template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
995
996VTK_ABI_NAMESPACE_END
997} // end namespace detail
998} // end namespace vtk
999
1001
1002#endif // vtkDataArrayValueRange_Generic_h
1003
1004// VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
Abstract superclass for all arrays.
ValueRange< AOSArrayType, TupleSize, ForceValueTypeForVtkDataArray > DeclareValueRangeSpecialization(ArrayType *)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType, ForceValueTypeForVtkDataArray >::APIType GetAPIType
vtkIdType TupleIdType
int ComponentIdType
vtkIdType ValueIdType
friend VTK_ITER_INLINE void swap(ConstValueIterator &lhs, ConstValueIterator &rhs) noexcept
VTK_ITER_INLINE reference operator*() const noexcept
VTK_ITER_INLINE ConstValueIterator(const ValueIterator< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > &o) noexcept
VTK_ITER_INLINE ConstValueIterator operator++(int) noexcept
friend VTK_ITER_INLINE ConstValueIterator operator-(const ConstValueIterator &it, difference_type offset) noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstValueIterator &it1, const ConstValueIterator &it2) noexcept
VTK_ITER_INLINE ConstValueIterator operator--(int) noexcept
VTK_ITER_INLINE ConstValueIterator & operator-=(difference_type offset) noexcept
ConstValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > reference
friend VTK_ITER_INLINE ConstValueIterator operator+(const ConstValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator & operator--() noexcept
VTK_ITER_INLINE ConstValueIterator & operator++() noexcept
VTK_ITER_INLINE ConstValueIterator(const ConstValueIterator &o) noexcept=default
VTK_ITER_INLINE ConstValueIterator & operator=(const ConstValueIterator &o) noexcept=default
VTK_ITER_INLINE ConstValueIterator(ArrayType *array, IdStorageType id) noexcept
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 ConstValueReference &o) noexcept=default
VTK_ITER_INLINE ConstValueReference(const ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > &o)
VTK_ITER_INLINE ConstValueReference(ArrayType *array, IdStorageType id) noexcept
VTK_ITER_INLINE ConstValueReference(ConstValueReference &&o) noexcept=default
VTK_ITER_INLINE ConstValueReference operator=(const ConstValueReference &o) noexcept
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
static constexpr bool value
friend VTK_ITER_INLINE ValueIterator operator+(const ValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ValueIterator & operator++() noexcept
VTK_ITER_INLINE reference operator*() const noexcept
std::random_access_iterator_tag iterator_category
ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > reference
VTK_ITER_INLINE ValueIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE ValueIterator operator--(int) noexcept
VTK_ITER_INLINE ValueIterator & operator=(const ValueIterator &o) noexcept
VTK_ITER_INLINE void DebugIdAsserts() const
ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > Ref
ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > pointer
VTK_ITER_INLINE ValueIterator & operator--() noexcept
friend VTK_ITER_INLINE ValueIterator operator+(difference_type offset, const ValueIterator &it) noexcept
GetAPIType< ArrayType, ForceValueTypeForVtkDataArray > value_type
VTK_ITER_INLINE ValueIterator() noexcept=default
friend VTK_ITER_INLINE ValueIterator operator-(const ValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ValueIterator operator++(int) noexcept
VTK_ITER_INLINE ValueIterator & operator+=(difference_type offset) noexcept
ArrayType * GetArray() const noexcept
friend VTK_ITER_INLINE void swap(ValueIterator &lhs, ValueIterator &rhs) noexcept
VTK_ITER_INLINE const pointer & operator->() const noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
const IdStorageType & GetId() const noexcept
friend VTK_ITER_INLINE difference_type operator-(const ValueIterator &it1, const ValueIterator &it2) noexcept
VTK_ITER_INLINE ValueIterator(const ValueIterator &o) noexcept=default
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE const_iterator begin() const noexcept
static constexpr ComponentIdType TupleSizeTag
GetAPIType< ArrayType, ForceValueTypeForVtkDataArray > ValueType
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ValueRange GetSubRange(ValueIdType beginValue=0, ValueIdType endValue=-1) const noexcept
VTK_ITER_INLINE iterator begin() noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
VTK_ITER_INLINE ValueIdType GetBeginValueId() const noexcept
VTK_ITER_INLINE ValueRange() noexcept=default
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > ReferenceType
ConstValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > ConstReferenceType
VTK_ITER_INLINE iterator end() noexcept
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
ConstValueIterator< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > ConstIteratorType
ValueIterator< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > IteratorType
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE ValueIdType GetEndValueId() const noexcept
VTK_ITER_INLINE ValueReference operator++() noexcept
VTK_ITER_INLINE ValueReference operator=(APIType val) noexcept
VTK_ITER_INLINE ValueReference operator=(ValueReference &&o) noexcept
VTK_ITER_INLINE ValueReference operator--() noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference< OArray, OSize, ForceValueTypeForVtkDataArray > &o) noexcept
void CopyReference(const ValueReference &o) noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference &o) noexcept
VTK_ITER_INLINE ValueReference(const ValueReference &o) noexcept=default
friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType &rhs) noexcept
friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference< OArray, OSize, ForceValueTypeForVtkDataArray > rhs) noexcept
friend VTK_ITER_INLINE void swap(APIType &lhs, ValueReference rhs) noexcept
VTK_ITER_INLINE APIType operator++(int) noexcept
VTK_ITER_INLINE ValueReference(ValueReference &&o) noexcept=default
VTK_ITER_INLINE ValueReference(ArrayType *array, IdStorageType id) noexcept
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)
#define VTK_DEPRECATED_IN_9_6_0(reason)