VTK  9.2.6
vtkDataArrayTupleRange_AOS.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataArrayTupleRange_AOS.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=========================================================================*/
19#ifndef vtkDataArrayTupleRange_AOS_h
20#define vtkDataArrayTupleRange_AOS_h
21
23#include "vtkDataArrayMeta.h"
25#include "vtkDebugRangeIterators.h"
26
27#include <algorithm>
28#include <cassert>
29#include <iterator>
30#include <type_traits>
31
32// Disable this specialization when iterator debugging is requested:
33#ifndef VTK_DEBUG_RANGE_ITERATORS
34
36
37namespace vtk
38{
39
40namespace detail
41{
42
43// Forward decs for friends/args
44template <typename ArrayType, ComponentIdType>
45struct ConstTupleReference;
46template <typename ArrayType, ComponentIdType>
47struct TupleReference;
48template <typename ArrayType, ComponentIdType>
49struct ConstTupleIterator;
50template <typename ArrayType, ComponentIdType>
51struct TupleIterator;
52template <typename ArrayType, ComponentIdType>
53struct TupleRange;
54
55//------------------------------------------------------------------------------
56// Const tuple reference
57template <typename ValueType, ComponentIdType TupleSize>
58struct ConstTupleReference<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
59{
60private:
63 using APIType = ValueType;
64
65public:
67 using value_type = APIType;
68 using const_reference = const ValueType&;
69 using iterator = const ValueType*;
70 using const_iterator = const ValueType*;
71
74 : Tuple{ nullptr }
75 {
76 }
77
79 ConstTupleReference(const ValueType* tuple, NumCompsType numComps) noexcept
80 : Tuple(tuple)
81 , NumComps(numComps)
82 {
83 }
84
87 : Tuple{ o.Tuple }
88 , NumComps{ o.NumComps }
89 {
90 }
91
93 ConstTupleReference(const ConstTupleReference&) noexcept = default;
96
97 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
99 ConstTupleReference* operator->() noexcept { return this; }
101 const ConstTupleReference* operator->() const noexcept { return this; }
102
103 // Caller must ensure that there are size() elements in array.
104 VTK_ITER_INLINE void GetTuple(volatile APIType* tuple) const noexcept
105 {
106 // Yes, the tuple argument is marked volatile. No, it's not a mistake.
107 //
108 // `volatile`'s intended usage per the standard is to disable optimizations
109 // when accessing a variable. Without it, GCC 8 will optimize the following
110 // loop to memcpy, but we're usually copying small tuples here, and the
111 // call to memcpy is more expensive than just doing an inline copy. By
112 // disabling the memcpy optimization, benchmarks are 60% faster when
113 // iterating with the Get/SetTuple methods, and are comparable to other
114 // methods of array access.
115 VTK_ITER_ASSUME(this->NumComps.value > 0);
116 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
117 {
118 tuple[i] = this->Tuple[i];
119 }
120 }
121
122 // skips some runtime checks when both sizes are fixed:
123 template <typename OArrayType, ComponentIdType OSize>
125 const TupleReference<OArrayType, OSize>& other) const noexcept
126 {
127 // Check that types are convertible:
128 using OAPIType = GetAPIType<OArrayType>;
129 static_assert(
130 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
131
132 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
133 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
134
135 return std::equal(this->cbegin(), this->cend(), other.cbegin());
136 }
137
138 // Needs a runtime check:
139 template <typename OArrayType, ComponentIdType OSize>
141 const TupleReference<OArrayType, OSize>& other) const noexcept
142 {
143 // Check that types are convertible:
144 using OAPIType = GetAPIType<OArrayType>;
145 static_assert(
146 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
147
148 // Need to check the size at runtime :-(
149 if (other.size() != this->NumComps.value)
150 {
151 return false;
152 }
153
154 return std::equal(this->cbegin(), this->cend(), other.cbegin());
155 }
156
157 // skips some runtime checks when both sizes are fixed:
158 template <typename OArrayType, ComponentIdType OSize>
160 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
161 {
162 // Check that types are convertible:
163 using OAPIType = GetAPIType<OArrayType>;
164 static_assert(
165 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
166
167 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
168 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
169
170 return std::equal(this->cbegin(), this->cend(), other.cbegin());
171 }
172
173 // Needs a runtime check:
174 template <typename OArrayType, ComponentIdType OSize>
176 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
177 {
178 // Check that types are convertible:
179 using OAPIType = GetAPIType<OArrayType>;
180 static_assert(
181 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
182
183 // Need to check the size at runtime :-(
184 if (other.size() != this->NumComps.value)
185 {
186 return false;
187 }
188
189 return std::equal(this->cbegin(), this->cend(), other.cbegin());
190 }
191
192 template <typename OArrayType, ComponentIdType OSize>
194 {
195 return !(*this == o);
196 }
197
198 template <typename OArray, ComponentIdType OSize>
200 {
201 return !(*this == o);
202 }
203
205 const_reference operator[](size_type i) const noexcept { return this->Tuple[i]; }
206
208 size_type size() const noexcept { return this->NumComps.value; }
209
211 const_iterator begin() const noexcept { return const_iterator{ this->Tuple }; }
212
214 const_iterator end() const noexcept
215 {
216 return const_iterator{ this->Tuple + this->NumComps.value };
217 }
218
220 const_iterator cbegin() const noexcept { return const_iterator{ this->Tuple }; }
221
223 const_iterator cend() const noexcept
224 {
225 return const_iterator{ this->Tuple + this->NumComps.value };
226 }
227
228 friend struct ConstTupleIterator<ArrayType, TupleSize>;
229
230protected:
231 // Intentionally hidden:
234
235 const ValueType* Tuple;
237};
238
239//------------------------------------------------------------------------------
240// Tuple reference
241template <typename ValueType, ComponentIdType TupleSize>
242struct TupleReference<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
243{
244private:
247 using APIType = ValueType;
248
249public:
251 using value_type = APIType;
252 using iterator = ValueType*;
253 using const_iterator = const ValueType*;
254 using reference = ValueType&;
255 using const_reference = ValueType const&;
256
258 TupleReference() noexcept
259 : Tuple{ nullptr }
260 {
261 }
262
264 TupleReference(ValueType* tuple, NumCompsType numComps) noexcept
265 : Tuple(tuple)
266 , NumComps(numComps)
267 {
268 }
269
271 TupleReference(const TupleReference&) noexcept = default;
273 TupleReference(TupleReference&&) noexcept = default;
274
275 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
277 TupleReference* operator->() noexcept { return this; }
279 const TupleReference* operator->() const noexcept { return this; }
280
281 // Caller must ensure that there are size() elements in array.
283 void GetTuple(volatile APIType* tuple) const noexcept
284 {
285 // Yes, the tuple argument is marked volatile. No, it's not a mistake.
286 //
287 // `volatile`'s intended usage per the standard is to disable optimizations
288 // when accessing a variable. Without it, GCC 8 will optimize the following
289 // loop to memcpy, but we're usually copying small tuples here, and the
290 // call to memcpy is more expensive than just doing an inline copy. By
291 // disabling the memcpy optimization, benchmarks are 60% faster when
292 // iterating with the Get/SetTuple methods, and are comparable to other
293 // methods of array access.
294 VTK_ITER_ASSUME(this->NumComps.value > 0);
295 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
296 {
297 tuple[i] = this->Tuple[i];
298 }
299 }
300
301 // Caller must ensure that there are size() elements in array.
303 void SetTuple(const APIType* tuple) noexcept
304 {
305 volatile APIType* out = this->Tuple;
306 // Yes, this variable argument is marked volatile. See the explanation in
307 // GetTuple.
308 VTK_ITER_ASSUME(this->NumComps.value > 0);
309 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
310 {
311 out[i] = tuple[i];
312 }
313 }
314
317 {
318 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
319 return *this;
320 }
321
322 template <typename OArrayType, ComponentIdType OSize>
324 const TupleReference<OArrayType, OSize>& other) noexcept
325 {
326 // Check that types are convertible:
327 using OAPIType = GetAPIType<OArrayType>;
328 static_assert(
329 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
330
331 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
332 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
333
334 std::copy_n(other.cbegin(), OSize, this->begin());
335 return *this;
336 }
337
338 template <typename OArrayType, ComponentIdType OSize>
340 const TupleReference<OArrayType, OSize>& other) noexcept
341 {
342 // Check that types are convertible:
343 using OAPIType = GetAPIType<OArrayType>;
344 static_assert(
345 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
346
347 // Note that the sizes are not checked here. Enable
348 // VTK_DEBUG_RANGE_ITERATORS to enable check.
349 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
350 return *this;
351 }
352
353 template <typename OArrayType, ComponentIdType OSize>
355 const ConstTupleReference<OArrayType, OSize>& other) noexcept
356 {
357 // Check that types are convertible:
358 using OAPIType = GetAPIType<OArrayType>;
359 static_assert(
360 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
361
362 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
363 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
364
365 std::copy_n(other.cbegin(), OSize, this->begin());
366 return *this;
367 }
368
369 template <typename OArrayType, ComponentIdType OSize>
371 const ConstTupleReference<OArrayType, OSize>& other) noexcept
372 {
373 // Check that types are convertible:
374 using OAPIType = GetAPIType<OArrayType>;
375 static_assert(
376 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
377
378 // Note that the sizes are not checked here. Enable
379 // VTK_DEBUG_RANGE_ITERATORS to enable check.
380 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
381 return *this;
382 }
383
384 // skips some runtime checks when both sizes are fixed:
385 template <typename OArrayType, ComponentIdType OSize>
387 const TupleReference<OArrayType, OSize>& other) const noexcept
388 {
389 // Check that types are convertible:
390 using OAPIType = GetAPIType<OArrayType>;
391 static_assert(
392 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
393
394 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
395 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
396
397 return std::equal(this->cbegin(), this->cend(), other.cbegin());
398 }
399
400 // Needs a runtime check:
401 template <typename OArrayType, ComponentIdType OSize>
403 const TupleReference<OArrayType, OSize>& other) const noexcept
404 {
405 // Check that types are convertible:
406 using OAPIType = GetAPIType<OArrayType>;
407 static_assert(
408 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
409
410 // Note that the sizes are not checked here. Enable
411 // VTK_DEBUG_RANGE_ITERATORS to enable check.
412 return std::equal(this->cbegin(), this->cend(), other.cbegin());
413 }
414
415 // skips some runtime checks when both sizes are fixed:
416 template <typename OArrayType, ComponentIdType OSize>
418 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
419 {
420 // Check that types are convertible:
421 using OAPIType = GetAPIType<OArrayType>;
422 static_assert(
423 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
424
425 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
426 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
427
428 return std::equal(this->cbegin(), this->cend(), other.cbegin());
429 }
430
431 // Needs a runtime check:
432 template <typename OArrayType, ComponentIdType OSize>
434 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
435 {
436 // Check that types are convertible:
437 using OAPIType = GetAPIType<OArrayType>;
438 static_assert(
439 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
440
441 // Note that the sizes are not checked here. Enable
442 // VTK_DEBUG_RANGE_ITERATORS to enable check.
443 return std::equal(this->cbegin(), this->cend(), other.cbegin());
444 }
445
446 template <typename OArrayType, ComponentIdType OSize>
448 {
449 return !(*this == o);
450 }
451
452 template <typename OArray, ComponentIdType OSize>
454 {
455 return !(*this == o);
456 }
457
458 // skips some runtime checks:
459 template <typename OArrayType, ComponentIdType OSize>
462 {
463 // Check that types are convertible:
464 using OAPIType = GetAPIType<OArrayType>;
465 static_assert((std::is_same<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
466
467 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
468 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
469
470 std::swap_ranges(this->begin(), this->end(), other.begin());
471 }
472
473 // Needs a runtime check:
474 template <typename OArrayType, ComponentIdType OSize>
477 {
478 // Check that types are convertible:
479 using OAPIType = GetAPIType<OArrayType>;
480 static_assert((std::is_same<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
481
482 // Note that the sizes are not checked here. Enable
483 // VTK_DEBUG_RANGE_ITERATORS to enable check.
484 std::swap_ranges(this->begin(), this->end(), other.begin());
485 }
486
487 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
488
489 template <typename OArray, ComponentIdType OSize>
491 {
492 a.swap(b);
493 }
494
496 reference operator[](size_type i) noexcept { return this->Tuple[i]; }
497
499 const_reference operator[](size_type i) const noexcept { return this->Tuple[i]; }
500
502 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
503
505 size_type size() const noexcept { return this->NumComps.value; }
506
508 iterator begin() noexcept { return iterator{ this->Tuple }; }
509
511 iterator end() noexcept { return iterator{ this->Tuple + this->NumComps.value }; }
512
514 const_iterator begin() const noexcept { return const_iterator{ this->Tuple }; }
515
517 const_iterator end() const noexcept
518 {
519 return const_iterator{ this->Tuple + this->NumComps.value };
520 }
521
523 const_iterator cbegin() const noexcept { return const_iterator{ this->Tuple }; }
524
526 const_iterator cend() const noexcept
527 {
528 return const_iterator{ this->Tuple + this->NumComps.value };
529 }
530
531 friend struct ConstTupleReference<ArrayType, TupleSize>;
532 friend struct TupleIterator<ArrayType, TupleSize>;
533
534protected:
536 void CopyReference(const TupleReference& o) noexcept
537 {
538 this->Tuple = o.Tuple;
539 this->NumComps = o.NumComps;
540 }
541
542 ValueType* Tuple;
544};
545
546//------------------------------------------------------------------------------
547// Const tuple iterator
548template <typename ValueType, ComponentIdType TupleSize>
549struct ConstTupleIterator<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
550{
551private:
554
555public:
556 using iterator_category = std::random_access_iterator_tag;
561
563 ConstTupleIterator() noexcept = default;
564
566 ConstTupleIterator(const ValueType* tuple, NumCompsType numComps) noexcept
567 : Ref(tuple, numComps)
568 {
569 }
570
573 : Ref{ o.Ref }
574 {
575 }
576
578 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
580 ConstTupleIterator& operator=(const ConstTupleIterator& o) noexcept = default;
581
583 ConstTupleIterator& operator++() noexcept // prefix
584 {
585 this->Ref.Tuple += this->Ref.NumComps.value;
586 return *this;
587 }
588
590 ConstTupleIterator operator++(int) noexcept // postfix
591 {
592 auto tuple = this->Ref.Tuple;
593 this->Ref.Tuple += this->Ref.NumComps.value;
594 return ConstTupleIterator{ tuple, this->Ref.NumComps };
595 }
596
598 ConstTupleIterator& operator--() noexcept // prefix
599 {
600 this->Ref.Tuple -= this->Ref.NumComps.value;
601 return *this;
602 }
603
605 ConstTupleIterator operator--(int) noexcept // postfix
606 {
607 auto tuple = this->Ref.Tuple;
608 this->Ref.Tuple -= this->Ref.NumComps.value;
609 return ConstTupleIterator{ tuple, this->Ref.NumComps };
610 }
611
614 {
615 return reference{ this->Ref.Tuple + i * this->Ref.NumComps, this->Ref.NumComps };
616 }
617
619 reference operator*() noexcept { return this->Ref; }
620
622 pointer& operator->() noexcept { return this->Ref; }
623
624#define VTK_TMP_MAKE_OPERATOR(OP) \
625 friend VTK_ITER_INLINE bool operator OP( \
626 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
627 { \
628 return lhs.GetTuple() OP rhs.GetTuple(); \
629 }
630
637
638#undef VTK_TMP_MAKE_OPERATOR
639
642 {
643 this->Ref.Tuple += offset * this->Ref.NumComps.value;
644 return *this;
645 }
646
648 const ConstTupleIterator& it, difference_type offset) noexcept
649 {
650 return ConstTupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
651 }
652
654 difference_type offset, const ConstTupleIterator& it) noexcept
655 {
656 return ConstTupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
657 }
658
661 {
662 this->Ref.Tuple -= offset * this->Ref.NumComps.value;
663 return *this;
664 }
665
667 const ConstTupleIterator& it, difference_type offset) noexcept
668 {
669 return ConstTupleIterator{ it.GetTuple() - offset * it.GetNumComps().value, it.GetNumComps() };
670 }
671
673 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
674 {
675 return static_cast<difference_type>(
676 (it1.GetTuple() - it2.GetTuple()) / it1.GetNumComps().value);
677 }
678
680 {
681 using std::swap;
682 swap(lhs.GetTuple(), rhs.GetTuple());
683 swap(lhs.GetNumComps(), rhs.GetNumComps());
684 }
685
686private:
688 const ValueType*& GetTuple() noexcept { return this->Ref.Tuple; }
690 const ValueType* GetTuple() const noexcept { return this->Ref.Tuple; }
692 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
694 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
695
696 ConstTupleReference<ArrayType, TupleSize> Ref;
697};
698
699//------------------------------------------------------------------------------
700// Tuple iterator
701template <typename ValueType, ComponentIdType TupleSize>
702struct TupleIterator<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
703{
704private:
707
708public:
709 using iterator_category = std::random_access_iterator_tag;
714
716 TupleIterator() noexcept = default;
717
719 TupleIterator(ValueType* tuple, NumCompsType numComps) noexcept
720 : Ref(tuple, numComps)
721 {
722 }
723
725 TupleIterator(const TupleIterator& o) noexcept = default;
726
729 {
730 this->Ref.CopyReference(o.Ref);
731 return *this;
732 }
733
735 TupleIterator& operator++() noexcept // prefix
736 {
737 this->Ref.Tuple += this->Ref.NumComps.value;
738 return *this;
739 }
740
742 TupleIterator operator++(int) noexcept // postfix
743 {
744 auto tuple = this->Ref.Tuple;
745 this->Ref.Tuple += this->Ref.NumComps.value;
746 return TupleIterator{ tuple, this->Ref.NumComps };
747 }
748
750 TupleIterator& operator--() noexcept // prefix
751 {
752 this->Ref.Tuple -= this->Ref.NumComps.value;
753 return *this;
754 }
755
757 TupleIterator operator--(int) noexcept // postfix
758 {
759 auto tuple = this->Ref.Tuple;
760 this->Ref.Tuple -= this->Ref.NumComps.value;
761 return TupleIterator{ tuple, this->Ref.NumComps };
762 }
763
766 {
767 return reference{ this->Ref.Tuple + i * this->Ref.NumComps.value, this->Ref.NumComps };
768 }
769
770 reference operator*() noexcept { return this->Ref; }
771
772 pointer& operator->() noexcept { return this->Ref; }
773
774#define VTK_TMP_MAKE_OPERATOR(OP) \
775 friend VTK_ITER_INLINE bool operator OP( \
776 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
777 { \
778 return lhs.GetTuple() OP rhs.GetTuple(); \
779 }
780
787
788#undef VTK_TMP_MAKE_OPERATOR
789
792 {
793 this->Ref.Tuple += offset * this->Ref.NumComps.value;
794 return *this;
795 }
796
798 const TupleIterator& it, difference_type offset) noexcept
799 {
800 return TupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
801 }
802
804 difference_type offset, const TupleIterator& it) noexcept
805 {
806 return TupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
807 }
808
811 {
812 this->Ref.Tuple -= offset * this->Ref.NumComps.value;
813 return *this;
814 }
815
817 const TupleIterator& it, difference_type offset) noexcept
818 {
819 return TupleIterator{ it.GetTuple() - offset * it.GetNumComps().value, it.GetNumComps() };
820 }
821
823 const TupleIterator& it1, const TupleIterator& it2) noexcept
824 {
825 return static_cast<difference_type>(
826 (it1.GetTuple() - it2.GetTuple()) / it1.GetNumComps().value);
827 }
828
829 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
830 {
831 using std::swap;
832 swap(lhs.GetTuple(), rhs.GetTuple());
833 swap(lhs.GetNumComps(), rhs.GetNumComps());
834 }
835
836 friend struct ConstTupleIterator<ArrayType, TupleSize>;
837
838protected:
840 ValueType* GetTuple() const noexcept { return this->Ref.Tuple; }
842 ValueType*& GetTuple() noexcept { return this->Ref.Tuple; }
844 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
846 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
847
849};
850
851//------------------------------------------------------------------------------
852// Tuple range
853template <typename ValueType, ComponentIdType TupleSize>
854struct TupleRange<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
855{
858
859private:
860 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
861 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
862
864
865public:
875
881
882 // May be DynamicTupleSize, or the actual tuple size.
883 constexpr static ComponentIdType TupleSizeTag = TupleSize;
884
886 TupleRange() noexcept = default;
887
889 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
890 : Array(arr)
891 , NumComps(arr)
892 , BeginTuple(TupleRange::GetTuplePointer(arr, beginTuple))
893 , EndTuple(TupleRange::GetTuplePointer(arr, endTuple))
894 {
895 assert(this->Array);
896 assert(beginTuple >= 0 && beginTuple <= endTuple);
897 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
898 }
899
901 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
902 {
903 const TupleIdType curBegin = this->GetTupleId(this->BeginTuple);
904 const TupleIdType realBegin = curBegin + beginTuple;
905 const TupleIdType realEnd =
906 endTuple >= 0 ? curBegin + endTuple : this->GetTupleId(this->EndTuple);
907
908 return TupleRange{ this->Array, realBegin, realEnd };
909 }
910
912 ArrayType* GetArray() const noexcept { return this->Array; }
913
915 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
916
918 TupleIdType GetBeginTupleId() const noexcept { return this->GetTupleId(this->BeginTuple); }
919
921 TupleIdType GetEndTupleId() const noexcept { return this->GetTupleId(this->EndTuple); }
922
924 size_type size() const noexcept
925 {
926 return static_cast<size_type>(this->EndTuple - this->BeginTuple) /
927 static_cast<size_type>(this->NumComps.value);
928 }
929
931 iterator begin() noexcept { return iterator(this->BeginTuple, this->NumComps); }
932
934 iterator end() noexcept { return iterator(this->EndTuple, this->NumComps); }
935
937 const_iterator begin() const noexcept { return const_iterator(this->BeginTuple, this->NumComps); }
938
940 const_iterator end() const noexcept { return const_iterator(this->EndTuple, this->NumComps); }
941
943 const_iterator cbegin() const noexcept
944 {
945 return const_iterator(this->BeginTuple, this->NumComps);
946 }
947
949 const_iterator cend() const noexcept { return const_iterator(this->EndTuple, this->NumComps); }
950
953 {
954 return reference{ this->BeginTuple + i * this->NumComps.value, this->NumComps };
955 }
956
959 {
960 return const_reference{ this->BeginTuple + i * this->NumComps.value, this->NumComps };
961 }
962
963private:
965 ValueType* GetTuplePointer(ArrayType* array, vtkIdType tuple) const noexcept
966 {
967 return array->GetPointer(tuple * this->NumComps.value);
968 }
969
971 TupleIdType GetTupleId(const ValueType* ptr) const noexcept
972 {
973 return static_cast<TupleIdType>((ptr - this->Array->GetPointer(0)) / this->NumComps.value);
974 }
975
976 mutable ArrayType* Array{ nullptr };
977 NumCompsType NumComps{};
978 ValueType* BeginTuple{ nullptr };
979 ValueType* EndTuple{ nullptr };
980};
981
982// Unimplemented, only used inside decltype in SelectTupleRange:
983template <typename ArrayType, ComponentIdType TupleSize,
984 // Convenience:
985 typename ValueType = typename ArrayType::ValueType,
986 typename AOSArrayType = vtkAOSDataArrayTemplate<ValueType>,
987 // SFINAE to select AOS arrays:
988 typename = typename std::enable_if<IsAOSDataArray<ArrayType>::value>::type>
990
991} // end namespace detail
992} // end namespace vtk
993
995
996#endif // VTK_DEBUG_RANGE_ITERATORS
997#endif // vtkDataArrayTupleRange_AOS_h
998
999// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_AOS.h
Array-Of-Structs implementation of vtkGenericDataArray.
typename std::enable_if< IsEitherTupleSizeDynamic< S1, S2 >::value, T >::type EnableIfEitherTupleSizeIsDynamic
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename detail::GetAPITypeImpl< ArrayType >::APIType GetAPIType
vtkIdType TupleIdType
int ComponentIdType
friend VTK_ITER_INLINE void swap(ConstTupleIterator &lhs, ConstTupleIterator &rhs) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator-=(difference_type offset) noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator+(difference_type offset, const ConstTupleIterator &it) noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator+(const ConstTupleIterator &it, difference_type offset) noexcept
friend VTK_ITER_INLINE ConstTupleIterator operator-(const ConstTupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator+=(difference_type offset) noexcept
VTK_ITER_INLINE ConstTupleIterator(const TupleIterator< ArrayType, TupleSize > &o) noexcept
friend VTK_ITER_INLINE difference_type operator-(const ConstTupleIterator &it1, const ConstTupleIterator &it2) noexcept
VTK_ITER_INLINE ConstTupleIterator & operator=(const ConstTupleIterator &o) noexcept=default
VTK_ITER_INLINE ConstTupleIterator(const ConstTupleIterator &o) noexcept=default
friend VTK_ITER_INLINE void swap(ConstTupleIterator &lhs, ConstTupleIterator &rhs) noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArray, OSize > &o) const noexcept
VTK_ITER_INLINE ConstTupleReference(const ConstTupleReference &) noexcept=default
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE ConstTupleReference(ConstTupleReference &&) noexcept=default
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE ConstTupleReference & operator=(const ConstTupleReference &) noexcept=default
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE ConstTupleReference(const ValueType *tuple, NumCompsType numComps) noexcept
VTK_ITER_INLINE ConstTupleReference(const TupleReference< ArrayType, TupleSize > &o) noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
friend VTK_ITER_INLINE TupleIterator operator+(const TupleIterator &it, difference_type offset) noexcept
friend VTK_ITER_INLINE TupleIterator operator-(const TupleIterator &it, difference_type offset) noexcept
VTK_ITER_INLINE TupleIterator & operator=(const TupleIterator &o) noexcept
VTK_ITER_INLINE TupleIterator(const TupleIterator &o) noexcept=default
friend VTK_ITER_INLINE TupleIterator operator+(difference_type offset, const TupleIterator &it) noexcept
VTK_ITER_INLINE TupleIterator & operator-=(difference_type offset) noexcept
VTK_ITER_INLINE TupleIterator & operator+=(difference_type offset) noexcept
friend VTK_ITER_INLINE difference_type operator-(const TupleIterator &it1, const TupleIterator &it2) noexcept
friend VTK_ITER_INLINE void swap(TupleIterator &lhs, TupleIterator &rhs) noexcept
TupleReference< ArrayType, TupleSize > Ref
VTK_ITER_INLINE const_reference operator[](size_type i) const noexcept
VTK_ITER_INLINE TupleRange GetSubRange(TupleIdType beginTuple=0, TupleIdType endTuple=-1) const noexcept
static constexpr ComponentIdType TupleSizeTag
TupleIterator< ArrayType, TupleSize > TupleIteratorType
ConstTupleIterator< ArrayType, TupleSize > ConstTupleIteratorType
TupleReference< ArrayType, TupleSize > TupleReferenceType
ConstTupleReference< ArrayType, TupleSize > ConstTupleReferenceType
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE TupleReference & operator=(const TupleReference &other) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, void > swap(TupleReference< OArrayType, OSize > other) noexcept
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept
VTK_ITER_INLINE void GetTuple(volatile APIType *tuple) const noexcept
VTK_ITER_INLINE TupleReference(ValueType *tuple, NumCompsType numComps) noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE bool operator!=(const TupleReference< OArrayType, OSize > &o) const noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE EnableIfStaticTupleSizes< TupleSize, OSize, bool > operator==(const TupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, bool > operator==(const ConstTupleReference< OArrayType, OSize > &other) const noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const TupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE EnableIfEitherTupleSizeIsDynamic< TupleSize, OSize, TupleReference & > operator=(const ConstTupleReference< OArrayType, OSize > &other) noexcept
VTK_ITER_INLINE TupleReference(const TupleReference &) noexcept=default
VTK_ITER_INLINE TupleReference(TupleReference &&) noexcept=default
friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference< OArray, OSize > b) noexcept
VTK_ITER_INLINE bool operator!=(const ConstTupleReference< OArray, OSize > &o) const noexcept
VTK_ITER_INLINE const_iterator cbegin() const noexcept
VTK_ITER_INLINE const_iterator cend() const noexcept
VTK_ITER_INLINE iterator begin() noexcept
VTK_ITER_INLINE iterator end() 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_ASSUME
#define VTK_TMP_MAKE_OPERATOR(OP)
int vtkIdType
Definition vtkType.h:332