]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multiprecision/cpp_int/add.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / multiprecision / cpp_int / add.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////
2// Copyright 2012 John Maddock. Distributed under the Boost
3// Software License, Version 1.0. (See accompanying file
92f5a8d4 4// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
7c673cae
FG
5//
6// Comparison operators for cpp_int_backend:
7//
8#ifndef BOOST_MP_CPP_INT_ADD_HPP
9#define BOOST_MP_CPP_INT_ADD_HPP
10
92f5a8d4 11#include <boost/multiprecision/detail/constexpr.hpp>
20effc67 12#include <boost/multiprecision/cpp_int/add_unsigned.hpp>
92f5a8d4
TL
13
14namespace boost { namespace multiprecision { namespace backends {
7c673cae
FG
15
16#ifdef _MSC_VER
17#pragma warning(push)
92f5a8d4 18#pragma warning(disable : 4127) // conditional expression is constant
7c673cae
FG
19#endif
20
7c673cae
FG
21//
22// As above, but for adding a single limb to a non-trivial cpp_int:
23//
24template <class CppInt1, class CppInt2>
92f5a8d4 25inline BOOST_MP_CXX14_CONSTEXPR void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
7c673cae
FG
26{
27 // Addition using modular arithmetic.
28 // Nothing fancy, just let uintmax_t take the strain:
92f5a8d4 29 if (&result != &a)
7c673cae 30 result.resize(a.size(), a.size());
92f5a8d4
TL
31 double_limb_type carry = o;
32 typename CppInt1::limb_pointer pr = result.limbs();
33 typename CppInt2::const_limb_pointer pa = a.limbs();
34 unsigned i = 0;
7c673cae 35 // Addition with carry until we either run out of digits or carry is zero:
92f5a8d4 36 for (; carry && (i < result.size()); ++i)
7c673cae
FG
37 {
38 carry += static_cast<double_limb_type>(pa[i]);
39#ifdef __MSVC_RUNTIME_CHECKS
40 pr[i] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
41#else
42 pr[i] = static_cast<limb_type>(carry);
43#endif
44 carry >>= CppInt1::limb_bits;
45 }
46 // Just copy any remaining digits:
92f5a8d4 47 if (&a != &result)
7c673cae 48 {
20effc67 49 std_constexpr::copy(pa + i, pa + a.size(), pr + i);
7c673cae 50 }
92f5a8d4 51 if (carry)
7c673cae
FG
52 {
53 // We overflowed, need to add one more limb:
54 unsigned x = result.size();
55 result.resize(x + 1, x + 1);
92f5a8d4 56 if (result.size() > x)
7c673cae
FG
57 result.limbs()[x] = static_cast<limb_type>(carry);
58 }
59 result.normalize();
60 result.sign(a.sign());
61}
62//
7c673cae
FG
63// And again to subtract a single limb:
64//
65template <class CppInt1, class CppInt2>
92f5a8d4 66inline BOOST_MP_CXX14_CONSTEXPR void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int<CppInt1>::value)
7c673cae
FG
67{
68 // Subtract one limb.
69 // Nothing fancy, just let uintmax_t take the strain:
92f5a8d4 70#ifdef BOOST_NO_CXX14_CONSTEXPR
7c673cae 71 BOOST_STATIC_CONSTANT(double_limb_type, borrow = static_cast<double_limb_type>(CppInt1::max_limb_value) + 1);
92f5a8d4
TL
72#else
73 constexpr double_limb_type borrow = static_cast<double_limb_type>(CppInt1::max_limb_value) + 1;
74#endif
7c673cae 75 result.resize(a.size(), a.size());
92f5a8d4 76 typename CppInt1::limb_pointer pr = result.limbs();
7c673cae 77 typename CppInt2::const_limb_pointer pa = a.limbs();
92f5a8d4 78 if (*pa >= b)
7c673cae
FG
79 {
80 *pr = *pa - b;
92f5a8d4 81 if (&result != &a)
7c673cae 82 {
92f5a8d4 83 std_constexpr::copy(pa + 1, pa + a.size(), pr + 1);
7c673cae
FG
84 result.sign(a.sign());
85 }
92f5a8d4 86 else if ((result.size() == 1) && (*pr == 0))
7c673cae
FG
87 {
88 result.sign(false); // zero is unsigned.
89 }
90 }
92f5a8d4 91 else if (result.size() == 1)
7c673cae
FG
92 {
93 *pr = b - *pa;
94 result.sign(!a.sign());
95 }
96 else
97 {
92f5a8d4 98 *pr = static_cast<limb_type>((borrow + *pa) - b);
7c673cae 99 unsigned i = 1;
92f5a8d4 100 while (!pa[i])
7c673cae
FG
101 {
102 pr[i] = CppInt1::max_limb_value;
103 ++i;
104 }
105 pr[i] = pa[i] - 1;
92f5a8d4 106 if (&result != &a)
7c673cae
FG
107 {
108 ++i;
92f5a8d4 109 std_constexpr::copy(pa + i, pa + a.size(), pr + i);
7c673cae
FG
110 }
111 result.normalize();
112 result.sign(a.sign());
113 }
114}
115
116//
117// Now the actual functions called by the front end, all of which forward to one of the above:
118//
119template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
120BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
121eval_add(
122 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
123 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae
FG
124{
125 eval_add(result, result, o);
126}
127template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
92f5a8d4
TL
128inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
129eval_add(
130 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
131 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
132 const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 133{
92f5a8d4 134 if (a.sign() != b.sign())
7c673cae
FG
135 {
136 subtract_unsigned(result, a, b);
137 return;
138 }
139 add_unsigned(result, a, b);
140}
141template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
142BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
143eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 144{
92f5a8d4 145 if (result.sign())
7c673cae
FG
146 {
147 subtract_unsigned(result, result, o);
148 }
149 else
150 add_unsigned(result, result, o);
151}
152template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
153BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
154eval_add(
155 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
156 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
157 const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 158{
92f5a8d4 159 if (a.sign())
7c673cae
FG
160 {
161 subtract_unsigned(result, a, o);
162 }
163 else
164 add_unsigned(result, a, o);
165}
166template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
167BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
168eval_add(
169 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
170 const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 171{
92f5a8d4 172 if (o < 0)
7c673cae 173 eval_subtract(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
92f5a8d4 174 else if (o > 0)
7c673cae
FG
175 eval_add(result, static_cast<limb_type>(o));
176}
177template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
178BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
179eval_add(
180 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
181 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
182 const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 183{
92f5a8d4 184 if (o < 0)
7c673cae 185 eval_subtract(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
92f5a8d4 186 else if (o > 0)
7c673cae 187 eval_add(result, a, static_cast<limb_type>(o));
92f5a8d4 188 else if (&result != &a)
7c673cae
FG
189 result = a;
190}
191template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
192BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
193eval_subtract(
194 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
195 const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 196{
92f5a8d4 197 if (result.sign())
7c673cae
FG
198 {
199 add_unsigned(result, result, o);
200 }
201 else
202 subtract_unsigned(result, result, o);
203}
204template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
205BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
206eval_subtract(
207 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
208 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
209 const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 210{
92f5a8d4 211 if (a.sign())
7c673cae
FG
212 {
213 add_unsigned(result, a, o);
214 }
215 else
216 {
217 subtract_unsigned(result, a, o);
218 }
219}
220template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
221BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
222eval_subtract(
223 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
224 const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 225{
92f5a8d4 226 if (o)
7c673cae 227 {
92f5a8d4 228 if (o < 0)
7c673cae
FG
229 eval_add(result, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
230 else
231 eval_subtract(result, static_cast<limb_type>(o));
232 }
233}
234template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
235BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
236eval_subtract(
237 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
238 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
239 const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 240{
92f5a8d4 241 if (o)
7c673cae 242 {
92f5a8d4 243 if (o < 0)
7c673cae
FG
244 eval_add(result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(o)));
245 else
246 eval_subtract(result, a, static_cast<limb_type>(o));
247 }
92f5a8d4 248 else if (&result != &a)
7c673cae
FG
249 result = a;
250}
251
252template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
253BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
254eval_increment(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 255{
92f5a8d4 256#ifdef BOOST_NO_CXX14_CONSTEXPR
7c673cae 257 static const limb_type one = 1;
92f5a8d4
TL
258#else
259 constexpr const limb_type one = 1;
260#endif
261 if (!result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
7c673cae 262 ++result.limbs()[0];
11fdf7f2
TL
263 else if (result.sign() && result.limbs()[0])
264 {
7c673cae 265 --result.limbs()[0];
11fdf7f2
TL
266 if (!result.limbs()[0])
267 result.sign(false);
268 }
7c673cae
FG
269 else
270 eval_add(result, one);
271}
272template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
273BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
274eval_decrement(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 275{
92f5a8d4 276#ifdef BOOST_NO_CXX14_CONSTEXPR
7c673cae 277 static const limb_type one = 1;
92f5a8d4
TL
278#else
279 constexpr const limb_type one = 1;
280#endif
281 if (!result.sign() && result.limbs()[0])
7c673cae 282 --result.limbs()[0];
11fdf7f2 283 else if (result.sign() && (result.limbs()[0] < cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value))
7c673cae
FG
284 ++result.limbs()[0];
285 else
286 eval_subtract(result, one);
287}
288template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
92f5a8d4
TL
289BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
290eval_subtract(
291 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
292 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae
FG
293{
294 eval_subtract(result, result, o);
295}
296template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
92f5a8d4
TL
297BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<!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
298eval_subtract(
299 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
300 const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
301 const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 302{
92f5a8d4 303 if (a.sign() != b.sign())
7c673cae
FG
304 {
305 add_unsigned(result, a, b);
306 return;
307 }
308 subtract_unsigned(result, a, b);
309}
310
311//
312// Simple addition and subtraction routine for trivial cpp_int's come last:
313//
314// One of the arguments is signed:
315//
316template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
317inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<
318 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
319eval_add(
320 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
321 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 322{
92f5a8d4 323 if (result.sign() != o.sign())
7c673cae 324 {
92f5a8d4 325 if (*o.limbs() > *result.limbs())
7c673cae
FG
326 {
327 *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
328 result.negate();
329 }
330 else
331 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
332 }
333 else
334 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
335 result.normalize();
336}
337// Simple version for two unsigned arguments:
338template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
339BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<
340 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
341eval_add(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
342 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae
FG
343{
344 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
345 result.normalize();
346}
347
348// signed subtraction:
349template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
350inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<
351 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
352eval_subtract(
353 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
354 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae 355{
92f5a8d4 356 if (result.sign() != o.sign())
7c673cae
FG
357 {
358 *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
359 }
92f5a8d4 360 else if (*result.limbs() < *o.limbs())
7c673cae
FG
361 {
362 *result.limbs() = detail::checked_subtract(*o.limbs(), *result.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
363 result.negate();
364 }
365 else
366 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
367 result.normalize();
368}
369
370template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
92f5a8d4
TL
371BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<
372 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
373eval_subtract(
374 cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
375 const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
7c673cae
FG
376{
377 *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
378 result.normalize();
379}
380
381#ifdef _MSC_VER
382#pragma warning(pop)
383#endif
384
92f5a8d4 385}}} // namespace boost::multiprecision::backends
7c673cae
FG
386
387#endif