File indexing completed on 2025-01-18 09:51:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
0012 #define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
0013
0014 #include <boost/limits.hpp>
0015 #include <boost/config.hpp>
0016 #include <boost/random/traits.hpp>
0017
0018 namespace boost {
0019 namespace random {
0020 namespace detail {
0021
0022
0023
0024
0025
0026
0027 template<class T, bool sgn = std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_bounded>
0028 struct subtract { };
0029
0030 template<class T>
0031 struct subtract<T, false>
0032 {
0033 typedef T result_type;
0034 result_type operator()(T x, T y) { return x - y; }
0035 };
0036
0037 template<class T>
0038 struct subtract<T, true>
0039 {
0040 typedef typename boost::random::traits::make_unsigned_or_unbounded<T>::type result_type;
0041 result_type operator()(T x, T y)
0042 {
0043 if (y >= 0)
0044 return result_type(x) - result_type(y);
0045 if (x >= 0)
0046
0047 return result_type(x) + result_type(-(y+1)) + 1;
0048
0049 return result_type(x - y);
0050 }
0051 };
0052
0053
0054
0055
0056
0057 template<class T1, class T2, bool sgn = (std::numeric_limits<T2>::is_signed && (std::numeric_limits<T1>::digits >= std::numeric_limits<T2>::digits))>
0058 struct add { };
0059
0060 template<class T1, class T2>
0061 struct add<T1, T2, false>
0062 {
0063 typedef T2 result_type;
0064 result_type operator()(T1 x, T2 y) { return T2(x) + y; }
0065 };
0066
0067 template<class T1, class T2>
0068 struct add<T1, T2, true>
0069 {
0070 typedef T2 result_type;
0071 result_type operator()(T1 x, T2 y)
0072 {
0073 if (y >= 0)
0074 return T2(x) + y;
0075
0076 if (x > T1(-(y+1)))
0077
0078 return T2(x - T1(-(y+1)) - 1);
0079
0080 return T2(x) + y;
0081 }
0082 };
0083
0084 }
0085 }
0086 }
0087
0088 #endif
0089