File indexing completed on 2025-01-18 09:42:13
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_MP_CPP_INT_CONFIG_HPP
0008 #define BOOST_MP_CPP_INT_CONFIG_HPP
0009
0010 #include <cstdint>
0011 #include <type_traits>
0012 #include <limits>
0013 #include <boost/multiprecision/detail/standalone_config.hpp>
0014 #include <boost/multiprecision/detail/assert.hpp>
0015
0016 namespace boost {
0017 namespace multiprecision {
0018
0019 namespace detail {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 template <std::size_t Bits>
0031 struct int_t
0032 {
0033 using exact = typename std::conditional<Bits <= sizeof(signed char) * CHAR_BIT, signed char,
0034 typename std::conditional<Bits <= sizeof(short) * CHAR_BIT, short,
0035 typename std::conditional<Bits <= sizeof(int) * CHAR_BIT, int,
0036 typename std::conditional<Bits <= sizeof(long) * CHAR_BIT, long,
0037 typename std::conditional<Bits <= sizeof(long long) * CHAR_BIT, long long, void
0038 >::type>::type>::type>::type>::type;
0039
0040 using least = typename std::conditional<Bits-1 <= std::numeric_limits<signed char>::digits, signed char,
0041 typename std::conditional<Bits-1 <= std::numeric_limits<short>::digits, short,
0042 typename std::conditional<Bits-1 <= std::numeric_limits<int>::digits, int,
0043 typename std::conditional<Bits-1 <= std::numeric_limits<long>::digits, long,
0044 typename std::conditional<Bits-1 <= std::numeric_limits<long long>::digits, long long, void
0045 >::type>::type>::type>::type>::type;
0046
0047 static_assert(!std::is_same<void, exact>::value && !std::is_same<void, least>::value, "Number of bits does not match any standard data type. \
0048 Please file an issue at https://github.com/boostorg/multiprecision/ referencing this error from cpp_int_config.hpp");
0049 };
0050
0051 template <std::size_t Bits>
0052 struct uint_t
0053 {
0054 using exact = typename std::conditional<Bits <= sizeof(unsigned char) * CHAR_BIT, unsigned char,
0055 typename std::conditional<Bits <= sizeof(unsigned short) * CHAR_BIT, unsigned short,
0056 typename std::conditional<Bits <= sizeof(unsigned int) * CHAR_BIT, unsigned int,
0057 typename std::conditional<Bits <= sizeof(unsigned long) * CHAR_BIT, unsigned long,
0058 typename std::conditional<Bits <= sizeof(unsigned long long) * CHAR_BIT, unsigned long long, void
0059 >::type>::type>::type>::type>::type;
0060
0061 using least = typename std::conditional<Bits <= std::numeric_limits<unsigned char>::digits, unsigned char,
0062 typename std::conditional<Bits <= std::numeric_limits<unsigned short>::digits, unsigned short,
0063 typename std::conditional<Bits <= std::numeric_limits<unsigned int>::digits, unsigned int,
0064 typename std::conditional<Bits <= std::numeric_limits<unsigned long>::digits, unsigned long,
0065 typename std::conditional<Bits <= std::numeric_limits<unsigned long long>::digits, unsigned long long, void
0066 >::type>::type>::type>::type>::type;
0067
0068 static_assert(!std::is_same<void, exact>::value && !std::is_same<void, least>::value, "Number of bits does not match any standard data type. \
0069 Please file an issue at https://github.com/boostorg/multiprecision/ referencing this error from cpp_int_config.hpp");
0070 };
0071
0072 template <std::size_t N>
0073 struct largest_signed_type
0074 {
0075 using type = typename std::conditional<
0076 1 + std::numeric_limits<long long>::digits == N,
0077 long long,
0078 typename std::conditional<
0079 1 + std::numeric_limits<long>::digits == N,
0080 long,
0081 typename std::conditional<
0082 1 + std::numeric_limits<int>::digits == N,
0083 int,
0084 typename int_t<N>::exact>::type>::type>::type;
0085 };
0086
0087 template <std::size_t N>
0088 struct largest_unsigned_type
0089 {
0090 using type = typename std::conditional<
0091 std::numeric_limits<unsigned long long>::digits == N,
0092 unsigned long long,
0093 typename std::conditional<
0094 std::numeric_limits<unsigned long>::digits == N,
0095 unsigned long,
0096 typename std::conditional<
0097 std::numeric_limits<unsigned int>::digits == N,
0098 unsigned int,
0099 typename uint_t<N>::exact>::type>::type>::type;
0100 };
0101
0102 }
0103
0104 #if defined(BOOST_HAS_INT128)
0105
0106 using limb_type = detail::largest_unsigned_type<64>::type;
0107 using signed_limb_type = detail::largest_signed_type<64>::type;
0108 using double_limb_type = boost::multiprecision::uint128_type;
0109 using signed_double_limb_type = boost::multiprecision::int128_type;
0110 constexpr limb_type max_block_10 = 1000000000000000000uLL;
0111 constexpr limb_type digits_per_block_10 = 18;
0112
0113 inline BOOST_MP_CXX14_CONSTEXPR limb_type block_multiplier(std::size_t count)
0114 {
0115 constexpr 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};
0116 BOOST_MP_ASSERT(count < digits_per_block_10);
0117 return values[count];
0118 }
0119
0120
0121 #define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
0122
0123 #else
0124
0125 using limb_type = detail::largest_unsigned_type<32>::type;
0126 using signed_limb_type = detail::largest_signed_type<32>::type ;
0127 using double_limb_type = detail::largest_unsigned_type<64>::type;
0128 using signed_double_limb_type = detail::largest_signed_type<64>::type ;
0129 constexpr limb_type max_block_10 = 1000000000;
0130 constexpr limb_type digits_per_block_10 = 9;
0131
0132 inline limb_type block_multiplier(std::size_t count)
0133 {
0134 constexpr limb_type values[digits_per_block_10] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
0135 BOOST_MP_ASSERT(count < digits_per_block_10);
0136 return values[count];
0137 }
0138
0139 #endif
0140
0141 constexpr std::size_t bits_per_limb = sizeof(limb_type) * CHAR_BIT;
0142
0143 template <class T>
0144 inline BOOST_MP_CXX14_CONSTEXPR void minmax(const T& a, const T& b, T& aa, T& bb)
0145 {
0146 if (a < b)
0147 {
0148 aa = a;
0149 bb = b;
0150 }
0151 else
0152 {
0153 aa = b;
0154 bb = a;
0155 }
0156 }
0157
0158 }
0159 }
0160
0161 #endif