VTK  9.4.20241108
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
8#ifndef vtkDataArrayValueRange_Generic_h
9#define vtkDataArrayValueRange_Generic_h
10
12#include "vtkDataArrayMeta.h"
13
14#include <algorithm>
15#include <cassert>
16#include <iterator>
17#include <tuple>
18#include <type_traits>
19
21
22namespace vtk
23{
24namespace detail
25{
26VTK_ABI_NAMESPACE_BEGIN
27
28// Forward decs for friends/args
29template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
30struct ValueReference;
31template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
32struct ConstValueReference;
33template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
34struct ValueIterator;
35template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
36struct ConstValueIterator;
37template <typename ArrayType, ComponentIdType, typename ForceValueTypeForVtkDataArray>
38struct ValueRange;
39
40//------------------------------------------------------------------------------
41// Helper that converts ValueId <--> { TupleId, ComponentId }
42// This class stores both representations. Profiling and assembly inspection
43// show that ValueId is much more efficient for comparing Ids, while Tuple/Comp
44// ids are much faster for looking up elements (especially when considering
45// SOA arrays). The overhead of maintaining both is low, and this class is
46// transparent enough that the compiler will produce efficient ASM with
47// simple optimizations enabled.
48template <ComponentIdType TupleSize>
50{
52
54 IdStorage() noexcept
55 : ValueId(0)
56 , TupleId(0)
57 , ComponentId(0)
58 {
59 }
60
62 IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
63 : ValueId(valueId)
64 , TupleId(static_cast<TupleIdType>(valueId) / static_cast<TupleIdType>(numComps.value))
65 , ComponentId(static_cast<ComponentIdType>(valueId % static_cast<ValueIdType>(numComps.value)))
66 , NumComps(numComps)
67 {
68 }
69
71 IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
72 : ValueId(tupleId * numComps.value + comp)
73 , TupleId(tupleId)
74 , ComponentId(comp)
75 , NumComps(numComps)
76 {
77 }
78
81 ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
82 : ValueId(valueId)
83 , TupleId(tupleId)
84 , ComponentId(comp)
85 , NumComps(numComps)
86 {
87 }
88
89 template <typename ArrayType>
90 VTK_ITER_INLINE void DebugAsserts(ArrayType* array) const noexcept
91 {
92 (void)array;
93 VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
94 VTK_ITER_ASSERT(this->ValueId == this->TupleId * this->GetTupleSize() + this->ComponentId,
95 "Inconsistent internal state in IdStorage.");
96 VTK_ITER_ASSERT(this->GetTupleSize() > 0, "Invalid number of components.");
98 this->ValueId >= 0 && this->ValueId <= array->GetNumberOfValues(), "Invalid value id.");
99 VTK_ITER_ASSERT(this->GetTupleId() >= 0 && this->GetTupleId() <= array->GetNumberOfTuples(),
100 "Invalid tuple id.");
101 VTK_ITER_ASSERT(this->GetComponentId() >= 0 &&
102 (this->GetComponentId() < this->GetTupleSize() ||
103 (this->GetComponentId() == this->GetTupleSize() &&
104 this->GetTupleId() == array->GetNumberOfTuples())),
105 "Invalid component id.");
106 VTK_ITER_ASSERT(this->GetValueId() >= 0 && this->GetValueId() <= array->GetNumberOfValues(),
107 "Invalid value id.");
108 }
109
111 IdStorage& operator++() noexcept // prefix
112 {
113 ++this->ValueId;
114 ++this->ComponentId;
115 if (this->ComponentId == this->GetTupleSize())
116 {
117 this->ComponentId = 0;
118 ++this->TupleId;
119 }
120 return *this;
121 }
122
124 IdStorage operator++(int) noexcept // postfix
125 {
126 auto v = this->ValueId++;
127 auto t = this->TupleId;
128 auto c = this->ComponentId++;
129 if (this->ComponentId == this->GetTupleSize())
130 {
131 this->ComponentId = 0;
132 ++this->TupleId;
133 }
134 return IdStorage{ v, t, c, this->NumComps };
135 }
136
137 friend VTK_ITER_INLINE IdStorage operator+(const IdStorage& id, ValueIdType offset) noexcept
138 {
139 IdStorage res = id;
140 res.AddOffset(offset);
141 return res;
142 }
143
145 IdStorage& operator--() noexcept // prefix
146 {
147 --this->ValueId;
148 --this->ComponentId;
149 if (this->ComponentId < 0)
150 {
151 this->ComponentId = this->GetTupleSize() - 1;
152 --this->TupleId;
153 }
154 return *this;
155 }
156
158 IdStorage operator--(int) noexcept // postfix
159 {
160 auto v = this->ValueId--;
161 auto t = this->TupleId;
162 auto c = this->ComponentId--;
163 if (this->ComponentId < 0)
164 {
165 this->ComponentId = this->GetTupleSize() - 1;
166 --this->TupleId;
167 }
168 return IdStorage{ v, t, c, this->NumComps };
169 }
170
172 ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
173 {
174 return static_cast<ValueIdType>(tuple) * this->NumComps.value + comp;
175 }
176
178 std::pair<TupleIdType, ComponentIdType> Convert(ValueIdType value) const noexcept
179 {
180 return std::make_pair(static_cast<TupleIdType>(value / this->NumComps.value),
181 static_cast<ComponentIdType>(value % this->NumComps.value));
182 }
183
185 void AddOffset(ValueIdType offset) noexcept
186 {
187 this->ValueId += offset;
188 std::tie(this->TupleId, this->ComponentId) = this->Convert(this->ValueId);
189 }
190
192 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
193
195 TupleIdType GetTupleId() const noexcept { return this->TupleId; }
196
198 ComponentIdType GetComponentId() const noexcept { return this->ComponentId; }
199
201 ValueIdType GetValueId() const noexcept { return this->ValueId; }
202
203 friend VTK_ITER_INLINE void swap(IdStorage& lhs, IdStorage& rhs) noexcept
204 {
205 using std::swap;
206 swap(lhs.ValueId, rhs.ValueId);
207 swap(lhs.TupleId, rhs.TupleId);
208 swap(lhs.ComponentId, rhs.ComponentId);
209 }
210
211private:
212 vtk::ValueIdType ValueId;
213 vtk::TupleIdType TupleId;
214 vtk::ComponentIdType ComponentId;
215 NumCompsType NumComps;
216};
217
218//------------------------------------------------------------------------------
219// Value reference
220template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
222{
223private:
224 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
225 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
226
229
230public:
231 using value_type = APIType;
232
235 : Array{ nullptr }
236 , Id{}
237 {
238 }
239
241 ConstValueReference(ArrayType* array, IdStorageType id) noexcept
242 : Array{ array }
243 , Id{ id }
244 {
245 this->Id.DebugAsserts(array);
246 }
247
250 : Array{ o.Array }
251 , Id{ o.Id }
252 {
253 }
254
256 ConstValueReference(const ConstValueReference& o) noexcept = default;
257
260
263 {
264 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
265 // Initialize the reference.
266 this->Array = o.Array;
267 this->Id = o.Id;
268 return *this;
269 }
270
273 {
274 VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
275 // Initialize the reference.
276 this->Array = std::move(o.Array);
277 this->Id = std::move(o.Id);
278 return *this;
279 }
280
281 VTK_ITER_INLINE operator APIType() const noexcept { return this->castOperator(); }
282
283protected:
284 template <typename AT = ArrayType>
285 typename std::enable_if<std::is_same<AT, vtkDataArray>::value, APIType>::type VTK_ITER_INLINE
286 castOperator() const noexcept
287 {
288 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
289 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
290 return this->Array->GetComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
291 }
292
293 template <typename AT = ArrayType>
294 typename std::enable_if<!std::is_same<AT, vtkDataArray>::value, APIType>::type VTK_ITER_INLINE
295 castOperator() const noexcept
296 {
297 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
298 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
299 return this->Array->GetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
300 }
301
302 mutable ArrayType* Array;
304};
305
306//------------------------------------------------------------------------------
307// Value reference
308template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
310{
311private:
312 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
313 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
314
317
318public:
319 using value_type = APIType;
320
322 ValueReference() noexcept
323 : Array{ nullptr }
324 , Id{}
325 {
326 }
327
329 ValueReference(ArrayType* array, IdStorageType id) noexcept
330 : Array{ array }
331 , Id{ id }
332 {
333 this->Id.DebugAsserts(this->Array);
334 }
335
337 ValueReference(const ValueReference& o) noexcept = default;
339 ValueReference(ValueReference&& o) noexcept = default;
340
343 {
344 if (this->Array)
345 { // Already initialized. Assign the value, not the reference:
346 return *this = static_cast<APIType>(o);
347 }
348 else
349 { // Initialize the reference:
350 this->Array = o.Array;
351 this->Id = o.Id;
352 return *this;
353 }
354 }
355
358 {
359 if (this->Array)
360 { // Already initialized. Assign the value, not the reference:
361 return *this = static_cast<APIType>(o);
362 }
363 else
364 { // Initialize the reference:
365 this->Array = std::move(o.Array);
366 this->Id = std::move(o.Id);
367 return *this;
368 }
369 }
370
371 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
379 VTK_ITER_INLINE operator APIType() const noexcept { return this->castOperator(); }
380
381 template <typename AT = ArrayType>
382 typename std::enable_if<std::is_same<AT, vtkDataArray>::value, ValueReference>::type
384 operator=(APIType val) noexcept
385 {
386 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
387 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
388 this->Array->SetComponent(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
389 return *this;
390 }
391
392 template <typename AT = ArrayType>
393 typename std::enable_if<!std::is_same<AT, vtkDataArray>::value, ValueReference>::type
395 operator=(APIType val) noexcept
396 {
397 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
398 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
399 this->Array->SetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
400 return *this;
401 }
402
403 friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
404 { // Swap values, not references:
405 APIType tmp = std::move(static_cast<APIType>(lhs));
406 lhs = std::move(static_cast<APIType>(rhs));
407 rhs = std::move(tmp);
408 }
409
410 template <typename OArray, ComponentIdType OSize>
413 { // Swap values, not references:
414 using OAPIType =
416 static_assert(
417 std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
418
419 APIType tmp = std::move(static_cast<APIType>(lhs));
420 lhs = std::move(static_cast<APIType>(rhs));
421 rhs = std::move(tmp);
422 }
423
424 friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
425 {
426 APIType tmp = std::move(static_cast<APIType>(lhs));
427 lhs = std::move(rhs);
428 rhs = std::move(tmp);
429 }
430
431 friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
432 {
433 APIType tmp = std::move(lhs);
434 lhs = std::move(static_cast<APIType>(rhs));
435 rhs = std::move(tmp);
436 }
437
439 ValueReference operator++() noexcept // prefix
440 {
441 const APIType newVal = *this + 1;
442 *this = newVal;
443 return *this;
444 }
445
447 APIType operator++(int) noexcept // postfix
448 {
449 const APIType retVal = *this;
450 *this = *this + 1;
451 return retVal;
452 }
453
455 ValueReference operator--() noexcept // prefix
456 {
457 const APIType newVal = *this - 1;
458 *this = newVal;
459 return *this;
460 }
461
463 APIType operator--(int) noexcept // postfix
464 {
465 const APIType retVal = *this;
466 *this = *this - 1;
467 return retVal;
468 }
469
470#define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
471 friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
472 { \
473 const APIType newVal = lhs ImplOp val; \
474 lhs = newVal; \
475 return lhs; \
476 } \
477 friend VTK_ITER_INLINE ValueReference operator Op( \
478 ValueReference lhs, ValueReference val) noexcept \
479 { \
480 const APIType newVal = lhs ImplOp val; \
481 lhs = newVal; \
482 return lhs; \
483 } \
484 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
485 { \
486 const APIType newVal = lhs ImplOp val; \
487 lhs = newVal; \
488 return lhs; \
489 }
490
495
496#undef VTK_REF_OP_OVERLOADS
497
498 friend struct ConstValueReference<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
499 friend struct ValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
500
501protected:
502 template <typename AT = ArrayType>
503 typename std::enable_if<std::is_same<AT, vtkDataArray>::value, APIType>::type VTK_ITER_INLINE
504 castOperator() const noexcept
505 {
506 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
507 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
508 return this->Array->GetComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
509 }
510
511 template <typename AT = ArrayType>
512 typename std::enable_if<!std::is_same<AT, vtkDataArray>::value, APIType>::type VTK_ITER_INLINE
513 castOperator() const noexcept
514 {
515 VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
516 VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
517 return this->Array->GetTypedComponent(this->Id.GetTupleId(), this->Id.GetComponentId());
518 }
519
520 void CopyReference(const ValueReference& o) noexcept
521 {
522 this->Array = o.Array;
523 this->Id = o.Id;
524 }
525
526 mutable ArrayType* Array;
528};
529
530//------------------------------------------------------------------------------
531// Const value iterator
532template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
534{
535private:
536 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
537 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
538
541
542public:
543 using iterator_category = std::random_access_iterator_tag;
544 using value_type = APIType;
546 using pointer = void;
548
551 : Array(nullptr)
552 , Id()
553 {
554 }
555
557 ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
558 : Array(array)
559 , Id(id)
560 {
561 this->Id.DebugAsserts(this->Array);
562 }
563
567 : Array{ o.GetArray() }
568 , Id{ o.GetId() }
569 {
570 }
571
573 ConstValueIterator(const ConstValueIterator& o) noexcept = default;
575 ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
576
578 ConstValueIterator& operator++() noexcept // prefix
579 {
580 ++this->Id;
581 this->Id.DebugAsserts(this->Array);
582 return *this;
583 }
584
586 ConstValueIterator operator++(int) noexcept // postfix
587 {
588 auto ret = this->Id++;
589 this->Id.DebugAsserts(this->Array);
590 return ConstValueIterator{ this->Array, ret };
591 }
592
594 ConstValueIterator& operator--() noexcept // prefix
595 {
596 --this->Id;
597 this->Id.DebugAsserts(this->Array);
598 return *this;
599 }
600
602 ConstValueIterator operator--(int) noexcept // postfix
603 {
604 auto ret = this->Id--;
605 this->Id.DebugAsserts(this->Array);
606 return ConstValueIterator{ this->Array, ret };
607 }
608
611 {
612 return reference{ this->Array, this->Id + i };
613 }
614
616 reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
617
618 // Using GetValueType here makes iteration 50% faster by reducing comparisons
619 // and jumps (instead of comparing std::tie(tupleId, compId)).
620#define VTK_TMP_MAKE_OPERATOR(OP) \
621 friend VTK_ITER_INLINE bool operator OP( \
622 const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
623 { \
624 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
625 return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
626 }
627
634
635#undef VTK_TMP_MAKE_OPERATOR
636
639 {
640 this->Id.AddOffset(offset);
641 this->Id.DebugAsserts(this->Array);
642 return *this;
643 }
644
646 const ConstValueIterator& it, difference_type offset) noexcept
647 {
648 return ConstValueIterator{ it.Array, it.Id + offset };
649 }
650
652 difference_type offset, const ConstValueIterator& it) noexcept
653 {
654 return ConstValueIterator{ it.Array, it.Id + offset };
655 }
656
659 {
660 this->Id.AddOffset(-offset);
661 this->Id.DebugAsserts(this->Array);
662 return *this;
663 }
664
666 const ConstValueIterator& it, difference_type offset) noexcept
667 {
668 return ConstValueIterator{ it.Array, it.Id + (-offset) };
669 }
670
672 const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
673 {
674 VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
675 return it1.Id.GetValueId() - it2.Id.GetValueId();
676 }
677
679 {
680 // Different arrays may use different iterator implementations.
681 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
682
683 using std::swap;
684 swap(lhs.Id, rhs.Id);
685 }
686
687private:
688 mutable ArrayType* Array;
689 IdStorageType Id;
690};
691
692//------------------------------------------------------------------------------
693// Component iterator
694template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
696{
697private:
698 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
699 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
700
703
704public:
705 using iterator_category = std::random_access_iterator_tag;
710
712 ValueIterator() noexcept = default;
713
715 ValueIterator(ArrayType* array, IdStorageType id) noexcept
716 : Ref{ array, id }
717 {
718 this->DebugIdAsserts();
719 }
720
722 ValueIterator(const ValueIterator& o) noexcept = default;
723
726 {
727 this->Ref.CopyReference(o.Ref);
728 this->DebugIdAsserts();
729 return *this;
730 }
731
733 ValueIterator& operator++() noexcept // prefix
734 {
735 ++this->Ref.Id;
736 this->DebugIdAsserts();
737 return *this;
738 }
739
741 ValueIterator operator++(int) noexcept // postfix
742 {
743 auto ret = this->Ref.Id++;
744 this->DebugIdAsserts();
745 return ValueIterator{ this->Ref.Array, ret };
746 }
747
749 ValueIterator& operator--() noexcept // prefix
750 {
751 --this->Ref.Id;
752 this->DebugIdAsserts();
753 return *this;
754 }
755
757 ValueIterator operator--(int) noexcept // postfix
758 {
759 auto ret = this->Ref.Id--;
760 this->DebugIdAsserts();
761 return ValueIterator{ this->Ref.Array, ret };
762 }
763
766 {
767 return reference{ this->Ref.Array, this->Ref.Id + i };
768 }
769
771 reference operator*() const noexcept { return this->Ref; }
772
774 const pointer& operator->() const noexcept { return this->Ref; }
775
776#define VTK_TMP_MAKE_OPERATOR(OP) \
777 friend VTK_ITER_INLINE bool operator OP( \
778 const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
779 { \
780 VTK_ITER_ASSERT( \
781 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
782 return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
783 }
784
791
792#undef VTK_TMP_MAKE_OPERATOR
793
796 {
797 this->Ref.Id.AddOffset(offset);
798 this->DebugIdAsserts();
799 return *this;
800 }
801
803 const ValueIterator& it, difference_type offset) noexcept
804 {
805 return ValueIterator{ it.GetArray(), it.GetId() + offset };
806 }
807
809 difference_type offset, const ValueIterator& it) noexcept
810 {
811 return ValueIterator{ it.GetArray(), it.GetId() + offset };
812 }
813
816 {
817 this->Ref.Id.AddOffset(-offset);
818 this->Ref.Id.DebugAsserts(this->Ref.Array);
819 return *this;
820 }
821
823 const ValueIterator& it, difference_type offset) noexcept
824 {
825 return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
826 }
827
829 const ValueIterator& it1, const ValueIterator& it2) noexcept
830 {
832 it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
833 return it1.GetId().GetValueId() - it2.GetId().GetValueId();
834 }
835
836 friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
837 {
838 // Different arrays may use different iterator implementations.
840 lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
841
842 using std::swap;
843 swap(lhs.GetId(), rhs.GetId());
844 }
845
846 friend struct ConstValueIterator<ArrayType, TupleSize, ForceValueTypeForVtkDataArray>;
847
848protected:
850 void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
851
852 // Needed for access from friend functions. We could just store the array
853 // and ID here instead of the ref, but meh.
854 ArrayType* GetArray() const noexcept { return this->Ref.Array; }
855 IdStorageType& GetId() noexcept { return this->Ref.Id; }
856 const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
857
859};
860
861//------------------------------------------------------------------------------
862// ValueRange
863template <typename ArrayTypeT, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
865{
866private:
867 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
868 static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
869
872
873public:
874 using ArrayType = ArrayTypeT;
876
882
883 // May be DynamicTupleSize, or the actual tuple size.
884 constexpr static ComponentIdType TupleSizeTag = TupleSize;
885
886 // STL-compat
893
895 ValueRange() noexcept = default;
896
898 ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
899 : Array(arr)
900 , NumComps(arr)
901 , BeginValue(beginValue, this->NumComps)
902 , EndValue(endValue, this->NumComps)
903 {
904 assert(this->Array);
905 assert(beginValue >= 0 && beginValue <= endValue);
906 assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
907 }
908
910 ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
911 {
912 const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
913 const ValueIdType realEnd =
914 endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
915
916 return ValueRange{ this->Array, realBegin, realEnd };
917 }
918
920 ArrayType* GetArray() const noexcept { return this->Array; }
922 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
923
925 ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
926
928 ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
929
931 size_type size() const noexcept
932 {
933 return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
934 }
935
937 iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
939 iterator end() noexcept { return this->NewIterator(this->EndValue); }
940
942 const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
944 const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
945
947 const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
949 const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
950
953 {
954 return reference{ this->Array, this->BeginValue + i };
955 }
958 {
959 return const_reference{ this->Array, this->BeginValue + i };
960 }
961
963
970 value_type* data() noexcept
971 {
972 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
973 }
974 value_type* data() const noexcept
975 {
976 return reinterpret_cast<value_type*>(this->Array->GetVoidPointer(0));
977 }
979
980private:
982 iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
983
985 const_iterator NewConstIterator(IdStorageType id) const noexcept
986 {
987 return const_iterator{ this->Array, id };
988 }
989
990 mutable ArrayType* Array{ nullptr };
991 NumCompsType NumComps{};
992 IdStorageType BeginValue{};
993 IdStorageType EndValue{};
994};
995
996// Unimplemented, only used inside decltype in SelectValueRange:
997template <typename ArrayType, ComponentIdType TupleSize, typename ForceValueTypeForVtkDataArray>
999 vtkDataArray*);
1000
1001VTK_ABI_NAMESPACE_END
1002} // end namespace detail
1003} // end namespace vtk
1004
1006
1007#endif // vtkDataArrayValueRange_Generic_h
1008
1009// VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
abstract superclass for arrays of numeric data
ValueRange< AOSArrayType, TupleSize, ForceValueTypeForVtkDataArray > DeclareValueRangeSpecialization(ArrayType *)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
vtkIdType ValueIdType
typename detail::GetAPITypeImpl< ArrayType, ForceValueTypeForVtkDataArray >::APIType GetAPIType
vtkIdType TupleIdType
int ComponentIdType
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
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
std::enable_if< std::is_same< AT, vtkDataArray >::value, APIType >::type VTK_ITER_INLINE castOperator() const noexcept
VTK_ITER_INLINE ConstValueReference(const ValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > &o)
VTK_ITER_INLINE ConstValueReference(ArrayType *array, IdStorageType id) noexcept
std::enable_if<!std::is_same< AT, vtkDataArray >::value, APIType >::type VTK_ITER_INLINE castOperator() const 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
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
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
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
ConstValueReference< ArrayType, TupleSize, ForceValueTypeForVtkDataArray > ConstReferenceType
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
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
value_type * data() const noexcept
VTK_ITER_INLINE ValueReference operator++() noexcept
std::enable_if< std::is_same< AT, vtkDataArray >::value, ValueReference >::type VTK_ITER_INLINE operator=(APIType val) noexcept
VTK_ITER_INLINE ValueReference operator=(ValueReference &&o) noexcept
VTK_ITER_INLINE ValueReference operator--() noexcept
std::enable_if<!std::is_same< AT, vtkDataArray >::value, APIType >::type VTK_ITER_INLINE castOperator() const 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
std::enable_if< std::is_same< AT, vtkDataArray >::value, APIType >::type VTK_ITER_INLINE castOperator() const noexcept
std::enable_if<!std::is_same< AT, vtkDataArray >::value, ValueReference >::type VTK_ITER_INLINE operator=(APIType val) 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)