1 /* boost random/detail/signed_unsigned_tools.hpp header file
\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
8 * See http://www.boost.org for most recent version including documentation.
\r
11 #ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
\r
12 #define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
\r
14 #include <boost/limits.hpp>
\r
15 #include <boost/config.hpp>
\r
16 #include <boost/type_traits/make_unsigned.hpp>
\r
24 * Compute x - y, we know that x >= y, return an unsigned value.
\r
27 template<class T, bool sgn = std::numeric_limits<T>::is_signed>
\r
28 struct subtract { };
\r
31 struct subtract<T, /* signed */ false>
\r
33 typedef T result_type;
\r
34 result_type operator()(T x, T y) { return x - y; }
\r
38 struct subtract<T, /* signed */ true>
\r
40 typedef typename make_unsigned<T>::type result_type;
\r
41 result_type operator()(T x, T y)
\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
54 * Compute x + y, x is unsigned, result fits in type of "y".
\r
57 template<class T1, class T2, bool sgn = std::numeric_limits<T2>::is_signed>
\r
60 template<class T1, class T2>
\r
61 struct add<T1, T2, /* signed */ false>
\r
63 typedef T2 result_type;
\r
64 result_type operator()(T1 x, T2 y) { return T2(x) + y; }
\r
67 template<class T1, class T2>
\r
68 struct add<T1, T2, /* signed */ true>
\r
70 typedef T2 result_type;
\r
71 result_type operator()(T1 x, T2 y)
\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
84 } // namespace detail
\r
85 } // namespace random
\r
86 } // namespace boost
\r
88 #endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
\r