1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkNumericTraits_h
19 #define itkNumericTraits_h
20 
21 #include "itkMacro.h"
22 
23 #undef min
24 #undef max
25 
26 #define itkNUMERIC_TRAITS_MIN_MAX_MACRO()          \
27   static constexpr ValueType min(ValueType)         \
28     {                                              \
29     return std::numeric_limits< ValueType >::min(); \
30     }                                              \
31   static constexpr ValueType max(ValueType)         \
32     {                                              \
33     return std::numeric_limits< ValueType >::max(); \
34     }                                              \
35   static constexpr ValueType min()                  \
36     {                                              \
37     return std::numeric_limits< ValueType >::min(); \
38     }                                              \
39   static constexpr ValueType max()                  \
40     {                                              \
41     return std::numeric_limits< ValueType >::max(); \
42     }
43 
44 #include <limits> // for std::numeric_limits
45 #include <complex>
46 
47 namespace itk
48 {
49 
50 // forward decare to avoid circular dependencies
51 template< typename TValue, unsigned int VLength>  class FixedArray;
52 
53 /** \class NumericTraits
54  * \brief Define additional traits for native types such as int or float.
55  *
56  * NumericTraits is used to extend the traits associated with native types
57  * such as float, char, int, and so on. These traits are extensions of the
58  * standard numeric_limits defined by the C++ compilers. Some of the added
59  * traits include minimum and maximum value; accumulation type; etc.
60  *
61  * \ingroup DataRepresentation
62  * \ingroup ITKCommon
63  *
64  * \wiki
65  * \wikiexample{SimpleOperations/NumericTraits,Get some basic information about a type}
66  * \endwiki
67  */
68 template< typename T >
69 class NumericTraits:public std::numeric_limits< T >
70 {
71 public:
72   /** The type of this limits trait object. */
73   using TraitsType = std::numeric_limits< T >;
74 
75   /** Return the type of this native type. */
76   using ValueType = T;
77 
78   /** Return the type that can be printed. */
79   using PrintType = T;
80 
81   /** Return value of std::abs(). */
82   using AbsType = T;
83 
84   /** Accumulation of addition and multiplication. */
85   using AccumulateType = double;
86 
87   /** Measurement vector type */
88   using MeasurementVectorType = FixedArray<ValueType, 1>;
89 
90   /** Typedef for operations that use floating point instead of real precision
91    *  to save memory */
92   using FloatType = float;
93 
94   /** Type for real-valued scalar operations. */
95   using RealType = double;
96 
97   /** Type for real-valued scalar operations. */
98   using ScalarRealType = RealType;
99 
100   /** Additive identity. */
101   static const T ITKCommon_EXPORT Zero;
102 
103   /** Multiplicative identity. */
104   static const T ITKCommon_EXPORT One;
105 
106   /** Smallest (most nonpositive) value */
NonpositiveMin()107   static constexpr T NonpositiveMin() { return TraitsType::lowest(); }
108 
109   /** Is a given value positive? */
IsPositive(T val)110   static bool IsPositive(T val) { return val > Zero; }
111 
112   /** Is a given value nonpositive? */
IsNonpositive(T val)113   static bool IsNonpositive(T val) { return val <= Zero; }
114 
115   /** Is a given value negative? */
IsNegative(T val)116   static bool IsNegative(T val) { return val < Zero; }
117 
118   /** Is a given value nonnegative? */
IsNonnegative(T val)119   static bool IsNonnegative(T val) { return val >= Zero; }
120 
121   /** Is a given type signed? -- default is no.
122       For uniform array data types in ITK, the value of IsSigned
123       is determined by the component elements of the array.*/
124   static constexpr bool IsSigned = false;
125 
126   /** Is a given type an integer? -- default is no.
127       For uniform array data types in ITK, the value of IsInteger
128       is determined by the component elements of the array.*/
129   static constexpr bool IsInteger = false;
130 
131   /** Is a given type complex? -- default is no.
132       For uniform array data types in ITK, the value of IsComplex
133       is determined by the component elements of the array.*/
134   static constexpr bool IsComplex = false;
135 
136   /** Return zero value. This function should be used to support
137    *  RGBPixel type and standard types (not vectors) */
ZeroValue()138   static T ZeroValue() { return Zero; }
139 
140   /** Return one value. This function should be used to support
141    *  RGBPixel type and standard types (not vectors) */
OneValue()142   static T OneValue() { return One; }
143 
144   /* Provide a default implementation of the max() method with
145    * argument. This API is needed for VariableLengthVector because
146    * its length is only known at run-time. Specializations of the
147    * VariableLengthVector will provide a different implementation
148    * where a vector of the correct size is built. */
max(const T &)149   static constexpr T max(const T &) { return TraitsType::max(); }
min(const T &)150   static constexpr T min(const T &) { return TraitsType::min(); }
151 
152   /** Scalars cannot be resized, so an exception will
153    * be thrown if the input size is not 1.  If the size is valid
154    * the will be zeros. This API is needed for VariableLengthVector because
155    * its length is only known at run-time. Specializations of the
156    * VariableLengthVector will provide a different implementation
157    * where a vector of the correct size is built.
158    */
SetLength(T & m,const unsigned int s)159   static void SetLength(T & m, const unsigned int s)
160   {
161     if ( s != 1 )
162       {
163       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
164       }
165     m = NumericTraits< ValueType >::ZeroValue();
166   }
167   /** Return the length of the scalar. This API is needed for
168    * VariableLengthVector because
169    * its length is only known at run-time. Specializations of the
170    * VariableLengthVector will provide a different implementation
171    * where a vector of the correct size is built.
172    */
GetLength(const T &)173   static unsigned int GetLength(const T &)
174   {
175     return GetLength();
176   }
177 
178   /** Return the length of the scalar: 1. Array types can return a different value */
GetLength()179   static unsigned int GetLength()
180   {
181     return 1;
182   }
183 
184   /** Smallest (most nonpositive) value. This API is needed for
185    * VariableLengthVector because its length is only known at run-time.
186    */
NonpositiveMin(const T &)187   static T NonpositiveMin(const T &)
188   {
189     return NonpositiveMin();
190   }
191 
192   /** Zero value. This API is needed for
193    * VariableLengthVector because its length is only known at run-time.
194    */
ZeroValue(const T &)195   static T ZeroValue(const T &)
196   {
197     return ZeroValue();
198   }
199 
200   /** One value. This API is needed for
201    * VariableLengthVector because its length is only known at run-time.
202    */
OneValue(const T &)203   static T OneValue(const T &)
204   {
205     return OneValue();
206   }
207 
208   /** assign the value to an array */
209   template<typename TArray>
AssignToArray(const T & v,TArray & mv)210   static void AssignToArray( const T & v, TArray & mv )
211   {
212     mv[0] = v;
213   }
214 
215 };
216 
217 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION
218 
219 /** \class NumericTraits<bool>
220  * \brief Define traits for type bool.
221  *
222  * \ingroup DataRepresentation
223  * \ingroup ITKCommon
224  */
225 
226 template< >
227 class NumericTraits< bool > :public std::numeric_limits< bool >
228 {
229 public:
230   using ValueType = bool;
231   using PrintType = bool;
232   using AbsType = unsigned char;
233   using AccumulateType = unsigned char;
234   using RealType = double;
235   using ScalarRealType = RealType;
236   using FloatType = float;
237   using MeasurementVectorType = FixedArray<ValueType, 1>;
238 
239   static constexpr bool ITKCommon_EXPORT Zero = false;
240   static constexpr bool ITKCommon_EXPORT One = true;
241 
min()242   static constexpr bool min() { return false; }
max()243   static constexpr bool max() { return true; }
min(bool)244   static constexpr bool min(bool) { return min(); }
max(bool)245   static constexpr bool max(bool) { return max(); }
NonpositiveMin()246   static constexpr bool NonpositiveMin() { return false; }
IsPositive(bool val)247   static constexpr bool IsPositive(bool val) { return val; }
IsNonpositive(bool val)248   static constexpr bool IsNonpositive(bool val) { return !val; }
IsNegative(bool val)249   static constexpr bool IsNegative(bool val) { return val ? false : false; }
IsNonnegative(bool val)250   static constexpr bool IsNonnegative(bool val) { return val ? true : true; }
251   static constexpr bool IsSigned = false;
252   static constexpr bool IsInteger = true;
253   static constexpr bool IsComplex = false;
ZeroValue()254   static constexpr bool ZeroValue() { return Zero; }
OneValue()255   static constexpr bool OneValue() { return One; }
GetLength(const ValueType &)256   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()257   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)258   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)259   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)260   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
261 
262   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)263   static void AssignToArray( const ValueType & v, TArray & mv )
264   {
265     mv[0] = v;
266   }
SetLength(ValueType & m,const unsigned int s)267   static void SetLength(ValueType & m, const unsigned int s)
268   {
269     if ( s != 1 )
270       {
271       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
272       }
273     m = NumericTraits< ValueType >::ZeroValue();
274   }
275 
276 };
277 
278 /** \class NumericTraits<char>
279  * \brief Define traits for type char.
280  * NOTE: char is not guaranteed to be signed. On SGI computers, the default is unsigned
281  * \ingroup ITKCommon
282  */
283 template< >
284 class NumericTraits< char > :public std::numeric_limits< char >
285 {
286 public:
287   using ValueType = char;
288   using PrintType = int;
289   using AbsType = unsigned char;
290   using AccumulateType = short;
291   using RealType = double;
292   using ScalarRealType = RealType;
293   using FloatType = float;
294   using MeasurementVectorType = FixedArray<ValueType, 1>;
295 
296   static constexpr char ITKCommon_EXPORT Zero = 0;
297   static constexpr char ITKCommon_EXPORT One = 1;
298 
299   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
300 
NonpositiveMin()301   static constexpr char NonpositiveMin() { return lowest(); }
IsPositive(char val)302   static constexpr bool IsPositive(char val) { return val > Zero; }
IsNonpositive(char val)303   static constexpr bool IsNonpositive(char val) { return val <= Zero; }
304 
IsNegative(char)305   static constexpr bool IsNegative(char) { return false; }
IsNonnegative(char)306   static constexpr bool IsNonnegative(char) { return true; }
307   static constexpr bool IsSigned = std::numeric_limits<char>::is_signed;
308 
309   static constexpr bool IsInteger = std::numeric_limits<char>::is_integer;
310   static constexpr bool IsComplex = false;
ZeroValue()311   static constexpr char ZeroValue() { return Zero; }
OneValue()312   static constexpr char OneValue() { return One; }
GetLength(const ValueType &)313   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()314   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)315   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)316   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)317   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
318 
319   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)320   static void AssignToArray( const ValueType & v, TArray & mv )
321   {
322     mv[0] = v;
323   }
SetLength(ValueType & m,const unsigned int s)324   static void SetLength(ValueType & m, const unsigned int s)
325   {
326     if ( s != 1 )
327       {
328       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
329       }
330     m = NumericTraits< ValueType >::ZeroValue();
331   }
332 };
333 
334 /** \class NumericTraits<char>
335  * \brief Define traits for type char.
336  * NOTE: char is not guaranteed to be signed. On SGI computers, the default is unsigned
337  * \ingroup ITKCommon
338  */
339 template< >
340 class NumericTraits< signed char > :public std::numeric_limits< signed char >
341 {
342 public:
343   using ValueType = signed char;
344   using PrintType = int;
345   using AbsType = unsigned char;
346   using AccumulateType = short;
347   using RealType = double;
348   using ScalarRealType = RealType;
349   using FloatType = float;
350   using MeasurementVectorType = FixedArray<ValueType, 1>;
351 
352   static constexpr signed char ITKCommon_EXPORT Zero = 0;
353   static constexpr signed char ITKCommon_EXPORT One = 1;
354 
min()355   static constexpr signed char min() { return -128; }
max()356   static constexpr signed char max() { return 127; }
min(signed char)357   static constexpr signed char min(signed char) { return min(); }
max(signed char)358   static constexpr signed char max(signed char) { return max(); }
NonpositiveMin()359   static constexpr signed char NonpositiveMin() { return lowest(); }
IsPositive(signed char val)360   static constexpr bool IsPositive(signed char val) { return val > Zero; }
IsNonpositive(signed char val)361   static constexpr bool IsNonpositive(signed char val) { return val <= Zero; }
IsNegative(signed char val)362   static constexpr bool IsNegative(signed char val) { return val < Zero; }
IsNonnegative(signed char val)363   static constexpr bool IsNonnegative(signed char val) { return val >= Zero; }
364   static constexpr bool IsSigned = true;
365   static constexpr bool IsInteger = true;
366   static constexpr bool IsComplex = false;
ZeroValue()367   static constexpr signed char  ZeroValue() { return Zero; }
OneValue()368   static constexpr signed char OneValue() { return One; }
GetLength(const ValueType &)369   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()370   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)371   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)372   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)373   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
374 
375   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)376   static void AssignToArray( const ValueType & v, TArray & mv )
377   {
378     mv[0] = v;
379   }
SetLength(ValueType & m,const unsigned int s)380   static void SetLength(ValueType & m, const unsigned int s)
381   {
382     if ( s != 1 )
383       {
384       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
385       }
386     m = NumericTraits< ValueType >::ZeroValue();
387   }
388 };
389 
390 /** \class NumericTraits<unsigned char>
391  * \brief Define traits for type unsigned char.
392  * \ingroup DataRepresentation
393  * \ingroup ITKCommon
394  */
395 template< >
396 class NumericTraits< unsigned char > :public std::numeric_limits< unsigned char >
397 {
398 public:
399   using ValueType = unsigned char;
400   using PrintType = int;
401   using AbsType = unsigned char;
402   using AccumulateType = unsigned short;
403   using RealType = double;
404   using ScalarRealType = RealType;
405   using FloatType = float;
406   using MeasurementVectorType = FixedArray<ValueType, 1>;
407 
408   static constexpr unsigned char ITKCommon_EXPORT Zero = 0;
409   static constexpr unsigned char ITKCommon_EXPORT One = 1;
410 
411   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
412 
NonpositiveMin()413   static constexpr unsigned char NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(unsigned char val)414   static constexpr bool IsPositive(unsigned char val) { return val != Zero; }
IsNonpositive(unsigned char val)415   static constexpr bool IsNonpositive(unsigned char val) { return val == Zero; }
IsNegative(unsigned char val)416   static constexpr bool IsNegative(unsigned char val) { return val ? false : false; }
IsNonnegative(unsigned char val)417   static constexpr bool IsNonnegative(unsigned char val) { return val ? true : true; }
418   static constexpr bool IsSigned = false;
419   static constexpr bool IsInteger = true;
420   static constexpr bool IsComplex = false;
ZeroValue()421   static constexpr unsigned char  ZeroValue() { return Zero; }
OneValue()422   static constexpr unsigned char OneValue() { return One; }
GetLength(const ValueType &)423   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()424   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)425   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)426   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)427   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
428 
429   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)430   static void AssignToArray( const ValueType & v, TArray & mv )
431   {
432     mv[0] = v;
433   }
SetLength(ValueType & m,const unsigned int s)434   static void SetLength(ValueType & m, const unsigned int s)
435   {
436     if ( s != 1 )
437       {
438       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
439       }
440     m = NumericTraits< ValueType >::ZeroValue();
441   }
442 };
443 
444 /** \class NumericTraits<short>
445  * \brief Define traits for type short.
446  * \ingroup ITKCommon
447  */
448 template< >
449 class NumericTraits< short > :public std::numeric_limits< short >
450 {
451 public:
452   using ValueType = short;
453   using PrintType = short;
454   using AbsType = unsigned short;
455   using AccumulateType = int;
456   using RealType = double;
457   using ScalarRealType = RealType;
458   using FloatType = float;
459   using MeasurementVectorType = FixedArray<ValueType, 1>;
460 
461   static constexpr short ITKCommon_EXPORT Zero = 0;
462   static constexpr short ITKCommon_EXPORT One = 1;
463 
464   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()465   static constexpr short NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(short val)466   static constexpr bool IsPositive(short val) { return val > Zero; }
IsNonpositive(short val)467   static constexpr bool IsNonpositive(short val) { return val <= Zero; }
IsNegative(short val)468   static constexpr bool IsNegative(short val) { return val < Zero; }
IsNonnegative(short val)469   static constexpr bool IsNonnegative(short val) { return val >= Zero; }
470   static constexpr bool IsSigned = true;
471   static constexpr bool IsInteger = true;
472   static constexpr bool IsComplex = false;
ZeroValue()473   static constexpr short  ZeroValue() { return Zero; }
OneValue()474   static constexpr short OneValue() { return One; }
GetLength(const ValueType &)475   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()476   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)477   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)478   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)479   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
480 
481   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)482   static void AssignToArray( const ValueType & v, TArray & mv )
483   {
484     mv[0] = v;
485   }
SetLength(ValueType & m,const unsigned int s)486   static void SetLength(ValueType & m, const unsigned int s)
487   {
488     if ( s != 1 )
489       {
490       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
491       }
492     m = NumericTraits< ValueType >::ZeroValue();
493   }
494 };
495 
496 /** \class NumericTraits<unsigned short>
497  * \brief Define traits for type unsigned short.
498  * \ingroup DataRepresentation
499  * \ingroup ITKCommon
500  */
501 template< >
502 class NumericTraits< unsigned short > :public std::numeric_limits< unsigned short >
503 {
504 public:
505   using ValueType = unsigned short;
506   using PrintType = unsigned short;
507   using AbsType = unsigned short;
508   using AccumulateType = unsigned int;
509   using RealType = double;
510   using ScalarRealType = RealType;
511   using FloatType = float;
512   using MeasurementVectorType = FixedArray<ValueType, 1>;
513 
514   static constexpr unsigned short ITKCommon_EXPORT Zero = 0;
515   static constexpr unsigned short ITKCommon_EXPORT One = 1;
516 
517   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()518   static constexpr unsigned short NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(unsigned short val)519   static constexpr bool IsPositive(unsigned short val) { return val != Zero; }
IsNonpositive(unsigned short val)520   static constexpr bool IsNonpositive(unsigned short val) { return val == Zero; }
IsNegative(unsigned short val)521   static constexpr bool IsNegative(unsigned short val) { return val ? false : false; }
IsNonnegative(unsigned short val)522   static constexpr bool IsNonnegative(unsigned short val) { return val ? true : true; }
523   static constexpr bool IsSigned = false;
524   static constexpr bool IsInteger = true;
525   static constexpr bool IsComplex = false;
ZeroValue()526   static constexpr unsigned short ZeroValue() { return Zero; }
OneValue()527   static constexpr unsigned short OneValue() { return One; }
GetLength(const ValueType &)528   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()529   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)530   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)531   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)532   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
533 
534   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)535   static void AssignToArray( const ValueType & v, TArray & mv )
536   {
537     mv[0] = v;
538   }
SetLength(ValueType & m,const unsigned int s)539   static void SetLength(ValueType & m, const unsigned int s)
540   {
541     if ( s != 1 )
542       {
543       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
544       }
545     m = NumericTraits< ValueType >::ZeroValue();
546   }
547 };
548 
549 /** \class NumericTraits<int>
550  * \brief Define traits for type int.
551  * \ingroup ITKCommon
552  */
553 template< >
554 class NumericTraits< int > :public std::numeric_limits< int >
555 {
556 public:
557   using ValueType = int;
558   using PrintType = int;
559   using AbsType = unsigned int;
560   using AccumulateType = long;
561   using RealType = double;
562   using ScalarRealType = RealType;
563   using FloatType = float;
564   using MeasurementVectorType = FixedArray<ValueType, 1>;
565 
566   static constexpr int ITKCommon_EXPORT Zero = 0;
567   static constexpr int ITKCommon_EXPORT One = 1;
568 
569   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()570   static constexpr int NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(int val)571   static constexpr bool IsPositive(int val) { return val > Zero; }
IsNonpositive(int val)572   static constexpr bool IsNonpositive(int val) { return val <= Zero; }
IsNegative(int val)573   static constexpr bool IsNegative(int val) { return val < Zero; }
IsNonnegative(int val)574   static constexpr bool IsNonnegative(int val) { return val >= Zero; }
575   static constexpr bool IsSigned = true;
576   static constexpr bool IsInteger = true;
577   static constexpr bool IsComplex = false;
ZeroValue()578   static constexpr int  ZeroValue() { return Zero; }
OneValue()579   static constexpr int OneValue() { return One; }
GetLength(const ValueType &)580   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()581   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)582   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)583   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)584   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
585 
586   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)587   static void AssignToArray( const ValueType & v, TArray & mv )
588   {
589     mv[0] = v;
590   }
SetLength(ValueType & m,const unsigned int s)591   static void SetLength(ValueType & m, const unsigned int s)
592   {
593     if ( s != 1 )
594       {
595       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
596       }
597     m = NumericTraits< ValueType >::ZeroValue();
598   }
599 };
600 
601 /** \class NumericTraits<unsigned int>
602  * \brief Define traits for type unsigned int.
603  * \ingroup DataRepresentation
604  * \ingroup ITKCommon
605  */
606 template< >
607 class NumericTraits< unsigned int > :public std::numeric_limits< unsigned int >
608 {
609 public:
610   using ValueType = unsigned int;
611   using PrintType = unsigned int;
612   using AbsType = unsigned int;
613   using AccumulateType = unsigned int;
614   using RealType = double;
615   using ScalarRealType = RealType;
616   using FloatType = float;
617   using MeasurementVectorType = FixedArray<ValueType, 1>;
618 
619   static constexpr unsigned int ITKCommon_EXPORT Zero = 0;
620   static constexpr unsigned int ITKCommon_EXPORT One = 1;
621 
min()622   static constexpr unsigned int min() { return 0; }
max()623   static constexpr unsigned int max() { return static_cast< unsigned int >( -1 ); }
min(unsigned int)624   static constexpr unsigned int min(unsigned int) { return std::numeric_limits< ValueType >::min(); }
max(unsigned int)625   static constexpr unsigned int max(unsigned int) { return std::numeric_limits< ValueType >::max(); }
NonpositiveMin()626   static constexpr unsigned int NonpositiveMin() { return 0; }
IsPositive(unsigned int val)627   static constexpr bool IsPositive(unsigned int val) { return val != Zero; }
IsNonpositive(unsigned int val)628   static constexpr bool IsNonpositive(unsigned int val) { return val == Zero; }
IsNegative(unsigned int val)629   static constexpr bool IsNegative(unsigned int val) { return val ? false : false; }
IsNonnegative(unsigned int val)630   static constexpr bool IsNonnegative(unsigned int val) { return val ? true : true; }
631   static constexpr bool IsSigned = false;
632   static constexpr bool IsInteger = true;
633   static constexpr bool IsComplex = false;
ZeroValue()634   static constexpr unsigned int  ZeroValue() { return Zero; }
OneValue()635   static constexpr unsigned int OneValue() { return One; }
GetLength(const ValueType &)636   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()637   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)638   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)639   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)640   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
641 
642   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)643   static void AssignToArray( const ValueType & v, TArray & mv )
644   {
645     mv[0] = v;
646   }
SetLength(ValueType & m,const unsigned int s)647   static void SetLength(ValueType & m, const unsigned int s)
648   {
649     if ( s != 1 )
650       {
651       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
652       }
653     m = NumericTraits< ValueType >::ZeroValue();
654   }
655 };
656 
657 /** \class NumericTraits<long>
658  * \brief Define traits for type long.
659  * \ingroup DataRepresentation
660  * \ingroup ITKCommon
661  */
662 template< >
663 class NumericTraits< long > :public std::numeric_limits< long >
664 {
665 public:
666   using ValueType = long;
667   using PrintType = long;
668   using AbsType = unsigned long;
669   using AccumulateType = long;
670   using RealType = double;
671   using ScalarRealType = RealType;
672   using FloatType = float;
673   using MeasurementVectorType = FixedArray<ValueType, 1>;
674 
675   static constexpr long ITKCommon_EXPORT Zero = 0L;
676   static constexpr long ITKCommon_EXPORT One = 1L;
677 
678   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()679   static constexpr long NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(long val)680   static constexpr bool IsPositive(long val) { return val > Zero; }
IsNonpositive(long val)681   static constexpr bool IsNonpositive(long val) { return val <= Zero; }
IsNegative(long val)682   static constexpr bool IsNegative(long val) { return val < Zero; }
IsNonnegative(long val)683   static constexpr bool IsNonnegative(long val) { return val >= Zero; }
684   static constexpr bool IsSigned = true;
685   static constexpr bool IsInteger = true;
686   static constexpr bool IsComplex = false;
ZeroValue()687   static constexpr long  ZeroValue() { return Zero; }
OneValue()688   static constexpr long OneValue() { return One; }
GetLength(const ValueType &)689   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()690   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)691   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)692   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)693   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
694 
695   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)696   static void AssignToArray( const ValueType & v, TArray & mv )
697   {
698     mv[0] = v;
699   }
SetLength(ValueType & m,const unsigned int s)700   static void SetLength(ValueType & m, const unsigned int s)
701   {
702     if ( s != 1 )
703       {
704       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
705       }
706     m = NumericTraits< ValueType >::ZeroValue();
707   }
708 };
709 
710 /** \class NumericTraits<unsigned long>
711  * \brief Define traits for type unsigned long.
712  * \ingroup DataRepresentation
713  * \ingroup ITKCommon
714  */
715 template< >
716 class NumericTraits< unsigned long > :public std::numeric_limits< unsigned long >
717 {
718 public:
719   using ValueType = unsigned long;
720   using PrintType = unsigned long;
721   using AbsType = unsigned long;
722   using AccumulateType = unsigned long;
723   using RealType = double;
724   using ScalarRealType = RealType;
725   using FloatType = float;
726   using MeasurementVectorType = FixedArray<ValueType, 1>;
727 
728   static constexpr unsigned long ITKCommon_EXPORT Zero = 0UL;
729   static constexpr unsigned long ITKCommon_EXPORT One = 1UL;
730 
731   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()732   static constexpr unsigned long NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(unsigned long val)733   static constexpr bool IsPositive(unsigned long val) { return val != Zero; }
IsNonpositive(unsigned long val)734   static constexpr bool IsNonpositive(unsigned long val) { return val == Zero; }
IsNegative(unsigned long)735   static constexpr bool IsNegative(unsigned long) { return false; }
IsNonnegative(unsigned long)736   static constexpr bool IsNonnegative(unsigned long) { return true; }
737   static constexpr bool IsSigned = false;
738   static constexpr bool IsInteger = true;
739   static constexpr bool IsComplex = false;
ZeroValue()740   static constexpr unsigned long  ZeroValue() { return Zero; }
OneValue()741   static constexpr unsigned long  OneValue() { return One; }
GetLength(const ValueType &)742   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()743   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)744   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)745   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)746   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
747 
748   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)749   static void AssignToArray( const ValueType & v, TArray & mv )
750   {
751     mv[0] = v;
752   }
SetLength(ValueType & m,const unsigned int s)753   static void SetLength(ValueType & m, const unsigned int s)
754   {
755     if ( s != 1 )
756       {
757       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
758       }
759     m = NumericTraits< ValueType >::ZeroValue();
760   }
761 };
762 
763 /** \class NumericTraits<float>
764  * \brief Define traits for type float.
765  * \ingroup DataRepresentation
766  * \ingroup ITKCommon
767  */
768 template< >
769 class NumericTraits< float > :public std::numeric_limits< float >
770 {
771 public:
772   using ValueType = float;
773   using PrintType = float;
774   using AbsType = float;
775   using AccumulateType = double;
776   using RealType = double;
777   using ScalarRealType = RealType;
778   using FloatType = float;
779   using MeasurementVectorType = FixedArray<ValueType, 1>;
780 
781 
782   static constexpr float ITKCommon_EXPORT Zero =0.0f;
783   static constexpr float ITKCommon_EXPORT One =1.0f;
784 
785   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()786   static constexpr float NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(float val)787   static constexpr bool IsPositive(float val) { return val > Zero; }
IsNonpositive(float val)788   static constexpr bool IsNonpositive(float val) { return val <= Zero; }
IsNegative(float val)789   static constexpr bool IsNegative(float val) { return val < Zero; }
IsNonnegative(float val)790   static constexpr bool IsNonnegative(float val) { return val >= Zero; }
791   static constexpr bool IsSigned = true;
792   static constexpr bool IsInteger = false;
793   static constexpr bool IsComplex = false;
ZeroValue()794   static constexpr float  ZeroValue() { return Zero; }
OneValue()795   static constexpr float  OneValue() { return One; }
GetLength(const ValueType &)796   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()797   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)798   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)799   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)800   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
801 
802   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)803   static void AssignToArray( const ValueType & v, TArray & mv )
804   {
805     mv[0] = v;
806   }
SetLength(ValueType & m,const unsigned int s)807   static void SetLength(ValueType & m, const unsigned int s)
808   {
809     if ( s != 1 )
810       {
811       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
812       }
813     m = NumericTraits< ValueType >::ZeroValue();
814   }
815 };
816 
817 /** \class NumericTraits<double>
818  * \brief Define traits for type double.
819  * \ingroup DataRepresentation
820  * \ingroup ITKCommon
821  */
822 template< >
823 class NumericTraits< double > :public std::numeric_limits< double >
824 {
825 public:
826   using ValueType = double;
827   using PrintType = double;
828   using AbsType = double;
829   using AccumulateType = double;
830   using RealType = double;
831   using ScalarRealType = RealType;
832   using FloatType = float;
833   using MeasurementVectorType = FixedArray<ValueType, 1>;
834 
835   static constexpr double ITKCommon_EXPORT Zero = 0.0;
836   static constexpr double ITKCommon_EXPORT One  = 1.0;
837 
838   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()839   static constexpr double NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(double val)840   static constexpr bool IsPositive(double val) { return val > Zero; }
IsNonpositive(double val)841   static constexpr bool IsNonpositive(double val) { return val <= Zero; }
IsNegative(double val)842   static constexpr bool IsNegative(double val) { return val < Zero; }
IsNonnegative(double val)843   static constexpr bool IsNonnegative(double val) { return val >= Zero; }
844   static constexpr bool IsSigned = true;
845   static constexpr bool IsInteger = false;
846   static constexpr bool IsComplex = false;
ZeroValue()847   static constexpr double  ZeroValue() { return Zero; }
OneValue()848   static constexpr double  OneValue() { return One; }
GetLength(const ValueType &)849   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()850   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)851   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)852   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)853   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
854 
855   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)856   static void AssignToArray( const ValueType & v, TArray & mv )
857   {
858     mv[0] = v;
859   }
SetLength(ValueType & m,const unsigned int s)860   static void SetLength(ValueType & m, const unsigned int s)
861   {
862     if ( s != 1 )
863       {
864       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
865       }
866     m = NumericTraits< ValueType >::ZeroValue();
867   }
868 };
869 
870 /** \class NumericTraits<long double>
871  * \brief Define traits for type long double.
872  * \ingroup DataRepresentation
873  * \ingroup ITKCommon
874  */
875 template< >
876 class NumericTraits< long double > :public std::numeric_limits< long double >
877 {
878 public:
879   using ValueType = long double;
880 #if defined( __SUNPRO_CC ) && defined( _ILP32 )
881   // sun studio in 32 bit mode is unable to print long double values: it
882   // segfaults.
883   // conversion to double will give usable results if the value is in the double
884   // range - better than nothing.
885   using PrintType = double;
886 #else
887   using PrintType = long double;
888 #endif
889   using AbsType = long double;
890   using AccumulateType = long double;
891   using RealType = long double;
892   using ScalarRealType = RealType;
893   using FloatType = float;
894   using MeasurementVectorType = FixedArray<ValueType, 1>;
895 
896   static constexpr long double ITKCommon_EXPORT Zero = 0.0;
897   static constexpr long double ITKCommon_EXPORT One = 1.0;
898 
899   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()900   static constexpr long double NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(long double val)901   static constexpr bool IsPositive(long double val) { return val > Zero; }
IsNonpositive(long double val)902   static constexpr bool IsNonpositive(long double val) { return val <= Zero; }
IsNegative(long double val)903   static constexpr bool IsNegative(long double val) { return val < Zero; }
IsNonnegative(long double val)904   static constexpr bool IsNonnegative(long double val) { return val >= Zero; }
905   static constexpr bool IsSigned = true;
906   static constexpr bool IsInteger = false;
907   static constexpr bool IsComplex = false;
ZeroValue()908   static constexpr long double ZeroValue() { return Zero; }
OneValue()909   static constexpr long double OneValue() { return One; }
GetLength(const ValueType &)910   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()911   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)912   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)913   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)914   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
915 
916   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)917   static void AssignToArray( const ValueType & v, TArray & mv )
918   {
919     mv[0] = v;
920   }
SetLength(ValueType & m,const unsigned int s)921   static void SetLength(ValueType & m, const unsigned int s)
922   {
923     if ( s != 1 )
924       {
925       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
926       }
927     m = NumericTraits< ValueType >::ZeroValue();
928   }
929 };
930 
931 
932 /** \class NumericTraits<long long>
933  * \brief Define traits for type long long.
934  * \ingroup DataRepresentation
935  * \ingroup ITKCommon
936  */
937 template< >
938 class NumericTraits< long long > :
939   public std::numeric_limits< long long >
940 {
941 public:
942   using ValueType = long long;
943   using PrintType = long long;
944   using AbsType = long long;
945   using AccumulateType = long long;
946   using RealType = double;
947   using ScalarRealType = RealType;
948   using FloatType = float;
949   using MeasurementVectorType = FixedArray<ValueType, 1>;
950 
951   static constexpr ValueType ITKCommon_EXPORT Zero = 0LL;
952   static constexpr ValueType ITKCommon_EXPORT One = 1LL;
953 
954   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()955   static constexpr ValueType NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(ValueType val)956   static constexpr bool IsPositive(ValueType val) { return val > Zero; }
IsNonpositive(ValueType val)957   static constexpr bool IsNonpositive(ValueType val) { return val <= Zero; }
IsNegative(ValueType val)958   static constexpr bool IsNegative(ValueType val) { return val < Zero; }
IsNonnegative(ValueType val)959   static constexpr bool IsNonnegative(ValueType val) { return val >= Zero; }
960   static constexpr bool IsSigned = true;
961   static constexpr bool IsInteger = true;
962   static constexpr bool IsComplex = false;
ZeroValue()963   static constexpr ValueType  ZeroValue() { return Zero; }
OneValue()964   static constexpr ValueType  OneValue() { return One; }
GetLength(const ValueType &)965   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()966   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)967   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)968   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)969   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
970 
971   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)972   static void AssignToArray( const ValueType & v, TArray & mv )
973   {
974     mv[0] = v;
975   }
SetLength(ValueType & m,const unsigned int s)976   static void SetLength(ValueType & m, const unsigned int s)
977   {
978     if ( s != 1 )
979       {
980       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
981       }
982     m = NumericTraits< ValueType >::ZeroValue();
983   }
984 };
985 
986 /** \class NumericTraits<unsigned long long>
987  * \brief Define traits for type unsigned long long.
988  * \ingroup DataRepresentation
989  * \ingroup ITKCommon
990  */
991 template< >
992 class NumericTraits< unsigned long long > :
993   public std::numeric_limits< unsigned long long >
994 {
995 public:
996   using ValueType = unsigned long long;
997   using PrintType = unsigned long long;
998   using AbsType = unsigned long long;
999   using AccumulateType = unsigned long long;
1000   using RealType = double;
1001   using ScalarRealType = RealType;
1002   using FloatType = float;
1003   using MeasurementVectorType = FixedArray<ValueType, 1>;
1004 
1005   static constexpr ValueType ITKCommon_EXPORT Zero = 0ULL;
1006   static constexpr ValueType ITKCommon_EXPORT One = 1ULL;
1007 
1008   itkNUMERIC_TRAITS_MIN_MAX_MACRO();
NonpositiveMin()1009   static constexpr ValueType NonpositiveMin() { return std::numeric_limits< ValueType >::lowest(); }
IsPositive(ValueType val)1010   static constexpr bool IsPositive(ValueType val) { return val != Zero; }
IsNonpositive(ValueType val)1011   static constexpr bool IsNonpositive(ValueType val) { return val == Zero; }
IsNegative(ValueType)1012   static constexpr bool IsNegative(ValueType) { return false; }
IsNonnegative(ValueType)1013   static constexpr bool IsNonnegative(ValueType) { return true; }
1014   static constexpr bool IsSigned = false;
1015   static constexpr bool IsInteger = true;
1016   static constexpr bool IsComplex = false;
ZeroValue()1017   static constexpr ValueType ZeroValue() { return Zero; }
OneValue()1018   static constexpr ValueType OneValue() { return One; }
GetLength(const ValueType &)1019   static constexpr unsigned int GetLength(const ValueType &) { return 1; }
GetLength()1020   static constexpr unsigned int GetLength() { return 1; }
NonpositiveMin(const ValueType &)1021   static constexpr ValueType NonpositiveMin(const ValueType &) { return NonpositiveMin(); }
ZeroValue(const ValueType &)1022   static constexpr ValueType ZeroValue(const ValueType &) { return ZeroValue(); }
OneValue(const ValueType &)1023   static constexpr ValueType OneValue(const ValueType &) { return OneValue(); }
1024 
1025   template<typename TArray>
AssignToArray(const ValueType & v,TArray & mv)1026   static void AssignToArray( const ValueType & v, TArray & mv )
1027   {
1028     mv[0] = v;
1029   }
SetLength(ValueType & m,const unsigned int s)1030   static void SetLength(ValueType & m, const unsigned int s)
1031   {
1032     if ( s != 1 )
1033       {
1034       itkGenericExceptionMacro(<< "Cannot set the size of a scalar to " << s);
1035       }
1036     m = NumericTraits< ValueType >::ZeroValue();
1037   }
1038 };
1039 
1040 
1041 /** \class NumericTraits< std::complex<TComponent> >
1042  * \brief Define traits for type std::complex<TComponent>.
1043  * \ingroup DataRepresentation
1044  * \ingroup ITKCommon
1045  */
1046 template<typename TComponent>
1047 class NumericTraits< std::complex< TComponent > >
1048 {
1049 public:
1050   using Self = std::complex< TComponent >;
1051   // for backward compatibility
1052   using TheType = Self;
1053   using ValueType = TComponent;
1054   using PrintType = Self;
1055   using AbsType = double;
1056   using AccumulateType = Self;
1057   using RealType = std::complex< double >;
1058   using ScalarRealType = double;
1059   using FloatType = std::complex< float >;
1060   using MeasurementVectorType = FixedArray<ValueType, 2>;
1061 
1062   static const Self ITKCommon_EXPORT Zero;
1063   static const Self ITKCommon_EXPORT One;
1064 
min()1065   static constexpr Self min() { return std::numeric_limits< ValueType >::min(); }
max()1066   static constexpr Self max() { return std::numeric_limits< ValueType >::max(); }
min(Self)1067   static constexpr Self min(Self) { return min(); }
max(Self)1068   static constexpr Self max(Self) { return max(); }
epsilon()1069   static constexpr ValueType epsilon() { return std::numeric_limits<ValueType>::epsilon(); }
NonpositiveMin()1070   static constexpr Self NonpositiveMin()
1071   {
1072     return Self(NumericTraits< ValueType >::NonpositiveMin(), 0);
1073   }
1074 
IsPositive(Self val)1075   static constexpr bool IsPositive(Self val) { return val.real() > 0; }
IsNonpositive(Self val)1076   static constexpr bool IsNonpositive(Self val) { return val.real() <= 0; }
IsNegative(Self val)1077   static constexpr bool IsNegative(Self val) { return val.real() < 0; }
IsNonnegative(Self val)1078   static constexpr bool IsNonnegative(Self val) { return val.real() >= 0; }
1079 
1080   static constexpr bool IsSigned = NumericTraits< ValueType >::IsSigned;
1081   static constexpr bool IsInteger = false;
1082   static constexpr bool IsComplex = true;
ZeroValue()1083   static Self ZeroValue() { return Self(0, 0); }
OneValue()1084   static Self OneValue() { return Self(1, 0); }
GetLength(const Self &)1085   static constexpr unsigned int GetLength(const Self &) { return 2; }
GetLength()1086   static constexpr unsigned int GetLength() { return 2; }
NonpositiveMin(const Self &)1087   static constexpr Self NonpositiveMin(const Self &) { return NonpositiveMin(); }
ZeroValue(const Self &)1088   static Self ZeroValue(const Self &) { return ZeroValue(); }
OneValue(const Self &)1089   static Self OneValue(const Self &) { return OneValue(); }
1090 
1091   template<typename TArray>
AssignToArray(const Self & v,TArray & mv)1092   static void AssignToArray( const Self & v, TArray & mv )
1093   {
1094     mv[0] = v.real();
1095     mv[1] = v.imag();
1096   }
SetLength(Self & m,const unsigned int s)1097   static void SetLength(Self & m, const unsigned int s)
1098   {
1099     if ( s != 2 )
1100       {
1101       itkGenericExceptionMacro(<< "Cannot set the size of a complex to " << s);
1102       }
1103     m = NumericTraits< ValueType >::ZeroValue();
1104   }
1105 };
1106 } // end namespace itk
1107 
1108 #include "itkFixedArray.h"
1109 
1110 #endif // itkNumericTraits_h
1111