]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/bool.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / bool.hpp
1 /*!
2 @file
3 Defines the `Logical` and `Comparable` models of `boost::hana::integral_constant`.
4
5 @copyright Louis Dionne 2013-2016
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10 #ifndef BOOST_HANA_BOOL_HPP
11 #define BOOST_HANA_BOOL_HPP
12
13 #include <boost/hana/fwd/bool.hpp>
14
15 #include <boost/hana/concept/integral_constant.hpp>
16 #include <boost/hana/config.hpp>
17 #include <boost/hana/core/to.hpp>
18 #include <boost/hana/core/when.hpp>
19 #include <boost/hana/detail/operators/arithmetic.hpp>
20 #include <boost/hana/detail/operators/comparable.hpp>
21 #include <boost/hana/detail/operators/logical.hpp>
22 #include <boost/hana/detail/operators/orderable.hpp>
23 #include <boost/hana/eval.hpp>
24 #include <boost/hana/fwd/core/tag_of.hpp>
25 #include <boost/hana/fwd/eval_if.hpp>
26 #include <boost/hana/fwd/if.hpp>
27 #include <boost/hana/fwd/value.hpp>
28
29 #include <cstddef>
30 #include <type_traits>
31 #include <utility>
32
33
34 BOOST_HANA_NAMESPACE_BEGIN
35 //////////////////////////////////////////////////////////////////////////
36 // integral_constant
37 //////////////////////////////////////////////////////////////////////////
38 //! @cond
39 namespace ic_detail {
40 template <typename T, T N, typename = std::make_integer_sequence<T, N>>
41 struct go;
42
43 template <typename T, T N, T ...i>
44 struct go<T, N, std::integer_sequence<T, i...>> {
45 using swallow = T[];
46
47 template <typename F>
48 static constexpr void with_index(F&& f)
49 { (void)swallow{T{}, ((void)f(integral_constant<T, i>{}), i)...}; }
50
51 template <typename F>
52 static constexpr void without_index(F&& f)
53 { (void)swallow{T{}, ((void)f(), i)...}; }
54 };
55
56 template <typename T, T v>
57 template <typename F>
58 constexpr void with_index_t<T, v>::operator()(F&& f) const
59 { go<T, ((void)sizeof(&f), v)>::with_index(static_cast<F&&>(f)); }
60
61 template <typename T, T v>
62 template <typename F>
63 constexpr void times_t<T, v>::operator()(F&& f) const
64 { go<T, ((void)sizeof(&f), v)>::without_index(static_cast<F&&>(f)); }
65
66 // avoid link-time error
67 template <typename T, T v>
68 constexpr with_index_t<T, v> times_t<T, v>::with_index;
69 }
70
71 // avoid link-time error
72 template <typename T, T v>
73 constexpr ic_detail::times_t<T, v> integral_constant<T, v>::times;
74
75 template <typename T, T v>
76 struct tag_of<integral_constant<T, v>> {
77 using type = integral_constant_tag<T>;
78 };
79 //! @endcond
80
81 //////////////////////////////////////////////////////////////////////////
82 // Operators
83 //////////////////////////////////////////////////////////////////////////
84 namespace detail {
85 template <typename T>
86 struct comparable_operators<integral_constant_tag<T>> {
87 static constexpr bool value = true;
88 };
89 template <typename T>
90 struct orderable_operators<integral_constant_tag<T>> {
91 static constexpr bool value = true;
92 };
93 template <typename T>
94 struct arithmetic_operators<integral_constant_tag<T>> {
95 static constexpr bool value = true;
96 };
97 template <typename T>
98 struct logical_operators<integral_constant_tag<T>> {
99 static constexpr bool value = true;
100 };
101 }
102
103 #define BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(op) \
104 template <typename U, U u, typename V, V v> \
105 constexpr integral_constant<decltype(u op v), (u op v)> \
106 operator op(integral_constant<U, u>, integral_constant<V, v>) \
107 { return {}; } \
108 /**/
109
110 #define BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(op) \
111 template <typename U, U u> \
112 constexpr integral_constant<decltype(op u), (op u)> \
113 operator op(integral_constant<U, u>) \
114 { return {}; } \
115 /**/
116
117 // Arithmetic
118 BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(+)
119
120 // Bitwise
121 BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP(~)
122 BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(&)
123 BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(|)
124 BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(^)
125 BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(<<)
126 BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP(>>)
127
128 #undef BOOST_HANA_INTEGRAL_CONSTANT_UNARY_OP
129 #undef BOOST_HANA_INTEGRAL_CONSTANT_BINARY_OP
130
131
132 //////////////////////////////////////////////////////////////////////////
133 // User-defined literal
134 //////////////////////////////////////////////////////////////////////////
135 namespace ic_detail {
136
137 constexpr int to_int(char c) {
138 int result = 0;
139
140 if (c >= 'A' && c <= 'F') {
141 result = static_cast<int>(c) - static_cast<int>('A') + 10;
142 }
143 else if (c >= 'a' && c <= 'f') {
144 result = static_cast<int>(c) - static_cast<int>('a') + 10;
145 }
146 else {
147 result = static_cast<int>(c) - static_cast<int>('0');
148 }
149
150 return result;
151 }
152
153 template<std::size_t N>
154 constexpr long long parse(const char (&arr)[N]) {
155 long long base = 10;
156 std::size_t offset = 0;
157
158 if (N > 2) {
159 bool starts_with_zero = arr[0] == '0';
160 bool is_hex = starts_with_zero && arr[1] == 'x';
161 bool is_binary = starts_with_zero && arr[1] == 'b';
162
163 if (is_hex) {
164 //0xDEADBEEF (hexadecimal)
165 base = 16;
166 offset = 2;
167 }
168 else if (is_binary) {
169 //0b101011101 (binary)
170 base = 2;
171 offset = 2;
172 }
173 else if (starts_with_zero) {
174 //012345 (octal)
175 base = 8;
176 offset = 1;
177 }
178 }
179
180 long long number = 0;
181 long long multiplier = 1;
182
183 for (std::size_t i = 0; i < N - offset; ++i) {
184 char c = arr[N - 1 - i];
185 number += to_int(c) * multiplier;
186 multiplier *= base;
187 }
188
189 return number;
190 }
191 }
192
193 namespace literals {
194 template <char ...c>
195 constexpr auto operator"" _c() {
196 return hana::llong<ic_detail::parse<sizeof...(c)>({c...})>{};
197 }
198 }
199
200 //////////////////////////////////////////////////////////////////////////
201 // Model of Constant/IntegralConstant
202 //////////////////////////////////////////////////////////////////////////
203 template <typename T>
204 struct IntegralConstant<integral_constant_tag<T>> {
205 static constexpr bool value = true;
206 };
207
208 template <typename T, typename C>
209 struct to_impl<integral_constant_tag<T>, C, when<hana::IntegralConstant<C>::value>>
210 : embedding<is_embedded<typename C::value_type, T>::value>
211 {
212 template <typename N>
213 static constexpr auto apply(N const&)
214 { return integral_constant<T, N::value>{}; }
215 };
216
217 //////////////////////////////////////////////////////////////////////////
218 // Optimizations
219 //////////////////////////////////////////////////////////////////////////
220 template <typename T>
221 struct eval_if_impl<integral_constant_tag<T>> {
222 template <typename Cond, typename Then, typename Else>
223 static constexpr decltype(auto)
224 apply(Cond const&, Then&& t, Else&& e) {
225 constexpr bool cond = static_cast<bool>(Cond::value);
226 return eval_if_impl::apply(hana::bool_<cond>{},
227 static_cast<Then&&>(t),
228 static_cast<Else&&>(e));
229 }
230
231 template <typename Then, typename Else>
232 static constexpr decltype(auto)
233 apply(hana::true_ const&, Then&& t, Else&&)
234 { return hana::eval(static_cast<Then&&>(t)); }
235
236 template <typename Then, typename Else>
237 static constexpr decltype(auto)
238 apply(hana::false_ const&, Then&&, Else&& e)
239 { return hana::eval(static_cast<Else&&>(e)); }
240 };
241
242 template <typename T>
243 struct if_impl<integral_constant_tag<T>> {
244 template <typename Cond, typename Then, typename Else>
245 static constexpr decltype(auto)
246 apply(Cond const&, Then&& t, Else&& e) {
247 constexpr bool cond = static_cast<bool>(Cond::value);
248 return if_impl::apply(hana::bool_<cond>{},
249 static_cast<Then&&>(t),
250 static_cast<Else&&>(e));
251 }
252
253 //! @todo We could return `Then` instead of `auto` to sometimes save
254 //! a copy, but that would break some code that would return a
255 //! reference to a `type` object. I think the code that would be
256 //! broken should be changed, but more thought needs to be given.
257 template <typename Then, typename Else>
258 static constexpr auto
259 apply(hana::true_ const&, Then&& t, Else&&)
260 { return static_cast<Then&&>(t); }
261
262 template <typename Then, typename Else>
263 static constexpr auto
264 apply(hana::false_ const&, Then&&, Else&& e)
265 { return static_cast<Else&&>(e); }
266 };
267 BOOST_HANA_NAMESPACE_END
268
269 #endif // !BOOST_HANA_BOOL_HPP