VTK  9.1.20211028
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 
32 #ifndef __VTK_WRAP__
33 
35 
36 namespace vtk
37 {
38 
39 namespace detail
40 {
41 
42 // Forward decs for friends/args
43 template <typename ArrayType, ComponentIdType>
44 struct ValueReference;
45 template <typename ArrayType, ComponentIdType>
46 struct ConstValueReference;
47 template <typename ArrayType, ComponentIdType>
48 struct ValueIterator;
49 template <typename ArrayType, ComponentIdType>
50 struct ConstValueIterator;
51 template <typename ArrayType, ComponentIdType>
52 struct ValueRange;
53 
54 //------------------------------------------------------------------------------
55 // Helper that converts ValueId <--> { TupleId, ComponentId }
56 // This class stores both representations. Profiling and assembly inspection
57 // show that ValueId is much more efficient for comparing Ids, while Tuple/Comp
58 // ids are much faster for looking up elements (especially when considering
59 // SOA arrays). The overhead of maintaining both is low, and this class is
60 // transparent enough that the compiler will produce efficient ASM with
61 // simple optimizations enabled.
62 template <ComponentIdType TupleSize>
63 struct IdStorage
64 {
66 
68  IdStorage() noexcept
69  : ValueId(0)
70  , TupleId(0)
71  , ComponentId(0)
72  {
73  }
74 
76  IdStorage(ValueIdType valueId, NumCompsType numComps) noexcept
77  : ValueId(valueId)
78  , TupleId(static_cast<TupleIdType>(valueId) / static_cast<TupleIdType>(numComps.value))
79  , ComponentId(static_cast<ComponentIdType>(valueId % static_cast<ValueIdType>(numComps.value)))
80  , NumComps(numComps)
81  {
82  }
83 
85  IdStorage(TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
86  : ValueId(tupleId * numComps.value + comp)
87  , TupleId(tupleId)
88  , ComponentId(comp)
89  , NumComps(numComps)
90  {
91  }
92 
95  ValueIdType valueId, TupleIdType tupleId, ComponentIdType comp, NumCompsType numComps) noexcept
96  : ValueId(valueId)
97  , TupleId(tupleId)
98  , ComponentId(comp)
99  , NumComps(numComps)
100  {
101  }
102 
103  template <typename ArrayType>
104  VTK_ITER_INLINE void DebugAsserts(ArrayType* array) const noexcept
105  {
106  (void)array;
107  VTK_ITER_ASSERT(array != nullptr, "Invalid array.");
108  VTK_ITER_ASSERT(this->ValueId == this->TupleId * this->GetTupleSize() + this->ComponentId,
109  "Inconsistent internal state in IdStorage.");
110  VTK_ITER_ASSERT(this->GetTupleSize() > 0, "Invalid number of components.");
112  this->ValueId >= 0 && this->ValueId <= array->GetNumberOfValues(), "Invalid value id.");
113  VTK_ITER_ASSERT(this->GetTupleId() >= 0 && this->GetTupleId() <= array->GetNumberOfTuples(),
114  "Invalid tuple id.");
115  VTK_ITER_ASSERT(this->GetComponentId() >= 0 &&
116  (this->GetComponentId() < this->GetTupleSize() ||
117  (this->GetComponentId() == this->GetTupleSize() &&
118  this->GetTupleId() == array->GetNumberOfTuples())),
119  "Invalid component id.");
120  VTK_ITER_ASSERT(this->GetValueId() >= 0 && this->GetValueId() <= array->GetNumberOfValues(),
121  "Invalid value id.");
122  }
123 
125  IdStorage& operator++() noexcept // prefix
126  {
127  ++this->ValueId;
128  ++this->ComponentId;
129  if (this->ComponentId == this->GetTupleSize())
130  {
131  this->ComponentId = 0;
132  ++this->TupleId;
133  }
134  return *this;
135  }
136 
138  IdStorage operator++(int) noexcept // postfix
139  {
140  auto v = this->ValueId++;
141  auto t = this->TupleId;
142  auto c = this->ComponentId++;
143  if (this->ComponentId == this->GetTupleSize())
144  {
145  this->ComponentId = 0;
146  ++this->TupleId;
147  }
148  return IdStorage{ v, t, c, this->NumComps };
149  }
150 
152  {
153  IdStorage res = id;
154  res.AddOffset(offset);
155  return res;
156  }
157 
159  IdStorage& operator--() noexcept // prefix
160  {
161  --this->ValueId;
162  --this->ComponentId;
163  if (this->ComponentId < 0)
164  {
165  this->ComponentId = this->GetTupleSize() - 1;
166  --this->TupleId;
167  }
168  return *this;
169  }
170 
172  IdStorage operator--(int) noexcept // postfix
173  {
174  auto v = this->ValueId--;
175  auto t = this->TupleId;
176  auto c = this->ComponentId--;
177  if (this->ComponentId < 0)
178  {
179  this->ComponentId = this->GetTupleSize() - 1;
180  --this->TupleId;
181  }
182  return IdStorage{ v, t, c, this->NumComps };
183  }
184 
186  ValueIdType Convert(TupleIdType tuple, ComponentIdType comp) const noexcept
187  {
188  return static_cast<ValueIdType>(tuple) * this->NumComps.value + comp;
189  }
190 
192  std::pair<TupleIdType, ComponentIdType> Convert(ValueIdType value) const noexcept
193  {
194  return std::make_pair(static_cast<TupleIdType>(value / this->NumComps.value),
195  static_cast<ComponentIdType>(value % this->NumComps.value));
196  }
197 
199  void AddOffset(ValueIdType offset) noexcept
200  {
201  this->ValueId += offset;
202  std::tie(this->TupleId, this->ComponentId) = this->Convert(this->ValueId);
203  }
204 
206  ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
207 
209  TupleIdType GetTupleId() const noexcept { return this->TupleId; }
210 
212  ComponentIdType GetComponentId() const noexcept { return this->ComponentId; }
213 
215  ValueIdType GetValueId() const noexcept { return this->ValueId; }
216 
217  friend VTK_ITER_INLINE void swap(IdStorage& lhs, IdStorage& rhs) noexcept
218  {
219  using std::swap;
220  swap(lhs.ValueId, rhs.ValueId);
221  swap(lhs.TupleId, rhs.TupleId);
222  swap(lhs.ComponentId, rhs.ComponentId);
223  }
224 
225 private:
226  vtk::ValueIdType ValueId;
227  vtk::TupleIdType TupleId;
228  vtk::ComponentIdType ComponentId;
229  NumCompsType NumComps;
230 };
231 
232 //------------------------------------------------------------------------------
233 // Value reference
234 template <typename ArrayType, ComponentIdType TupleSize>
236 {
237 private:
238  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
239  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
240 
242  using APIType = GetAPIType<ArrayType>;
243 
244 public:
245  using value_type = APIType;
246 
249  : Array{ nullptr }
250  , Id{}
251  {
252  }
253 
255  ConstValueReference(ArrayType* array, IdStorageType id) noexcept
256  : Array{ array }
257  , Id{ id }
258  {
259  this->Id.DebugAsserts(array);
260  }
261 
264  : Array{ o.Array }
265  , Id{ o.Id }
266  {
267  }
268 
270  ConstValueReference(const ConstValueReference& o) noexcept = default;
271 
273  ConstValueReference(ConstValueReference&& o) noexcept = default;
274 
277  {
278  VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
279  // Initialize the reference.
280  this->Array = o.Array;
281  this->Id = o.Id;
282  return *this;
283  }
284 
287  {
288  VTK_ITER_ASSERT(!this->Array, "Const reference already initialized.");
289  // Initialize the reference.
290  this->Array = std::move(o.Array);
291  this->Id = std::move(o.Id);
292  return *this;
293  }
294 
296  operator APIType() const noexcept
297  {
298  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
299  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
301  return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
302  }
303 
304 protected:
305  mutable ArrayType* Array;
307 };
308 
309 //------------------------------------------------------------------------------
310 // Value reference
311 template <typename ArrayType, ComponentIdType TupleSize>
313 {
314 private:
315  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
316  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
317 
318  using APIType = GetAPIType<ArrayType>;
320 
321 public:
322  using value_type = APIType;
323 
325  ValueReference() noexcept
326  : Array{ nullptr }
327  , Id{}
328  {
329  }
330 
332  ValueReference(ArrayType* array, IdStorageType id) noexcept
333  : Array{ array }
334  , Id{ id }
335  {
336  this->Id.DebugAsserts(this->Array);
337  }
338 
340  ValueReference(const ValueReference& o) noexcept = default;
342  ValueReference(ValueReference&& o) noexcept = default;
343 
346  {
347  if (this->Array)
348  { // Already initialized. Assign the value, not the reference:
349  return *this = static_cast<APIType>(o);
350  }
351  else
352  { // Initialize the reference:
353  this->Array = o.Array;
354  this->Id = o.Id;
355  return *this;
356  }
357  }
358 
361  {
362  if (this->Array)
363  { // Already initialized. Assign the value, not the reference:
364  return *this = static_cast<APIType>(o);
365  }
366  else
367  { // Initialize the reference:
368  this->Array = std::move(o.Array);
369  this->Id = std::move(o.Id);
370  return *this;
371  }
372  }
373 
374  template <typename OArray, ComponentIdType OSize>
376  { // Always copy the value for different reference types:
377  const APIType tmp = o;
378  return *this = std::move(tmp);
379  }
380 
382  operator APIType() const noexcept
383  {
384  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
385  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
387  return acc.Get(this->Id.GetTupleId(), this->Id.GetComponentId());
388  }
389 
391  ValueReference operator=(APIType val) noexcept
392  {
393  VTK_ITER_ASSUME(this->Id.GetTupleSize() > 0);
394  VTK_ITER_ASSUME(this->Array->GetNumberOfComponents() == this->Id.GetTupleSize());
396  acc.Set(this->Id.GetTupleId(), this->Id.GetComponentId(), val);
397  return *this;
398  }
399 
400  friend VTK_ITER_INLINE void swap(ValueReference lhs, ValueReference rhs) noexcept
401  { // Swap values, not references:
402  APIType tmp = std::move(static_cast<APIType>(lhs));
403  lhs = std::move(static_cast<APIType>(rhs));
404  rhs = std::move(tmp);
405  }
406 
407  template <typename OArray, ComponentIdType OSize>
409  { // Swap values, not references:
410  using OAPIType = typename ValueReference<OArray, OSize>::value_type;
411  static_assert(
412  std::is_same<APIType, OAPIType>::value, "Cannot swap components with different types.");
413 
414  APIType tmp = std::move(static_cast<APIType>(lhs));
415  lhs = std::move(static_cast<APIType>(rhs));
416  rhs = std::move(tmp);
417  }
418 
419  friend VTK_ITER_INLINE void swap(ValueReference lhs, APIType& rhs) noexcept
420  {
421  APIType tmp = std::move(static_cast<APIType>(lhs));
422  lhs = std::move(rhs);
423  rhs = std::move(tmp);
424  }
425 
426  friend VTK_ITER_INLINE void swap(APIType& lhs, ValueReference rhs) noexcept
427  {
428  APIType tmp = std::move(lhs);
429  lhs = std::move(static_cast<APIType>(rhs));
430  rhs = std::move(tmp);
431  }
432 
434  ValueReference operator++() noexcept // prefix
435  {
436  const APIType newVal = *this + 1;
437  *this = newVal;
438  return *this;
439  }
440 
442  APIType operator++(int) noexcept // postfix
443  {
444  const APIType retVal = *this;
445  *this = *this + 1;
446  return retVal;
447  }
448 
450  ValueReference operator--() noexcept // prefix
451  {
452  const APIType newVal = *this - 1;
453  *this = newVal;
454  return *this;
455  }
456 
458  APIType operator--(int) noexcept // postfix
459  {
460  const APIType retVal = *this;
461  *this = *this - 1;
462  return retVal;
463  }
464 
465 #define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
466  friend VTK_ITER_INLINE ValueReference operator Op(ValueReference lhs, APIType val) noexcept \
467  { \
468  const APIType newVal = lhs ImplOp val; \
469  lhs = newVal; \
470  return lhs; \
471  } \
472  friend VTK_ITER_INLINE ValueReference operator Op( \
473  ValueReference lhs, ValueReference val) noexcept \
474  { \
475  const APIType newVal = lhs ImplOp val; \
476  lhs = newVal; \
477  return lhs; \
478  } \
479  friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ValueReference val) noexcept \
480  { \
481  const APIType newVal = lhs ImplOp val; \
482  lhs = newVal; \
483  return lhs; \
484  }
485 
486  VTK_REF_OP_OVERLOADS(+=, +)
487  VTK_REF_OP_OVERLOADS(-=, -)
488  VTK_REF_OP_OVERLOADS(*=, *)
489  VTK_REF_OP_OVERLOADS(/=, /)
490 
491 #undef VTK_REF_OP_OVERLOADS
492 
493  friend struct ConstValueReference<ArrayType, TupleSize>;
494  friend struct ValueIterator<ArrayType, TupleSize>;
495 
496 protected:
497  void CopyReference(const ValueReference& o) noexcept
498  {
499  this->Array = o.Array;
500  this->Id = o.Id;
501  }
502 
503  mutable ArrayType* Array;
505 };
506 
507 //------------------------------------------------------------------------------
508 // Const value iterator
509 template <typename ArrayType, ComponentIdType TupleSize>
511 {
512 private:
513  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
514  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
515 
516  using APIType = GetAPIType<ArrayType>;
518 
519 public:
520  using iterator_category = std::random_access_iterator_tag;
521  using value_type = APIType;
523  using pointer = void;
525 
528  : Array(nullptr)
529  , Id()
530  {
531  }
532 
534  ConstValueIterator(ArrayType* array, IdStorageType id) noexcept
535  : Array(array)
536  , Id(id)
537  {
538  this->Id.DebugAsserts(this->Array);
539  }
540 
543  : Array{ o.GetArray() }
544  , Id{ o.GetId() }
545  {
546  }
547 
549  ConstValueIterator(const ConstValueIterator& o) noexcept = default;
551  ConstValueIterator& operator=(const ConstValueIterator& o) noexcept = default;
552 
554  ConstValueIterator& operator++() noexcept // prefix
555  {
556  ++this->Id;
557  this->Id.DebugAsserts(this->Array);
558  return *this;
559  }
560 
562  ConstValueIterator operator++(int) noexcept // postfix
563  {
564  auto ret = this->Id++;
565  this->Id.DebugAsserts(this->Array);
566  return ConstValueIterator{ this->Array, ret };
567  }
568 
570  ConstValueIterator& operator--() noexcept // prefix
571  {
572  --this->Id;
573  this->Id.DebugAsserts(this->Array);
574  return *this;
575  }
576 
578  ConstValueIterator operator--(int) noexcept // postfix
579  {
580  auto ret = this->Id--;
581  this->Id.DebugAsserts(this->Array);
582  return ConstValueIterator{ this->Array, ret };
583  }
584 
587  {
588  return reference{ this->Array, this->Id + i };
589  }
590 
592  reference operator*() const noexcept { return reference{ this->Array, this->Id }; }
593 
594  // Using GetValueType here makes iteration 50% faster by reducing comparisons
595  // and jumps (instead of comparing std::tie(tupleId, compId)).
596 #define VTK_TMP_MAKE_OPERATOR(OP) \
597  friend VTK_ITER_INLINE bool operator OP( \
598  const ConstValueIterator& lhs, const ConstValueIterator& rhs) noexcept \
599  { \
600  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
601  return lhs.Id.GetValueId() OP rhs.Id.GetValueId(); \
602  }
603 
610 
611 #undef VTK_TMP_MAKE_OPERATOR
612 
615  {
616  this->Id.AddOffset(offset);
617  this->Id.DebugAsserts(this->Array);
618  return *this;
619  }
620 
622  const ConstValueIterator& it, difference_type offset) noexcept
623  {
624  return ConstValueIterator{ it.Array, it.Id + offset };
625  }
626 
628  difference_type offset, const ConstValueIterator& it) noexcept
629  {
630  return ConstValueIterator{ it.Array, it.Id + offset };
631  }
632 
635  {
636  this->Id.AddOffset(-offset);
637  this->Id.DebugAsserts(this->Array);
638  return *this;
639  }
640 
642  const ConstValueIterator& it, difference_type offset) noexcept
643  {
644  return ConstValueIterator{ it.Array, it.Id + (-offset) };
645  }
646 
648  const ConstValueIterator& it1, const ConstValueIterator& it2) noexcept
649  {
650  VTK_ITER_ASSERT(it1.Array == it2.Array, "Cannot do math with iterators from different arrays.");
651  return it1.Id.GetValueId() - it2.Id.GetValueId();
652  }
653 
655  {
656  // Different arrays may use different iterator implementations.
657  VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Cannot swap iterators from different arrays.");
658 
659  using std::swap;
660  swap(lhs.Id, rhs.Id);
661  }
662 
663 private:
664  mutable ArrayType* Array;
665  IdStorageType Id;
666 };
667 
668 //------------------------------------------------------------------------------
669 // Component iterator
670 template <typename ArrayType, ComponentIdType TupleSize>
672 {
673 private:
674  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
675  static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
676 
677  using APIType = GetAPIType<ArrayType>;
679 
680 public:
681  using iterator_category = std::random_access_iterator_tag;
686 
688  ValueIterator() noexcept = default;
689 
691  ValueIterator(ArrayType* array, IdStorageType id) noexcept
692  : Ref{ array, id }
693  {
694  this->DebugIdAsserts();
695  }
696 
698  ValueIterator(const ValueIterator& o) noexcept = default;
699 
702  {
703  this->Ref.CopyReference(o.Ref);
704  this->DebugIdAsserts();
705  return *this;
706  }
707 
709  ValueIterator& operator++() noexcept // prefix
710  {
711  ++this->Ref.Id;
712  this->DebugIdAsserts();
713  return *this;
714  }
715 
717  ValueIterator operator++(int) noexcept // postfix
718  {
719  auto ret = this->Ref.Id++;
720  this->DebugIdAsserts();
721  return ValueIterator{ this->Ref.Array, ret };
722  }
723 
725  ValueIterator& operator--() noexcept // prefix
726  {
727  --this->Ref.Id;
728  this->DebugIdAsserts();
729  return *this;
730  }
731 
733  ValueIterator operator--(int) noexcept // postfix
734  {
735  auto ret = this->Ref.Id--;
736  this->DebugIdAsserts();
737  return ValueIterator{ this->Ref.Array, ret };
738  }
739 
742  {
743  return reference{ this->Ref.Array, this->Ref.Id + i };
744  }
745 
747  reference operator*() const noexcept { return this->Ref; }
748 
750  const pointer& operator->() const noexcept { return this->Ref; }
751 
752 #define VTK_TMP_MAKE_OPERATOR(OP) \
753  friend VTK_ITER_INLINE bool operator OP( \
754  const ValueIterator& lhs, const ValueIterator& rhs) noexcept \
755  { \
756  VTK_ITER_ASSERT( \
757  lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
758  return lhs.GetId().GetValueId() OP rhs.GetId().GetValueId(); \
759  }
760 
767 
768 #undef VTK_TMP_MAKE_OPERATOR
769 
772  {
773  this->Ref.Id.AddOffset(offset);
774  this->DebugIdAsserts();
775  return *this;
776  }
777 
779  const ValueIterator& it, difference_type offset) noexcept
780  {
781  return ValueIterator{ it.GetArray(), it.GetId() + offset };
782  }
783 
785  difference_type offset, const ValueIterator& it) noexcept
786  {
787  return ValueIterator{ it.GetArray(), it.GetId() + offset };
788  }
789 
792  {
793  this->Ref.Id.AddOffset(-offset);
794  this->Ref.Id.DebugAsserts(this->Ref.Array);
795  return *this;
796  }
797 
799  const ValueIterator& it, difference_type offset) noexcept
800  {
801  return ValueIterator{ it.GetArray(), it.GetId() + (-offset) };
802  }
803 
805  const ValueIterator& it1, const ValueIterator& it2) noexcept
806  {
808  it1.Ref.Array == it2.Ref.Array, "Cannot do math with iterators from different arrays.");
809  return it1.GetId().GetValueId() - it2.GetId().GetValueId();
810  }
811 
812  friend VTK_ITER_INLINE void swap(ValueIterator& lhs, ValueIterator& rhs) noexcept
813  {
814  // Different arrays may use different iterator implementations.
816  lhs.GetArray() == rhs.GetArray(), "Cannot swap iterators from different arrays.");
817 
818  using std::swap;
819  swap(lhs.GetId(), rhs.GetId());
820  }
821 
822  friend struct ConstValueIterator<ArrayType, TupleSize>;
823 
824 protected:
826  void DebugIdAsserts() const { this->Ref.Id.DebugAsserts(this->Ref.Array); }
827 
828  // Needed for access from friend functions. We could just store the array
829  // and ID here instead of the ref, but meh.
830  ArrayType* GetArray() const noexcept { return this->Ref.Array; }
831  IdStorageType& GetId() noexcept { return this->Ref.Id; }
832  const IdStorageType& GetId() const noexcept { return this->Ref.Id; }
833 
835 };
836 
837 //------------------------------------------------------------------------------
838 // ValueRange
839 template <typename ArrayTypeT, ComponentIdType TupleSize>
841 {
842 private:
843  static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
844  static_assert(IsVtkDataArray<ArrayTypeT>::value, "Invalid array type.");
845 
848 
849 public:
850  using ArrayType = ArrayTypeT;
852 
857 
858  // May be DynamicTupleSize, or the actual tuple size.
859  constexpr static ComponentIdType TupleSizeTag = TupleSize;
860 
861  // STL-compat
868 
870  ValueRange() noexcept = default;
871 
873  ValueRange(ArrayType* arr, ValueIdType beginValue, ValueIdType endValue) noexcept
874  : Array(arr)
875  , NumComps(arr)
876  , BeginValue(beginValue, this->NumComps)
877  , EndValue(endValue, this->NumComps)
878  {
879  assert(this->Array);
880  assert(beginValue >= 0 && beginValue <= endValue);
881  assert(endValue >= 0 && endValue <= this->Array->GetNumberOfValues());
882  }
883 
885  ValueRange GetSubRange(ValueIdType beginValue = 0, ValueIdType endValue = -1) const noexcept
886  {
887  const ValueIdType realBegin = this->BeginValue.GetValueId() + beginValue;
888  const ValueIdType realEnd =
889  endValue >= 0 ? this->BeginValue.GetValueId() + endValue : this->EndValue.GetValueId();
890 
891  return ValueRange{ this->Array, realBegin, realEnd };
892  }
893 
895  ArrayType* GetArray() const noexcept { return this->Array; }
897  ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
898 
900  ValueIdType GetBeginValueId() const noexcept { return this->BeginValue.GetValueId(); }
901 
903  ValueIdType GetEndValueId() const noexcept { return this->EndValue.GetValueId(); }
904 
906  size_type size() const noexcept
907  {
908  return this->EndValue.GetValueId() - this->BeginValue.GetValueId();
909  }
910 
912  iterator begin() noexcept { return this->NewIterator(this->BeginValue); }
914  iterator end() noexcept { return this->NewIterator(this->EndValue); }
915 
917  const_iterator begin() const noexcept { return this->NewConstIterator(this->BeginValue); }
919  const_iterator end() const noexcept { return this->NewConstIterator(this->EndValue); }
920 
922  const_iterator cbegin() const noexcept { return this->NewConstIterator(this->BeginValue); }
924  const_iterator cend() const noexcept { return this->NewConstIterator(this->EndValue); }
925 
928  {
929  return reference{ this->Array, this->BeginValue + i };
930  }
933  {
934  return const_reference{ this->Array, this->BeginValue + i };
935  }
936 
937 private:
939  iterator NewIterator(IdStorageType id) const noexcept { return iterator{ this->Array, id }; }
940 
942  const_iterator NewConstIterator(IdStorageType id) const noexcept
943  {
944  return const_iterator{ this->Array, id };
945  }
946 
947  mutable ArrayType* Array{ nullptr };
948  NumCompsType NumComps{};
949  IdStorageType BeginValue{};
950  IdStorageType EndValue{};
951 };
952 
953 // Unimplemented, only used inside decltype in SelectValueRange:
954 template <typename ArrayType, ComponentIdType TupleSize>
956 
957 } // end namespace detail
958 } // end namespace vtk
959 
961 
962 #endif // __VTK_WRAP__
963 #endif // vtkDataArrayValueRange_Generic_h
964 
965 // VTK-HeaderTest-Exclude: vtkDataArrayValueRange_Generic.h
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:159
@ value
Definition: vtkX3D.h:226
@ offset
Definition: vtkX3D.h:444
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)