cpp_int_config.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. #ifndef BOOST_MP_CPP_INT_CORE_HPP
  6. #define BOOST_MP_CPP_INT_CORE_HPP
  7. #include <boost/integer.hpp>
  8. #include <boost/integer_traits.hpp>
  9. #include <boost/mpl/if.hpp>
  10. #include <boost/mpl/int.hpp>
  11. #include <boost/static_assert.hpp>
  12. #include <boost/assert.hpp>
  13. namespace boost {
  14. namespace multiprecision {
  15. namespace detail {
  16. //
  17. // These traits calculate the largest type in the list
  18. // [unsigned] boost::long_long_type, long, int, which has the specified number
  19. // of bits. Note that intN_t and boost::int_t<N> find the first
  20. // member of the above list, not the last. We want the last in the
  21. // list to ensure that mixed arithmetic operations are as efficient
  22. // as possible.
  23. //
  24. template <unsigned N>
  25. struct largest_signed_type
  26. {
  27. typedef typename mpl::if_c<
  28. 1 + std::numeric_limits<boost::long_long_type>::digits == N,
  29. boost::long_long_type,
  30. typename mpl::if_c<
  31. 1 + std::numeric_limits<long>::digits == N,
  32. long,
  33. typename mpl::if_c<
  34. 1 + std::numeric_limits<int>::digits == N,
  35. int,
  36. typename boost::int_t<N>::exact>::type>::type>::type type;
  37. };
  38. template <unsigned N>
  39. struct largest_unsigned_type
  40. {
  41. typedef typename mpl::if_c<
  42. std::numeric_limits<boost::ulong_long_type>::digits == N,
  43. boost::ulong_long_type,
  44. typename mpl::if_c<
  45. std::numeric_limits<unsigned long>::digits == N,
  46. unsigned long,
  47. typename mpl::if_c<
  48. std::numeric_limits<unsigned int>::digits == N,
  49. unsigned int,
  50. typename boost::uint_t<N>::exact>::type>::type>::type type;
  51. };
  52. } // namespace detail
  53. #if defined(BOOST_HAS_INT128)
  54. typedef detail::largest_unsigned_type<64>::type limb_type;
  55. typedef detail::largest_signed_type<64>::type signed_limb_type;
  56. typedef boost::uint128_type double_limb_type;
  57. typedef boost::int128_type signed_double_limb_type;
  58. static const limb_type max_block_10 = 1000000000000000000uLL;
  59. static const limb_type digits_per_block_10 = 18;
  60. inline BOOST_MP_CXX14_CONSTEXPR limb_type block_multiplier(unsigned count)
  61. {
  62. #ifdef BOOST_NO_CXX14_CONSTEXPR
  63. static
  64. #else
  65. constexpr
  66. #endif
  67. const limb_type values[digits_per_block_10] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000};
  68. BOOST_ASSERT(count < digits_per_block_10);
  69. return values[count];
  70. }
  71. // Can't do formatted IO on an __int128
  72. #define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
  73. // Need to specialise integer_traits for __int128 as it's not a normal native type:
  74. } // namespace multiprecision
  75. template <>
  76. class integer_traits<multiprecision::double_limb_type>
  77. : public std::numeric_limits<multiprecision::double_limb_type>,
  78. public detail::integer_traits_base<multiprecision::double_limb_type, 0, ~static_cast<multiprecision::double_limb_type>(0)>
  79. {};
  80. template <>
  81. class integer_traits<multiprecision::signed_double_limb_type>
  82. : public std::numeric_limits<multiprecision::signed_double_limb_type>,
  83. public detail::integer_traits_base<multiprecision::signed_double_limb_type, static_cast<multiprecision::signed_double_limb_type>((static_cast<multiprecision::double_limb_type>(1) << 127)), static_cast<multiprecision::signed_double_limb_type>(((~static_cast<multiprecision::double_limb_type>(0)) >> 1))>
  84. {};
  85. namespace multiprecision {
  86. #else
  87. typedef detail::largest_unsigned_type<32>::type limb_type;
  88. typedef detail::largest_signed_type<32>::type signed_limb_type;
  89. typedef detail::largest_unsigned_type<64>::type double_limb_type;
  90. typedef detail::largest_signed_type<64>::type signed_double_limb_type;
  91. static const limb_type max_block_10 = 1000000000;
  92. static const limb_type digits_per_block_10 = 9;
  93. inline limb_type block_multiplier(unsigned count)
  94. {
  95. #ifdef BOOST_NO_CXX14_CONSTEXPR
  96. static
  97. #else
  98. constexpr
  99. #endif
  100. const limb_type values[digits_per_block_10] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
  101. BOOST_ASSERT(count < digits_per_block_10);
  102. return values[count];
  103. }
  104. #endif
  105. static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT;
  106. template <class T>
  107. inline BOOST_MP_CXX14_CONSTEXPR void minmax(const T& a, const T& b, T& aa, T& bb)
  108. {
  109. if (a < b)
  110. {
  111. aa = a;
  112. bb = b;
  113. }
  114. else
  115. {
  116. aa = b;
  117. bb = a;
  118. }
  119. }
  120. enum cpp_integer_type
  121. {
  122. signed_magnitude = 1,
  123. unsigned_magnitude = 0,
  124. signed_packed = 3,
  125. unsigned_packed = 2
  126. };
  127. enum cpp_int_check_type
  128. {
  129. checked = 1,
  130. unchecked = 0
  131. };
  132. } // namespace multiprecision
  133. } // namespace boost
  134. //
  135. // Figure out whether to support user-defined-literals or not:
  136. //
  137. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS) && !defined(BOOST_NO_CXX11_CONSTEXPR)
  138. #define BOOST_MP_USER_DEFINED_LITERALS
  139. #endif
  140. #endif // BOOST_MP_CPP_INT_CORE_HPP