test_nothrow_cpp_int.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2015 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_0.txt)
  5. #include <boost/multiprecision/cpp_int.hpp>
  6. #include <boost/type_traits/is_nothrow_move_constructible.hpp>
  7. #include <boost/type_traits/is_nothrow_move_assignable.hpp>
  8. #include <boost/type_traits/has_nothrow_constructor.hpp>
  9. #include <boost/type_traits/has_nothrow_assign.hpp>
  10. #include <boost/type_traits/has_nothrow_copy.hpp>
  11. #include <boost/static_assert.hpp>
  12. #ifndef BOOST_NO_CXX11_NOEXCEPT
  13. #if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_IS_NOTHROW_MOVE_CONSTRUCT)
  14. //
  15. // Move construct:
  16. //
  17. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::cpp_int>::value);
  18. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::int128_t>::value);
  19. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::checked_int128_t>::value);
  20. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::uint128_t>::value);
  21. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::checked_uint128_t>::value);
  22. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::int512_t>::value);
  23. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::checked_int512_t>::value);
  24. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::uint512_t>::value);
  25. BOOST_STATIC_ASSERT(boost::is_nothrow_move_constructible<boost::multiprecision::checked_uint512_t>::value);
  26. #endif
  27. #if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) || defined(BOOST_IS_NOTHROW_MOVE_ASSIGN)
  28. //
  29. // Move assign:
  30. //
  31. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::cpp_int>::value);
  32. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::int128_t>::value);
  33. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::checked_int128_t>::value);
  34. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::uint128_t>::value);
  35. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::checked_uint128_t>::value);
  36. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::int512_t>::value);
  37. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::checked_int512_t>::value);
  38. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::uint512_t>::value);
  39. BOOST_STATIC_ASSERT(boost::is_nothrow_move_assignable<boost::multiprecision::checked_uint512_t>::value);
  40. #endif
  41. //
  42. // Construct:
  43. //
  44. #ifdef BOOST_HAS_NOTHROW_CONSTRUCTOR
  45. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::cpp_int>::value);
  46. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::int128_t>::value);
  47. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::checked_int128_t>::value);
  48. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::uint128_t>::value);
  49. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::checked_uint128_t>::value);
  50. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::int512_t>::value);
  51. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::checked_int512_t>::value);
  52. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::uint512_t>::value);
  53. BOOST_STATIC_ASSERT(boost::has_nothrow_constructor<boost::multiprecision::checked_uint512_t>::value);
  54. #endif
  55. //
  56. // Copy construct:
  57. //
  58. #ifdef BOOST_HAS_NOTHROW_COPY
  59. BOOST_STATIC_ASSERT(!boost::has_nothrow_copy<boost::multiprecision::cpp_int>::value);
  60. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::int128_t>::value);
  61. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::checked_int128_t>::value);
  62. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::uint128_t>::value);
  63. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::checked_uint128_t>::value);
  64. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::int512_t>::value);
  65. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::checked_int512_t>::value);
  66. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::uint512_t>::value);
  67. BOOST_STATIC_ASSERT(boost::has_nothrow_copy<boost::multiprecision::checked_uint512_t>::value);
  68. #endif
  69. //
  70. // Assign:
  71. //
  72. #ifdef BOOST_HAS_NOTHROW_ASSIGN
  73. BOOST_STATIC_ASSERT(!boost::has_nothrow_assign<boost::multiprecision::cpp_int>::value);
  74. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::int128_t>::value);
  75. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::checked_int128_t>::value);
  76. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::uint128_t>::value);
  77. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::checked_uint128_t>::value);
  78. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::int512_t>::value);
  79. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::checked_int512_t>::value);
  80. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::uint512_t>::value);
  81. BOOST_STATIC_ASSERT(boost::has_nothrow_assign<boost::multiprecision::checked_uint512_t>::value);
  82. #endif
  83. //
  84. // Construct from int:
  85. //
  86. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::cpp_int(std::declval<boost::multiprecision::signed_limb_type>())));
  87. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int128_t(std::declval<boost::multiprecision::signed_limb_type>())));
  88. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int128_t(std::declval<boost::multiprecision::signed_limb_type>())));
  89. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint128_t(std::declval<boost::multiprecision::signed_limb_type>())));
  90. BOOST_STATIC_ASSERT(!noexcept(boost::multiprecision::checked_uint128_t(std::declval<boost::multiprecision::signed_limb_type>())));
  91. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int512_t(std::declval<boost::multiprecision::signed_limb_type>())));
  92. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int512_t(std::declval<boost::multiprecision::signed_limb_type>())));
  93. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint512_t(std::declval<boost::multiprecision::signed_limb_type>())));
  94. BOOST_STATIC_ASSERT(!noexcept(boost::multiprecision::checked_uint512_t(std::declval<boost::multiprecision::signed_limb_type>())));
  95. //
  96. // Construct from unsigned int:
  97. //
  98. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::cpp_int(std::declval<boost::multiprecision::limb_type>())));
  99. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int128_t(std::declval<boost::multiprecision::limb_type>())));
  100. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int128_t(std::declval<boost::multiprecision::limb_type>())));
  101. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint128_t(std::declval<boost::multiprecision::limb_type>())));
  102. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_uint128_t(std::declval<boost::multiprecision::limb_type>())));
  103. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int512_t(std::declval<boost::multiprecision::limb_type>())));
  104. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int512_t(std::declval<boost::multiprecision::limb_type>())));
  105. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint512_t(std::declval<boost::multiprecision::limb_type>())));
  106. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_uint512_t(std::declval<boost::multiprecision::limb_type>())));
  107. //
  108. // Assign from int:
  109. //
  110. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::cpp_int>() = std::declval<boost::multiprecision::signed_limb_type>()));
  111. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int128_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  112. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int128_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  113. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint128_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  114. BOOST_STATIC_ASSERT(!noexcept(std::declval<boost::multiprecision::checked_uint128_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  115. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int512_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  116. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int512_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  117. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint512_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  118. BOOST_STATIC_ASSERT(!noexcept(std::declval<boost::multiprecision::checked_uint512_t>() = std::declval<boost::multiprecision::signed_limb_type>()));
  119. //
  120. // Assign from unsigned int:
  121. //
  122. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::cpp_int>() = std::declval<boost::multiprecision::limb_type>()));
  123. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int128_t>() = std::declval<boost::multiprecision::limb_type>()));
  124. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int128_t>() = std::declval<boost::multiprecision::limb_type>()));
  125. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint128_t>() = std::declval<boost::multiprecision::limb_type>()));
  126. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_uint128_t>() = std::declval<boost::multiprecision::limb_type>()));
  127. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int512_t>() = std::declval<boost::multiprecision::limb_type>()));
  128. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int512_t>() = std::declval<boost::multiprecision::limb_type>()));
  129. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint512_t>() = std::declval<boost::multiprecision::limb_type>()));
  130. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_uint512_t>() = std::declval<boost::multiprecision::limb_type>()));
  131. #if defined(BOOST_LITTLE_ENDIAN) && !defined(BOOST_MP_TEST_NO_LE)
  132. //
  133. // We can also nothrow construct from a double_limb_type (or smaller obviously) as long as double_limb_type is smaller than the type
  134. // in question (so don't test 128-bit integers in case double_limb_type is __int128).
  135. //
  136. // Construct from int:
  137. //
  138. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::cpp_int(std::declval<boost::multiprecision::signed_double_limb_type>())));
  139. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int512_t(std::declval<boost::multiprecision::signed_double_limb_type>())));
  140. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int512_t(std::declval<boost::multiprecision::signed_double_limb_type>())));
  141. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint512_t(std::declval<boost::multiprecision::signed_double_limb_type>())));
  142. BOOST_STATIC_ASSERT(!noexcept(boost::multiprecision::checked_uint512_t(std::declval<boost::multiprecision::signed_double_limb_type>())));
  143. //
  144. // Construct from unsigned int:
  145. //
  146. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::cpp_int(std::declval<boost::multiprecision::double_limb_type>())));
  147. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::int512_t(std::declval<boost::multiprecision::double_limb_type>())));
  148. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_int512_t(std::declval<boost::multiprecision::double_limb_type>())));
  149. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::uint512_t(std::declval<boost::multiprecision::double_limb_type>())));
  150. BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::checked_uint512_t(std::declval<boost::multiprecision::double_limb_type>())));
  151. //
  152. // Assign from int:
  153. //
  154. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::cpp_int>() = std::declval<boost::multiprecision::signed_double_limb_type>()));
  155. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int512_t>() = std::declval<boost::multiprecision::signed_double_limb_type>()));
  156. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int512_t>() = std::declval<boost::multiprecision::signed_double_limb_type>()));
  157. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint512_t>() = std::declval<boost::multiprecision::signed_double_limb_type>()));
  158. BOOST_STATIC_ASSERT(!noexcept(std::declval<boost::multiprecision::checked_uint512_t>() = std::declval<boost::multiprecision::signed_double_limb_type>()));
  159. //
  160. // Assign from unsigned int:
  161. //
  162. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::cpp_int>() = std::declval<boost::multiprecision::double_limb_type>()));
  163. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::int512_t>() = std::declval<boost::multiprecision::double_limb_type>()));
  164. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_int512_t>() = std::declval<boost::multiprecision::double_limb_type>()));
  165. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::uint512_t>() = std::declval<boost::multiprecision::double_limb_type>()));
  166. BOOST_STATIC_ASSERT(noexcept(std::declval<boost::multiprecision::checked_uint512_t>() = std::declval<boost::multiprecision::double_limb_type>()));
  167. #endif // little endian
  168. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > checked_int32_t;
  169. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > checked_uint32_t;
  170. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > unchecked_int32_t;
  171. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<32, 32, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > unchecked_uint32_t;
  172. //
  173. // Construct from int:
  174. //
  175. BOOST_STATIC_ASSERT(noexcept(unchecked_int32_t(std::declval<boost::int32_t>())));
  176. BOOST_STATIC_ASSERT(noexcept(checked_int32_t(std::declval<boost::int32_t>())));
  177. BOOST_STATIC_ASSERT(noexcept(unchecked_uint32_t(std::declval<boost::int32_t>())));
  178. BOOST_STATIC_ASSERT(!noexcept(checked_uint32_t(std::declval<boost::int32_t>())));
  179. //
  180. // Construct from unsigned int:
  181. //
  182. BOOST_STATIC_ASSERT(noexcept(unchecked_int32_t(std::declval<boost::uint32_t>())));
  183. BOOST_STATIC_ASSERT(noexcept(checked_int32_t(std::declval<boost::uint32_t>())));
  184. BOOST_STATIC_ASSERT(noexcept(unchecked_uint32_t(std::declval<boost::uint32_t>())));
  185. BOOST_STATIC_ASSERT(noexcept(checked_uint32_t(std::declval<boost::uint32_t>())));
  186. //
  187. // Assign from int:
  188. //
  189. BOOST_STATIC_ASSERT(noexcept(std::declval<unchecked_int32_t>() = std::declval<boost::int32_t>()));
  190. BOOST_STATIC_ASSERT(noexcept(std::declval<checked_int32_t>() = std::declval<boost::int32_t>()));
  191. BOOST_STATIC_ASSERT(noexcept(std::declval<unchecked_uint32_t>() = std::declval<boost::int32_t>()));
  192. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_uint32_t>() = std::declval<boost::int32_t>()));
  193. //
  194. // Assign from unsigned int:
  195. //
  196. BOOST_STATIC_ASSERT(noexcept(std::declval<unchecked_int32_t>() = std::declval<boost::uint32_t>()));
  197. BOOST_STATIC_ASSERT(noexcept(std::declval<checked_int32_t>() = std::declval<boost::uint32_t>()));
  198. BOOST_STATIC_ASSERT(noexcept(std::declval<unchecked_uint32_t>() = std::declval<boost::uint32_t>()));
  199. BOOST_STATIC_ASSERT(noexcept(std::declval<checked_uint32_t>() = std::declval<boost::uint32_t>()));
  200. //
  201. // And finally some things which should *not* be noexcept:
  202. //
  203. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<30, 30, boost::multiprecision::signed_magnitude, boost::multiprecision::checked, void> > checked_int30_t;
  204. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<30, 30, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > checked_uint30_t;
  205. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<30, 30, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > unchecked_int30_t;
  206. typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<30, 30, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > unchecked_uint30_t;
  207. //
  208. // Construct from int:
  209. //
  210. BOOST_STATIC_ASSERT(!noexcept(checked_int30_t(std::declval<boost::int32_t>())));
  211. BOOST_STATIC_ASSERT(!noexcept(checked_uint30_t(std::declval<boost::int32_t>())));
  212. BOOST_STATIC_ASSERT(!noexcept(checked_int32_t(std::declval<boost::int64_t>())));
  213. BOOST_STATIC_ASSERT(!noexcept(checked_uint32_t(std::declval<boost::int64_t>())));
  214. //
  215. // Construct from unsigned int:
  216. //
  217. BOOST_STATIC_ASSERT(!noexcept(checked_int30_t(std::declval<boost::uint32_t>())));
  218. BOOST_STATIC_ASSERT(!noexcept(checked_uint30_t(std::declval<boost::uint32_t>())));
  219. BOOST_STATIC_ASSERT(!noexcept(checked_int32_t(std::declval<boost::uint64_t>())));
  220. BOOST_STATIC_ASSERT(!noexcept(checked_uint32_t(std::declval<boost::uint64_t>())));
  221. //
  222. // Assign from int:
  223. //
  224. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_int30_t>() = std::declval<boost::int32_t>()));
  225. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_uint30_t>() = std::declval<boost::int32_t>()));
  226. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_int32_t>() = std::declval<boost::int64_t>()));
  227. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_uint32_t>() = std::declval<boost::int64_t>()));
  228. //
  229. // Assign from unsigned int:
  230. //
  231. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_int30_t>() = std::declval<boost::uint32_t>()));
  232. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_uint30_t>() = std::declval<boost::uint32_t>()));
  233. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_int32_t>() = std::declval<boost::uint64_t>()));
  234. BOOST_STATIC_ASSERT(!noexcept(std::declval<checked_uint32_t>() = std::declval<boost::uint64_t>()));
  235. #endif // noexcept