VTK  9.6.20260410
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
507
508#undef VTK_REF_OP_OVERLOADS
509
510 friend struct ConstValueReference<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
511 friend struct ValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
512
513protected:
514 void CopyReference(const ValueReference& o) noexcept
515 {
516 this->Array = o.Array;
517 this->Id = o.Id;
518 }
519
520 mutable ArrayType* Array;
521 IdStorageType Id;
522};
523
524//------------------------------------------------------------------------------
525// Const value iterator
526template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
528{
529private:
530 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
531 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
532
534 using IdStorageType = IdStorage<TupleSize>;
535
536public:
537 using iterator_category = std::random_access_iterator_tag;
538 using value_type = APIType;
540 using pointer = void;
542
545 : Array(nullptr)
546 , Id()
547 {
548 }
549
551 ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
552 : Array(array)
553 , Id(id)
554 {
555 this->Id.DebugAsserts(this->Array);
556 }
557
561 : Array{ o.GetArray() }
562 , Id{ o.GetId() }
563 {
564 }
565
567 ConstValueIterator(const ConstValueIterator& o) noexcept = default;
569 ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
570
572 ConstValueIterator& operator++() noexcept // prefix
573 {
574 ++this->Id;
575 this->Id.DebugAsserts(this->Array);
576 return *this;
577 }
578
580 ConstValueIterator operator++(int) noexcept // postfix
581 {
582 auto ret = this->Id++;
583 this->Id.DebugAsserts(this->Array);
584 return ConstValueIterator{ this->Array, ret };
585 }
586
588 ConstValueIterator& operator--() noexcept // prefix
589 {
590 --this->Id;
591 this->Id.DebugAsserts(this->Array);
592 return *this;
593 }
594
596 ConstValueIterator operator--(int) noexcept // postfix
597 {
598 auto ret = this->Id--;
599 this->Id.DebugAsserts(this->Array);
600 return ConstValueIterator{ this->Array, ret };
601 }
602
605 {
606 return reference{ this->Array, this->Id + i };
607 }
608
610 reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
611
612 // Using GetValueType here makes iteration 50% faster by reducing comparisons
613 // and jumps (instead of comparing std::tie(tupleId, compId)).
614#define VTK_TMP_MAKE_OPERATOR(OP) \
615 friend VTK_ITER_INLINE bool operator OP( \
616 const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
617 { \
618 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
619 return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
620 }
621
628
629#undef VTK_TMP_MAKE_OPERATOR
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 difference_type offset, const ConstValueIterator& it) noexcept
647 {
648 return ConstValueIterator{ it.Array, it.Id + offset };
649 }
650
653 {
654 this->Id.AddOffset(-offset);
655 this->Id.DebugAsserts(this->Array);
656 return *this;
657 }
658
660 const ConstValueIterator& it, difference_type offset) noexcept
661 {
662 return ConstValueIterator{ it.Array, it.Id + (-offset) };
663 }
664
666 const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
667 {
668 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
669 return it1.Id.GetValueId() - it2.Id.GetValueId();
670 }
671
673 {
674 // Different arrays may use different iterator implementations.
675 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
676
677 using std::swap;
678 swap(lhs.Id, rhs.Id);
679 }
680
681private:
682 mutable ArrayType* Array;
683 IdStorageType Id;
684};
685
686//------------------------------------------------------------------------------
687// Component iterator
688template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
690{
691private:
692 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
693 static_assert(IsVtkArray<ArrayType>::value, "Invalid array type.");
694
696 using IdStorageType = IdStorage<TupleSize>;
697
698public:
699 using iterator_category = std::random_access_iterator_tag;
704
706 ValueIterator() noexcept = default;
707
709 ValueIterator(ArrayType* array, IdStorageType id) noexcept
710 : Ref{ array, id }
711 {
712 this->DebugIdAsserts();
713 }
714
716 ValueIterator(const ValueIterator& o) noexcept = default;
717
720 {
721 this->Ref.CopyReference(o.Ref);
722 this->DebugIdAsserts();
723 return *this;
724 }
725
727 ValueIterator& operator++() noexcept // prefix
728 {
729 ++this->Ref.Id;
730 this->DebugIdAsserts();
731 return *this;
732 }
733
735 ValueIterator operator++(int) noexcept // postfix
736 {
737 auto ret = this->Ref.Id++;
738 this->DebugIdAsserts();
739 return ValueIterator{ this->Ref.Array, ret };
740 }
741
743 ValueIterator& operator--() noexcept // prefix
744 {
745 --this->Ref.Id;
746 this->DebugIdAsserts();
747 return *this;
748 }
749
751 ValueIterator operator--(int) noexcept // postfix
752 {
753 auto ret = this->Ref.Id--;
754 this->DebugIdAsserts();
755 return ValueIterator{ this->Ref.Array, ret };
756 }
757
760 {
761 return reference{ this->Ref.Array, this->Ref.Id + i };
762 }
763
765 reference operator*() const noexcept { return this->Ref; }
766
768 const pointer& operator->() const noexcept { return this->Ref; }
769
770#define VTK_TMP_MAKE_OPERATOR(OP) \
771 friend VTK_ITER_INLINE bool operator OP( \
772 const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
773 { \
774 VTK_ITER_ASSERT( \
775 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
776 return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
777 }
778
785
786#undef VTK_TMP_MAKE_OPERATOR
787
790 {
791 this->Ref.Id.AddOffset(offset);
792 this->DebugIdAsserts();
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 difference_type offset, const ValueIterator& it) noexcept
804 {
805 return ValueIterator{ it.GetArray(), it.GetId() + offset };
806 }
807
810 {
811 this->Ref.Id.AddOffset(-offset);
812 this->Ref.Id.DebugAsserts(this->Ref.Array);
813 return *this;
814 }
815
817 const ValueIterator& it, difference_type offset) noexcept
818 {
819 return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
820 }
821
823 const ValueIterator& it1, const ValueIterator& it2) noexcept
824 {
826 it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
827 return it1.GetId().GetValueId() - it2.GetId().GetValueId();
828 }
829
830 friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
831 {
832 // Different arrays may use different iterator implementations.
834 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
835
836 using std::swap;
837 swap(lhs.GetId(), rhs.GetId());
838 }
839
840 friend struct ConstValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
841
842protected:
844 void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
845
846 // Needed for access from friend functions. We could just store the array
847 // and ID here instead of the ref, but meh.
848 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
849 IdStorageType& GetId() noexcept { return this->Ref.Id; }
850 const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
851
853};
854
855//------------------------------------------------------------------------------
856// ValueRange
857template <typename ArrayTypeT, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
859{
860private:
861 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
862 static_assert(IsVtkArray<ArrayTypeT>::value, "Invalid array type.");
863
864 using IdStorageType = IdStorage<TupleSize>;
865 using NumCompsType = GenericTupleSize<TupleSize>;
866
867public:
868 using ArrayType = ArrayTypeT;
870
876
877 // May be DynamicTupleSize, or the actual tuple size.
878 constexpr static ComponentIdType TupleSizeTag = TupleSize;
879
880 // STL-compat
887
889 ValueRange() noexcept = default;
890
892 ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
893 : Array(arr)
894 , NumComps(arr)
895 , BeginValue(beginValue, this->NumComps)
896 , EndValue(endValue, this->NumComps)
897 {
898 assert(this->Array);
899 assert(beginValue >= 0 && beginValue <= endValue);
900 assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
901 }
902
904 ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
905 {
906 const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
907 const ValueIdType realEnd =
908 endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
909
910 return ValueRange{ this->Array, realBegin, realEnd };
911 }
912
914 ArrayType* GetArray() const noexcept { return this->Array; }
916 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
917
919 ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
920
922 ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
923
925 size_type size() const noexcept
926 {
927 return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
928 }
929
931 iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
933 iterator end() noexcept { return this->NewIterator(this->EndValue); }
934
936 const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
938 const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
939
941 const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
943 const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
944
947 {
948 return reference{ this->Array, this->BeginValue + i };
949 }
952 {
953 return const_reference{ this->Array, this->BeginValue + i };
954 }
955
957
964 VTK_DEPRECATED_IN_9_6_0("Use iterators instead.")
965 value_type* data() noexcept
966 {
967 // NOLINTNEXTLINE(bugprone-unsafe-functions)
968 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
969 }
970 VTK_DEPRECATED_IN_9_6_0("Use iterators instead.")
971 value_type* data() const noexcept
972 {
973 // NOLINTNEXTLINE(bugprone-unsafe-functions)
974 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
975 }
976
977
978private:
980 iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
981
983 const_iterator NewConstIterator(IdStorageType id) const noexcept
984 {
985 return const_iterator{ this->Array, id };
986 }
987
988 mutable ArrayType* Array{ nullptr };
989 NumCompsType NumComps{};
990 IdStorageType BeginValue{};
991 IdStorageType EndValue{};
992};
993
994// Unimplemented, only used inside decltype in SelectValueRange:
995template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
998
999VTK_ABI_NAMESPACE_END
1000} // end namespace detail
1001} // end namespace vtk
1002
1004
1005#endif // vtkDataArrayValueRange_Generic_h
1006
1007// 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)