Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:13

0001 ///////////////////////////////////////////////////////////////
0002 //  Copyright 2012 - 2021 John Maddock.
0003 //  Copyright 2021 Matt Borland.
0004 //  Distributed under the Boost Software License, Version 1.0.
0005 //  See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
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 // These traits calculate the largest type in the list
0023 // [unsigned] long long, long, int, which has the specified number
0024 // of bits.  Note that int_t and uint_t find the first
0025 // member of the above list, not the last.  We want the last in the
0026 // list to ensure that mixed arithmetic operations are as efficient
0027 // as possible.
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 } // namespace detail
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 // Can't do formatted IO on an __int128
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 } // namespace multiprecision
0159 } // namespace boost
0160 
0161 #endif // BOOST_MP_CPP_INT_CONFIG_HPP