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

source code of boost/libs/multiprecision/include/boost/multiprecision/cpp_int/comparison.hpp