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