File indexing completed on 2025-10-31 08:55:37
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