20 #ifndef vtkDataArrayTupleRange_Generic_h
21 #define vtkDataArrayTupleRange_Generic_h
30 #include <type_traits>
43 template <
typename ArrayType, ComponentIdType>
44 struct ConstComponentReference;
45 template <
typename ArrayType, ComponentIdType>
46 struct ComponentReference;
47 template <
typename ArrayType, ComponentIdType>
48 struct ConstComponentIterator;
49 template <
typename ArrayType, ComponentIdType>
50 struct ComponentIterator;
51 template <
typename ArrayType, ComponentIdType>
52 struct ConstTupleReference;
53 template <
typename ArrayType, ComponentIdType>
54 struct TupleReference;
55 template <
typename ArrayType, ComponentIdType>
56 struct ConstTupleIterator;
57 template <
typename ArrayType, ComponentIdType>
59 template <
typename ArrayType, ComponentIdType>
64 template <
typename ArrayType, ComponentIdType TupleSize>
97 tuple >= 0 && tuple <= array->GetNumberOfTuples(),
"Invalid tuple accessed by iterator.");
99 "Invalid component accessed by iterator.");
122 this->
Array = o.Array;
133 this->
Array = std::move(o.Array);
134 this->
NumComps = std::move(o.NumComps);
135 this->
TupleId = std::move(o.TupleId);
140 operator APIType() const noexcept
157 template <
typename ArrayType, ComponentIdType TupleSize>
190 tuple >= 0 && tuple <= array->GetNumberOfTuples(),
"Invalid tuple accessed by iterator.");
192 "Invalid component accessed by iterator.");
205 return *
this =
static_cast<APIType
>(o);
209 this->
Array = o.Array;
223 return *
this = std::move(
static_cast<APIType
>(o));
227 this->
Array = std::move(o.Array);
228 this->
NumComps = std::move(o.NumComps);
229 this->
TupleId = std::move(o.TupleId);
236 template <
typename OArray, ComponentIdType OSize>
239 const APIType tmp = o;
240 return *
this = std::move(tmp);
244 operator APIType() const noexcept
264 APIType tmp = std::move(
static_cast<APIType
>(lhs));
265 lhs = std::move(
static_cast<APIType
>(rhs));
266 rhs = std::move(tmp);
269 template <
typename OArray, ComponentIdType OSize>
277 APIType tmp = std::move(
static_cast<APIType
>(lhs));
278 lhs = std::move(
static_cast<APIType
>(rhs));
279 rhs = std::move(tmp);
284 APIType tmp = std::move(
static_cast<APIType
>(lhs));
285 lhs = std::move(rhs);
286 rhs = std::move(tmp);
291 APIType tmp = std::move(lhs);
292 lhs = std::move(
static_cast<APIType
>(rhs));
293 rhs = std::move(tmp);
299 const APIType newVal = *
this + 1;
307 const APIType retVal = *
this;
315 const APIType newVal = *
this - 1;
323 const APIType retVal = *
this;
328 #define VTK_REF_OP_OVERLOADS(Op, ImplOp) \
329 friend VTK_ITER_INLINE ComponentReference operator Op( \
330 ComponentReference lhs, APIType val) noexcept \
332 const APIType newVal = lhs ImplOp val; \
336 friend VTK_ITER_INLINE ComponentReference operator Op( \
337 ComponentReference lhs, ComponentReference val) noexcept \
339 const APIType newVal = lhs ImplOp val; \
343 friend VTK_ITER_INLINE APIType& operator Op(APIType& lhs, ComponentReference val) noexcept \
345 const APIType newVal = lhs ImplOp val; \
355 #undef VTK_REF_OP_OVERLOADS
357 friend struct ConstComponentReference<ArrayType, TupleSize>;
358 friend struct ComponentIterator<ArrayType, TupleSize>;
364 this->
Array = o.Array;
378 template <
typename ArrayType, ComponentIdType TupleSize>
413 "Const component iterator at invalid tuple id.");
415 "Const component iterator at invalid component id.");
420 : Array{ o.GetArray() }
421 , NumComps{ o.GetNumComps() }
422 , TupleId{ o.GetTupleId() }
423 , ComponentId{ o.GetComponentId() }
436 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
437 "Const component iterator at invalid component id.");
445 this->ComponentId++ };
452 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
453 "Const component iterator at invalid component id.");
461 this->ComponentId-- };
467 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId + i };
473 return reference{ this->Array, this->NumComps, this->TupleId, this->ComponentId };
476 #define VTK_TMP_MAKE_OPERATOR(OP) \
477 friend VTK_ITER_INLINE bool operator OP( \
478 const ConstComponentIterator& lhs, const ConstComponentIterator& rhs) noexcept \
480 VTK_ITER_ASSERT(lhs.Array == rhs.Array, "Mismatched arrays in iterator comparison."); \
481 VTK_ITER_ASSERT(lhs.TupleId == rhs.TupleId, "Mismatched tuple ids in iterator comparison."); \
482 VTK_ITER_ASSUME(lhs.NumComps.value > 0); \
483 VTK_ITER_ASSUME(lhs.NumComps.value == rhs.NumComps.value); \
484 return lhs.ComponentId OP rhs.ComponentId; \
494 #undef VTK_TMP_MAKE_OPERATOR
499 this->ComponentId +=
offset;
500 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
501 "Const component iterator at invalid component id.");
520 this->ComponentId -=
offset;
521 VTK_ITER_ASSERT(this->ComponentId >= 0 && this->ComponentId <= this->NumComps.value,
522 "Const component iterator at invalid component id.");
535 VTK_ITER_ASSERT(it1.Array == it2.Array,
"Cannot do math with iterators from different arrays.");
537 "Cannot do math with component iterators from different "
539 return it1.ComponentId - it2.ComponentId;
546 VTK_ITER_ASSERT(lhs.Array == rhs.Array,
"Cannot swap iterators from different arrays.");
549 swap(lhs.TupleId, rhs.TupleId);
550 swap(lhs.ComponentId, rhs.ComponentId);
554 mutable ArrayType* Array;
555 NumCompsType NumComps;
562 template <
typename ArrayType, ComponentIdType TupleSize>
585 :
Ref(array, numComps, tupleId, comp)
590 "Component iterator at invalid tuple id.");
592 comp >= 0 && comp <= numComps.value,
"Component iterator at invalid component id.");
601 this->
Ref.CopyReference(o.Ref);
608 ++this->
Ref.ComponentId;
609 VTK_ITER_ASSERT(this->
Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
610 "Component iterator at invalid component id.");
618 this->
Ref.ComponentId++ };
624 --this->
Ref.ComponentId;
625 VTK_ITER_ASSERT(this->
Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
626 "Component iterator at invalid component id.");
634 this->
Ref.ComponentId-- };
641 this->
Ref.ComponentId + i };
650 #define VTK_TMP_MAKE_OPERATOR(OP) \
651 friend VTK_ITER_INLINE bool operator OP( \
652 const ComponentIterator& lhs, const ComponentIterator& rhs) noexcept \
655 lhs.GetArray() == rhs.GetArray(), "Mismatched arrays in iterator comparison."); \
657 lhs.GetTupleId() == rhs.GetTupleId(), "Mismatched tuple ids in iterator comparison."); \
658 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
659 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
660 return lhs.GetComponentId() OP rhs.GetComponentId(); \
670 #undef VTK_TMP_MAKE_OPERATOR
676 VTK_ITER_ASSERT(this->
Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
677 "Component iterator at invalid component id.");
685 it.GetComponentId() +
offset };
692 it.GetComponentId() +
offset };
699 VTK_ITER_ASSERT(this->
Ref.ComponentId >= 0 && this->Ref.ComponentId <= this->Ref.NumComps.value,
700 "Component iterator at invalid component id.");
708 it.GetComponentId() -
offset };
715 "Cannot do math with component iterators from different "
718 "Cannot do math with component iterators from different "
720 return it1.GetComponentId() - it2.GetComponentId();
727 lhs.GetArray() == rhs.GetArray(),
"Cannot swap iterators from different arrays.");
730 swap(lhs.GetTupleId(), rhs.GetTupleId());
731 swap(lhs.GetComponentId(), rhs.GetComponentId());
752 template <
typename ArrayType, ComponentIdType TupleSize>
785 "Const tuple reference at invalid tuple id.");
818 template <
typename OArrayType, ComponentIdType OSize>
825 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
828 static_assert(TupleSize == OSize,
"Cannot compare tuples with different sizes.");
830 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
834 template <
typename OArrayType, ComponentIdType OSize>
841 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
844 other.size() == this->NumComps.value,
"Cannot compare tuples with different sizes.");
846 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
850 template <
typename OArrayType, ComponentIdType OSize>
857 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
860 static_assert(TupleSize == OSize,
"Cannot compare tuples with different sizes.");
862 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
866 template <
typename OArrayType, ComponentIdType OSize>
873 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
876 other.size() == this->NumComps.value,
"Cannot compare tuples with different sizes.");
878 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
881 template <
typename OArrayType, ComponentIdType OSize>
884 return !(*
this == o);
887 template <
typename OArrayT, ComponentIdType OSize>
890 return !(*
this == o);
942 template <
typename ArrayType, ComponentIdType TupleSize>
976 "Tuple reference at invalid tuple id.");
1007 acc.Set(this->
TupleId, tuple);
1013 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1018 template <
typename OArrayType, ComponentIdType OSize>
1025 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when assigning tuples.");
1028 static_assert(TupleSize == OSize,
"Cannot assign tuples with different sizes.");
1030 std::copy_n(other.cbegin(), OSize, this->begin());
1035 template <
typename OArrayType, ComponentIdType OSize>
1042 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when assigning tuples.");
1045 other.size() == this->NumComps.value,
"Cannot assign tuples with different sizes.");
1047 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1052 template <
typename OArrayType, ComponentIdType OSize>
1059 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when assigning tuples.");
1062 static_assert(TupleSize == OSize,
"Cannot assign tuples with different sizes.");
1064 std::copy_n(other.cbegin(), OSize, this->begin());
1069 template <
typename OArrayType, ComponentIdType OSize>
1076 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when assigning tuples.");
1079 other.size() == this->NumComps.value,
"Cannot assign tuples with different sizes.");
1081 std::copy_n(other.cbegin(), this->NumComps.value, this->begin());
1086 template <
typename OArrayType, ComponentIdType OSize>
1093 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
1096 static_assert(TupleSize == OSize,
"Cannot compare tuples with different sizes.");
1098 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
1102 template <
typename OArrayType, ComponentIdType OSize>
1109 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
1112 other.size() == this->NumComps.value,
"Cannot compare tuples with different sizes.");
1114 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
1118 template <
typename OArrayType, ComponentIdType OSize>
1125 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
1128 static_assert(TupleSize == OSize,
"Cannot compare tuples with different sizes.");
1130 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
1134 template <
typename OArrayType, ComponentIdType OSize>
1141 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when comparing tuples.");
1144 other.size() == this->NumComps.value,
"Cannot compare tuples with different sizes.");
1146 return std::equal(this->
cbegin(), this->
cend(), other.cbegin());
1149 template <
typename OArrayType, ComponentIdType OSize>
1152 return !(*
this == o);
1155 template <
typename OArray, ComponentIdType OSize>
1158 return !(*
this == o);
1162 template <
typename OArrayType, ComponentIdType OSize>
1169 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when swapping tuples.");
1172 static_assert(TupleSize == OSize,
"Cannot swap tuples with different sizes.");
1174 std::swap_ranges(this->
begin(), this->
end(), other.begin());
1178 template <
typename OArrayType, ComponentIdType OSize>
1185 (std::is_convertible<OAPIType, APIType>{}),
"Incompatible types when swapping tuples.");
1188 other.size() == this->NumComps.value,
"Cannot swap tuples with different sizes.");
1190 std::swap_ranges(this->
begin(), this->
end(), other.begin());
1195 template <
typename OArray, ComponentIdType OSize>
1269 template <
typename ArrayType, ComponentIdType TupleSize>
1290 : Ref(array, numComps, tupleId)
1294 VTK_ITER_ASSERT(tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
1295 "Const tuple iterator at invalid tuple id.");
1309 this->Ref.CopyReference(o.Ref);
1316 ++this->Ref.TupleId;
1318 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1319 "Const tuple iterator at invalid component id.");
1326 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId++ };
1332 --this->Ref.TupleId;
1334 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1335 "Const tuple iterator at invalid component id.");
1342 return ConstTupleIterator{ this->Ref.Array, this->Ref.NumComps, this->Ref.TupleId-- };
1348 return reference{ this->GetArray(), this->GetNumComps(), this->GetTupleId() + i };
1357 #define VTK_TMP_MAKE_OPERATOR(OP) \
1358 friend VTK_ITER_INLINE bool operator OP( \
1359 const ConstTupleIterator& lhs, const ConstTupleIterator& rhs) noexcept \
1362 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1363 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1364 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1365 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1375 #undef VTK_TMP_MAKE_OPERATOR
1380 this->Ref.TupleId +=
offset;
1382 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1383 "Const tuple iterator at invalid component id.");
1402 this->Ref.TupleId -=
offset;
1404 this->Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1405 "Const tuple iterator at invalid component id.");
1419 "Cannot do math with tuple iterators from different "
1421 return it1.GetTupleId() - it2.GetTupleId();
1428 lhs.GetArray() == rhs.GetArray(),
"Cannot swap iterators from different arrays.");
1431 swap(lhs.GetTupleId(), rhs.GetTupleId());
1436 ArrayType* GetArray() const noexcept {
return this->Ref.Array; }
1438 ArrayType*& GetArray() noexcept {
return this->Ref.Array; }
1440 NumCompsType GetNumComps() const noexcept {
return this->Ref.NumComps; }
1442 NumCompsType& GetNumComps() noexcept {
return this->Ref.NumComps; }
1444 TupleIdType GetTupleId() const noexcept {
return this->Ref.TupleId; }
1446 TupleIdType& GetTupleId() noexcept {
return this->Ref.TupleId; }
1448 ConstTupleReference<ArrayType, TupleSize> Ref;
1453 template <
typename ArrayType, ComponentIdType TupleSize>
1474 :
Ref(array, numComps, tupleId)
1479 tupleId >= 0 && tupleId <= array->GetNumberOfTuples(),
"Tuple iterator at invalid tuple id.");
1488 this->
Ref.CopyReference(o.Ref);
1495 ++this->
Ref.TupleId;
1497 this->
Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1498 "Tuple iterator at invalid component id.");
1511 --this->
Ref.TupleId;
1513 this->
Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1514 "Tuple iterator at invalid component id.");
1536 #define VTK_TMP_MAKE_OPERATOR(OP) \
1537 friend VTK_ITER_INLINE bool operator OP( \
1538 const TupleIterator& lhs, const TupleIterator& rhs) noexcept \
1541 lhs.GetArray() == rhs.GetArray(), "Cannot compare iterators from different arrays."); \
1542 VTK_ITER_ASSUME(lhs.GetNumComps().value > 0); \
1543 VTK_ITER_ASSUME(lhs.GetNumComps().value == rhs.GetNumComps().value); \
1544 return lhs.GetTupleId() OP rhs.GetTupleId(); \
1554 #undef VTK_TMP_MAKE_OPERATOR
1561 this->
Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1562 "Tuple iterator at invalid component id.");
1583 this->
Ref.TupleId >= 0 && this->Ref.TupleId <= this->Ref.Array->GetNumberOfTuples(),
1584 "Tuple iterator at invalid component id.");
1598 "Cannot do math with tuple iterators from different "
1600 return it1.GetTupleId() - it2.GetTupleId();
1607 lhs.GetArray() == rhs.GetArray(),
"Cannot swap iterators from different arrays.");
1610 swap(lhs.GetTupleId(), rhs.GetTupleId());
1635 template <
typename ArrayTypeT, ComponentIdType TupleSize>
1672 , BeginTuple(beginTuple)
1673 , EndTuple(endTuple)
1675 assert(this->Array);
1676 assert(beginTuple >= 0 && beginTuple <= endTuple);
1677 assert(endTuple >= 0 && endTuple <= this->Array->GetNumberOfTuples());
1683 const TupleIdType realBegin = this->BeginTuple + beginTuple;
1684 const TupleIdType realEnd = endTuple >= 0 ? this->BeginTuple + endTuple : this->EndTuple;
1686 return TupleRange{ this->Array, realBegin, realEnd };
1719 return reference{ this->Array, this->NumComps, this->BeginTuple + i };
1725 return const_reference{ this->Array, this->NumComps, this->BeginTuple + i };
1739 NumCompsType NumComps{};
1745 template <
typename ArrayType, ComponentIdType TupleSize>
1753 #endif // __VTK_WRAP__
1754 #endif // vtkDataArrayTupleRange_Generic_h