Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////
0002 //  Copyright 2013 John Maddock. Distributed under the Boost
0003 //  Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
0005 
0006 #ifndef BOOST_MP_CPP_INT_LITERALS_HPP
0007 #define BOOST_MP_CPP_INT_LITERALS_HPP
0008 
0009 #include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
0010 
0011 namespace boost { namespace multiprecision {
0012 
0013 namespace literals {
0014 namespace detail {
0015 
0016 template <char>
0017 struct hex_value;
0018 template <>
0019 struct hex_value<'0'>
0020 {
0021    static constexpr limb_type value = 0;
0022 };
0023 template <>
0024 struct hex_value<'1'>
0025 {
0026    static constexpr limb_type value = 1;
0027 };
0028 template <>
0029 struct hex_value<'2'>
0030 {
0031    static constexpr limb_type value = 2;
0032 };
0033 template <>
0034 struct hex_value<'3'>
0035 {
0036    static constexpr limb_type value = 3;
0037 };
0038 template <>
0039 struct hex_value<'4'>
0040 {
0041    static constexpr limb_type value = 4;
0042 };
0043 template <>
0044 struct hex_value<'5'>
0045 {
0046    static constexpr limb_type value = 5;
0047 };
0048 template <>
0049 struct hex_value<'6'>
0050 {
0051    static constexpr limb_type value = 6;
0052 };
0053 template <>
0054 struct hex_value<'7'>
0055 {
0056    static constexpr limb_type value = 7;
0057 };
0058 template <>
0059 struct hex_value<'8'>
0060 {
0061    static constexpr limb_type value = 8;
0062 };
0063 template <>
0064 struct hex_value<'9'>
0065 {
0066    static constexpr limb_type value = 9;
0067 };
0068 template <>
0069 struct hex_value<'a'>
0070 {
0071    static constexpr limb_type value = 10;
0072 };
0073 template <>
0074 struct hex_value<'b'>
0075 {
0076    static constexpr limb_type value = 11;
0077 };
0078 template <>
0079 struct hex_value<'c'>
0080 {
0081    static constexpr limb_type value = 12;
0082 };
0083 template <>
0084 struct hex_value<'d'>
0085 {
0086    static constexpr limb_type value = 13;
0087 };
0088 template <>
0089 struct hex_value<'e'>
0090 {
0091    static constexpr limb_type value = 14;
0092 };
0093 template <>
0094 struct hex_value<'f'>
0095 {
0096    static constexpr limb_type value = 15;
0097 };
0098 template <>
0099 struct hex_value<'A'>
0100 {
0101    static constexpr limb_type value = 10;
0102 };
0103 template <>
0104 struct hex_value<'B'>
0105 {
0106    static constexpr limb_type value = 11;
0107 };
0108 template <>
0109 struct hex_value<'C'>
0110 {
0111    static constexpr limb_type value = 12;
0112 };
0113 template <>
0114 struct hex_value<'D'>
0115 {
0116    static constexpr limb_type value = 13;
0117 };
0118 template <>
0119 struct hex_value<'E'>
0120 {
0121    static constexpr limb_type value = 14;
0122 };
0123 template <>
0124 struct hex_value<'F'>
0125 {
0126    static constexpr limb_type value = 15;
0127 };
0128 
0129 template <class Pack, limb_type value>
0130 struct combine_value_to_pack;
0131 template <limb_type first, limb_type... ARGS, limb_type value>
0132 struct combine_value_to_pack<value_pack<first, ARGS...>, value>
0133 {
0134    using type = value_pack<first | value, ARGS...>;
0135 };
0136 
0137 template <char NextChar, char... CHARS>
0138 struct pack_values
0139 {
0140    static constexpr std::size_t chars_per_limb = sizeof(limb_type) * CHAR_BIT / 4;
0141    static constexpr std::size_t shift          = ((sizeof...(CHARS)) % chars_per_limb) * 4;
0142    static constexpr limb_type value_to_add  = shift ? hex_value<NextChar>::value << shift : hex_value<NextChar>::value;
0143 
0144    using recursive_packed_type = typename pack_values<CHARS...>::type                         ;
0145    using pack_type = typename std::conditional<shift == 0,
0146                                      typename recursive_packed_type::next_type,
0147                                      recursive_packed_type>::type;
0148    using type = typename combine_value_to_pack<pack_type, value_to_add>::type;
0149 };
0150 template <char NextChar>
0151 struct pack_values<NextChar>
0152 {
0153    static constexpr limb_type value_to_add = hex_value<NextChar>::value;
0154 
0155    using type = value_pack<value_to_add>;
0156 };
0157 
0158 template <class T>
0159 struct strip_leading_zeros_from_pack;
0160 template <limb_type... PACK>
0161 struct strip_leading_zeros_from_pack<value_pack<PACK...> >
0162 {
0163    using type = value_pack<PACK...>;
0164 };
0165 template <limb_type... PACK>
0166 struct strip_leading_zeros_from_pack<value_pack<0u, PACK...> >
0167 {
0168    using type = typename strip_leading_zeros_from_pack<value_pack<PACK...> >::type;
0169 };
0170 
0171 template <limb_type v, class PACK>
0172 struct append_value_to_pack;
0173 template <limb_type v, limb_type... PACK>
0174 struct append_value_to_pack<v, value_pack<PACK...> >
0175 {
0176    using type = value_pack<PACK..., v>;
0177 };
0178 
0179 template <class T>
0180 struct reverse_value_pack;
0181 template <limb_type v, limb_type... VALUES>
0182 struct reverse_value_pack<value_pack<v, VALUES...> >
0183 {
0184    using lead_values = typename reverse_value_pack<value_pack<VALUES...> >::type;
0185    using type = typename append_value_to_pack<v, lead_values>::type      ;
0186 };
0187 template <limb_type v>
0188 struct reverse_value_pack<value_pack<v> >
0189 {
0190    using type = value_pack<v>;
0191 };
0192 template <>
0193 struct reverse_value_pack<value_pack<> >
0194 {
0195    using type = value_pack<>;
0196 };
0197 
0198 template <char l1, char l2, char... STR>
0199 struct make_packed_value_from_str
0200 {
0201    static_assert(l1 == '0', "Multi-precision integer literals must be in hexadecimal notation.");
0202    static_assert((l2 == 'X') || (l2 == 'x'), "Multi-precision integer literals must be in hexadecimal notation.");
0203    using packed_type = typename pack_values<STR...>::type                       ;
0204    using stripped_type = typename strip_leading_zeros_from_pack<packed_type>::type;
0205    using type = typename reverse_value_pack<stripped_type>::type         ;
0206 };
0207 
0208 template <class Pack, class B>
0209 struct make_backend_from_pack
0210 {
0211    static constexpr Pack p  = {};
0212    static constexpr B value = p;
0213 };
0214 
0215 #if !defined(__cpp_inline_variables)
0216 template <class Pack, class B>
0217 constexpr B make_backend_from_pack<Pack, B>::value;
0218 #endif
0219 
0220 template <unsigned Digits>
0221 struct signed_cpp_int_literal_result_type
0222 {
0223    static constexpr unsigned                                                                               bits = Digits * 4;
0224    using backend_type = boost::multiprecision::backends::cpp_int_backend<bits, bits, signed_magnitude, unchecked, void>;
0225    using number_type = number<backend_type, et_off>                                                                   ;
0226 };
0227 
0228 template <unsigned Digits>
0229 struct unsigned_cpp_int_literal_result_type
0230 {
0231    static constexpr unsigned                                                                                 bits = Digits * 4;
0232    using backend_type = boost::multiprecision::backends::cpp_int_backend<bits, bits, unsigned_magnitude, unchecked, void>;
0233    using number_type = number<backend_type, et_off>                                                                     ;
0234 };
0235 
0236 } // namespace detail
0237 
0238 template <char... STR>
0239 constexpr typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::number_type operator"" _cppi()
0240 {
0241    using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type;
0242    return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::backend_type>::value;
0243 }
0244 
0245 template <char... STR>
0246 constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::number_type operator"" _cppui()
0247 {
0248    using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type;
0249    return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::backend_type>::value;
0250 }
0251 
0252 #define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits)                                                                                                                                                                                \
0253    template <char... STR>                                                                                                                                                                                                          \
0254    constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > operator"" BOOST_JOIN(_cppi, Bits)()    \
0255    {                                                                                                                                                                                                                               \
0256       using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type;                                                                                                                       \
0257       return boost::multiprecision::literals::detail::make_backend_from_pack<                                                                                                                                                      \
0258           pt,                                                                                                                                                                                                                      \
0259           boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >::value;                                                                  \
0260    }                                                                                                                                                                                                                               \
0261    template <char... STR>                                                                                                                                                                                                          \
0262    constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > operator"" BOOST_JOIN(_cppui, Bits)() \
0263    {                                                                                                                                                                                                                               \
0264       using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type;                                                                                                                       \
0265       return boost::multiprecision::literals::detail::make_backend_from_pack<                                                                                                                                                      \
0266           pt,                                                                                                                                                                                                                      \
0267           boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> >::value;                                                                \
0268    }
0269 
0270 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128)
0271 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256)
0272 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512)
0273 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024)
0274 
0275 } // namespace literals
0276 
0277 //
0278 // Overload unary minus operator for constexpr use:
0279 //
0280 template <std::size_t MinBits, cpp_int_check_type Checked>
0281 constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
0282 operator-(const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>& a)
0283 {
0284    return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(a.backend(), boost::multiprecision::literals::detail::make_negate_tag());
0285 }
0286 template <std::size_t MinBits, cpp_int_check_type Checked>
0287 constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
0288 operator-(number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&& a)
0289 {
0290    return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(static_cast<const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&>(a).backend(), boost::multiprecision::literals::detail::make_negate_tag());
0291 }
0292 
0293 }} // namespace boost::multiprecision
0294 
0295 #endif // BOOST_MP_CPP_INT_CORE_HPP