18#ifndef itkVariableLengthVector_h
19#define itkVariableLengthVector_h
33template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
34struct VariableLengthVectorExpression;
90template <
typename TValue>
110 struct AllocateRootPolicy
126 struct AlwaysReallocate : AllocateRootPolicy
129 operator()(
unsigned int itkNotUsed(newSize),
unsigned int itkNotUsed(oldSize))
const
152 struct NeverReallocate : AllocateRootPolicy
155 operator()([[maybe_unused]]
unsigned int newSize, [[maybe_unused]]
unsigned int oldSize)
const
157 itkAssertInDebugAndIgnoreInReleaseMacro(newSize == oldSize &&
158 "SetSize is expected to never change the VariableLengthVector size...");
180 struct ShrinkToFit : AllocateRootPolicy
183 operator()(
unsigned int newSize,
unsigned int oldSize)
const
185 return newSize != oldSize;
215 struct DontShrinkToFit : AllocateRootPolicy
218 operator()(
unsigned int newSize,
unsigned int oldSize)
const
220 return newSize > oldSize;
242 struct KeepValuesRootPolicy
266 struct KeepOldValues : KeepValuesRootPolicy
268 template <
typename TValue2>
270 operator()(
unsigned int newSize,
unsigned int oldSize, TValue2 * oldBuffer, TValue2 * newBuffer)
const
272 itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer);
273 const size_t nb = std::min(newSize, oldSize);
274 itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0 && oldBuffer !=
nullptr));
275 std::copy_n(oldBuffer, nb, newBuffer);
295 struct DumpOldValues : KeepValuesRootPolicy
297 template <
typename TValue2>
299 operator()(
unsigned int itkNotUsed(newSize),
300 unsigned int itkNotUsed(oldSize),
301 TValue2 * itkNotUsed(oldBuffer),
302 TValue2 * itkNotUsed(newBuffer))
const
309 using ValueType = TValue;
310 using ComponentType = TValue;
311 using RealValueType =
typename NumericTraits<ValueType>::RealType;
312 using Self = VariableLengthVector;
315 using ElementIdentifier =
unsigned int;
323 VariableLengthVector() =
default;
333 explicit VariableLengthVector(
unsigned int length);
348 VariableLengthVector(ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
369 VariableLengthVector(
const ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
390 template <
typename T>
391 VariableLengthVector(
const VariableLengthVector<T> & v)
392 : m_NumElements(v.Size())
394 if (m_NumElements != 0)
396 m_Data = this->AllocateElements(m_NumElements);
397 itkAssertInDebugAndIgnoreInReleaseMacro(m_Data !=
nullptr);
398 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
400 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
417 VariableLengthVector(
const VariableLengthVector<TValue> & v);
428 Swap(Self & v)
noexcept
430 itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
432 swap(v.m_Data, m_Data);
433 swap(v.m_NumElements, m_NumElements);
443 VariableLengthVector(Self && v)
noexcept;
454 operator=(Self && v)
noexcept;
472 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
473 VariableLengthVector(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs);
494 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
496 operator=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs);
502 Fill(
const TValue & v);
516 template <
typename T>
518 operator=(
const VariableLengthVector<T> & v)
527 const ElementIdentifier N = v.Size();
528 this->SetSize(N, DontShrinkToFit(), DumpOldValues());
529 for (ElementIdentifier i = 0; i < N; ++i)
531 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
552 operator=(
const Self & v);
563 FastAssign(
const Self & v);
573 operator=(
const TValue & v);
577 [[nodiscard]]
unsigned int
580 return m_NumElements;
582 [[nodiscard]]
unsigned int
585 return m_NumElements;
587 [[nodiscard]]
unsigned int
588 GetNumberOfElements()
const
590 return m_NumElements;
595 operator[](
unsigned int i)
597 return this->m_Data[i];
602 operator[](
unsigned int i)
const
604 return this->m_Data[i];
608 [[nodiscard]]
const TValue &
609 GetElement(
unsigned int i)
const
616 SetElement(
unsigned int i,
const TValue & value)
654 template <
typename TReallocatePolicy,
typename TKeepValuesPolicy>
656 SetSize(
unsigned int sz, TReallocatePolicy reallocatePolicy, TKeepValuesPolicy keepValues);
669 SetSize(
unsigned int sz,
bool destroyExistingData =
true)
674 if (destroyExistingData)
676 SetSize(sz, AlwaysReallocate(), KeepOldValues());
680 SetSize(sz, ShrinkToFit(), KeepOldValues());
687 DestroyExistingData();
702 SetData(TValue * datain,
bool LetArrayManageMemory =
false);
719 SetData(TValue * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
731 ~VariableLengthVector();
748 Reserve(ElementIdentifier size);
754 [[nodiscard]] TValue *
755 AllocateElements(ElementIdentifier size)
const;
757 [[nodiscard]]
const TValue *
758 GetDataPointer()
const
768 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
770 this->m_Data[i] -=
static_cast<ValueType
>(1.0);
779 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
781 this->m_Data[i] +=
static_cast<ValueType
>(1.0);
815 template <
typename T>
817 operator-=(
const VariableLengthVector<T> & v)
819 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
820 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
822 m_Data[i] -=
static_cast<ValueType
>(v[i]);
831 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
846 template <
typename T>
848 operator+=(
const VariableLengthVector<T> & v)
850 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
851 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
853 m_Data[i] +=
static_cast<ValueType
>(v[i]);
862 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
878 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
880 operator+=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs)
882 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
883 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
885 m_Data[i] +=
static_cast<ValueType
>(rhs[i]);
899 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
901 operator-=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs)
903 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
904 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
906 m_Data[i] -=
static_cast<ValueType
>(rhs[i]);
916 template <
typename T>
920 const ValueType & sc =
static_cast<ValueType
>(s);
921 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
934 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
947 template <
typename T>
951 const RealValueType sc = s;
952 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
954 m_Data[i] =
static_cast<ValueType
>(
static_cast<RealValueType
>(m_Data[i]) / sc);
969 ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(Self);
972 [[nodiscard]] RealValueType
976 [[nodiscard]] RealValueType
977 GetSquaredNorm()
const;
983 return !m_LetArrayManageMemory;
987 bool m_LetArrayManageMemory{
true };
990 ElementIdentifier m_NumElements{ 0 };
1005template <
typename T>
1006struct IsArray : FalseType
1010template <
typename T>
1011struct IsArray<itk::VariableLengthVector<T>> : TrueType
1014template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1015struct IsArray<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>> : TrueType
1036template <
typename TExpr>
1045 Load(
const Type & v,
unsigned int itkNotUsed(idx))
1061template <
typename TExpr1,
typename TExpr2>
1062inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>::Value,
unsigned int>
1063GetSize(
const TExpr1 & lhs, [[maybe_unused]]
const TExpr2 & rhs)
1065 itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
1079template <
typename TExpr1,
typename TExpr2>
1080inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2>>>::Value,
unsigned int>
1081GetSize(
const TExpr1 & lhs,
const TExpr2 & itkNotUsed(rhs))
1095template <
typename TExpr1,
typename TExpr2>
1096inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1>>>::Value,
unsigned int>
1097GetSize(
const TExpr1 & itkNotUsed(lhs),
const TExpr2 & rhs)
1102template <
typename T>
1103struct GetType<VariableLengthVector<T>>
1107 Load(
const VariableLengthVector<T> & v,
unsigned int idx)
1112template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1113struct GetType<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>>
1115 using Type =
typename VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>::ResType;
1117 Load(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & v,
unsigned int idx)
1138template <
typename TExpr1,
typename TExpr2>
1139struct CanBeAddedOrSubtracted
1140 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>,
1141 mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1142 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1156template <
typename TExpr1,
typename TExpr2>
1157struct CanBeMultiplied
1158 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1159 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1173template <
typename TExpr1,
typename TExpr2>
1174struct CanBeDivided : mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>
1205template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1206struct VariableLengthVectorExpression
1208 VariableLengthVectorExpression(
const TExpr1 & lhs,
const TExpr2 & rhs)
1214 static_assert(std::is_base_of_v<Details::op::BinaryOperationConcept, TBinaryOp>,
1215 "The Binary Operation shall inherit from BinaryOperationConcept");
1219 [[nodiscard]]
unsigned int
1222 return Details::GetSize(m_lhs, m_rhs);
1227 typename mpl::PromoteType<typename Details::GetType<TExpr1>::Type,
typename Details::GetType<TExpr2>::Type>::Type;
1229 using RealValueType =
typename NumericTraits<ResType>::RealType;
1242 operator[](
unsigned int idx)
const
1244 itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
1245 return TBinaryOp::Apply(Details::GetType<TExpr1>::Load(m_lhs, idx), Details::GetType<TExpr2>::Load(m_rhs, idx));
1249 [[nodiscard]] RealValueType
1253 [[nodiscard]] RealValueType
1254 GetSquaredNorm()
const;
1257 const TExpr1 & m_lhs;
1258 const TExpr2 & m_rhs;
1270template <
typename TExpr1,
typename TExpr2>
1271inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1272 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>>
1273operator+(
const TExpr1 & lhs,
const TExpr2 & rhs)
1275 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>(lhs, rhs);
1287template <
typename TExpr1,
typename TExpr2>
1288inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1289 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>>
1290operator-(
const TExpr1 & lhs,
const TExpr2 & rhs)
1292 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>(lhs, rhs);
1303template <
typename TExpr1,
typename TExpr2>
1304inline std::enable_if_t<Details::op::CanBeMultiplied<TExpr1, TExpr2>::Value,
1305 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>>
1306operator*(
const TExpr1 & lhs,
const TExpr2 & rhs)
1308 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>(lhs, rhs);
1318template <
typename TExpr1,
typename TExpr2>
1319inline std::enable_if_t<Details::op::CanBeDivided<TExpr1, TExpr2>::Value,
1320 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>>
1321operator/(
const TExpr1 & lhs,
const TExpr2 & rhs)
1323 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>(lhs, rhs);
1329template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1331operator<<(std::ostream & os,
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & v)
1337 for (
unsigned int i = 1, N = v.Size(); i != N; ++i)
1350template <
typename TExpr>
1351inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1352GetNorm(
const TExpr & v)
1354 return static_cast<typename TExpr::RealValueType
>(std::sqrt(
static_cast<double>(GetSquaredNorm(v))));
1362template <
typename TExpr>
1363inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1364GetSquaredNorm(
const TExpr & v)
1366 using RealValueType =
typename TExpr::RealValueType;
1367 RealValueType sum = 0.0;
1368 for (
unsigned int i = 0, N = v.Size(); i < N; ++i)
1370 const RealValueType value = v[i];
1371 sum += value * value;
1381template <
typename TValue>
1385 const unsigned int length = arr.Size();
1386 const int last =
static_cast<unsigned int>(length) - 1;
1389 for (
int i = 0; i < last; ++i)
1391 os << arr[i] <<
", ";
1420template <
typename T>
1431#ifndef ITK_MANUAL_INSTANTIATION
1432# include "itkVariableLengthVector.hxx"
bool ITKIOXML_EXPORT operator==(itk::FancyString &s, const std::string &)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
void swap(Array< T > &a, Array< T > &b) noexcept
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
CovariantVector< T, VVectorDimension > operator*(const T &scalar, const CovariantVector< T, VVectorDimension > &v)
ConstNeighborhoodIterator< TImage > operator-(const ConstNeighborhoodIterator< TImage > &it, const typename ConstNeighborhoodIterator< TImage >::OffsetType &ind)
ConstNeighborhoodIterator< TImage > operator+(const ConstNeighborhoodIterator< TImage > &it, const typename ConstNeighborhoodIterator< TImage >::OffsetType &ind)