]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/include/boost/multiprecision/cpp_int/literals.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / multiprecision / include / boost / multiprecision / cpp_int / literals.hpp
1 ///////////////////////////////////////////////////////////////
2 // Copyright 2013 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5
6 #ifndef BOOST_MP_CPP_INT_LITERALS_HPP
7 #define BOOST_MP_CPP_INT_LITERALS_HPP
8
9 #include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
10
11 namespace boost{ namespace multiprecision{
12
13 namespace literals{ namespace detail{
14
15 template <char> struct hex_value;
16 template <> struct hex_value<'0'> { static constexpr limb_type value = 0; };
17 template <> struct hex_value<'1'> { static constexpr limb_type value = 1; };
18 template <> struct hex_value<'2'> { static constexpr limb_type value = 2; };
19 template <> struct hex_value<'3'> { static constexpr limb_type value = 3; };
20 template <> struct hex_value<'4'> { static constexpr limb_type value = 4; };
21 template <> struct hex_value<'5'> { static constexpr limb_type value = 5; };
22 template <> struct hex_value<'6'> { static constexpr limb_type value = 6; };
23 template <> struct hex_value<'7'> { static constexpr limb_type value = 7; };
24 template <> struct hex_value<'8'> { static constexpr limb_type value = 8; };
25 template <> struct hex_value<'9'> { static constexpr limb_type value = 9; };
26 template <> struct hex_value<'a'> { static constexpr limb_type value = 10; };
27 template <> struct hex_value<'b'> { static constexpr limb_type value = 11; };
28 template <> struct hex_value<'c'> { static constexpr limb_type value = 12; };
29 template <> struct hex_value<'d'> { static constexpr limb_type value = 13; };
30 template <> struct hex_value<'e'> { static constexpr limb_type value = 14; };
31 template <> struct hex_value<'f'> { static constexpr limb_type value = 15; };
32 template <> struct hex_value<'A'> { static constexpr limb_type value = 10; };
33 template <> struct hex_value<'B'> { static constexpr limb_type value = 11; };
34 template <> struct hex_value<'C'> { static constexpr limb_type value = 12; };
35 template <> struct hex_value<'D'> { static constexpr limb_type value = 13; };
36 template <> struct hex_value<'E'> { static constexpr limb_type value = 14; };
37 template <> struct hex_value<'F'> { static constexpr limb_type value = 15; };
38
39 template <class Pack, limb_type value>
40 struct combine_value_to_pack;
41 template <limb_type first, limb_type...ARGS, limb_type value>
42 struct combine_value_to_pack<value_pack<first, ARGS...>, value>
43 {
44 typedef value_pack<first | value, ARGS...> type;
45 };
46
47 template <char NextChar, char...CHARS>
48 struct pack_values
49 {
50 static constexpr unsigned chars_per_limb = sizeof(limb_type) * CHAR_BIT / 4;
51 static constexpr unsigned shift = ((sizeof...(CHARS)) % chars_per_limb) * 4;
52 static constexpr limb_type value_to_add = shift ? hex_value<NextChar>::value << shift : hex_value<NextChar>::value;
53
54 typedef typename pack_values<CHARS...>::type recursive_packed_type;
55 typedef typename boost::mpl::if_c<shift == 0,
56 typename recursive_packed_type::next_type,
57 recursive_packed_type>::type pack_type;
58 typedef typename combine_value_to_pack<pack_type, value_to_add>::type type;
59 };
60 template <char NextChar>
61 struct pack_values<NextChar>
62 {
63 static constexpr limb_type value_to_add = hex_value<NextChar>::value;
64
65 typedef value_pack<value_to_add> type;
66 };
67
68 template <class T>
69 struct strip_leading_zeros_from_pack;
70 template <limb_type...PACK>
71 struct strip_leading_zeros_from_pack<value_pack<PACK...> >
72 {
73 typedef value_pack<PACK...> type;
74 };
75 template <limb_type...PACK>
76 struct strip_leading_zeros_from_pack<value_pack<0u, PACK...> >
77 {
78 typedef typename strip_leading_zeros_from_pack<value_pack<PACK...> >::type type;
79 };
80
81 template <limb_type v, class PACK>
82 struct append_value_to_pack;
83 template <limb_type v, limb_type...PACK>
84 struct append_value_to_pack<v, value_pack<PACK...> >
85 {
86 typedef value_pack<PACK..., v> type;
87 };
88
89 template <class T>
90 struct reverse_value_pack;
91 template <limb_type v, limb_type...VALUES>
92 struct reverse_value_pack<value_pack<v, VALUES...> >
93 {
94 typedef typename reverse_value_pack<value_pack<VALUES...> >::type lead_values;
95 typedef typename append_value_to_pack<v, lead_values>::type type;
96 };
97 template <limb_type v>
98 struct reverse_value_pack<value_pack<v> >
99 {
100 typedef value_pack<v> type;
101 };
102 template <>
103 struct reverse_value_pack<value_pack<> >
104 {
105 typedef value_pack<> type;
106 };
107
108 template <char l1, char l2, char...STR>
109 struct make_packed_value_from_str
110 {
111 BOOST_STATIC_ASSERT_MSG(l1 == '0', "Multi-precision integer literals must be in hexadecimal notation.");
112 BOOST_STATIC_ASSERT_MSG((l2 == 'X') || (l2 == 'x'), "Multi-precision integer literals must be in hexadecimal notation.");
113 typedef typename pack_values<STR...>::type packed_type;
114 typedef typename strip_leading_zeros_from_pack<packed_type>::type stripped_type;
115 typedef typename reverse_value_pack<stripped_type>::type type;
116 };
117
118 template <class Pack, class B>
119 struct make_backend_from_pack
120 {
121 static constexpr Pack p = {};
122 static constexpr B value = p;
123 };
124
125 template <class Pack, class B>
126 constexpr B make_backend_from_pack<Pack, B>::value;
127
128 template <unsigned Digits>
129 struct signed_cpp_int_literal_result_type
130 {
131 static constexpr unsigned bits = Digits * 4;
132 typedef boost::multiprecision::backends::cpp_int_backend<bits, bits, signed_magnitude, unchecked, void> backend_type;
133 typedef number<backend_type, et_off> number_type;
134 };
135
136 template <unsigned Digits>
137 struct unsigned_cpp_int_literal_result_type
138 {
139 static constexpr unsigned bits = Digits * 4;
140 typedef boost::multiprecision::backends::cpp_int_backend<bits, bits, unsigned_magnitude, unchecked, void> backend_type;
141 typedef number<backend_type, et_off> number_type;
142 };
143
144 }
145
146 template <char... STR>
147 constexpr typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::number_type operator "" _cppi()
148 {
149 typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;
150 return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::signed_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::backend_type>::value;
151 }
152
153 template <char... STR>
154 constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::number_type operator "" _cppui()
155 {
156 typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;
157 return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<(sizeof...(STR)) - 2>::backend_type>::value;
158 }
159
160 #define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits)\
161 template <char... STR> \
162 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)()\
163 {\
164 typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;\
165 return boost::multiprecision::literals::detail::make_backend_from_pack<\
166 pt, \
167 boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> \
168 >::value;\
169 }\
170 template <char... STR> \
171 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)()\
172 {\
173 typedef typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type pt;\
174 return boost::multiprecision::literals::detail::make_backend_from_pack<\
175 pt, \
176 boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>\
177 >::value;\
178 }\
179
180 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128)
181 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256)
182 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512)
183 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024)
184
185 }
186
187 //
188 // Overload unary minus operator for constexpr use:
189 //
190 template <unsigned MinBits, cpp_int_check_type Checked>
191 constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
192 operator - (const number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>& a)
193 {
194 return cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>(a.backend(), boost::multiprecision::literals::detail::make_negate_tag());
195 }
196 template <unsigned MinBits, cpp_int_check_type Checked>
197 constexpr number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>
198 operator - (number<cpp_int_backend<MinBits, MinBits, signed_magnitude, Checked, void>, et_off>&& a)
199 {
200 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());
201 }
202
203 }} // namespaces
204
205 #endif // BOOST_MP_CPP_INT_CORE_HPP
206