Chris@16: /////////////////////////////////////////////////////////////// Chris@16: // Copyright 2012 John Maddock. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ Chris@16: Chris@16: #ifndef BOOST_MP_CPP_INT_CORE_HPP Chris@16: #define BOOST_MP_CPP_INT_CORE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{ namespace multiprecision{ Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: // Chris@16: // These traits calculate the largest type in the list Chris@16: // [unsigned] long long, long, int, which has the specified number Chris@16: // of bits. Note that intN_t and boost::int_t find the first Chris@16: // member of the above list, not the last. We want the last in the Chris@16: // list to ensure that mixed arithmetic operations are as efficient Chris@16: // as possible. Chris@16: // Chris@16: template Chris@16: struct largest_signed_type Chris@16: { Chris@16: typedef typename mpl::if_c< Chris@16: 1 + std::numeric_limits::digits == N, Chris@16: long long, Chris@16: typename mpl::if_c< Chris@16: 1 + std::numeric_limits::digits == N, Chris@16: long, Chris@16: typename mpl::if_c< Chris@16: 1 + std::numeric_limits::digits == N, Chris@16: int, Chris@16: typename boost::int_t::exact Chris@16: >::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct largest_unsigned_type Chris@16: { Chris@16: typedef typename mpl::if_c< Chris@16: std::numeric_limits::digits == N, Chris@16: unsigned long long, Chris@16: typename mpl::if_c< Chris@16: std::numeric_limits::digits == N, Chris@16: unsigned long, Chris@16: typename mpl::if_c< Chris@16: std::numeric_limits::digits == N, Chris@16: unsigned int, Chris@16: typename boost::uint_t::exact Chris@16: >::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: #if defined(BOOST_HAS_INT128) Chris@16: Chris@16: typedef detail::largest_unsigned_type<64>::type limb_type; Chris@16: typedef detail::largest_signed_type<64>::type signed_limb_type; Chris@16: typedef boost::uint128_type double_limb_type; Chris@16: typedef boost::int128_type signed_double_limb_type; Chris@16: static const limb_type max_block_10 = 1000000000000000000uLL; Chris@16: static const limb_type digits_per_block_10 = 18; Chris@16: Chris@16: inline limb_type block_multiplier(unsigned count) Chris@16: { Chris@16: static const limb_type values[digits_per_block_10] Chris@16: = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 }; Chris@16: BOOST_ASSERT(count < digits_per_block_10); Chris@16: return values[count]; Chris@16: } Chris@16: Chris@16: // Can't do formatted IO on an __int128 Chris@16: #define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO Chris@16: Chris@16: // Need to specialise integer_traits for __int128 as it's not a normal native type: Chris@16: } // namespace multiprecision Chris@16: Chris@16: template<> Chris@16: class integer_traits Chris@16: : public std::numeric_limits, Chris@16: public detail::integer_traits_base(0)> Chris@16: { }; Chris@16: template<> Chris@16: class integer_traits Chris@16: : public std::numeric_limits, Chris@16: public detail::integer_traits_base((static_cast(1) << 127)), static_cast(((~static_cast(0)) >> 1))> Chris@16: { }; Chris@16: Chris@16: namespace multiprecision{ Chris@16: Chris@16: #else Chris@16: Chris@16: typedef detail::largest_unsigned_type<32>::type limb_type; Chris@16: typedef detail::largest_signed_type<32>::type signed_limb_type; Chris@101: typedef detail::largest_unsigned_type<64>::type double_limb_type; Chris@101: typedef detail::largest_signed_type<64>::type signed_double_limb_type; Chris@16: static const limb_type max_block_10 = 1000000000; Chris@16: static const limb_type digits_per_block_10 = 9; Chris@16: Chris@16: inline limb_type block_multiplier(unsigned count) Chris@16: { Chris@16: static const limb_type values[digits_per_block_10] Chris@16: = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; Chris@16: BOOST_ASSERT(count < digits_per_block_10); Chris@16: return values[count]; Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: static const unsigned bits_per_limb = sizeof(limb_type) * CHAR_BIT; Chris@16: Chris@16: template Chris@16: inline void minmax(const T& a, const T& b, T& aa, T& bb) Chris@16: { Chris@16: if(a < b) Chris@16: { Chris@16: aa = a; Chris@16: bb = b; Chris@16: } Chris@16: else Chris@16: { Chris@16: aa = b; Chris@16: bb = a; Chris@16: } Chris@16: } Chris@16: Chris@16: enum cpp_integer_type Chris@16: { Chris@16: signed_magnitude = 1, Chris@16: unsigned_magnitude = 0, Chris@16: signed_packed = 3, Chris@16: unsigned_packed = 2 Chris@16: }; Chris@16: Chris@16: enum cpp_int_check_type Chris@16: { Chris@16: checked = 1, Chris@16: unchecked = 0 Chris@16: }; Chris@16: Chris@16: }} Chris@16: Chris@16: // Chris@16: // Figure out whether to support user-defined-literals or not: Chris@16: // Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS) \ Chris@16: && !defined(BOOST_NO_CXX11_CONSTEXPR) Chris@16: # define BOOST_MP_USER_DEFINED_LITERALS Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_MP_CPP_INT_CORE_HPP Chris@16: