comparison.hpp 19 KB

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