]> git.proxmox.com Git - ceph.git/blob - 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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