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
154 struct NeverReallocate : AllocateRootPolicy
157 operator()(
unsigned int newSize,
unsigned int oldSize)
const
161 itkAssertInDebugAndIgnoreInReleaseMacro(newSize == oldSize &&
162 "SetSize is expected to never change the VariableLengthVector size...");
185 struct ShrinkToFit : AllocateRootPolicy
188 operator()(
unsigned int newSize,
unsigned int oldSize)
const
190 return newSize != oldSize;
221 struct DontShrinkToFit : AllocateRootPolicy
224 operator()(
unsigned int newSize,
unsigned int oldSize)
const
226 return newSize > oldSize;
249 struct KeepValuesRootPolicy
273 struct KeepOldValues : KeepValuesRootPolicy
275 template <
typename TValue2>
277 operator()(
unsigned int newSize,
unsigned int oldSize, TValue2 * oldBuffer, TValue2 * newBuffer)
const
279 itkAssertInDebugAndIgnoreInReleaseMacro(newBuffer);
280 const size_t nb = std::min(newSize, oldSize);
281 itkAssertInDebugAndIgnoreInReleaseMacro(nb == 0 || (nb > 0 && oldBuffer !=
nullptr));
282 std::copy_n(oldBuffer, nb, newBuffer);
303 struct DumpOldValues : KeepValuesRootPolicy
305 template <
typename TValue2>
307 operator()(
unsigned int itkNotUsed(newSize),
308 unsigned int itkNotUsed(oldSize),
309 TValue2 * itkNotUsed(oldBuffer),
310 TValue2 * itkNotUsed(newBuffer))
const
318 using ValueType = TValue;
319 using ComponentType = TValue;
321 using Self = VariableLengthVector;
324 using ElementIdentifier =
unsigned int;
332 VariableLengthVector() =
default;
342 explicit VariableLengthVector(
unsigned int length);
357 VariableLengthVector(ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
378 VariableLengthVector(
const ValueType * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
399 template <
typename T>
400 VariableLengthVector(
const VariableLengthVector<T> & v)
402 m_NumElements = v.Size();
403 m_LetArrayManageMemory =
true;
404 if (m_NumElements != 0)
406 m_Data = this->AllocateElements(m_NumElements);
407 itkAssertInDebugAndIgnoreInReleaseMacro(m_Data !=
nullptr);
408 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
410 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
428 VariableLengthVector(
const VariableLengthVector<TValue> & v);
439 Swap(
Self & v)
noexcept
441 itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
443 swap(v.m_Data, m_Data);
444 swap(v.m_NumElements, m_NumElements);
455 VariableLengthVector(
Self && v)
noexcept;
466 operator=(
Self && v)
noexcept;
484 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
485 VariableLengthVector(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & rhs);
506 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
508 operator=(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & rhs);
514 Fill(TValue
const & v);
528 template <
typename T>
530 operator=(
const VariableLengthVector<T> & v)
539 ElementIdentifier
const N = v.Size();
540 this->SetSize(N, DontShrinkToFit(), DumpOldValues());
541 for (ElementIdentifier i = 0; i < N; ++i)
543 this->m_Data[i] =
static_cast<ValueType
>(v[i]);
565 operator=(
const Self & v);
576 FastAssign(
const Self & v);
586 operator=(TValue
const & v);
592 return m_NumElements;
597 return m_NumElements;
600 GetNumberOfElements()
const
602 return m_NumElements;
607 TValue & operator[](
unsigned int i) {
return this->m_Data[i]; }
610 TValue
const & operator[](
unsigned int i)
const {
return this->m_Data[i]; }
614 GetElement(
unsigned int i)
const
621 SetElement(
unsigned int i,
const TValue & value)
659 template <
typename TReallocatePolicy,
typename TKeepValuesPolicy>
661 SetSize(
unsigned int sz, TReallocatePolicy reallocatePolicy, TKeepValuesPolicy keepValues);
674 SetSize(
unsigned int sz,
bool destroyExistingData =
true)
679 if (destroyExistingData)
681 SetSize(sz, AlwaysReallocate(), KeepOldValues());
685 SetSize(sz, ShrinkToFit(), KeepOldValues());
693 DestroyExistingData();
708 SetData(TValue * datain,
bool LetArrayManageMemory =
false);
725 SetData(TValue * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
737 ~VariableLengthVector();
754 Reserve(ElementIdentifier size);
762 AllocateElements(ElementIdentifier size)
const;
765 GetDataPointer()
const
775 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
777 this->m_Data[i] -=
static_cast<ValueType
>(1.0);
787 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
789 this->m_Data[i] +=
static_cast<ValueType
>(1.0);
826 template <
typename T>
828 operator-=(
const VariableLengthVector<T> & v)
830 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
831 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
833 m_Data[i] -=
static_cast<ValueType
>(v[i]);
843 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
859 template <
typename T>
861 operator+=(
const VariableLengthVector<T> & v)
863 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.GetSize());
864 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
866 m_Data[i] +=
static_cast<ValueType
>(v[i]);
876 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
893 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
895 operator+=(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & rhs)
897 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
898 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
900 m_Data[i] +=
static_cast<ValueType
>(rhs[i]);
915 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
917 operator-=(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & rhs)
919 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() == Size());
920 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
922 m_Data[i] -=
static_cast<ValueType
>(rhs[i]);
933 template <
typename T>
937 const ValueType & sc =
static_cast<ValueType
>(s);
938 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
952 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
966 template <
typename T>
970 const RealValueType sc = s;
971 for (ElementIdentifier i = 0; i < m_NumElements; ++i)
973 m_Data[i] =
static_cast<ValueType
>(
static_cast<RealValueType
>(m_Data[i]) / sc);
989 ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(
Self);
997 GetSquaredNorm()
const;
1003 return !m_LetArrayManageMemory;
1007 bool m_LetArrayManageMemory{
true };
1010 ElementIdentifier m_NumElements{ 0 };
1025template <
typename T>
1026struct IsArray : FalseType
1030template <
typename T>
1031struct IsArray<
itk::VariableLengthVector<T>> : TrueType
1034template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1035struct IsArray<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>> : TrueType
1056template <
typename TExpr>
1065 Load(Type
const & v,
unsigned int idx)
1083template <
typename TExpr1,
typename TExpr2>
1084inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>::Value,
unsigned int>
1085GetSize(TExpr1
const & lhs, TExpr2
const & rhs)
1088 itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
1103template <
typename TExpr1,
typename TExpr2>
1104inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2>>>::Value,
unsigned int>
1105GetSize(TExpr1
const & lhs, TExpr2
const & itkNotUsed(rhs))
1119template <
typename TExpr1,
typename TExpr2>
1120inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1>>>::Value,
unsigned int>
1121GetSize(TExpr1
const & itkNotUsed(lhs), TExpr2
const & rhs)
1126template <
typename T>
1127struct GetType<VariableLengthVector<T>>
1131 Load(VariableLengthVector<T>
const & v,
unsigned int idx)
1136template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1137struct GetType<VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>>
1139 using Type =
typename VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>::ResType;
1141 Load(VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & v,
unsigned int idx)
1162template <
typename TExpr1,
typename TExpr2>
1163struct CanBeAddedOrSubtracted
1164 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>,
1165 mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1166 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1180template <
typename TExpr1,
typename TExpr2>
1181struct CanBeMultiplied
1182 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1183 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1197template <
typename TExpr1,
typename TExpr2>
1198struct CanBeDivided : mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>
1229template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1230struct VariableLengthVectorExpression
1232 VariableLengthVectorExpression(TExpr1
const & lhs, TExpr2
const & rhs)
1238 static_assert(std::is_base_of_v<Details::op::BinaryOperationConcept, TBinaryOp>,
1239 "The Binary Operation shall inherit from BinaryOperationConcept");
1246 return Details::GetSize(m_lhs, m_rhs);
1251 typename mpl::PromoteType<typename Details::GetType<TExpr1>::Type,
typename Details::GetType<TExpr2>::Type>::Type;
1265 ResType operator[](
unsigned int idx)
const
1267 itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
1268 return TBinaryOp::Apply(Details::GetType<TExpr1>::Load(m_lhs, idx), Details::GetType<TExpr2>::Load(m_rhs, idx));
1278 GetSquaredNorm()
const;
1281 TExpr1
const & m_lhs;
1282 TExpr2
const & m_rhs;
1294template <
typename TExpr1,
typename TExpr2>
1295inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1296 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>>
1297operator+(TExpr1
const & lhs, TExpr2
const & rhs)
1299 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Plus>(lhs, rhs);
1311template <
typename TExpr1,
typename TExpr2>
1312inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1313 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>>
1314operator-(TExpr1
const & lhs, TExpr2
const & rhs)
1316 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Sub>(lhs, rhs);
1327template <
typename TExpr1,
typename TExpr2>
1328inline std::enable_if_t<Details::op::CanBeMultiplied<TExpr1, TExpr2>::Value,
1329 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>>
1330operator*(TExpr1
const & lhs, TExpr2
const & rhs)
1332 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Mult>(lhs, rhs);
1342template <
typename TExpr1,
typename TExpr2>
1343inline std::enable_if_t<Details::op::CanBeDivided<TExpr1, TExpr2>::Value,
1344 VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>>
1345operator/(TExpr1
const & lhs, TExpr2
const & rhs)
1347 return VariableLengthVectorExpression<TExpr1, TExpr2, Details::op::Div>(lhs, rhs);
1353template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1355operator<<(std::ostream & os, VariableLengthVectorExpression<TExpr1, TExpr2, TBinaryOp>
const & v)
1361 for (
unsigned int i = 1, N = v.Size(); i != N; ++i)
1375template <
typename TExpr>
1376inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1377GetNorm(TExpr
const & v)
1379 return static_cast<typename TExpr::RealValueType
>(std::sqrt(
static_cast<double>(GetSquaredNorm(v))));
1387template <
typename TExpr>
1388inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1389GetSquaredNorm(TExpr
const & v)
1391 using RealValueType =
typename TExpr::RealValueType;
1392 RealValueType sum = 0.0;
1393 for (
unsigned int i = 0, N = v.Size(); i < N; ++i)
1395 const RealValueType value = v[i];
1396 sum += value * value;
1408template <
typename TValue>
1410operator<<(std::ostream & os,
const VariableLengthVector<TValue> & arr)
1412 const unsigned int length = arr.Size();
1413 const int last =
static_cast<unsigned int>(length) - 1;
1417 for (
int i = 0; i < last; ++i)
1419 os << arr[i] <<
", ";
1450template <
typename T>
1452swap(VariableLengthVector<T> & l_, VariableLengthVector<T> & r_)
noexcept
1463#ifndef ITK_MANUAL_INSTANTIATION
1464# 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)
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)
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
ConstNeighborhoodIterator< TImage > operator+(const ConstNeighborhoodIterator< TImage > &it, const typename ConstNeighborhoodIterator< TImage >::OffsetType &ind)