1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2012 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5 //
6 // Comparison operators for cpp_int_backend:
7 //
8 #ifndef BOOST_MP_CPP_INT_COMPARISON_HPP
9 #define BOOST_MP_CPP_INT_COMPARISON_HPP
10 
11 #include <boost/type_traits/make_unsigned.hpp>
12 
13 namespace boost{ namespace multiprecision{ namespace backends{
14 
15 #ifdef BOOST_MSVC
16 #pragma warning(push)
17 #pragma warning(disable:4018 4389 4996)
18 #endif
19 
20 //
21 // Start with non-trivial cpp_int's:
22 //
23 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
24 BOOST_MP_FORCEINLINE typename enable_if_c<
25       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
26       bool
27    >::type
eval_eq(const cpp_int_backend<MinBits,MaxBits,SignType,Checked,Allocator> & a,const cpp_int_backend<MinBits,MaxBits,SignType,Checked,Allocator> & b)28    eval_eq(const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) BOOST_NOEXCEPT
29 {
30 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
31    return (a.sign() == b.sign())
32       && (a.size() == b.size())
33       && std::equal(a.limbs(), a.limbs() + a.size(),
34          stdext::checked_array_iterator<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::const_limb_pointer>(b.limbs(), b.size()));
35 #else
36    return (a.sign() == b.sign())
37       && (a.size() == b.size())
38       && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
39 #endif
40 }
41 template <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>
42 BOOST_MP_FORCEINLINE typename enable_if_c<
43       !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
44       && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
45       bool
46    >::type
eval_eq(const cpp_int_backend<MinBits1,MaxBits1,SignType1,Checked1,Allocator1> & a,const cpp_int_backend<MinBits2,MaxBits2,SignType2,Checked2,Allocator2> & b)47    eval_eq(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) BOOST_NOEXCEPT
48 {
49 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
50    return (a.sign() == b.sign())
51       && (a.size() == b.size())
52       && std::equal(a.limbs(), a.limbs() + a.size(), stdext::checked_array_iterator<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer>(b.limbs(), b.size()));
53 #else
54    return (a.sign() == b.sign())
55       && (a.size() == b.size())
56       && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
57 #endif
58 }
59 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
60 BOOST_MP_FORCEINLINE typename enable_if_c<
61       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
62       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,limb_type b)63    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
64 {
65    return (a.sign() == false)
66       && (a.size() == 1)
67       && (*a.limbs() == b);
68 }
69 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
70 BOOST_MP_FORCEINLINE typename enable_if_c<
71       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
72       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,signed_limb_type b)73    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
74 {
75    return (a.sign() == (b < 0))
76       && (a.size() == 1)
77       && (*a.limbs() == boost::multiprecision::detail::unsigned_abs(b));
78 }
79 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
80 BOOST_MP_FORCEINLINE typename enable_if_c<
81       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
82       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,limb_type b)83    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
84 {
85    return (a.size() == 1)
86       && (*a.limbs() == b);
87 }
88 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
89 BOOST_MP_FORCEINLINE typename enable_if_c<
90       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
91       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,signed_limb_type b)92    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
93 {
94    return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
95 }
96 
97 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
98 BOOST_MP_FORCEINLINE typename enable_if_c<
99       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
100       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,limb_type b)101    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
102 {
103    if(a.sign())
104       return true;
105    if(a.size() > 1)
106       return false;
107    return *a.limbs() < b;
108 }
109 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
110 inline typename enable_if_c<
111       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
112       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,signed_limb_type b)113    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
114 {
115    if((b == 0) || (a.sign() != (b < 0)))
116       return a.sign();
117    if(a.sign())
118    {
119       if(a.size() > 1)
120          return true;
121       return *a.limbs() > boost::multiprecision::detail::unsigned_abs(b);
122    }
123    else
124    {
125       if(a.size() > 1)
126          return false;
127       return *a.limbs() < boost::multiprecision::detail::unsigned_abs(b);
128    }
129 }
130 
131 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
132 BOOST_MP_FORCEINLINE typename enable_if_c<
133       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
134       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,limb_type b)135    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
136 {
137    if(a.size() > 1)
138       return false;
139    return *a.limbs() < b;
140 }
141 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
142 BOOST_MP_FORCEINLINE typename enable_if_c<
143       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
144       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,signed_limb_type b)145    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
146 {
147    return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
148 }
149 
150 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
151 BOOST_MP_FORCEINLINE typename enable_if_c<
152       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
153       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,limb_type b)154    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
155 {
156    if(a.sign())
157       return false;
158    if(a.size() > 1)
159       return true;
160    return *a.limbs() > b;
161 }
162 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
163 inline typename enable_if_c<
164       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
165       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,Allocator> & a,signed_limb_type b)166    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
167 {
168    if(b == 0)
169       return !a.sign() && ((a.size() > 1) || *a.limbs());
170    if(a.sign() != (b < 0))
171       return !a.sign();
172    if(a.sign())
173    {
174       if(a.size() > 1)
175          return false;
176       return *a.limbs() < boost::multiprecision::detail::unsigned_abs(b);
177    }
178    else
179    {
180       if(a.size() > 1)
181          return true;
182       return *a.limbs() > boost::multiprecision::detail::unsigned_abs(b);
183    }
184 }
185 
186 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
187 BOOST_MP_FORCEINLINE typename enable_if_c<
188       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
189       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,limb_type b)190    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
191 {
192    if(a.size() > 1)
193       return true;
194    return *a.limbs() > b;
195 }
196 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
197 BOOST_MP_FORCEINLINE typename enable_if_c<
198       !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
199       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,Allocator> & a,signed_limb_type b)200    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
201 {
202    return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison.
203 }
204 //
205 // And again for trivial cpp_ints:
206 //
207 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
208 BOOST_MP_FORCEINLINE typename enable_if_c<
209       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
210       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & b)211    >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
212 {
213    return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs());
214 }
215 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
216 BOOST_MP_FORCEINLINE typename enable_if_c<
217       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
218       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & b)219    >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
220 {
221    return *a.limbs() == *b.limbs();
222 }
223 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
224 BOOST_MP_FORCEINLINE typename enable_if_c<
225       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
226       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,U b)227    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
228 {
229    return !a.sign() && (*a.limbs() == b);
230 }
231 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
232 BOOST_MP_FORCEINLINE typename enable_if_c<
233       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
234       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,S b)235    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
236 {
237    return (a.sign() == (b < 0)) && (*a.limbs() == boost::multiprecision::detail::unsigned_abs(b));
238 }
239 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
240 BOOST_MP_FORCEINLINE typename enable_if_c<
241       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
242       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,U b)243    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
244 {
245    return *a.limbs() == b;
246 }
247 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
248 BOOST_MP_FORCEINLINE typename enable_if_c<
249       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
250       bool
eval_eq(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,S b)251    >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
252 {
253    typedef typename make_unsigned<S>::type ui_type;
254    if(b < 0)
255    {
256       cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
257       return *a.limbs() == *t.limbs();
258    }
259    else
260    {
261       return *a.limbs() == static_cast<ui_type>(b);
262    }
263 }
264 
265 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
266 BOOST_MP_FORCEINLINE typename enable_if_c<
267       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
268       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & b)269    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
270 {
271    if(a.sign() != b.sign())
272       return a.sign();
273    return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs();
274 }
275 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
276 BOOST_MP_FORCEINLINE typename enable_if_c<
277       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
278       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & b)279    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
280 {
281    return *a.limbs() < *b.limbs();
282 }
283 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
284 BOOST_MP_FORCEINLINE typename enable_if_c<
285       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
286       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,U b)287    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
288 {
289    if(a.sign())
290       return true;
291    return *a.limbs() < b;
292 }
293 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
294 BOOST_MP_FORCEINLINE typename enable_if_c<
295       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
296       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,S b)297    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
298 {
299    if(a.sign() != (b < 0))
300       return a.sign();
301    return a.sign() ? (*a.limbs() > boost::multiprecision::detail::unsigned_abs(b)) : (*a.limbs() < boost::multiprecision::detail::unsigned_abs(b));
302 }
303 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
304 BOOST_MP_FORCEINLINE typename enable_if_c<
305       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
306       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,U b)307    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
308 {
309    return *a.limbs() < b;
310 }
311 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
312 BOOST_MP_FORCEINLINE typename enable_if_c<
313       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
314       bool
eval_lt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,S b)315    >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
316 {
317    typedef typename make_unsigned<S>::type ui_type;
318    if(b < 0)
319    {
320       cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
321       return *a.limbs() < *t.limbs();
322    }
323    else
324    {
325       return *a.limbs() < static_cast<ui_type>(b);
326    }
327 }
328 
329 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
330 BOOST_MP_FORCEINLINE typename enable_if_c<
331       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
332       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & b)333    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
334 {
335    if(a.sign() != b.sign())
336       return !a.sign();
337    return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs();
338 }
339 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
340 BOOST_MP_FORCEINLINE typename enable_if_c<
341       is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
342       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & b)343    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
344 {
345    return *a.limbs() > *b.limbs();
346 }
347 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
348 BOOST_MP_FORCEINLINE typename enable_if_c<
349       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
350       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,U b)351    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
352 {
353    if(a.sign())
354       return false;
355    return *a.limbs() > b;
356 }
357 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
358 BOOST_MP_FORCEINLINE typename enable_if_c<
359       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
360       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,signed_magnitude,Checked,void> & a,S b)361    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
362 {
363    if(a.sign() != (b < 0))
364       return !a.sign();
365    return a.sign() ? (*a.limbs() < boost::multiprecision::detail::unsigned_abs(b)) : (*a.limbs() > boost::multiprecision::detail::unsigned_abs(b));
366 }
367 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
368 BOOST_MP_FORCEINLINE typename enable_if_c<
369       is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
370       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,U b)371    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
372 {
373    return *a.limbs() > b;
374 }
375 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
376 BOOST_MP_FORCEINLINE typename enable_if_c<
377       is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
378       bool
eval_gt(const cpp_int_backend<MinBits,MaxBits,unsigned_magnitude,Checked,void> & a,S b)379    >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
380 {
381    typedef typename make_unsigned<S>::type ui_type;
382    if(b < 0)
383    {
384       cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
385       return *a.limbs() > *t.limbs();
386    }
387    else
388    {
389       return *a.limbs() > static_cast<ui_type>(b);
390    }
391 }
392 
393 #ifdef BOOST_MSVC
394 #pragma warning(pop)
395 #endif
396 
397 }}} // namespaces
398 
399 #endif
400