VTK  9.3.0
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 
11 #include "vtkDataArrayAccessor.h"
12 #include "vtkDataArrayMeta.h"
13 
14 #include <algorithm>
15 #include <cassert>
16 #include <iterator>
17 #include <tuple>
18 #include <type_traits>
19 
21 
22 namespace vtk
23 {
24 namespace detail
25 {
26 VTK_ABI_NAMESPACE_BEGIN
27 
28 // Forward decs for friends/args
29 template <typename ArrayType, ComponentIdType>
30 struct ValueReference;
31 template <typename ArrayType, ComponentIdType>
32 struct ConstValueReference;
33 template <typename ArrayType, ComponentIdType>
34 struct ValueIterator;
35 template <typename ArrayType, ComponentIdType>
36 struct ConstValueIterator;
37 template <typename ArrayType, ComponentIdType>
38 struct 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.
48 template <ComponentIdType TupleSize>
49 struct IdStorage
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 
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 
211 private:
212  vtk::ValueIdType ValueId;
213  vtk::TupleIdType TupleId;
214  vtk::ComponentIdType ComponentId;
215  NumCompsType NumComps;
216 };
217 
218 //------------------------------------------------------------------------------
219 // Value reference
220 template <typename ArrayType, ComponentIdType TupleSize>
222 {
223 private:
224  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
225  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
226 
228  using APIType = GetAPIType<ArrayType>;
229 
230 public:
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 
259  ConstValueReference(ConstValueReference&& o) noexcept = default;
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 
282  operator APIType() const noexcept
283  {
284  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
285  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
287  return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
288  }
289 
290 protected:
291  mutable ArrayType* Array;
293 };
294 
295 //------------------------------------------------------------------------------
296 // Value reference
297 template <typename ArrayType, ComponentIdType TupleSize>
299 {
300 private:
301  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
302  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
303 
304  using APIType = GetAPIType<ArrayType>;
306 
307 public:
308  using value_type = APIType;
309 
311  ValueReference() noexcept
312  : Array{ nullptr }
313  , Id{}
314  {
315  }
316 
318  ValueReference(ArrayType* array, IdStorageType id) noexcept
319  : Array{ array }
320  , Id{ id }
321  {
322  this->Id.DebugAsserts(this->Array);
323  }
324 
326  ValueReference(const ValueReference& o) noexcept = default;
328  ValueReference(ValueReference&& o) noexcept = default;
329 
332  {
333  if (this->Array)
334  { // Already initialized. Assign the value, not the reference:
335  return *this = static_cast<APIType>(o);
336  }
337  else
338  { // Initialize the reference:
339  this->Array = o.Array;
340  this->Id = o.Id;
341  return *this;
342  }
343  }
344 
347  {
348  if (this->Array)
349  { // Already initialized. Assign the value, not the reference:
350  return *this = static_cast<APIType>(o);
351  }
352  else
353  { // Initialize the reference:
354  this->Array = std::move(o.Array);
355  this->Id = std::move(o.Id);
356  return *this;
357  }
358  }
359 
360  template <typename OArray, ComponentIdType OSize>
362  { // Always copy the value for different reference types:
363  const APIType tmp = o;
364  return *this = std::move(tmp);
365  }
366 
368  operator APIType() const noexcept
369  {
370  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
371  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
373  return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
374  }
375 
377  ValueReference operator=(APIType val) noexcept
378  {
379  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
380  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
382  acc.Set(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
383  return *this;
384  }
385 
386  friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
387  { // Swap values, not references:
388  APIType tmp = std::move(static_cast<APIType>(lhs));
389  lhs = std::move(static_cast<APIType>(rhs));
390  rhs = std::move(tmp);
391  }
392 
393  template <typename OArray, ComponentIdType OSize>
395  { // Swap values, not references:
396  using OAPIType = typename ValueReference<OArray, OSize>::value_type;
397  static_assert(
398  std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
399 
400  APIType tmp = std::move(static_cast<APIType>(lhs));
401  lhs = std::move(static_cast<APIType>(rhs));
402  rhs = std::move(tmp);
403  }
404 
405  friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
406  {
407  APIType tmp = std::move(static_cast<APIType>(lhs));
408  lhs = std::move(rhs);
409  rhs = std::move(tmp);
410  }
411 
412  friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
413  {
414  APIType tmp = std::move(lhs);
415  lhs = std::move(static_cast<APIType>(rhs));
416  rhs = std::move(tmp);
417  }
418 
420  ValueReference operator++() noexcept // prefix
421  {
422  const APIType newVal = *this + 1;
423  *this = newVal;
424  return *this;
425  }
426 
428  APIType operator++(int) noexcept // postfix
429  {
430  const APIType retVal = *this;
431  *this = *this + 1;
432  return retVal;
433  }
434 
436  ValueReference operator--() noexcept // prefix
437  {
438  const APIType newVal = *this - 1;
439  *this = newVal;
440  return *this;
441  }
442 
444  APIType operator--(int) noexcept // postfix
445  {
446  const APIType retVal = *this;
447  *this = *this - 1;
448  return retVal;
449  }
450 
451 #define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
452  friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
453  { \
454  const APIType newVal = lhs ImplOp val; \
455  lhs = newVal; \
456  return lhs; \
457  } \
458  friend VTK_ITER_INLINE ValueReference operator Op( \
459  ValueReference lhs, ValueReference val) noexcept \
460  { \
461  const APIType newVal = lhs ImplOp val; \
462  lhs = newVal; \
463  return lhs; \
464  } \
465  friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
466  { \
467  const APIType newVal = lhs ImplOp val; \
468  lhs = newVal; \
469  return lhs; \
470  }
471 
472  VTK_REF_OP_OVERLOADS(+=, +)
473  VTK_REF_OP_OVERLOADS(-=, -)
474  VTK_REF_OP_OVERLOADS(*=, *)
475  VTK_REF_OP_OVERLOADS(/=, /)
476 
477 #undef VTK_REF_OP_OVERLOADS
478 
479  friend struct ConstValueReference<ArrayType, TupleSize>;
480  friend struct ValueIterator<ArrayType, TupleSize>;
481 
482 protected:
483  void CopyReference(const ValueReference& o) noexcept
484  {
485  this->Array = o.Array;
486  this->Id = o.Id;
487  }
488 
489  mutable ArrayType* Array;
491 };
492 
493 //------------------------------------------------------------------------------
494 // Const value iterator
495 template <typename ArrayType, ComponentIdType TupleSize>
497 {
498 private:
499  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
500  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
501 
502  using APIType = GetAPIType<ArrayType>;
504 
505 public:
506  using iterator_category = std::random_access_iterator_tag;
507  using value_type = APIType;
509  using pointer = void;
511 
514  : Array(nullptr)
515  , Id()
516  {
517  }
518 
520  ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
521  : Array(array)
522  , Id(id)
523  {
524  this->Id.DebugAsserts(this->Array);
525  }
526 
529  : Array{ o.GetArray() }
530  , Id{ o.GetId() }
531  {
532  }
533 
535  ConstValueIterator(const ConstValueIterator& o) noexcept = default;
537  ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
538 
540  ConstValueIterator& operator++() noexcept // prefix
541  {
542  ++this->Id;
543  this->Id.DebugAsserts(this->Array);
544  return *this;
545  }
546 
548  ConstValueIterator operator++(int) noexcept // postfix
549  {
550  auto ret = this->Id++;
551  this->Id.DebugAsserts(this->Array);
552  return ConstValueIterator{ this->Array, ret };
553  }
554 
556  ConstValueIterator& operator--() noexcept // prefix
557  {
558  --this->Id;
559  this->Id.DebugAsserts(this->Array);
560  return *this;
561  }
562 
564  ConstValueIterator operator--(int) noexcept // postfix
565  {
566  auto ret = this->Id--;
567  this->Id.DebugAsserts(this->Array);
568  return ConstValueIterator{ this->Array, ret };
569  }
570 
573  {
574  return reference{ this->Array, this->Id + i };
575  }
576 
578  reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
579 
580  // Using GetValueType here makes iteration 50% faster by reducing comparisons
581  // and jumps (instead of comparing std::tie(tupleId, compId)).
582 #define VTK_TMP_MAKE_OPERATOR(OP) \
583  friend VTK_ITER_INLINE bool operator OP( \
584  const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
585  { \
586  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
587  return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
588  }
589 
596 
597 #undef VTK_TMP_MAKE_OPERATOR
598 
601  {
602  this->Id.AddOffset(offset);
603  this->Id.DebugAsserts(this->Array);
604  return *this;
605  }
606 
608  const ConstValueIterator& it, difference_type offset) noexcept
609  {
610  return ConstValueIterator{ it.Array, it.Id + offset };
611  }
612 
614  difference_type offset, const ConstValueIterator& it) noexcept
615  {
616  return ConstValueIterator{ it.Array, it.Id + offset };
617  }
618 
621  {
622  this->Id.AddOffset(-offset);
623  this->Id.DebugAsserts(this->Array);
624  return *this;
625  }
626 
628  const ConstValueIterator& it, difference_type offset) noexcept
629  {
630  return ConstValueIterator{ it.Array, it.Id + (-offset) };
631  }
632 
634  const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
635  {
636  VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
637  return it1.Id.GetValueId() - it2.Id.GetValueId();
638  }
639 
641  {
642  // Different arrays may use different iterator implementations.
643  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
644 
645  using std::swap;
646  swap(lhs.Id, rhs.Id);
647  }
648 
649 private:
650  mutable ArrayType* Array;
651  IdStorageType Id;
652 };
653 
654 //------------------------------------------------------------------------------
655 // Component iterator
656 template <typename ArrayType, ComponentIdType TupleSize>
658 {
659 private:
660  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
661  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
662 
663  using APIType = GetAPIType<ArrayType>;
665 
666 public:
667  using iterator_category = std::random_access_iterator_tag;
672 
674  ValueIterator() noexcept = default;
675 
677  ValueIterator(ArrayType* array, IdStorageType id) noexcept
678  : Ref{ array, id }
679  {
680  this->DebugIdAsserts();
681  }
682 
684  ValueIterator(const ValueIterator& o) noexcept = default;
685 
688  {
689  this->Ref.CopyReference(o.Ref);
690  this->DebugIdAsserts();
691  return *this;
692  }
693 
695  ValueIterator& operator++() noexcept // prefix
696  {
697  ++this->Ref.Id;
698  this->DebugIdAsserts();
699  return *this;
700  }
701 
703  ValueIterator operator++(int) noexcept // postfix
704  {
705  auto ret = this->Ref.Id++;
706  this->DebugIdAsserts();
707  return ValueIterator{ this->Ref.Array, ret };
708  }
709 
711  ValueIterator& operator--() noexcept // prefix
712  {
713  --this->Ref.Id;
714  this->DebugIdAsserts();
715  return *this;
716  }
717 
719  ValueIterator operator--(int) noexcept // postfix
720  {
721  auto ret = this->Ref.Id--;
722  this->DebugIdAsserts();
723  return ValueIterator{ this->Ref.Array, ret };
724  }
725 
728  {
729  return reference{ this->Ref.Array, this->Ref.Id + i };
730  }
731 
733  reference operator*() const noexcept { return this->Ref; }
734 
736  const pointer& operator->() const noexcept { return this->Ref; }
737 
738 #define VTK_TMP_MAKE_OPERATOR(OP) \
739  friend VTK_ITER_INLINE bool operator OP( \
740  const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
741  { \
742  VTK_ITER_ASSERT( \
743  lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
744  return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
745  }
746 
753 
754 #undef VTK_TMP_MAKE_OPERATOR
755 
758  {
759  this->Ref.Id.AddOffset(offset);
760  this->DebugIdAsserts();
761  return *this;
762  }
763 
765  const ValueIterator& it, difference_type offset) noexcept
766  {
767  return ValueIterator{ it.GetArray(), it.GetId() + offset };
768  }
769 
771  difference_type offset, const ValueIterator& it) noexcept
772  {
773  return ValueIterator{ it.GetArray(), it.GetId() + offset };
774  }
775 
778  {
779  this->Ref.Id.AddOffset(-offset);
780  this->Ref.Id.DebugAsserts(this->Ref.Array);
781  return *this;
782  }
783 
785  const ValueIterator& it, difference_type offset) noexcept
786  {
787  return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
788  }
789 
791  const ValueIterator& it1, const ValueIterator& it2) noexcept
792  {
794  it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
795  return it1.GetId().GetValueId() - it2.GetId().GetValueId();
796  }
797 
798  friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
799  {
800  // Different arrays may use different iterator implementations.
802  lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
803 
804  using std::swap;
805  swap(lhs.GetId(), rhs.GetId());
806  }
807 
808  friend struct ConstValueIterator<ArrayType, TupleSize>;
809 
810 protected:
812  void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
813 
814  // Needed for access from friend functions. We could just store the array
815  // and ID here instead of the ref, but meh.
816  ArrayType* GetArray() const noexcept { return this->Ref.Array; }
817  IdStorageType& GetId() noexcept { return this->Ref.Id; }
818  const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
819 
821 };
822 
823 //------------------------------------------------------------------------------
824 // ValueRange
825 template <typename ArrayTypeT, ComponentIdType TupleSize>
827 {
828 private:
829  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
830  static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
831 
834 
835 public:
836  using ArrayType = ArrayTypeT;
838 
843 
844  // May be DynamicTupleSize, or the actual tuple size.
845  constexpr static ComponentIdType TupleSizeTag = TupleSize;
846 
847  // STL-compat
854 
856  ValueRange() noexcept = default;
857 
859  ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
860  : Array(arr)
861  , NumComps(arr)
862  , BeginValue(beginValue, this->NumComps)
863  , EndValue(endValue, this->NumComps)
864  {
865  assert(this->Array);
866  assert(beginValue >= 0 && beginValue <= endValue);
867  assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
868  }
869 
871  ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
872  {
873  const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
874  const ValueIdType realEnd =
875  endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
876 
877  return ValueRange{ this->Array, realBegin, realEnd };
878  }
879 
881  ArrayType* GetArray() const noexcept { return this->Array; }
883  ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
884 
886  ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
887 
889  ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
890 
892  size_type size() const noexcept
893  {
894  return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
895  }
896 
898  iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
900  iterator end() noexcept { return this->NewIterator(this->EndValue); }
901 
903  const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
905  const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
906 
908  const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
910  const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
911 
914  {
915  return reference{ this->Array, this->BeginValue + i };
916  }
919  {
920  return const_reference{ this->Array, this->BeginValue + i };
921  }
922 
923 private:
925  iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
926 
928  const_iterator NewConstIterator(IdStorageType id) const noexcept
929  {
930  return const_iterator{ this->Array, id };
931  }
932 
933  mutable ArrayType* Array{ nullptr };
934  NumCompsType NumComps{};
935  IdStorageType BeginValue{};
936  IdStorageType EndValue{};
937 };
938 
939 // Unimplemented, only used inside decltype in SelectValueRange:
940 template <typename ArrayType, ComponentIdType TupleSize>
942 
943 VTK_ABI_NAMESPACE_END
944 } // end namespace detail
945 } // end namespace vtk
946 
948 
949 #endif // vtkDataArrayValueRange_Generic_h
950 
951 // VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:45
@ value
Definition: vtkX3D.h:220
@ offset
Definition: vtkX3D.h:438
ValueRange< AOSArrayType, TupleSize > DeclareValueRangeSpecialization(ArrayType *)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType >::APIType GetAPIType
vtkIdType ValueIdType
vtkIdType TupleIdType
int ComponentIdType
Efficient templated access to vtkDataArray.
friend VTK_ITER_INLINE void swap(ConstValueIterator &lhs, ConstValueIterator &rhs) noexcept
VTK_ITER_INLINE ConstValueIterator & operator=(const ConstValueIterator &o) noexcept=default
VTK_ITER_INLINE ConstValueIterator & operator++() noexcept
friend VTK_ITER_INLINE ConstValueIterator operator-(const ConstValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator(const ConstValueIterator &o) noexcept=default
VTK_ITER_INLINE ConstValueIterator(ArrayType *array, IdStorageType id) noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstValueIterator &it1, const ConstValueIterator &it2) noexcept
VTK_ITER_INLINE ConstValueIterator(const ValueIterator< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE ConstValueIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator operator++(int) noexcept
friend VTK_ITER_INLINE ConstValueIterator operator+(const ConstValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstValueIterator operator--(int) noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
VTK_ITER_INLINE ConstValueIterator & operator--() noexcept
VTK_ITER_INLINE reference operator*() const noexcept
std::random_access_iterator_tag iterator_category
VTK_ITER_INLINE ConstValueIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE ConstValueIterator operator+(difference_type offset, const ConstValueIterator &it) noexcept
VTK_ITER_INLINE ConstValueReference(const ValueReference< ArrayType, TupleSize > &o)
VTK_ITER_INLINE ConstValueReference operator=(const ConstValueReference &o) noexcept
VTK_ITER_INLINE ConstValueReference(ConstValueReference &&o) noexcept=default
VTK_ITER_INLINE ConstValueReference(ArrayType *array, IdStorageType id) noexcept
VTK_ITER_INLINE ConstValueReference(const ConstValueReference &o) noexcept=default
VTK_ITER_INLINE ConstValueReference operator=(ConstValueReference &&o) noexcept
GenericTupleSize< TupleSize > NumCompsType
VTK_ITER_INLINE ComponentIdType GetComponentId() const noexcept
VTK_ITER_INLINE IdStorage & operator++() noexcept
VTK_ITER_INLINE IdStorage operator--(int) noexcept
VTK_ITER_INLINE IdStorage(ValueIdType valueId, NumCompsType numComps) 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 std::pair< TupleIdType, ComponentIdType > Convert(ValueIdType value) const 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
VTK_ITER_INLINE IdStorage & operator--() noexcept
friend VTK_ITER_INLINE ValueIterator operator+(const ValueIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE reference operator*() const noexcept
VTK_ITER_INLINE reference operator[](difference_type i) const noexcept
VTK_ITER_INLINE ValueIterator operator--(int) noexcept
VTK_ITER_INLINE ValueIterator(const ValueIterator &o) noexcept=default
VTK_ITER_INLINE ValueIterator & operator=(const ValueIterator &o) noexcept
VTK_ITER_INLINE ValueIterator() noexcept=default
VTK_ITER_INLINE ValueIterator operator++(int) noexcept
VTK_ITER_INLINE void DebugIdAsserts() const
VTK_ITER_INLINE const pointer & operator->() const noexcept
const IdStorageType & GetId() const noexcept
friend VTK_ITER_INLINE ValueIterator operator+(difference_type offset, const ValueIterator &it) noexcept
VTK_ITER_INLINE ValueIterator & operator-=(difference_type offset) noexcept
ArrayType * GetArray() const noexcept
VTK_ITER_INLINE ValueIterator & operator--() noexcept
friend VTK_ITER_INLINE ValueIterator operator-(const ValueIterator &it, difference_type offset) noexcept
ValueReference< ArrayType, TupleSize > Ref
friend VTK_ITER_INLINE void swap(ValueIterator &lhs, ValueIterator &rhs) noexcept
VTK_ITER_INLINE ValueIterator & operator++() noexcept
VTK_ITER_INLINE ValueIterator & operator+=(difference_type offset) noexcept
std::random_access_iterator_tag iterator_category
friend VTK_ITER_INLINE difference_type operator-(const ValueIterator &it1, const ValueIterator &it2) noexcept
VTK_ITER_INLINE ValueRange() noexcept=default
VTK_ITER_INLINE size_type size() const noexcept
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE iterator end() noexcept
ConstValueReference< ArrayType, TupleSize > ConstReferenceType
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE ComponentIdType GetTupleSize() const noexcept
VTK_ITER_INLINE const_iterator begin() const noexcept
ValueIterator< ArrayType, TupleSize > IteratorType
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE ValueIdType GetEndValueId() const noexcept
VTK_ITER_INLINE ArrayType * GetArray() const noexcept
VTK_ITER_INLINE ValueIdType GetBeginValueId() const noexcept
constexpr static ComponentIdType TupleSizeTag
VTK_ITER_INLINE ValueRange GetSubRange(ValueIdType beginValue=0, ValueIdType endValue=-1) const noexcept
ValueReference< ArrayType, TupleSize > ReferenceType
VTK_ITER_INLINE iterator begin() noexcept
VTK_ITER_INLINE const_iterator end() const noexcept
ConstValueIterator< ArrayType, TupleSize > ConstIteratorType
VTK_ITER_INLINE reference operator[](size_type i) noexcept
VTK_ITER_INLINE ValueReference() noexcept
VTK_ITER_INLINE ValueReference(ArrayType *array, IdStorageType id) noexcept
VTK_ITER_INLINE ValueReference operator=(ValueReference &&o) noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference &o) noexcept
friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType &rhs) noexcept
friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference< OArray, OSize > rhs) noexcept
VTK_ITER_INLINE ValueReference(const ValueReference &o) noexcept=default
friend VTK_ITER_INLINE void swap(APIType &lhs, ValueReference rhs) noexcept
VTK_ITER_INLINE ValueReference operator=(const ValueReference< OArray, OSize > &o) noexcept
void CopyReference(const ValueReference &o) noexcept
VTK_ITER_INLINE ValueReference operator=(APIType val) noexcept
VTK_ITER_INLINE ValueReference operator++() noexcept
VTK_ITER_INLINE APIType operator++(int) noexcept
VTK_ITER_INLINE ValueReference operator--() noexcept
VTK_ITER_INLINE ValueReference(ValueReference &&o) noexcept=default
friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
This file contains a variety of metaprogramming constructs for working with vtkDataArrays.
#define VTK_ITER_OPTIMIZE_START
#define VTK_ITER_INLINE
#define VTK_ITER_OPTIMIZE_END
#define VTK_ITER_ASSERT(x, msg)
#define VTK_ITER_ASSUME
#define VTK_TMP_MAKE_OPERATOR(OP)
#define VTK_REF_OP_OVERLOADS(Op, ImplOp)