]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/detail/numeric_traits.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
a44db9e5fe4600904850e6673ae8e17b0bd915f4
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / detail / numeric_traits.hpp
1 // (C) Copyright David Abrahams 2001, Howard Hinnant 2001.\r
2 //\r
3 // Distributed under the Boost Software License, Version 1.0. (See\r
4 // accompanying file LICENSE_1_0.txt or copy at\r
5 // http://www.boost.org/LICENSE_1_0.txt)\r
6 //\r
7 // Template class numeric_traits<Number> --\r
8 //\r
9 //    Supplies:\r
10 //\r
11 //      typedef difference_type -- a type used to represent the difference\r
12 //      between any two values of Number.\r
13 //\r
14 //    Support:\r
15 //      1. Not all specializations are supplied\r
16 //\r
17 //      2. Use of specializations that are not supplied will cause a\r
18 //      compile-time error\r
19 //\r
20 //      3. Users are free to specialize numeric_traits for any type.\r
21 //\r
22 //      4. Right now, specializations are only supplied for integer types.\r
23 //\r
24 //      5. On implementations which do not supply compile-time constants in\r
25 //      std::numeric_limits<>, only specializations for built-in integer types\r
26 //      are supplied.\r
27 //\r
28 //      6. Handling of numbers whose range of representation is at least as\r
29 //      great as boost::intmax_t can cause some differences to be\r
30 //      unrepresentable in difference_type:\r
31 //\r
32 //        Number    difference_type\r
33 //        ------    ---------------\r
34 //        signed    Number\r
35 //        unsigned  intmax_t\r
36 //\r
37 // template <class Number> typename numeric_traits<Number>::difference_type\r
38 // numeric_distance(Number x, Number y)\r
39 //    computes (y - x), attempting to avoid overflows.\r
40 //\r
41 \r
42 // See http://www.boost.org for most recent version including documentation.\r
43 \r
44 // Revision History\r
45 // 11 Feb 2001 - Use BOOST_STATIC_CONSTANT (David Abrahams)\r
46 // 11 Feb 2001 - Rolled back ineffective Borland-specific code\r
47 //               (David Abrahams)\r
48 // 10 Feb 2001 - Rolled in supposed Borland fixes from John Maddock, but\r
49 //               not seeing any improvement yet (David Abrahams)\r
50 // 06 Feb 2001 - Factored if_true out into boost/detail/select_type.hpp\r
51 //               (David Abrahams)\r
52 // 23 Jan 2001 - Fixed logic of difference_type selection, which was\r
53 //               completely wack. In the process, added digit_traits<>\r
54 //               to compute the number of digits in intmax_t even when\r
55 //               not supplied by numeric_limits<>. (David Abrahams)\r
56 // 21 Jan 2001 - Created (David Abrahams)\r
57 \r
58 #ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901\r
59 # define BOOST_NUMERIC_TRAITS_HPP_DWA20001901\r
60 \r
61 # include <boost/config.hpp>\r
62 # include <boost/cstdint.hpp>\r
63 # include <boost/static_assert.hpp>\r
64 # include <boost/type_traits.hpp>\r
65 # include <boost/detail/select_type.hpp>\r
66 # include <boost/limits.hpp>\r
67 \r
68 namespace boost { namespace detail {\r
69 \r
70   // Template class is_signed -- determine whether a numeric type is signed\r
71   // Requires that T is constructable from the literals -1 and 0.  Compile-time\r
72   // error results if that requirement is not met (and thus signedness is not\r
73   // likely to have meaning for that type).\r
74   template <class Number>\r
75   struct is_signed\r
76   {\r
77 #if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300\r
78     BOOST_STATIC_CONSTANT(bool, value = (Number(-1) < Number(0)));\r
79 #else\r
80     BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<Number>::is_signed);\r
81 #endif\r
82   };\r
83 \r
84 # ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
85   // digit_traits - compute the number of digits in a built-in integer\r
86   // type. Needed for implementations on which numeric_limits is not specialized\r
87   // for intmax_t (e.g. VC6).\r
88   template <bool is_specialized> struct digit_traits_select;\r
89 \r
90   // numeric_limits is specialized; just select that version of digits\r
91   template <> struct digit_traits_select<true>\r
92   {\r
93       template <class T> struct traits\r
94       {\r
95           BOOST_STATIC_CONSTANT(int, digits = std::numeric_limits<T>::digits);\r
96       };\r
97   };\r
98 \r
99   // numeric_limits is not specialized; compute digits from sizeof(T)\r
100   template <> struct digit_traits_select<false>\r
101   {\r
102       template <class T> struct traits\r
103       {\r
104           BOOST_STATIC_CONSTANT(int, digits = (\r
105               sizeof(T) * std::numeric_limits<unsigned char>::digits\r
106               - (is_signed<T>::value ? 1 : 0))\r
107               );\r
108       };\r
109   };\r
110 \r
111   // here's the "usable" template\r
112   template <class T> struct digit_traits\r
113   {\r
114       typedef digit_traits_select<\r
115                 ::std::numeric_limits<T>::is_specialized> selector;\r
116       typedef typename selector::template traits<T> traits;\r
117       BOOST_STATIC_CONSTANT(int, digits = traits::digits);\r
118   };\r
119 #endif\r
120 \r
121   // Template class integer_traits<Integer> -- traits of various integer types\r
122   // This should probably be rolled into boost::integer_traits one day, but I\r
123   // need it to work without <limits>\r
124   template <class Integer>\r
125   struct integer_traits\r
126   {\r
127 # ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
128    private:\r
129       typedef Integer integer_type;\r
130       typedef std::numeric_limits<integer_type> x;\r
131 #   if defined(BOOST_MSVC) && BOOST_MSVC <= 1300\r
132       // for some reason, MSVC asserts when it shouldn't unless we make these\r
133       // local definitions\r
134       BOOST_STATIC_CONSTANT(bool, is_integer = x::is_integer);\r
135       BOOST_STATIC_CONSTANT(bool, is_specialized = x::is_specialized);\r
136       \r
137       BOOST_STATIC_ASSERT(is_integer);\r
138       BOOST_STATIC_ASSERT(is_specialized);\r
139 #   endif\r
140    public:\r
141       typedef typename\r
142       if_true<(int(x::is_signed)\r
143               && (!int(x::is_bounded)\r
144                  // digits is the number of no-sign bits\r
145                   || (int(x::digits) + 1 >= digit_traits<boost::intmax_t>::digits)))>::template then<\r
146         Integer,\r
147           \r
148       typename if_true<(int(x::digits) + 1 < digit_traits<signed int>::digits)>::template then<\r
149         signed int,\r
150 \r
151       typename if_true<(int(x::digits) + 1 < digit_traits<signed long>::digits)>::template then<\r
152         signed long,\r
153 \r
154    // else\r
155         intmax_t\r
156       >::type>::type>::type difference_type;\r
157 #else\r
158       BOOST_STATIC_ASSERT(boost::is_integral<Integer>::value);\r
159 \r
160       typedef typename\r
161       if_true<(sizeof(Integer) >= sizeof(intmax_t))>::template then<\r
162                \r
163         typename if_true<(is_signed<Integer>::value)>::template then<\r
164           Integer,\r
165           intmax_t\r
166         >::type,\r
167 \r
168         typename if_true<(sizeof(Integer) < sizeof(std::ptrdiff_t))>::template then<\r
169           std::ptrdiff_t,\r
170           intmax_t\r
171         >::type\r
172       >::type difference_type;\r
173 # endif\r
174   };\r
175 \r
176   // Right now, only supports integers, but should be expanded.\r
177   template <class Number>\r
178   struct numeric_traits\r
179   {\r
180       typedef typename integer_traits<Number>::difference_type difference_type;\r
181   };\r
182 \r
183   template <class Number>\r
184   typename numeric_traits<Number>::difference_type numeric_distance(Number x, Number y)\r
185   {\r
186       typedef typename numeric_traits<Number>::difference_type difference_type;\r
187       return difference_type(y) - difference_type(x);\r
188   }\r
189 }}\r
190 \r
191 #endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901\r