VTK  9.3.0
vtkDataArrayTupleRange_AOS.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
7#ifndef vtkDataArrayTupleRange_AOS_h
8#define vtkDataArrayTupleRange_AOS_h
9
11#include "vtkDataArrayMeta.h"
13#include "vtkDebugRangeIterators.h"
14
15#include <algorithm>
16#include <cassert>
17#include <iterator>
18#include <type_traits>
19
20// Disable this specialization when iterator debugging is requested:
21#ifndef VTK_DEBUG_RANGE_ITERATORS
22
24
25namespace vtk
26{
27namespace detail
28{
29VTK_ABI_NAMESPACE_BEGIN
30
31// Forward decs for friends/args
32template <typename ArrayType, ComponentIdType>
33struct ConstTupleReference;
34template <typename ArrayType, ComponentIdType>
35struct TupleReference;
36template <typename ArrayType, ComponentIdType>
37struct ConstTupleIterator;
38template <typename ArrayType, ComponentIdType>
39struct TupleIterator;
40template <typename ArrayType, ComponentIdType>
41struct TupleRange;
42
43//------------------------------------------------------------------------------
44// Const tuple reference
45template <typename ValueType, ComponentIdType TupleSize>
46struct ConstTupleReference<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
47{
48private:
51 using APIType = ValueType;
52
53public:
55 using value_type = APIType;
56 using const_reference = const ValueType&;
57 using iterator = const ValueType*;
58 using const_iterator = const ValueType*;
59
62 : Tuple{ nullptr }
63 {
64 }
65
67 ConstTupleReference(const ValueType* tuple, NumCompsType numComps) noexcept
68 : Tuple(tuple)
69 , NumComps(numComps)
70 {
71 }
72
75 : Tuple{ o.Tuple }
76 , NumComps{ o.NumComps }
77 {
78 }
79
81 ConstTupleReference(const ConstTupleReference&) noexcept = default;
84
85 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
87 ConstTupleReference* operator->() noexcept { return this; }
89 const ConstTupleReference* operator->() const noexcept { return this; }
90
91 // Caller must ensure that there are size() elements in array.
92 VTK_ITER_INLINE void GetTuple(volatile APIType* tuple) const noexcept
93 {
94 // Yes, the tuple argument is marked volatile. No, it's not a mistake.
95 //
96 // `volatile`'s intended usage per the standard is to disable optimizations
97 // when accessing a variable. Without it, GCC 8 will optimize the following
98 // loop to memcpy, but we're usually copying small tuples here, and the
99 // call to memcpy is more expensive than just doing an inline copy. By
100 // disabling the memcpy optimization, benchmarks are 60% faster when
101 // iterating with the Get/SetTuple methods, and are comparable to other
102 // methods of array access.
103 VTK_ITER_ASSUME(this->NumComps.value > 0);
104 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
105 {
106 tuple[i] = this->Tuple[i];
107 }
108 }
109
110 // skips some runtime checks when both sizes are fixed:
111 template <typename OArrayType, ComponentIdType OSize>
113 const TupleReference<OArrayType, OSize>& other) const noexcept
114 {
115 // Check that types are convertible:
116 using OAPIType = GetAPIType<OArrayType>;
117 static_assert(
118 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
119
120 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
121 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
122
123 return std::equal(this->cbegin(), this->cend(), other.cbegin());
124 }
125
126 // Needs a runtime check:
127 template <typename OArrayType, ComponentIdType OSize>
129 const TupleReference<OArrayType, OSize>& other) const noexcept
130 {
131 // Check that types are convertible:
132 using OAPIType = GetAPIType<OArrayType>;
133 static_assert(
134 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
135
136 // Need to check the size at runtime :-(
137 if (other.size() != this->NumComps.value)
138 {
139 return false;
140 }
141
142 return std::equal(this->cbegin(), this->cend(), other.cbegin());
143 }
144
145 // skips some runtime checks when both sizes are fixed:
146 template <typename OArrayType, ComponentIdType OSize>
148 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
149 {
150 // Check that types are convertible:
151 using OAPIType = GetAPIType<OArrayType>;
152 static_assert(
153 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
154
155 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
156 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
157
158 return std::equal(this->cbegin(), this->cend(), other.cbegin());
159 }
160
161 // Needs a runtime check:
162 template <typename OArrayType, ComponentIdType OSize>
164 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
165 {
166 // Check that types are convertible:
167 using OAPIType = GetAPIType<OArrayType>;
168 static_assert(
169 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
170
171 // Need to check the size at runtime :-(
172 if (other.size() != this->NumComps.value)
173 {
174 return false;
175 }
176
177 return std::equal(this->cbegin(), this->cend(), other.cbegin());
178 }
179
180 template <typename OArrayType, ComponentIdType OSize>
182 {
183 return !(*this == o);
184 }
185
186 template <typename OArray, ComponentIdType OSize>
188 {
189 return !(*this == o);
190 }
191
193 const_reference operator[](size_type i) const noexcept { return this->Tuple[i]; }
194
196 size_type size() const noexcept { return this->NumComps.value; }
197
199 const_iterator begin() const noexcept { return const_iterator{ this->Tuple }; }
200
202 const_iterator end() const noexcept
203 {
204 return const_iterator{ this->Tuple + this->NumComps.value };
205 }
206
208 const_iterator cbegin() const noexcept { return const_iterator{ this->Tuple }; }
209
211 const_iterator cend() const noexcept
212 {
213 return const_iterator{ this->Tuple + this->NumComps.value };
214 }
215
216 friend struct ConstTupleIterator<ArrayType, TupleSize>;
217
218protected:
219 // Intentionally hidden:
222
223 const ValueType* Tuple;
225};
226
227//------------------------------------------------------------------------------
228// Tuple reference
229template <typename ValueType, ComponentIdType TupleSize>
230struct TupleReference<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
231{
232private:
235 using APIType = ValueType;
236
237public:
239 using value_type = APIType;
240 using iterator = ValueType*;
241 using const_iterator = const ValueType*;
242 using reference = ValueType&;
243 using const_reference = ValueType const&;
244
246 TupleReference() noexcept
247 : Tuple{ nullptr }
248 {
249 }
250
252 TupleReference(ValueType* tuple, NumCompsType numComps) noexcept
253 : Tuple(tuple)
254 , NumComps(numComps)
255 {
256 }
257
259 TupleReference(const TupleReference&) noexcept = default;
261 TupleReference(TupleReference&&) noexcept = default;
262
263 // Allow this type to masquerade as a pointer, so that tupleIiter->foo works.
265 TupleReference* operator->() noexcept { return this; }
267 const TupleReference* operator->() const noexcept { return this; }
268
269 // Caller must ensure that there are size() elements in array.
271 void GetTuple(volatile APIType* tuple) const noexcept
272 {
273 // Yes, the tuple argument is marked volatile. No, it's not a mistake.
274 //
275 // `volatile`'s intended usage per the standard is to disable optimizations
276 // when accessing a variable. Without it, GCC 8 will optimize the following
277 // loop to memcpy, but we're usually copying small tuples here, and the
278 // call to memcpy is more expensive than just doing an inline copy. By
279 // disabling the memcpy optimization, benchmarks are 60% faster when
280 // iterating with the Get/SetTuple methods, and are comparable to other
281 // methods of array access.
282 VTK_ITER_ASSUME(this->NumComps.value > 0);
283 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
284 {
285 tuple[i] = this->Tuple[i];
286 }
287 }
288
289 // Caller must ensure that there are size() elements in array.
291 void SetTuple(const APIType* tuple) noexcept
292 {
293 volatile APIType* out = this->Tuple;
294 // Yes, this variable argument is marked volatile. See the explanation in
295 // GetTuple.
296 VTK_ITER_ASSUME(this->NumComps.value > 0);
297 for (ComponentIdType i = 0; i < this->NumComps.value; ++i)
298 {
299 out[i] = tuple[i];
300 }
301 }
302
305 {
306 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
307 return *this;
308 }
309
310 template <typename OArrayType, ComponentIdType OSize>
312 const TupleReference<OArrayType, OSize>& other) noexcept
313 {
314 // Check that types are convertible:
315 using OAPIType = GetAPIType<OArrayType>;
316 static_assert(
317 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
318
319 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
320 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
321
322 std::copy_n(other.cbegin(), OSize, this->begin());
323 return *this;
324 }
325
326 template <typename OArrayType, ComponentIdType OSize>
328 const TupleReference<OArrayType, OSize>& other) noexcept
329 {
330 // Check that types are convertible:
331 using OAPIType = GetAPIType<OArrayType>;
332 static_assert(
333 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
334
335 // Note that the sizes are not checked here. Enable
336 // VTK_DEBUG_RANGE_ITERATORS to enable check.
337 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
338 return *this;
339 }
340
341 template <typename OArrayType, ComponentIdType OSize>
343 const ConstTupleReference<OArrayType, OSize>& other) noexcept
344 {
345 // Check that types are convertible:
346 using OAPIType = GetAPIType<OArrayType>;
347 static_assert(
348 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
349
350 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
351 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
352
353 std::copy_n(other.cbegin(), OSize, this->begin());
354 return *this;
355 }
356
357 template <typename OArrayType, ComponentIdType OSize>
359 const ConstTupleReference<OArrayType, OSize>& other) noexcept
360 {
361 // Check that types are convertible:
362 using OAPIType = GetAPIType<OArrayType>;
363 static_assert(
364 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
365
366 // Note that the sizes are not checked here. Enable
367 // VTK_DEBUG_RANGE_ITERATORS to enable check.
368 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
369 return *this;
370 }
371
372 // skips some runtime checks when both sizes are fixed:
373 template <typename OArrayType, ComponentIdType OSize>
375 const TupleReference<OArrayType, OSize>& other) const noexcept
376 {
377 // Check that types are convertible:
378 using OAPIType = GetAPIType<OArrayType>;
379 static_assert(
380 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
381
382 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
383 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
384
385 return std::equal(this->cbegin(), this->cend(), other.cbegin());
386 }
387
388 // Needs a runtime check:
389 template <typename OArrayType, ComponentIdType OSize>
391 const TupleReference<OArrayType, OSize>& other) const noexcept
392 {
393 // Check that types are convertible:
394 using OAPIType = GetAPIType<OArrayType>;
395 static_assert(
396 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
397
398 // Note that the sizes are not checked here. Enable
399 // VTK_DEBUG_RANGE_ITERATORS to enable check.
400 return std::equal(this->cbegin(), this->cend(), other.cbegin());
401 }
402
403 // skips some runtime checks when both sizes are fixed:
404 template <typename OArrayType, ComponentIdType OSize>
406 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
407 {
408 // Check that types are convertible:
409 using OAPIType = GetAPIType<OArrayType>;
410 static_assert(
411 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
412
413 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
414 static_assert(TupleSize == OSize, "Cannot assign tuples with different sizes.");
415
416 return std::equal(this->cbegin(), this->cend(), other.cbegin());
417 }
418
419 // Needs a runtime check:
420 template <typename OArrayType, ComponentIdType OSize>
422 const ConstTupleReference<OArrayType, OSize>& other) const noexcept
423 {
424 // Check that types are convertible:
425 using OAPIType = GetAPIType<OArrayType>;
426 static_assert(
427 (std::is_convertible<OAPIType, APIType>{}), "Incompatible types when assigning tuples.");
428
429 // Note that the sizes are not checked here. Enable
430 // VTK_DEBUG_RANGE_ITERATORS to enable check.
431 return std::equal(this->cbegin(), this->cend(), other.cbegin());
432 }
433
434 template <typename OArrayType, ComponentIdType OSize>
436 {
437 return !(*this == o);
438 }
439
440 template <typename OArray, ComponentIdType OSize>
442 {
443 return !(*this == o);
444 }
445
446 // skips some runtime checks:
447 template <typename OArrayType, ComponentIdType OSize>
450 {
451 // Check that types are convertible:
452 using OAPIType = GetAPIType<OArrayType>;
453 static_assert((std::is_same<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
454
455 // SFINAE guarantees that the tuple sizes are not dynamic in this overload:
456 static_assert(TupleSize == OSize, "Cannot swap tuples with different sizes.");
457
458 std::swap_ranges(this->begin(), this->end(), other.begin());
459 }
460
461 // Needs a runtime check:
462 template <typename OArrayType, ComponentIdType OSize>
465 {
466 // Check that types are convertible:
467 using OAPIType = GetAPIType<OArrayType>;
468 static_assert((std::is_same<OAPIType, APIType>{}), "Incompatible types when swapping tuples.");
469
470 // Note that the sizes are not checked here. Enable
471 // VTK_DEBUG_RANGE_ITERATORS to enable check.
472 std::swap_ranges(this->begin(), this->end(), other.begin());
473 }
474
475 friend VTK_ITER_INLINE void swap(TupleReference a, TupleReference b) noexcept { a.swap(b); }
476
477 template <typename OArray, ComponentIdType OSize>
479 {
480 a.swap(b);
481 }
482
484 reference operator[](size_type i) noexcept { return this->Tuple[i]; }
485
487 const_reference operator[](size_type i) const noexcept { return this->Tuple[i]; }
488
490 void fill(const value_type& v) noexcept { std::fill(this->begin(), this->end(), v); }
491
493 size_type size() const noexcept { return this->NumComps.value; }
494
496 iterator begin() noexcept { return iterator{ this->Tuple }; }
497
499 iterator end() noexcept { return iterator{ this->Tuple + this->NumComps.value }; }
500
502 const_iterator begin() const noexcept { return const_iterator{ this->Tuple }; }
503
505 const_iterator end() const noexcept
506 {
507 return const_iterator{ this->Tuple + this->NumComps.value };
508 }
509
511 const_iterator cbegin() const noexcept { return const_iterator{ this->Tuple }; }
512
514 const_iterator cend() const noexcept
515 {
516 return const_iterator{ this->Tuple + this->NumComps.value };
517 }
518
519 friend struct ConstTupleReference<ArrayType, TupleSize>;
520 friend struct TupleIterator<ArrayType, TupleSize>;
521
522protected:
524 void CopyReference(const TupleReference& o) noexcept
525 {
526 this->Tuple = o.Tuple;
527 this->NumComps = o.NumComps;
528 }
529
530 ValueType* Tuple;
532};
533
534//------------------------------------------------------------------------------
535// Const tuple iterator
536template <typename ValueType, ComponentIdType TupleSize>
537struct ConstTupleIterator<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
538{
539private:
542
543public:
544 using iterator_category = std::random_access_iterator_tag;
549
551 ConstTupleIterator() noexcept = default;
552
554 ConstTupleIterator(const ValueType* tuple, NumCompsType numComps) noexcept
555 : Ref(tuple, numComps)
556 {
557 }
558
561 : Ref{ o.Ref }
562 {
563 }
564
566 ConstTupleIterator(const ConstTupleIterator& o) noexcept = default;
568 ConstTupleIterator& operator=(const ConstTupleIterator& o) noexcept = default;
569
571 ConstTupleIterator& operator++() noexcept // prefix
572 {
573 this->Ref.Tuple += this->Ref.NumComps.value;
574 return *this;
575 }
576
578 ConstTupleIterator operator++(int) noexcept // postfix
579 {
580 auto tuple = this->Ref.Tuple;
581 this->Ref.Tuple += this->Ref.NumComps.value;
582 return ConstTupleIterator{ tuple, this->Ref.NumComps };
583 }
584
586 ConstTupleIterator& operator--() noexcept // prefix
587 {
588 this->Ref.Tuple -= this->Ref.NumComps.value;
589 return *this;
590 }
591
593 ConstTupleIterator operator--(int) noexcept // postfix
594 {
595 auto tuple = this->Ref.Tuple;
596 this->Ref.Tuple -= this->Ref.NumComps.value;
597 return ConstTupleIterator{ tuple, this->Ref.NumComps };
598 }
599
602 {
603 return reference{ this->Ref.Tuple + i * this->Ref.NumComps, this->Ref.NumComps };
604 }
605
607 reference operator*() noexcept { return this->Ref; }
608
610 pointer& operator->() noexcept { return this->Ref; }
611
612#define VTK_TMP_MAKE_OPERATOR(OP) \
613 friend VTK_ITER_INLINE bool operator OP( \
614 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
615 { \
616 return lhs.GetTuple() OP rhs.GetTuple(); \
617 }
618
625
626#undef VTK_TMP_MAKE_OPERATOR
627
630 {
631 this->Ref.Tuple += offset * this->Ref.NumComps.value;
632 return *this;
633 }
634
636 const ConstTupleIterator& it, difference_type offset) noexcept
637 {
638 return ConstTupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
639 }
640
642 difference_type offset, const ConstTupleIterator& it) noexcept
643 {
644 return ConstTupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
645 }
646
649 {
650 this->Ref.Tuple -= offset * this->Ref.NumComps.value;
651 return *this;
652 }
653
655 const ConstTupleIterator& it, difference_type offset) noexcept
656 {
657 return ConstTupleIterator{ it.GetTuple() - offset * it.GetNumComps().value, it.GetNumComps() };
658 }
659
661 const ConstTupleIterator& it1, const ConstTupleIterator& it2) noexcept
662 {
663 return static_cast<difference_type>(
664 (it1.GetTuple() - it2.GetTuple()) / it1.GetNumComps().value);
665 }
666
668 {
669 using std::swap;
670 swap(lhs.GetTuple(), rhs.GetTuple());
671 swap(lhs.GetNumComps(), rhs.GetNumComps());
672 }
673
674private:
676 const ValueType*& GetTuple() noexcept { return this->Ref.Tuple; }
678 const ValueType* GetTuple() const noexcept { return this->Ref.Tuple; }
680 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
682 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
683
684 ConstTupleReference<ArrayType, TupleSize> Ref;
685};
686
687//------------------------------------------------------------------------------
688// Tuple iterator
689template <typename ValueType, ComponentIdType TupleSize>
690struct TupleIterator<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
691{
692private:
695
696public:
697 using iterator_category = std::random_access_iterator_tag;
702
704 TupleIterator() noexcept = default;
705
707 TupleIterator(ValueType* tuple, NumCompsType numComps) noexcept
708 : Ref(tuple, numComps)
709 {
710 }
711
713 TupleIterator(const TupleIterator& o) noexcept = default;
714
717 {
718 this->Ref.CopyReference(o.Ref);
719 return *this;
720 }
721
723 TupleIterator& operator++() noexcept // prefix
724 {
725 this->Ref.Tuple += this->Ref.NumComps.value;
726 return *this;
727 }
728
730 TupleIterator operator++(int) noexcept // postfix
731 {
732 auto tuple = this->Ref.Tuple;
733 this->Ref.Tuple += this->Ref.NumComps.value;
734 return TupleIterator{ tuple, this->Ref.NumComps };
735 }
736
738 TupleIterator& operator--() noexcept // prefix
739 {
740 this->Ref.Tuple -= this->Ref.NumComps.value;
741 return *this;
742 }
743
745 TupleIterator operator--(int) noexcept // postfix
746 {
747 auto tuple = this->Ref.Tuple;
748 this->Ref.Tuple -= this->Ref.NumComps.value;
749 return TupleIterator{ tuple, this->Ref.NumComps };
750 }
751
754 {
755 return reference{ this->Ref.Tuple + i * this->Ref.NumComps.value, this->Ref.NumComps };
756 }
757
758 reference operator*() noexcept { return this->Ref; }
759
760 pointer& operator->() noexcept { return this->Ref; }
761
762#define VTK_TMP_MAKE_OPERATOR(OP) \
763 friend VTK_ITER_INLINE bool operator OP( \
764 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
765 { \
766 return lhs.GetTuple() OP rhs.GetTuple(); \
767 }
768
775
776#undef VTK_TMP_MAKE_OPERATOR
777
780 {
781 this->Ref.Tuple += offset * this->Ref.NumComps.value;
782 return *this;
783 }
784
786 const TupleIterator& it, difference_type offset) noexcept
787 {
788 return TupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
789 }
790
792 difference_type offset, const TupleIterator& it) noexcept
793 {
794 return TupleIterator{ it.GetTuple() + offset * it.GetNumComps().value, it.GetNumComps() };
795 }
796
799 {
800 this->Ref.Tuple -= offset * this->Ref.NumComps.value;
801 return *this;
802 }
803
805 const TupleIterator& it, difference_type offset) noexcept
806 {
807 return TupleIterator{ it.GetTuple() - offset * it.GetNumComps().value, it.GetNumComps() };
808 }
809
811 const TupleIterator& it1, const TupleIterator& it2) noexcept
812 {
813 return static_cast<difference_type>(
814 (it1.GetTuple() - it2.GetTuple()) / it1.GetNumComps().value);
815 }
816
817 friend VTK_ITER_INLINE void swap(TupleIterator& lhs, TupleIterator& rhs) noexcept
818 {
819 using std::swap;
820 swap(lhs.GetTuple(), rhs.GetTuple());
821 swap(lhs.GetNumComps(), rhs.GetNumComps());
822 }
823
824 friend struct ConstTupleIterator<ArrayType, TupleSize>;
825
826protected:
828 ValueType* GetTuple() const noexcept { return this->Ref.Tuple; }
830 ValueType*& GetTuple() noexcept { return this->Ref.Tuple; }
832 NumCompsType GetNumComps() const noexcept { return this->Ref.NumComps; }
834 NumCompsType& GetNumComps() noexcept { return this->Ref.NumComps; }
835
837};
838
839//------------------------------------------------------------------------------
840// Tuple range
841template <typename ValueType, ComponentIdType TupleSize>
842struct TupleRange<vtkAOSDataArrayTemplate<ValueType>, TupleSize>
843{
846
847private:
848 static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
849 static_assert(IsVtkDataArray<ArrayType>::value, "Invalid array type.");
850
852
853public:
863
869
870 // May be DynamicTupleSize, or the actual tuple size.
871 constexpr static ComponentIdType TupleSizeTag = TupleSize;
872
874 TupleRange() noexcept = default;
875
877 TupleRange(ArrayType* arr, TupleIdType beginTuple, TupleIdType endTuple) noexcept
878 : Array(arr)
879 , NumComps(arr)
880 , BeginTuple(TupleRange::GetTuplePointer(arr, beginTuple))
881 , EndTuple(TupleRange::GetTuplePointer(arr, endTuple))
882 {
883 assert(this->Array);
884 assert(beginTuple >= 0 && beginTuple <= endTuple);
885 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
886 }
887
889 TupleRange GetSubRange(TupleIdType beginTuple = 0, TupleIdType endTuple = -1) const noexcept
890 {
891 const TupleIdType curBegin = this->GetTupleId(this->BeginTuple);
892 const TupleIdType realBegin = curBegin + beginTuple;
893 const TupleIdType realEnd =
894 endTuple >= 0 ? curBegin + endTuple : this->GetTupleId(this->EndTuple);
895
896 return TupleRange{ this->Array, realBegin, realEnd };
897 }
898
900 ArrayType* GetArray() const noexcept { return this->Array; }
901
903 ComponentIdType GetTupleSize() const noexcept { return this->NumComps.value; }
904
906 TupleIdType GetBeginTupleId() const noexcept { return this->GetTupleId(this->BeginTuple); }
907
909 TupleIdType GetEndTupleId() const noexcept { return this->GetTupleId(this->EndTuple); }
910
912 size_type size() const noexcept
913 {
914 return static_cast<size_type>(this->EndTuple - this->BeginTuple) /
915 static_cast<size_type>(this->NumComps.value);
916 }
917
919 iterator begin() noexcept { return iterator(this->BeginTuple, this->NumComps); }
920
922 iterator end() noexcept { return iterator(this->EndTuple, this->NumComps); }
923
925 const_iterator begin() const noexcept { return const_iterator(this->BeginTuple, this->NumComps); }
926
928 const_iterator end() const noexcept { return const_iterator(this->EndTuple, this->NumComps); }
929
931 const_iterator cbegin() const noexcept
932 {
933 return const_iterator(this->BeginTuple, this->NumComps);
934 }
935
937 const_iterator cend() const noexcept { return const_iterator(this->EndTuple, this->NumComps); }
938
941 {
942 return reference{ this->BeginTuple + i * this->NumComps.value, this->NumComps };
943 }
944
947 {
948 return const_reference{ this->BeginTuple + i * this->NumComps.value, this->NumComps };
949 }
950
951private:
953 ValueType* GetTuplePointer(ArrayType* array, vtkIdType tuple) const noexcept
954 {
955 return array->GetPointer(tuple * this->NumComps.value);
956 }
957
959 TupleIdType GetTupleId(const ValueType* ptr) const noexcept
960 {
961 return static_cast<TupleIdType>((ptr - this->Array->GetPointer(0)) / this->NumComps.value);
962 }
963
964 mutable ArrayType* Array{ nullptr };
965 NumCompsType NumComps{};
966 ValueType* BeginTuple{ nullptr };
967 ValueType* EndTuple{ nullptr };
968};
969
970// Unimplemented, only used inside decltype in SelectTupleRange:
971template <typename ArrayType, ComponentIdType TupleSize,
972 // Convenience:
973 typename ValueType = typename ArrayType::ValueType,
974 typename AOSArrayType = vtkAOSDataArrayTemplate<ValueType>,
975 // SFINAE to select AOS arrays:
976 typename = typename std::enable_if<IsAOSDataArray<ArrayType>::value>::type>
978
979VTK_ABI_NAMESPACE_END
980} // end namespace detail
981} // end namespace vtk
982
984
985#endif // VTK_DEBUG_RANGE_ITERATORS
986#endif // vtkDataArrayTupleRange_AOS_h
987
988// VTK-HeaderTest-Exclude: vtkDataArrayTupleRange_AOS.h
Array-Of-Structs implementation of vtkGenericDataArray.
typename std::enable_if< AreStaticTupleSizes< S1, S2 >::value, T >::type EnableIfStaticTupleSizes
TupleRange< AOSArrayType, TupleSize > DeclareTupleRangeSpecialization(ArrayType *)
typename std::enable_if< IsEitherTupleSizeDynamic< S1, S2 >::value, T >::type EnableIfEitherTupleSizeIsDynamic
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:315