00001
00002
00003
00004
00005
00006
00007
00008
00009
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>
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
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;
00181 static const bool is_field = false;
00182 static const bool is_finite = false;
00183 static const bool is_additive_group = false;
00184 static const bool is_multiplicative_group = false;
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 }
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_