type_traits.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     type_traits.hpp -- additional information about types.
00004 
00005     This file is part of the Arageli library.
00006 
00007     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00008     Copyright (C) Sergey S. Lyalin, 2005--2006
00009     University of Nizhni Novgorod, Russia
00010 
00011 *****************************************************************************/
00012 
00024 #ifndef _ARAGELI_type_traits_hpp_
00025 #define _ARAGELI_type_traits_hpp_
00026 
00027 
00028 #include "config.hpp"
00029 
00030 #include <cstddef>
00031 #include <limits>
00032 #include <complex>  // for specialization of type_traits
00033 #include <iostream>
00034 
00035 #include "type_opers.hpp"
00036 
00037 
00038 //****************************************************************************
00039 
00040 
00041 namespace std
00042 {
00043 
00044 #define _ARAGELI_STCONS(TYPE, NAME, VALUE)static const TYPE NAME = VALUE
00045 
00047 
00049 template <typename T, std::size_t Size> class numeric_limits<T[Size]>
00050 {
00051 public:
00052 
00053     _ARAGELI_STCONS(float_denorm_style, has_denorm, denorm_absent);
00054     _ARAGELI_STCONS(bool, has_denorm_loss, false);
00055     _ARAGELI_STCONS(bool, has_infinity, false);
00056     _ARAGELI_STCONS(bool, has_quiet_NaN, false);
00057     _ARAGELI_STCONS(bool, has_signaling_NaN, false);
00058     _ARAGELI_STCONS(bool, is_bounded, false);
00059     _ARAGELI_STCONS(bool, is_exact, false);
00060     _ARAGELI_STCONS(bool, is_iec559, false);
00061     _ARAGELI_STCONS(bool, is_integer, false);
00062     _ARAGELI_STCONS(bool, is_modulo, false);
00063     _ARAGELI_STCONS(bool, is_signed, false);
00064     _ARAGELI_STCONS(bool, is_specialized, false);
00065     _ARAGELI_STCONS(bool, tinyness_before, false);
00066     _ARAGELI_STCONS(bool, traps, false);
00067     _ARAGELI_STCONS(float_round_style, round_style, round_toward_zero);
00068     _ARAGELI_STCONS(int, digits, 0);
00069     _ARAGELI_STCONS(int, digits10, 0);
00070     _ARAGELI_STCONS(int, max_exponent, 0);
00071     _ARAGELI_STCONS(int, max_exponent10, 0);
00072     _ARAGELI_STCONS(int, min_exponent, 0);
00073     _ARAGELI_STCONS(int, min_exponent10, 0);
00074     _ARAGELI_STCONS(int, radix, 0);
00075 
00076 };
00077 
00078 #undef _ARAGELI_STCONS
00079 
00080 }
00081 
00082 
00083 //****************************************************************************
00084 
00085 
00086 namespace Arageli
00087 {
00088 
00089 
00091 
00096 namespace type_category
00097 {
00099     class type {};
00100     
00101     class matrix : public type {};
00102     class dense_matrix : public matrix {};
00103     class sparse_matrix : public matrix {};
00104 
00105     class vector : public type {};
00106     class dense_vector : public vector {};
00107     class sparse_vector : public vector {};
00108 
00109     class polynom : public type {};
00110     class dense_polynom : public polynom {};
00111     class sparse_polynom : public polynom {};
00112 
00113     class number : public type {};
00114     class rational : public number {};
00115     class integer : public number {};
00116     class real : public number {};
00117     class complex : public number {};
00118     class algebraic : public number {};
00119 
00120     class factory : public type {};
00121     class type_traits : public type {};
00122     class iomanip : public type {};
00123     class iostream : public type {};
00124     class iterator : public type {};
00125     class string : public type {};
00126 }
00127 
00128 
00129 namespace _Internal
00130 {
00131     
00132 // Select from interger and real category based on some properties.
00133 template <bool is_specialized, bool is_integer>
00134 struct auto_type_category_by_numeric_limits_helper
00135 { typedef type_category::type value_type; };
00136 
00137 template <>
00138 struct auto_type_category_by_numeric_limits_helper<true, false>
00139 { typedef type_category::real value_type; };
00140 
00141 template <>
00142 struct auto_type_category_by_numeric_limits_helper<true, true>
00143 { typedef type_category::integer value_type; };
00144 
00145 }
00146 
00148 
00151 template <typename T>
00152 struct auto_type_category_by_numeric_limits
00153 {
00154     typedef
00155         typename _Internal::auto_type_category_by_numeric_limits_helper
00156         <
00157             std::numeric_limits<T>::is_specialized,
00158             std::numeric_limits<T>::is_integer
00159         >::value_type
00160             value_type;
00161 };
00162 
00163 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00164 
00166 template <typename T>
00167 struct type_traits_default
00168 {
00169     static const bool is_specialized = false;
00170 
00172     static const bool is_rational = false;
00173     
00174     static const bool is_number = false;
00175     static const bool is_integer_number = false;
00176     static const bool is_polynom = false;
00177     static const bool is_real_number = false;
00178     static const bool is_rational_number = false;
00179     static const bool is_complex_number = false;
00180     static const bool is_ring = false;  // +, -, *, null, unit
00181     static const bool is_field = false; // +, -, *, /, null, unit
00182     static const bool is_finite = false;
00183     static const bool is_additive_group = false;    // +, -, null
00184     static const bool is_multiplicative_group = false;  // *, /, unit
00185     static const bool is_integer_modulo_ring = false;
00186     static const bool is_matrix = false;
00187     static const bool is_vector = false;
00188     
00189     static const bool has_zero_divisor = true;
00190     static const bool has_commutative_multiplication = false;
00191     static const bool has_commutative_addition = false;
00192     static const bool has_associative_multiplication = false;
00193     static const bool has_associative_addition = false;
00194     static const bool has_distributive_multiplication = false;
00195     static const bool has_distributive_addition = false;
00196     static const bool has_null = false;
00197     static const bool has_unit = false;
00198     static const bool has_opposite_unit = false;
00199     static const bool is_entire_ring = false;
00200 
00202     static const bool is_aggregate = false;
00203 
00205     typedef T element_type;
00206 
00207     template <typename T1, bool REFCNT2>
00208     struct other_element_type_refcnt;
00209 
00210     typedef type_category::type category_type;
00211     static const category_type category_value;
00212 };
00213 
00214 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00215 
00217 
00219 template <typename T>
00220 struct type_traits : public type_traits_default<T>
00221 {
00222 private:
00223     
00224     typedef std::numeric_limits<T> numeric_limits;
00225 
00226 public:
00227     
00228     static const bool is_specialized = numeric_limits::is_specialized;
00229     static const bool is_rational = false;
00230     static const bool is_number = numeric_limits::is_specialized;
00231     static const bool is_integer_number = numeric_limits::is_integer;
00232     static const bool is_polynom = false;
00233     static const bool is_real_number = !numeric_limits::is_integer;
00234     static const bool is_rational_number = false;
00235     static const bool is_complex_number = false;
00236     static const bool is_ring = numeric_limits::is_integer;
00237 
00238     static const bool is_field =
00239                         !numeric_limits::is_integer ||
00240                         equal_types<bool, T>::bvalue;
00241 
00242     static const bool is_finite = equal_types<bool, T>::bvalue;
00243     static const bool is_additive_group = numeric_limits::is_signed;
00244 
00245     static const bool is_multiplicative_group =
00246                         !numeric_limits::is_integer ||
00247                         equal_types<bool, T>::bvalue;
00248 
00249     static const bool has_zero_divisor = false;
00250     static const bool is_integer_modulo_ring = equal_types<bool, T>::bvalue;
00251     static const bool is_matrix = false;
00252     static const bool is_vector = false;
00253     static const bool has_commutative_multiplication = true;
00254     static const bool has_commutative_addition = true;
00255     static const bool has_associative_multiplication = true;
00256     static const bool has_associative_addition = true;
00257     static const bool has_distributive_multiplication = true;
00258     static const bool has_distributive_addition = true;
00259     static const bool has_null = true;
00260     static const bool has_unit = true;
00261     static const bool has_opposite_unit = true;
00262 
00263     static const bool is_entire_ring =
00264                         is_ring &&
00265                         has_associative_multiplication &&
00266                         has_commutative_multiplication;
00267 
00268     static const bool is_aggregate = false;
00269     typedef T element_type;
00270     typedef typename auto_type_category_by_numeric_limits<T>::value_type category_type;
00271     static const category_type category_value;
00272 };
00273 
00274 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00275 
00277 template <typename T>
00278 struct type_traits<std::complex<T> >
00279     : public type_traits_default<std::complex<T> >
00280 {
00281     static const bool is_specialized = type_traits<T>::is_specialized;
00282     static const bool is_number = type_traits<T>::is_number;
00283     static const bool is_integer_number = false;
00284     static const bool is_polynom = false;
00285     static const bool is_real_number = false;
00286     static const bool is_rational_number = false;
00287     static const bool is_complex_number = type_traits<T>::is_number;
00288     static const bool is_ring = type_traits<T>::is_ring;
00289     static const bool is_field = type_traits<T>::is_field;
00290     static const bool is_finite = type_traits<T>::is_finite;
00291     static const bool is_additive_group = type_traits<T>::is_additive_group;
00292     static const bool is_multiplicative_group = type_traits<T>::is_multiplicative_group;
00293     static const bool has_zero_divisor = type_traits<T>::has_zero_divisor;
00294     static const bool is_integer_modulo_ring = false;
00295     static const bool is_matrix = false;
00296     static const bool is_vector = false;
00297     
00298     static const bool has_commutative_multiplication =
00299                         type_traits<T>::has_commutative_multiplication;
00300     
00301     static const bool has_commutative_addition =
00302                         type_traits<T>::has_commutative_addition;
00303 
00304     static const bool has_null = type_traits<T>::has_null;
00305     static const bool has_unit = type_traits<T>::has_unit;
00306     static const bool has_opposite_unit = type_traits<T>::has_opposite_unit;
00307     typedef type_category::complex category_type;
00308     static const category_type category_value;
00309 };
00310 
00311 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00312 
00313 template <typename Iter, typename Val>
00314 struct type_traits_iterator : public type_traits_default<Iter>
00315 {
00316     static const bool is_specialized = true;
00317     static const bool is_aggregate = true;
00318     typedef Val element_type;
00319     typedef type_category::iterator category_type;
00320     static const category_type category_value;
00321 };
00322 
00323 template <typename T>
00324 struct type_traits<T*> : public type_traits_iterator<T*, T> {};
00325 
00326 template <typename T, std::size_t Size>
00327 struct type_traits<T[Size]> : public type_traits_iterator<T[Size], T> {};
00328 
00329 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00330 
00331 template <typename Str, typename Char>
00332 struct type_traits_string : public type_traits_default<Str>
00333 {
00334     static const bool is_specialized = true;
00335     static const bool is_aggregate = true;
00336     typedef char element_type;
00337     typedef type_category::string category_type;
00338     static const category_type category_value;
00339 };
00340 
00341 
00342 template <> struct type_traits<const char*>
00343     : public type_traits_string<const char*, char> {};
00344 
00345 template <> struct type_traits<char*>
00346     : public type_traits_string<char*, char> {};
00347 
00348 template <std::size_t Size> struct type_traits<const char[Size]>
00349     : public type_traits_string<const char[Size], char> {};
00350 
00351 template <std::size_t Size> struct type_traits<char[Size]>
00352     : public type_traits_string<char[Size], char> {};
00353 
00354 template <> struct type_traits<const wchar_t*>
00355     : public type_traits_string<const wchar_t*, wchar_t> {};
00356 
00357 template <> struct type_traits<wchar_t*>
00358     : public type_traits_string<wchar_t*, wchar_t> {};
00359 
00360 template <std::size_t Size> struct type_traits<const wchar_t[Size]>
00361     : public type_traits_string<const wchar_t[Size], wchar_t> {};
00362 
00363 template <std::size_t Size> struct type_traits<wchar_t[Size]>
00364     : public type_traits_string<wchar_t[Size], wchar_t> {};
00365 
00366 template <typename Char, typename CharTr, typename A>
00367 struct type_traits<std::basic_string<Char, CharTr, A> >
00368     : public type_traits_string<std::basic_string<Char, CharTr, A>, Char> {};
00369 
00370 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00371 
00372 template <typename Str>
00373 struct type_traits_iostream : public type_traits_default<Str>
00374 {
00375     static const bool is_specialized = true;
00376     static const bool is_aggregate = false;
00377     typedef type_category::iostream category_type;
00378     static const category_type category_value;
00379 };
00380 
00381 
00382 template <typename Ch, typename ChT>
00383 struct type_traits<std::basic_istream<Ch, ChT> >
00384     : public type_traits_iostream<std::basic_istream<Ch, ChT> > {};
00385 
00386 template <typename Ch, typename ChT>
00387 struct type_traits<std::basic_ostream<Ch, ChT> >
00388     : public type_traits_iostream<std::basic_ostream<Ch, ChT> > {};
00389 
00390 
00391 
00392 } // namespace Arageli
00393 
00394 
00395 
00396 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00397     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_TYPE_TRAITS
00398     #include "type_traits.cpp"
00399     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_TYPE_TRAITS
00400 #endif
00401 
00402 
00403 #endif  //  #ifndef _ARAGELI_typetraits_hpp_

Generated on Thu Aug 31 17:38:12 2006 for Arageli by  doxygen 1.4.7