/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkNumericTraitsFixedArrayPixel_h #define itkNumericTraitsFixedArrayPixel_h #include "itkNumericTraits.h" #include "itkFixedArray.h" namespace itk { /** * \brief Define numeric traits for FixedArray. * \tparam T Component type of the FixedArray * \tparam D Dimension of the FixedArray * * We provide here a generic implementation based on creating types of * FixedArray whose components are the types of the NumericTraits from * the original FixedArray components. This implementation require * support for partial specializations, since it is based on the * concept that: * NumericTraits > is defined piecewise by * FixedArray< NumericTraits< T > > * * \sa NumericTraits * \ingroup DataRepresentation * \ingroup ITKCommon */ template class NumericTraits> { private: using ElementAbsType = typename NumericTraits::AbsType; using ElementAccumulateType = typename NumericTraits::AccumulateType; using ElementFloatType = typename NumericTraits::FloatType; using ElementPrintType = typename NumericTraits::PrintType; using ElementRealType = typename NumericTraits::RealType; public: /** Return the type of the native component type. */ using ValueType = T; using Self = FixedArray; /** Unsigned component type */ using AbsType = FixedArray; /** Accumulation of addition and multiplication. */ using AccumulateType = FixedArray; /** Typedef for operations that use floating point instead of real precision */ using FloatType = FixedArray; /** Return the type that can be printed. */ using PrintType = FixedArray; /** Type for real-valued scalar operations. */ using RealType = FixedArray; /** Type for real-valued scalar operations. */ using ScalarRealType = ElementRealType; /** Measurement vector type */ using MeasurementVectorType = Self; /** Component wise defined element * * \note minimum value for floating pointer types is defined as * minimum positive normalize value. */ static const Self max(const Self &) { return MakeFilled(NumericTraits::max()); } static const Self min(const Self &) { return MakeFilled(NumericTraits::min()); } static const Self max() { return MakeFilled(NumericTraits::max()); } static const Self min() { return MakeFilled(NumericTraits::min()); } static const Self NonpositiveMin() { return MakeFilled(NumericTraits::NonpositiveMin()); } static const Self ZeroValue() { return Self{}; } static const Self OneValue() { return MakeFilled(NumericTraits::OneValue()); } static const Self NonpositiveMin(const Self &) { return NonpositiveMin(); } static const Self ZeroValue(const Self &) { return ZeroValue(); } static const Self OneValue(const Self &) { return OneValue(); } /** Fixed length vectors cannot be resized, so an exception will * be thrown if the input size is not valid. If the size is valid * the vector will be filled with zeros. */ static void SetLength(FixedArray & m, const unsigned int s) { if (s != D) { itkGenericExceptionMacro("Cannot set the size of a FixedArray of length " << D << " to " << s); } m.Fill(T{}); } /** Return the length of the array. */ static unsigned int GetLength(const FixedArray &) { return D; } /** Return the length of the array. */ static unsigned int GetLength() { return D; } static void AssignToArray(const Self & v, MeasurementVectorType & mv) { mv = v; } template static void AssignToArray(const Self & v, TArray & mv) { for (unsigned int i = 0; i < D; ++i) { mv[i] = v[i]; } } /** \note: the functions are preferred over the member variables as * they are defined for all partial specialization */ static const Self ITKCommon_EXPORT Zero; static const Self ITKCommon_EXPORT One; }; // a macro to define and initialize static member variables, // NOTE: (T)(NumericTraits< T >::[Zero|One]) is needed to generate // a temporary variable that is initialized from the // constexpr [Zero|One] to be passed by const reference // to the GENERIC_ARRAY constructor. #define itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, D) \ template <> \ ITKCommon_EXPORT const GENERIC_ARRAY NumericTraits>::Zero = \ MakeFilled>(NumericTraits::Zero); \ template <> \ ITKCommon_EXPORT const GENERIC_ARRAY NumericTraits>::One = \ MakeFilled>(NumericTraits::One); // // List here the array dimension specializations of these static // Traits: // #define itkStaticNumericTraitsGenericArrayDimensionsMacro(GENERIC_ARRAY, T) \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 1); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 2); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 3); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 4); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 5); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 6); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 7); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 8); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 9); \ itkStaticNumericTraitsGenericArrayMacro(GENERIC_ARRAY, T, 10); } // end namespace itk #endif // itkNumericTraitsFixedArrayPixel_h