]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multiprecision / include / boost / multiprecision / cpp_int / comparison.hpp
CommitLineData
7c673cae
FG
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
13namespace 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//
23template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
24BOOST_MP_FORCEINLINE typename enable_if_c<
25 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
26 bool
27 >::type
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}
41template <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>
42BOOST_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
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}
59template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
60BOOST_MP_FORCEINLINE typename enable_if_c<
61 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
62 bool
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}
69template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
70BOOST_MP_FORCEINLINE typename enable_if_c<
71 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
72 bool
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}
79template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
80BOOST_MP_FORCEINLINE typename enable_if_c<
81 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
82 bool
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}
88template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
89BOOST_MP_FORCEINLINE typename enable_if_c<
90 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
91 bool
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
97template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
98BOOST_MP_FORCEINLINE typename enable_if_c<
99 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
100 bool
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}
109template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
110inline typename enable_if_c<
111 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
112 bool
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
131template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
132BOOST_MP_FORCEINLINE typename enable_if_c<
133 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
134 bool
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}
141template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
142BOOST_MP_FORCEINLINE typename enable_if_c<
143 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
144 bool
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
150template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
151BOOST_MP_FORCEINLINE typename enable_if_c<
152 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
153 bool
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}
162template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
163inline typename enable_if_c<
164 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
165 bool
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
186template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
187BOOST_MP_FORCEINLINE typename enable_if_c<
188 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
189 bool
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}
196template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
197BOOST_MP_FORCEINLINE typename enable_if_c<
198 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
199 bool
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//
207template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
208BOOST_MP_FORCEINLINE typename enable_if_c<
209 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
210 bool
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}
215template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
216BOOST_MP_FORCEINLINE typename enable_if_c<
217 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
218 bool
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}
223template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
224BOOST_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
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}
231template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
232BOOST_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
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}
239template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
240BOOST_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
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}
247template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
248BOOST_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
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
265template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
266BOOST_MP_FORCEINLINE typename enable_if_c<
267 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
268 bool
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}
275template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
276BOOST_MP_FORCEINLINE typename enable_if_c<
277 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
278 bool
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}
283template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
284BOOST_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
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}
293template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
294BOOST_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
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}
303template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
304BOOST_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
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}
311template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
312BOOST_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
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
329template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
330BOOST_MP_FORCEINLINE typename enable_if_c<
331 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
332 bool
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}
339template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
340BOOST_MP_FORCEINLINE typename enable_if_c<
341 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
342 bool
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}
347template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
348BOOST_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
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}
357template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
358BOOST_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
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}
367template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
368BOOST_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
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}
375template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
376BOOST_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
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