#ifndef FIELD_TRAITS_DEFINED #define FIELD_TRAITS_DEFINED #include #ifdef RATIONAL #include #endif struct arith_unknown {}; struct arith_exact : public arith_unknown {}; struct arith_approx : public arith_unknown {}; //For any field F, a type Field_traits::arith_type will be defined. //It will be one of the three types above. This template will define it to //be arith_unknown. Normally this should be modified by an explicit or //partial specialization of the template. template< class F> struct Field_traits { typedef arith_unknown arith_type; }; // Specializations of Field_traits for builtin and standard library field // types with approximate arithmetic. For each such type, we define // a static member function insignificant() returning double (or // convertible to double). // Type double has approximate arithmetic. template<> struct Field_traits { typedef arith_approx arith_type; static double insignificant() { return 1.0e-12;} }; // Type float has approximate arithmetic template<> struct Field_traits { typedef arith_approx arith_type; static double insignificant() { return 1.0e-4;} }; // Type long double has approximate arithmetic. template<> struct Field_traits { typedef arith_approx arith_type; static double insignificant() { return 1.0e-15;} }; // Type complex has the same type of arithmetic as class X (in // practice, approximate). template struct Field_traits > { typedef typename Field_traits::arith_type arith_type; static double insignificant() { return 1.5 * Field_traits::insignificant();} }; #ifdef RATIONAL // Specialization of Field_traits for class Rational of libg++, with exact // arithmetic. template<> struct Field_traits { typedef arith_unknown arith_exact; }; #endif #endif