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

Private GIT Repository
c1344a3dec9495b05e03c8cd09e53813b7a8de79
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / random / detail / signed_unsigned_tools.hpp
1 /* boost random/detail/signed_unsigned_tools.hpp header file\r
2  *\r
3  * Copyright Jens Maurer 2006\r
4  * Distributed under the Boost Software License, Version 1.0. (See\r
5  * accompanying file LICENSE_1_0.txt or copy at\r
6  * http://www.boost.org/LICENSE_1_0.txt)\r
7  *\r
8  * See http://www.boost.org for most recent version including documentation.\r
9  */\r
10 \r
11 #ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS\r
12 #define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS\r
13 \r
14 #include <boost/limits.hpp>\r
15 #include <boost/config.hpp>\r
16 #include <boost/type_traits/make_unsigned.hpp>\r
17 \r
18 namespace boost {\r
19 namespace random {\r
20 namespace detail {\r
21 \r
22 \r
23 /*\r
24  * Compute x - y, we know that x >= y, return an unsigned value.\r
25  */\r
26 \r
27 template<class T, bool sgn = std::numeric_limits<T>::is_signed>\r
28 struct subtract { };\r
29 \r
30 template<class T>\r
31 struct subtract<T, /* signed */ false>\r
32 {\r
33   typedef T result_type;\r
34   result_type operator()(T x, T y) { return x - y; }\r
35 };\r
36 \r
37 template<class T>\r
38 struct subtract<T, /* signed */ true>\r
39 {\r
40   typedef typename make_unsigned<T>::type result_type;\r
41   result_type operator()(T x, T y)\r
42   {\r
43     if (y >= 0)   // because x >= y, it follows that x >= 0, too\r
44       return result_type(x) - result_type(y);\r
45     if (x >= 0)   // y < 0\r
46       // avoid the nasty two's complement case for y == min()\r
47       return result_type(x) + result_type(-(y+1)) + 1;\r
48     // both x and y are negative: no signed overflow\r
49     return result_type(x - y);\r
50   }\r
51 };\r
52 \r
53 /*\r
54  * Compute x + y, x is unsigned, result fits in type of "y".\r
55  */\r
56 \r
57 template<class T1, class T2, bool sgn = std::numeric_limits<T2>::is_signed>\r
58 struct add { };\r
59 \r
60 template<class T1, class T2>\r
61 struct add<T1, T2, /* signed */ false>\r
62 {\r
63   typedef T2 result_type;\r
64   result_type operator()(T1 x, T2 y) { return T2(x) + y; }\r
65 };\r
66 \r
67 template<class T1, class T2>\r
68 struct add<T1, T2, /* signed */ true>\r
69 {\r
70   typedef T2 result_type;\r
71   result_type operator()(T1 x, T2 y)\r
72   {\r
73     if (y >= 0)\r
74       return T2(x) + y;\r
75     // y < 0\r
76     if (x >= T1(-(y+1)))  // result >= 0 after subtraction\r
77       // avoid the nasty two's complement edge case for y == min()\r
78       return T2(x - T1(-(y+1)) - 1);\r
79     // abs(x) < abs(y), thus T2 able to represent x\r
80     return T2(x) + y;\r
81   }\r
82 };\r
83 \r
84 } // namespace detail\r
85 } // namespace random\r
86 } // namespace boost\r
87 \r
88 #endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS\r
89 \r