Chris@16: /////////////////////////////////////////////////////////////// Chris@16: // Copyright 2013 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_LITERALS_HPP Chris@16: #define BOOST_MP_CPP_INT_LITERALS_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost{ namespace multiprecision{ Chris@16: Chris@16: namespace literals{ namespace detail{ Chris@16: Chris@16: template struct hex_value; Chris@16: template <> struct hex_value<'0'> { static constexpr limb_type value = 0; }; Chris@16: template <> struct hex_value<'1'> { static constexpr limb_type value = 1; }; Chris@16: template <> struct hex_value<'2'> { static constexpr limb_type value = 2; }; Chris@16: template <> struct hex_value<'3'> { static constexpr limb_type value = 3; }; Chris@16: template <> struct hex_value<'4'> { static constexpr limb_type value = 4; }; Chris@16: template <> struct hex_value<'5'> { static constexpr limb_type value = 5; }; Chris@16: template <> struct hex_value<'6'> { static constexpr limb_type value = 6; }; Chris@16: template <> struct hex_value<'7'> { static constexpr limb_type value = 7; }; Chris@16: template <> struct hex_value<'8'> { static constexpr limb_type value = 8; }; Chris@16: template <> struct hex_value<'9'> { static constexpr limb_type value = 9; }; Chris@16: template <> struct hex_value<'a'> { static constexpr limb_type value = 10; }; Chris@16: template <> struct hex_value<'b'> { static constexpr limb_type value = 11; }; Chris@16: template <> struct hex_value<'c'> { static constexpr limb_type value = 12; }; Chris@16: template <> struct hex_value<'d'> { static constexpr limb_type value = 13; }; Chris@16: template <> struct hex_value<'e'> { static constexpr limb_type value = 14; }; Chris@16: template <> struct hex_value<'f'> { static constexpr limb_type value = 15; }; Chris@16: template <> struct hex_value<'A'> { static constexpr limb_type value = 10; }; Chris@16: template <> struct hex_value<'B'> { static constexpr limb_type value = 11; }; Chris@16: template <> struct hex_value<'C'> { static constexpr limb_type value = 12; }; Chris@16: template <> struct hex_value<'D'> { static constexpr limb_type value = 13; }; Chris@16: template <> struct hex_value<'E'> { static constexpr limb_type value = 14; }; Chris@16: template <> struct hex_value<'F'> { static constexpr limb_type value = 15; }; Chris@16: Chris@16: template Chris@16: struct combine_value_to_pack; Chris@16: template Chris@16: struct combine_value_to_pack, value> Chris@16: { Chris@16: typedef value_pack type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct pack_values Chris@16: { Chris@16: static constexpr unsigned chars_per_limb = sizeof(limb_type) * CHAR_BIT / 4; Chris@16: static constexpr unsigned shift = ((sizeof...(CHARS)) % chars_per_limb) * 4; Chris@16: static constexpr limb_type value_to_add = shift ? hex_value::value << shift : hex_value::value; Chris@16: Chris@16: typedef typename pack_values::type recursive_packed_type; Chris@16: typedef typename boost::mpl::if_c::type pack_type; Chris@16: typedef typename combine_value_to_pack::type type; Chris@16: }; Chris@16: template Chris@16: struct pack_values Chris@16: { Chris@16: static constexpr limb_type value_to_add = hex_value::value; Chris@16: Chris@16: typedef value_pack type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct strip_leading_zeros_from_pack; Chris@16: template Chris@16: struct strip_leading_zeros_from_pack > Chris@16: { Chris@16: typedef value_pack type; Chris@16: }; Chris@16: template Chris@16: struct strip_leading_zeros_from_pack > Chris@16: { Chris@16: typedef typename strip_leading_zeros_from_pack >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct append_value_to_pack; Chris@16: template Chris@16: struct append_value_to_pack > Chris@16: { Chris@16: typedef value_pack type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct reverse_value_pack; Chris@16: template Chris@16: struct reverse_value_pack > Chris@16: { Chris@16: typedef typename reverse_value_pack >::type lead_values; Chris@16: typedef typename append_value_to_pack::type type; Chris@16: }; Chris@16: template Chris@16: struct reverse_value_pack > Chris@16: { Chris@16: typedef value_pack type; Chris@16: }; Chris@16: template <> Chris@16: struct reverse_value_pack > Chris@16: { Chris@16: typedef value_pack<> type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct make_packed_value_from_str Chris@16: { Chris@16: BOOST_STATIC_ASSERT_MSG(l1 == '0', "Multi-precision integer literals must be in hexadecimal notation."); Chris@16: BOOST_STATIC_ASSERT_MSG((l2 == 'X') || (l2 == 'x'), "Multi-precision integer literals must be in hexadecimal notation."); Chris@16: typedef typename pack_values::type packed_type; Chris@16: typedef typename strip_leading_zeros_from_pack::type stripped_type; Chris@16: typedef typename reverse_value_pack::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct make_backend_from_pack Chris@16: { Chris@16: static constexpr Pack p = {}; Chris@16: static constexpr B value = p; Chris@16: }; Chris@16: Chris@16: template Chris@16: constexpr B make_backend_from_pack::value; Chris@16: Chris@16: template Chris@16: struct signed_cpp_int_literal_result_type Chris@16: { Chris@16: static constexpr unsigned bits = Digits * 4; Chris@16: typedef boost::multiprecision::backends::cpp_int_backend backend_type; Chris@16: typedef number number_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct unsigned_cpp_int_literal_result_type Chris@16: { Chris@16: static constexpr unsigned bits = Digits * 4; Chris@16: typedef boost::multiprecision::backends::cpp_int_backend backend_type; Chris@16: typedef number number_type; Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: template Chris@16: constexpr typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::number_type operator "" _cppi() Chris@16: { Chris@16: typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str::type pt; Chris@16: return boost::multiprecision::literals::detail::make_backend_from_pack::backend_type>::value; Chris@16: } Chris@16: Chris@16: template Chris@16: constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::number_type operator "" _cppui() Chris@16: { Chris@16: typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str::type pt; Chris@16: return boost::multiprecision::literals::detail::make_backend_from_pack::backend_type>::value; Chris@16: } Chris@16: Chris@16: #define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits)\ Chris@16: template \ Chris@16: constexpr boost::multiprecision::number > operator "" BOOST_JOIN(_cppi, Bits)()\ Chris@16: {\ Chris@16: typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str::type pt;\ Chris@16: return boost::multiprecision::literals::detail::make_backend_from_pack<\ Chris@16: pt, \ Chris@16: boost::multiprecision::backends::cpp_int_backend \ Chris@16: >::value;\ Chris@16: }\ Chris@16: template \ Chris@16: constexpr boost::multiprecision::number > operator "" BOOST_JOIN(_cppui, Bits)()\ Chris@16: {\ Chris@16: typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str::type pt;\ Chris@16: return boost::multiprecision::literals::detail::make_backend_from_pack<\ Chris@16: pt, \ Chris@16: boost::multiprecision::backends::cpp_int_backend\ Chris@16: >::value;\ Chris@16: }\ Chris@16: Chris@16: BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128) Chris@16: BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256) Chris@16: BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512) Chris@16: BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024) Chris@16: Chris@16: } Chris@16: Chris@16: // Chris@16: // Overload unary minus operator for constexpr use: Chris@16: // Chris@16: template Chris@16: constexpr number, et_off> Chris@16: operator - (const number, et_off>& a) Chris@16: { Chris@16: return cpp_int_backend(a.backend(), boost::multiprecision::literals::detail::make_negate_tag()); Chris@16: } Chris@16: template Chris@16: constexpr number, et_off> Chris@16: operator - (number, et_off>&& a) Chris@16: { Chris@16: return cpp_int_backend(static_cast, et_off>&>(a).backend(), boost::multiprecision::literals::detail::make_negate_tag()); Chris@16: } Chris@16: Chris@16: }} // namespaces Chris@16: Chris@16: #endif // BOOST_MP_CPP_INT_CORE_HPP Chris@16: