18#ifndef itkVariableLengthVector_h
19#define itkVariableLengthVector_h
33template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
34struct VariableLengthVectorExpression;
90template <
typename TValue>
91class ITK_TEMPLATE_EXPORT VariableLengthVector
110 struct AllocateRootPolicy
126 struct AlwaysReallocate : AllocateRootPolicy
129 operator()(
unsigned int itkNotUsed(newSize),
unsigned int itkNotUsed(oldSize))
const
153 struct NeverReallocate : AllocateRootPolicy
156 operator()([[maybe_unused]]
unsigned int newSize, [[maybe_unused]]
unsigned int oldSize)
const
158 itkAssertInDebugAndIgnoreInReleaseMacro(newSize == oldSize &&
159 "SetSize is expected to never change the VariableLengthVector size...");
182 struct ShrinkToFit : AllocateRootPolicy
185 operator()(
unsigned int newSize,
unsigned int oldSize)
const
187 return newSize != oldSize;
218 struct DontShrinkToFit : AllocateRootPolicy
221 operator()(
unsigned int newSize,
unsigned int oldSize)
const
223 return newSize > oldSize;
246 struct KeepValuesRootPolicy
270 struct KeepOldValues : KeepValuesRootPolicy
272 template <
typename TValue2>
274 operator()(
unsigned int newSize,
unsigned int oldSize, TValue2 * oldBuffer, TValue2 * newBuffer)
const
276 itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer);
277 const size_t nb = std::min(newSize, oldSize);
278 itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0 && oldBuffer !=
nullptr));
279 std::copy_n(oldBuffer, nb, newBuffer);
300 struct DumpOldValues : KeepValuesRootPolicy
302 template <
typename TValue2>
304 operator()(
unsigned int itkNotUsed(newSize),
305 unsigned int itkNotUsed(oldSize),
306 TValue2 * itkNotUsed(oldBuffer),
307 TValue2 * itkNotUsed(newBuffer))
const
315 using ValueType = TValue;
316 using ComponentType = TValue;
318 using Self = VariableLengthVector;
321 using ElementIdentifier =
unsigned int;
329 VariableLengthVector() =
default;
339 explicit VariableLengthVector(
unsigned int length);
354 VariableLengthVector(ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
375 VariableLengthVector(
const ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
396 template <
typename T>
397 VariableLengthVector(
const VariableLengthVector<T> & v)
399 m_NumElements = v.Size();
400 m_LetArrayManageMemory =
true;
401 if (m_NumElements != 0)
403 m_Data = this->AllocateElements(m_NumElements);
404 itkAssertInDebugAndIgnoreInReleaseMacro(m_Data !=
nullptr);
405 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
407 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
425 VariableLengthVector(
const VariableLengthVector<TValue> & v);
436 Swap(
Self & v)
noexcept
438 itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
440 swap(v.m_Data, m_Data);
441 swap(v.m_NumElements, m_NumElements);
452 VariableLengthVector(
Self && v)
noexcept;
463 operator=(
Self && v)
noexcept;
481 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
482 VariableLengthVector(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs);
503 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
505 operator=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs);
511 Fill(
const TValue & v);
525 template <
typename T>
527 operator=(
const VariableLengthVector<T> & v)
536 const ElementIdentifier N = v.Size();
537 this->SetSize(N, DontShrinkToFit(), DumpOldValues());
538 for (ElementIdentifier i = 0; i < N; ++i)
540 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
562 operator=(
const Self & v);
573 FastAssign(
const Self & v);
583 operator=(
const TValue & v);
589 return m_NumElements;
594 return m_NumElements;
597 GetNumberOfElements()
const
599 return m_NumElements;
605 operator[](
unsigned int i)
607 return this->m_Data[i];
612 operator[](
unsigned int i)
const
614 return this->m_Data[i];
619 GetElement(
unsigned int i)
const
626 SetElement(
unsigned int i,
const TValue & value)
664 template <
typename TReallocatePolicy,
typename TKeepValuesPolicy>
666 SetSize(
unsigned int sz, TReallocatePolicy reallocatePolicy, TKeepValuesPolicy keepValues);
679 SetSize(
unsigned int sz,
bool destroyExistingData =
true)
684 if (destroyExistingData)
686 SetSize(sz, AlwaysReallocate(), KeepOldValues());
690 SetSize(sz, ShrinkToFit(), KeepOldValues());
698 DestroyExistingData();
713 SetData(TValue * datain,
bool LetArrayManageMemory =
false);
730 SetData(TValue * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
742 ~VariableLengthVector();
759 Reserve(ElementIdentifier size);
767 AllocateElements(ElementIdentifier size)
const;
770 GetDataPointer()
const
780 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
782 this->m_Data[i] -=
static_cast<ValueType
>(1.0);
792 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
794 this->m_Data[i] +=
static_cast<ValueType
>(1.0);
831 template <
typename T>
833 operator-=(
const VariableLengthVector<T> & v)
835 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
836 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
838 m_Data[i] -=
static_cast<ValueType
>(v[i]);
848 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
864 template <
typename T>
866 operator+=(
const VariableLengthVector<T> & v)
868 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
869 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
871 m_Data[i] +=
static_cast<ValueType
>(v[i]);
881 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
898 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
900 operator+=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs)
902 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
903 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
905 m_Data[i] +=
static_cast<ValueType
>(rhs[i]);
920 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
922 operator-=(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & rhs)
924 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
925 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
927 m_Data[i] -=
static_cast<ValueType
>(rhs[i]);
938 template <
typename T>
942 const ValueType & sc =
static_cast<ValueType
>(s);
943 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
957 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
971 template <
typename T>
975 const RealValueType sc = s;
976 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
978 m_Data[i] =
static_cast<ValueType
>(
static_cast<RealValueType
>(m_Data[i]) / sc);
994 ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(
Self);
1002 GetSquaredNorm()
const;
1008 return !m_LetArrayManageMemory;
1012 bool m_LetArrayManageMemory{
true };
1015 ElementIdentifier m_NumElements{ 0 };
1030template <
typename T>
1031struct IsArray : FalseType
1035template <
typename T>
1036struct IsArray<
itk::VariableLengthVector<T>> : TrueType
1039template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1040struct IsArray<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>> : TrueType
1061template <
typename TExpr>
1070 Load(
const Type & v,
unsigned int itkNotUsed(idx))
1087template <
typename TExpr1,
typename TExpr2>
1088inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>::Value,
unsigned int>
1089GetSize(
const TExpr1 & lhs, [[maybe_unused]]
const TExpr2 & rhs)
1091 itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
1106template <
typename TExpr1,
typename TExpr2>
1107inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2>>>::Value,
unsigned int>
1108GetSize(
const TExpr1 & lhs,
const TExpr2 & itkNotUsed(rhs))
1122template <
typename TExpr1,
typename TExpr2>
1123inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1>>>::Value,
unsigned int>
1124GetSize(
const TExpr1 & itkNotUsed(lhs),
const TExpr2 & rhs)
1129template <
typename T>
1130struct GetType<VariableLengthVector<T>>
1134 Load(
const VariableLengthVector<T> & v,
unsigned int idx)
1139template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1140struct GetType<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>>
1142 using Type =
typename VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>::ResType;
1144 Load(
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & v,
unsigned int idx)
1165template <
typename TExpr1,
typename TExpr2>
1166struct CanBeAddedOrSubtracted
1167 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>,
1168 mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1169 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1183template <
typename TExpr1,
typename TExpr2>
1184struct CanBeMultiplied
1185 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1186 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1200template <
typename TExpr1,
typename TExpr2>
1201struct CanBeDivided : mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>
1232template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1233struct VariableLengthVectorExpression
1235 VariableLengthVectorExpression(
const TExpr1 & lhs,
const TExpr2 & rhs)
1241 static_assert(std::is_base_of_v<Details::op::BinaryOperationConcept, TBinaryOp>,
1242 "The Binary Operation shall inherit from BinaryOperationConcept");
1249 return Details::GetSize(m_lhs, m_rhs);
1254 typename mpl::PromoteType<typename Details::GetType<TExpr1>::Type,
typename Details::GetType<TExpr2>::Type>::Type;
1269 operator[](
unsigned int idx)
const
1271 itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
1272 return TBinaryOp::Apply(Details::GetType<TExpr1>::Load(m_lhs, idx), Details::GetType<TExpr2>::Load(m_rhs, idx));
1282 GetSquaredNorm()
const;
1285 const TExpr1 & m_lhs;
1286 const TExpr2 & m_rhs;
1298template <
typename TExpr1,
typename TExpr2>
1299inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1300 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>>
1301operator+(
const TExpr1 & lhs,
const TExpr2 & rhs)
1303 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>(lhs, rhs);
1315template <
typename TExpr1,
typename TExpr2>
1316inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1317 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>>
1318operator-(
const TExpr1 & lhs,
const TExpr2 & rhs)
1320 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>(lhs, rhs);
1331template <
typename TExpr1,
typename TExpr2>
1332inline std::enable_if_t<Details::op::CanBeMultiplied<TExpr1, TExpr2>::Value,
1333 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>>
1334operator*(
const TExpr1 & lhs,
const TExpr2 & rhs)
1336 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>(lhs, rhs);
1346template <
typename TExpr1,
typename TExpr2>
1347inline std::enable_if_t<Details::op::CanBeDivided<TExpr1, TExpr2>::Value,
1348 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>>
1349operator/(
const TExpr1 & lhs,
const TExpr2 & rhs)
1351 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>(lhs, rhs);
1357template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1359operator<<(std::ostream & os,
const VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp> & v)
1365 for (
unsigned int i = 1, N = v.Size(); i != N; ++i)
1379template <
typename TExpr>
1380inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1381GetNorm(
const TExpr & v)
1383 return static_cast<typename TExpr::RealValueType
>(std::sqrt(
static_cast<double>(GetSquaredNorm(v))));
1391template <
typename TExpr>
1392inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1393GetSquaredNorm(
const TExpr & v)
1395 using RealValueType =
typename TExpr::RealValueType;
1396 RealValueType sum = 0.0;
1397 for (
unsigned int i = 0, N = v.Size(); i < N; ++i)
1399 const RealValueType value = v[i];
1400 sum += value * value;
1412template <
typename TValue>
1414operator<<(std::ostream & os,
const VariableLengthVector<TValue> & arr)
1416 const unsigned int length = arr.Size();
1417 const int last =
static_cast<unsigned int>(length) - 1;
1421 for (
int i = 0; i < last; ++i)
1423 os << arr[i] <<
", ";
1454template <
typename T>
1456swap(VariableLengthVector<T> & l_, VariableLengthVector<T> & r_)
noexcept
1467#ifndef ITK_MANUAL_INSTANTIATION
1468# include "itkVariableLengthVector.hxx"
Pixel-wise addition of two images.
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)
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
ConstNeighborhoodIterator< TImage > operator+(const ConstNeighborhoodIterator< TImage > &it, const typename ConstNeighborhoodIterator< TImage >::OffsetType &ind)