18 #ifndef itkVariableLengthVector_h
19 #define itkVariableLengthVector_h
23 #include <type_traits>
33 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
90 template <
typename TValue>
129 operator()(
unsigned int itkNotUsed(newSize),
unsigned int itkNotUsed(oldSize))
const
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...");
187 return newSize != oldSize;
223 return newSize > oldSize;
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);
302 template <
typename TValue2>
305 unsigned int itkNotUsed(oldSize),
306 TValue2 * itkNotUsed(oldBuffer),
307 TValue2 * itkNotUsed(newBuffer))
const
396 template <
typename T>
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);
407 this->m_Data[i] = static_cast<ValueType>(v[i]);
438 itkAssertInDebugAndIgnoreInReleaseMacro(m_LetArrayManageMemory == v.m_LetArrayManageMemory);
440 swap(v.m_Data, m_Data);
441 swap(v.m_NumElements, m_NumElements);
463 operator=(
Self && v) noexcept;
481 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
503 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
511 Fill(TValue
const & v);
525 template <
typename T>
540 this->m_Data[i] = static_cast<ValueType>(v[i]);
562 operator=(
const Self & v);
573 FastAssign(
const Self & v);
583 operator=(TValue
const & v);
589 return m_NumElements;
594 return m_NumElements;
599 return m_NumElements;
604 TValue &
operator[](
unsigned int i) {
return this->m_Data[i]; }
607 TValue
const &
operator[](
unsigned int i)
const {
return this->m_Data[i]; }
656 template <
typename TReallocatePolicy,
typename TKeepValuesPolicy>
658 SetSize(
unsigned int sz, TReallocatePolicy reallocatePolicy, TKeepValuesPolicy keepValues);
671 SetSize(
unsigned int sz,
bool destroyExistingData =
true)
676 if (destroyExistingData)
690 DestroyExistingData();
705 SetData(TValue * datain,
bool LetArrayManageMemory =
false);
722 SetData(TValue * datain,
unsigned int sz,
bool LetArrayManageMemory =
false);
751 Reserve(ElementIdentifier size);
759 AllocateElements(ElementIdentifier size)
const;
774 this->m_Data[i] -= static_cast<ValueType>(1.0);
786 this->m_Data[i] += static_cast<ValueType>(1.0);
823 template <
typename T>
827 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.
GetSize());
830 m_Data[i] -= static_cast<ValueType>(v[i]);
856 template <
typename T>
860 itkAssertInDebugAndIgnoreInReleaseMacro(m_NumElements == v.
GetSize());
863 m_Data[i] += static_cast<ValueType>(v[i]);
890 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
894 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() ==
Size());
897 m_Data[i] += static_cast<ValueType>(rhs[i]);
912 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
916 itkAssertInDebugAndIgnoreInReleaseMacro(rhs.Size() ==
Size());
919 m_Data[i] -= static_cast<ValueType>(rhs[i]);
930 template <
typename T>
934 const ValueType & sc = static_cast<ValueType>(s);
963 template <
typename T>
970 m_Data[i] = static_cast<ValueType>(static_cast<RealValueType>(m_Data[i]) / sc);
986 ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(
Self);
994 GetSquaredNorm()
const;
1000 return !m_LetArrayManageMemory;
1004 bool m_LetArrayManageMemory{
true };
1022 template <
typename T>
1023 struct IsArray : FalseType
1027 template <
typename T>
1028 struct IsArray<
itk::VariableLengthVector<T>> : TrueType
1031 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1053 template <
typename TExpr>
1062 Load(Type
const & v,
unsigned int itkNotUsed(idx))
1079 template <
typename TExpr1,
typename TExpr2>
1080 inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>::Value,
unsigned int>
1081 GetSize(TExpr1
const & lhs, [[maybe_unused]] TExpr2
const & rhs)
1083 itkAssertInDebugAndIgnoreInReleaseMacro(lhs.Size() == rhs.Size());
1098 template <
typename TExpr1,
typename TExpr2>
1099 inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr1>, mpl::Not<mpl::IsArray<TExpr2>>>::Value,
unsigned int>
1100 GetSize(TExpr1
const & lhs, TExpr2
const & itkNotUsed(rhs))
1114 template <
typename TExpr1,
typename TExpr2>
1115 inline std::enable_if_t<mpl::And<mpl::IsArray<TExpr2>, mpl::Not<mpl::IsArray<TExpr1>>>::Value,
unsigned int>
1116 GetSize(TExpr1
const & itkNotUsed(lhs), TExpr2
const & rhs)
1121 template <
typename T>
1122 struct GetType<VariableLengthVector<T>>
1126 Load(VariableLengthVector<T>
const & v,
unsigned int idx)
1131 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1157 template <
typename TExpr1,
typename TExpr2>
1159 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsArray<TExpr2>>,
1160 mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1161 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1175 template <
typename TExpr1,
typename TExpr2>
1177 : mpl::Or<mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>,
1178 mpl::And<mpl::IsNumber<TExpr1>, mpl::IsArray<TExpr2>>>
1192 template <
typename TExpr1,
typename TExpr2>
1193 struct CanBeDivided : mpl::And<mpl::IsArray<TExpr1>, mpl::IsNumber<TExpr2>>
1224 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1233 static_assert(std::is_base_of_v<Details::op::BinaryOperationConcept, TBinaryOp>,
1234 "The Binary Operation shall inherit from BinaryOperationConcept");
1241 return Details::GetSize(m_lhs, m_rhs);
1246 typename mpl::PromoteType<typename Details::GetType<TExpr1>::Type,
typename Details::GetType<TExpr2>::Type>::Type;
1262 itkAssertInDebugAndIgnoreInReleaseMacro(idx < Size());
1263 return TBinaryOp::Apply(Details::GetType<TExpr1>::Load(m_lhs, idx), Details::GetType<TExpr2>::Load(m_rhs, idx));
1289 template <
typename TExpr1,
typename TExpr2>
1290 inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1306 template <
typename TExpr1,
typename TExpr2>
1307 inline std::enable_if_t<Details::op::CanBeAddedOrSubtracted<TExpr1, TExpr2>::Value,
1322 template <
typename TExpr1,
typename TExpr2>
1323 inline std::enable_if_t<Details::op::CanBeMultiplied<TExpr1, TExpr2>::Value,
1337 template <
typename TExpr1,
typename TExpr2>
1338 inline std::enable_if_t<Details::op::CanBeDivided<TExpr1, TExpr2>::Value,
1348 template <
typename TExpr1,
typename TExpr2,
typename TBinaryOp>
1356 for (
unsigned int i = 1, N = v.Size(); i != N; ++i)
1370 template <
typename TExpr>
1371 inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1374 return static_cast<typename TExpr::RealValueType>(std::sqrt(static_cast<double>(GetSquaredNorm(v))));
1382 template <
typename TExpr>
1383 inline std::enable_if_t<mpl::IsArray<TExpr>::Value,
typename TExpr::RealValueType>
1386 using RealValueType =
typename TExpr::RealValueType;
1387 RealValueType sum = 0.0;
1388 for (
unsigned int i = 0, N = v.Size(); i < N; ++i)
1390 const RealValueType value = v[i];
1391 sum += value * value;
1403 template <
typename TValue>
1407 const unsigned int length = arr.
Size();
1408 const int last = static_cast<unsigned int>(length) - 1;
1412 for (
int i = 0; i < last; ++i)
1414 os << arr[i] <<
", ";
1445 template <
typename T>
1458 #ifndef ITK_MANUAL_INSTANTIATION
1459 # include "itkVariableLengthVector.hxx"