File indexing completed on 2025-01-18 09:42:12
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MP_CPP_INT_ADD_HPP
0009 #define BOOST_MP_CPP_INT_ADD_HPP
0010
0011 #include <boost/multiprecision/detail/constexpr.hpp>
0012 #include <boost/multiprecision/cpp_int/add_unsigned.hpp>
0013
0014 namespace boost { namespace multiprecision { namespace backends {
0015
0016
0017
0018
0019 template <class CppInt1, class CppInt2>
0020 inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) noexcept(is_non_throwing_cpp_int<CppInt1>::value)
0021 {
0022
0023
0024 if (&result != &a)
0025 result.resize(a.size(), a.size());
0026 double_limb_type carry = o;
0027 typename CppInt1::limb_pointer pr = result.limbs();
0028 typename CppInt2::const_limb_pointer pa = a.limbs();
0029 std::size_t i = 0;
0030
0031 for (; carry && (i < result.size()); ++i)
0032 {
0033 carry += static_cast<double_limb_type>(pa[i]);
0034 #ifdef __MSVC_RUNTIME_CHECKS
0035 pr[i] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
0036 #else
0037 pr[i] = static_cast<limb_type>(carry);
0038 #endif
0039 carry >>= CppInt1::limb_bits;
0040 }
0041
0042 if (&a != &result)
0043 {
0044 std_constexpr::copy(pa + i, pa + a.size(), pr + i);
0045 }
0046 if (carry)
0047 {
0048
0049 std::size_t x = result.size();
0050 result.resize(x + 1, x + 1);
0051 if (result.size() > x)
0052 result.limbs()[x] = static_cast<limb_type>(carry);
0053 }
0054 result.normalize();
0055 result.sign(a.sign());
0056 }
0057
0058
0059
0060 template <class CppInt1, class CppInt2>
0061 inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) noexcept(is_non_throwing_cpp_int<CppInt1>::value)
0062 {
0063
0064
0065 constexpr double_limb_type borrow = static_cast<double_limb_type>(CppInt1::max_limb_value) + 1;
0066 result.resize(a.size(), a.size());
0067 typename CppInt1::limb_pointer pr = result.limbs();
0068 typename CppInt2::const_limb_pointer pa = a.limbs();
0069 if (*pa >= b)
0070 {
0071 *pr = *pa - b;
0072 if (&result != &a)
0073 {
0074 std_constexpr::copy(pa + 1, pa + a.size(), pr + 1);
0075 result.sign(a.sign());
0076 }
0077 else if ((result.size() == 1) && (*pr == 0))
0078 {
0079 result.sign(false);
0080 }
0081 }
0082 else if (result.size() == 1)
0083 {
0084 *pr = b - *pa;
0085 result.sign(!a.sign());
0086 }
0087 else
0088 {
0089 *pr = static_cast<limb_type>((borrow + *pa) - b);
0090 std::size_t i = 1;
0091 while (!pa[i])
0092 {
0093 pr[i] = CppInt1::max_limb_value;
0094 ++i;
0095 }
0096 pr[i] = pa[i] - 1;
0097 if (&result != &a)
0098 {
0099 ++i;
0100 std_constexpr::copy(pa + i, pa + a.size(), pr + i);
0101 }
0102 result.normalize();
0103 result.sign(a.sign());
0104 }
0105 }
0106
0107
0108
0109
0110 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0111 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0112 eval_add(
0113 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0114 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0115 {
0116 eval_add(result, result, o);
0117 }
0118 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
0119 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type
0120 eval_add(
0121 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0122 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0123 const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0124 {
0125 if (a.sign() != b.sign())
0126 {
0127 subtract_unsigned(result, a, b);
0128 return;
0129 }
0130 add_unsigned(result, a, b);
0131 }
0132 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0133 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0134 eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0135 {
0136 if (result.sign())
0137 {
0138 subtract_unsigned(result, result, o);
0139 }
0140 else
0141 add_unsigned(result, result, o);
0142 }
0143 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0144 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0145 eval_add(
0146 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0147 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0148 const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0149 {
0150 if (a.sign())
0151 {
0152 subtract_unsigned(result, a, o);
0153 }
0154 else
0155 add_unsigned(result, a, o);
0156 }
0157 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0158 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0159 eval_add(
0160 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0161 const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0162 {
0163 if (o < 0)
0164 eval_subtract(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
0165 else if (o > 0)
0166 eval_add(result, static_cast<limb_type>(o));
0167 }
0168 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0169 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0170 eval_add(
0171 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0172 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0173 const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0174 {
0175 if (o < 0)
0176 eval_subtract(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
0177 else if (o > 0)
0178 eval_add(result, a, static_cast<limb_type>(o));
0179 else if (&result != &a)
0180 result = a;
0181 }
0182 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0183 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0184 eval_subtract(
0185 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0186 const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0187 {
0188 if (result.sign())
0189 {
0190 add_unsigned(result, result, o);
0191 }
0192 else
0193 subtract_unsigned(result, result, o);
0194 }
0195 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0196 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0197 eval_subtract(
0198 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0199 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0200 const limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0201 {
0202 if (a.sign())
0203 {
0204 add_unsigned(result, a, o);
0205 }
0206 else
0207 {
0208 subtract_unsigned(result, a, o);
0209 }
0210 }
0211 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0212 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0213 eval_subtract(
0214 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0215 const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0216 {
0217 if (o)
0218 {
0219 if (o < 0)
0220 eval_add(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
0221 else
0222 eval_subtract(result, static_cast<limb_type>(o));
0223 }
0224 }
0225 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0226 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0227 eval_subtract(
0228 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0229 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0230 const signed_limb_type& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0231 {
0232 if (o)
0233 {
0234 if (o < 0)
0235 eval_add(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
0236 else
0237 eval_subtract(result, a, static_cast<limb_type>(o));
0238 }
0239 else if (&result != &a)
0240 result = a;
0241 }
0242
0243 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0244 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0245 eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0246 {
0247 constexpr limb_type one = 1;
0248
0249 if (!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
0250 ++result.limbs()[0];
0251 else if (result.sign() && result.limbs()[0])
0252 {
0253 --result.limbs()[0];
0254 if (!result.limbs()[0] && (result.size() == 1))
0255 result.sign(false);
0256 }
0257 else
0258 eval_add(result, one);
0259 }
0260 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0261 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0262 eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0263 {
0264 constexpr limb_type one = 1;
0265
0266 if (!result.sign() && result.limbs()[0])
0267 --result.limbs()[0];
0268 else if (result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
0269 ++result.limbs()[0];
0270 else
0271 eval_subtract(result, one);
0272 }
0273 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
0274 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value>::type
0275 eval_subtract(
0276 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0277 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0278 {
0279 eval_subtract(result, result, o);
0280 }
0281 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, std::size_t MinBits2, std::size_t MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, std::size_t MinBits3, std::size_t MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
0282 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value>::type
0283 eval_subtract(
0284 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0285 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
0286 const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0287 {
0288 if (a.sign() != b.sign())
0289 {
0290 add_unsigned(result, a, b);
0291 return;
0292 }
0293 subtract_unsigned(result, a, b);
0294 }
0295
0296
0297
0298
0299
0300
0301 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0302 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0303 is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type
0304 eval_add(
0305 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0306 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0307 {
0308 if (result.sign() != o.sign())
0309 {
0310 if (*o.limbs() > *result.limbs())
0311 {
0312 *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0313 result.negate();
0314 }
0315 else
0316 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0317 }
0318 else
0319 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0320 result.normalize();
0321 }
0322
0323 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0324 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0325 is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0326 eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0327 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0328 {
0329 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0330 result.normalize();
0331 }
0332
0333
0334 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0335 inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0336 is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)>::type
0337 eval_subtract(
0338 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0339 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0340 {
0341 if (result.sign() != o.sign())
0342 {
0343 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0344 }
0345 else if (*result.limbs() < *o.limbs())
0346 {
0347 *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0348 result.negate();
0349 }
0350 else
0351 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0352 result.normalize();
0353 }
0354
0355 template <std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
0356 BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<
0357 is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
0358 eval_subtract(
0359 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
0360 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
0361 {
0362 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
0363 result.normalize();
0364 }
0365
0366 }}}
0367
0368 #endif