[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

template<> struct NumericTraits<ArithmeticType> VIGRA

Unary traits for promotion, conversion, creation of arithmetic objects.

#include <vigra/numerictraits.hxx>

This traits class is used derive important properties of an arithmetic type. Consider the following algorithm:

// calculate the sum of a sequence of bytes
int sumBytes(unsigned char * begin, unsigned char * end)
{
int result = 0;
for(; begin != end; ++begin) result += *begin;
return result;
}

The return type of this function can not be 'unsigned char' because the summation would very likely overflow. Since we know the source type, we can easily choose 'int' as an appropriate return type. Likewise, we would have chosen 'float' if we had to sum a sequence of floats. If we want to make this algorithm generic, we would like to derive the appropriate return type automatically. This can be done with NumericTraits. The code would look like this (we use Data Accessors to read the data from the sequence):

// calculate the sum of any sequence
template <class Iterator, class Accessor>
typename vigra::NumericTraits<typename Accessor::value_type>::Promote
sumSequence(Iterator begin, Iterator end, Accessor a)
{
// an abbreviation
typedef vigra::NumericTraits<typename Accessor::value_type> SrcTraits;
// find out result type
typedef typename SrcTraits::Promote ResultType;
// init result to zero
ResultType result = vigra::NumericTraits<ResultType>::zero();
for(; begin != end; ++begin)
{
// cast current item to ResultType and add
result += SrcTraits::toPromote(a(begin));
}
return result;
}

In this example NumericTraits is not only used to deduce the ReturnType of the operation, but also to initialize it with the constant 'zero'. This is necessary since we do not know in general, which expression must be used to obtain a zero of some arbitrary type - 'ResultType result = 0;' would only work if the ResultType had an constructor taking an 'int' argument, and we would not even have any guarantee as to what the semantics of this constructor are. In addition, the traits are used to cast the source type into the promote type.

Similarly, an algorithm that needs multiplication would use the return type RealPromote and the functions one() and toRealPromote(). The following members are defined in NumericTraits<ArithmeticType>:

typedef ... Type;

the type itself

typedef ... Promote;

promote type for addition and subtraction

typedef ... RealPromote;

promote type for multiplication and division with a real number

(only defined if ArithmeticType supports these operations)

typedef ... ComplexPromote;

promote type for complex arithmetic

typedef ... ValueType;

for scalar types: the type itself
otherwise: typename Type::value_type (if defined)

static Promote toPromote(ArithmeticType v);

convert to Promote type

static RealPromote toRealPromote(ArithmeticType v);

convert to RealPromote type

(only defined if ArithmeticType supports multiplication)

static ArithmeticType fromPromote(Promote v);

convert from Promote type

if v is outside the range of ArithmeticType it is clipped;

static ArithmeticType fromRealPromote(RealPromote v);

convert from RealPromote type

(only defined if ArithmeticType supports multiplication)

if ArithmeticType is an integral type, the result is rounded

if v is outside the range of ArithmeticType it is clipped

static ArithmeticType zero();

create neutral element of addition

i.e. (ArithmeticType a = ..., a + NumericTraits<ArithmeticType>::zero() == a) must always yield true

static ArithmeticType nonZero();

create a non-zero element (if multiplication is defined, this yields one())

i.e. (ArithmeticType a = ..., a + NumericTraits<ArithmeticType>::nonZero() == a) must always yield false

static ArithmeticType min();

the smallest number representable in this type.
Only available if isOrdered is VigraTrueType. For integral types, this equals INT_MIN etc., for real valued types it is -FLT_MAX etc. (not FLT_MIN – this is the smallest positive float)

static ArithmeticType max();

the largest number representable in this type.
Only available if isOrdered is VigraTrueType. For integral types, this equals INT_MAX etc., for real valued types it is FLT_MAX etc.

static ArithmeticType one();

create neutral element of multiplication

(only defined if ArithmeticType supports multiplication)

i.e. (ArithmeticType a = ..., a * NumericTraits<ArithmeticType>::one() == a) must always yield true

typedef ... isIntegral;

VigraTrueType if ArithmeticType is an integral type, VigraFalseType otherwise

typedef ... isScalar;

VigraTrueType if ArithmeticType is a scalar type, VigraFalseType otherwise

typedef ... isSigned;

VigraTrueType if ArithmeticType is a signed type, VigraFalseType otherwise

typedef ... isOrdered;

VigraTrueType if ArithmeticType supports operator<(), VigraFalseType otherwise

typedef ... isComplex;

VigraTrueType if ArithmeticType is a complex number, VigraFalseType otherwise

NumericTraits for the built-in types are defined in #include <vigra/numerictraits.hxx>

Namespace: vigra

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)