We use the following conventions: The type defined by a trait class is denoted by `T`

. The integer value defined by a trait class is denoted by `V`

. For example, the trait `kernelof`

(see below), defines the arithmetic kernel associated to `C`

by `kernelof<C>::T`

.

Usually the default value is `type::null_t`

for traits defining a type and `type::false_t`

for boolean traits. Traits on arithmetic data types are not directly specialized, each trait class, say `X`

, uses the trait `X_`

for specialization. The reason for this mechanism is that generally the traits do not depend on type qualifiers, such as `const`

or `&`

. For instance, {kernelof<const C&>T} is associated to `kernelof_<C>::T`

.

**See also:**`synaps/arithm/traits.h`

Until now *synaps* used *gmp* library for extended, rational and integer arithmetic, and traits were defined for each *gmp* particular data type. In this release of *synaps* library, the *gmp* numbers are put together into a kernel named `GMP`

which is simply a data structure containing the following type definition (as `typedef`

):

`integer`

, assumed to be an exact integer implementation.

`rational`

, assumed to be an exact rational implementation.

`floating`

, assumed to be an extended floating point arithmetic.

`ieee`

, assumed to be a fixed precision ieee compliant number type.

`GMP`

kernel), available by the traits class `kernelof`

.
By default, `kernelof_<X>::T`

is `type::null_t`

.

After an `#include <synaps/arithm/gmp.h>`

, `kernelof<X>::T`

is `GMP`

for `X = `

`ZZ`

, `QQ`

, `RR`

.

This new feature will soon allow *synaps* library to work with other library than `GMP`

, such as `CLN`

.

`isring<C>`

is a boolean trait, which specifies if`C`

implements a ring.

`isfield<C>`

is also provided. Notice that we consider`double`

as field.

`ringof<X,Y>::T`

specify which data type can be used to represent sum and multiplication between type`X`

and type`Y`

. For example, given a kernel`K`

,definesringof<K::integer,K::floating>::T

`K::integer`

. It is used for example in the dotproduct of two different vector types.

`fieldof<X,Y>::T`

is similar for field operations. Notice again that we consider`double`

as a field.

ringof<K::integer,K::floating>::T --> K::floating ringof<K::integer,K::rational>::T --> K::rational ringof<K::integer,K::ieee>::T --> K::ieee ringof<K::floating,K::rational>::T --> K::rational ringof<K::floating,K::ieee>::T --> K::floating ringof<K::ieee,K::rational>::T --> K::rational fieldof<K::integer,K::floating>::T --> K::rational fieldof<K::integer,K::rational>::T --> K::rational fieldof<K::integer,K::ieee>::T --> K::rational fieldof<K::floating,K::rational>::T --> K::rational fieldof<K::floating,K::ieee>::T --> K::floating fieldof<K::ieee,K::rational>::T --> K::rational

`floating`

and `ieee`

data types for ring operations.

For field operations we take the supset that can represent each inverses, when the two data types are inexact we take the best of the two.

Note that if a type `C`

is exact for the operations it implement then `isexact<C>::T`

is `true_t`

.

`subsetof<X,Y>`

trait is a boolean trait class, specifying if `X`

is a subset of `Y`

. For example given a kernel `K`

, `subsetof<K::integer,K::rational>`

`T`

is `true_t.`

The `sup<X,Y>`

is a more general concept used to choose a data type enclosing `X`

and `Y`

for all these operations, `it correspond to default value of `

`ringof`

and `fieldof`

, if `sup<X,Y>`

is not defined but `X`

`issubsetof`

of `Y`

, then `sup<X,Y>`

is defined by `Y`

.

`integerof`

(`rationalof,floatingof,ieeeof`

) trait.
For number type defined outside a kernel, `ieeeof`

defines `double`

.

`isinteger<C>::T`

(`isrational,isfloating,isieee`

) is `true_t`

if `C`

is an integer (rational, floating, ieee).

`C`

. This type is given by `algebraic_closure<C>::T`

. It can be used as follows:

algebraic_closure< complex<double> >::T // is complex<double> algebraic_closure<double>::T // is complex<double>

`realof<C>`

is a traits class used to specify the type corresponding to the real closure of `C`

. This type is given by \ `realof<C>::T`

. Here is an example:

realof<complex<double> >::T // is double realof<double>::T // is double