]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/leaf/pred.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / leaf / pred.hpp
1 #ifndef BOOST_LEAF_PRED_HPP_INCLUDED
2 #define BOOST_LEAF_PRED_HPP_INCLUDED
3
4 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
5
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9 #ifndef BOOST_LEAF_ENABLE_WARNINGS
10 # if defined(__clang__)
11 # pragma clang system_header
12 # elif (__GNUC__*100+__GNUC_MINOR__>301)
13 # pragma GCC system_header
14 # elif defined(_MSC_VER)
15 # pragma warning(push,1)
16 # endif
17 #endif
18
19 #include <boost/leaf/handle_errors.hpp>
20
21 #if __cplusplus >= 201703L
22 # define BOOST_LEAF_MATCH_ARGS(et,v1,v) auto v1, auto... v
23 #else
24 # define BOOST_LEAF_MATCH_ARGS(et,v1,v) typename leaf_detail::et::type v1, typename leaf_detail::et::type... v
25 #endif
26 #define BOOST_LEAF_ESC(...) __VA_ARGS__
27
28 namespace boost { namespace leaf {
29
30 namespace leaf_detail
31 {
32 #if __cplusplus >= 201703L
33 template <class MatchType, class T>
34 BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) noexcept ) noexcept
35 {
36 BOOST_LEAF_ASSERT(P != 0);
37 return P(e);
38 }
39
40 template <class MatchType, class T>
41 BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) )
42 {
43 BOOST_LEAF_ASSERT(P != 0);
44 return P(e);
45 }
46 #endif
47
48 template <class MatchType, class V>
49 BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, V v )
50 {
51 return e == v;
52 }
53
54 template <class MatchType, class VCar, class... VCdr>
55 BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, VCar car, VCdr ... cdr )
56 {
57 return cmp_value_pack(e, car) || cmp_value_pack(e, cdr...);
58 }
59 }
60
61 ////////////////////////////////////////
62
63 template <class E, class Enum = E>
64 struct condition
65 {
66 static_assert(std::is_error_condition_enum<Enum>::value || std::is_error_code_enum<Enum>::value, "leaf::condition<E, Enum> requires Enum to be registered either with std::is_error_condition_enum or std::is_error_code_enum.");
67 };
68
69 template <class Enum>
70 struct condition<Enum, Enum>
71 {
72 static_assert(std::is_error_condition_enum<Enum>::value || std::is_error_code_enum<Enum>::value, "leaf::condition<Enum> requires Enum to be registered either with std::is_error_condition_enum or std::is_error_code_enum.");
73 };
74
75 #if __cplusplus >= 201703L
76 template <class ErrorCodeEnum>
77 BOOST_LEAF_CONSTEXPR inline bool category( std::error_code const & ec )
78 {
79 static_assert(std::is_error_code_enum<ErrorCodeEnum>::value, "leaf::category requires an error code enum");
80 return &ec.category() == &std::error_code(ErrorCodeEnum{}).category();
81 }
82 #endif
83
84 ////////////////////////////////////////
85
86 namespace leaf_detail
87 {
88 template <class T>
89 struct match_enum_type
90 {
91 using type = T;
92 };
93
94 template <class Enum>
95 struct match_enum_type<condition<Enum, Enum>>
96 {
97 using type = Enum;
98 };
99
100 template <class E, class Enum>
101 struct match_enum_type<condition<E, Enum>>
102 {
103 static_assert(sizeof(Enum) == 0, "leaf::condition<E, Enum> should be used with leaf::match_value<>, not with leaf::match<>");
104 };
105 }
106
107 template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
108 struct match
109 {
110 using error_type = E;
111 E matched;
112
113 template <class T>
114 BOOST_LEAF_CONSTEXPR static bool evaluate(T && x)
115 {
116 return leaf_detail::cmp_value_pack(std::forward<T>(x), V1, V...);
117 }
118 };
119
120 template <class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_enum_type<condition<Enum, Enum>>), V1, V)>
121 struct match<condition<Enum, Enum>, V1, V...>
122 {
123 using error_type = std::error_code;
124 std::error_code const & matched;
125
126 BOOST_LEAF_CONSTEXPR static bool evaluate(std::error_code const & e) noexcept
127 {
128 return leaf_detail::cmp_value_pack(e, V1, V...);
129 }
130 };
131
132 template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
133 struct is_predicate<match<E, V1, V...>>: std::true_type
134 {
135 };
136
137 ////////////////////////////////////////
138
139 namespace leaf_detail
140 {
141 template <class E>
142 struct match_value_enum_type
143 {
144 using type = typename std::remove_reference<decltype(std::declval<E>().value)>::type;
145 };
146
147 template <class E, class Enum>
148 struct match_value_enum_type<condition<E, Enum>>
149 {
150 using type = Enum;
151 };
152
153 template <class Enum>
154 struct match_value_enum_type<condition<Enum, Enum>>
155 {
156 static_assert(sizeof(Enum)==0, "leaf::condition<Enum> should be used with leaf::match<>, not with leaf::match_value<>");
157 };
158 }
159
160 template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
161 struct match_value
162 {
163 using error_type = E;
164 E const & matched;
165
166 BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
167 {
168 return leaf_detail::cmp_value_pack(e.value, V1, V...);
169 }
170 };
171
172 template <class E, class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_value_enum_type<condition<E, Enum>>), V1, V)>
173 struct match_value<condition<E, Enum>, V1, V...>
174 {
175 using error_type = E;
176 E const & matched;
177
178 BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e)
179 {
180 return leaf_detail::cmp_value_pack(e.value, V1, V...);
181 }
182 };
183
184 template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
185 struct is_predicate<match_value<E, V1, V...>>: std::true_type
186 {
187 };
188
189 ////////////////////////////////////////
190
191 #if __cplusplus >= 201703L
192 template <auto, auto, auto...>
193 struct match_member;
194
195 template <class T, class E, T E::* P, auto V1, auto... V>
196 struct match_member<P, V1, V...>
197 {
198 using error_type = E;
199 E const & matched;
200
201 BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
202 {
203 return leaf_detail::cmp_value_pack(e.*P, V1, V...);
204 }
205 };
206
207 template <auto P, auto V1, auto... V>
208 struct is_predicate<match_member<P, V1, V...>>: std::true_type
209 {
210 };
211 #endif
212
213 ////////////////////////////////////////
214
215 template <class P>
216 struct if_not
217 {
218 using error_type = typename P::error_type;;
219 decltype(std::declval<P>().matched) matched;
220
221 template <class E>
222 BOOST_LEAF_CONSTEXPR static bool evaluate(E && e) noexcept
223 {
224 return !P::evaluate(std::forward<E>(e));
225 }
226 };
227
228 template <class P>
229 struct is_predicate<if_not<P>>: std::true_type
230 {
231 };
232
233 ////////////////////////////////////////
234
235
236 #ifndef BOOST_LEAF_NO_EXCEPTIONS
237
238 namespace leaf_detail
239 {
240 template <class Ex>
241 BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const * ) noexcept
242 {
243 return dynamic_cast<Ex const *>(&ex)!=0;
244 }
245
246 template <class Ex, class... ExRest>
247 BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const *, ExRest const * ... ex_rest ) noexcept
248 {
249 return dynamic_cast<Ex const *>(&ex)!=0 || check_exception_pack(ex, ex_rest...);
250 }
251
252 BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ) noexcept
253 {
254 return true;
255 }
256 }
257
258 template <class... Ex>
259 struct catch_
260 {
261 using error_type = void;
262 std::exception const & matched;
263
264 BOOST_LEAF_CONSTEXPR static bool evaluate(std::exception const & ex) noexcept
265 {
266 return leaf_detail::check_exception_pack(ex, static_cast<Ex const *>(0)...);
267 }
268 };
269
270 template <class Ex>
271 struct catch_<Ex>
272 {
273 using error_type = void;
274 Ex const & matched;
275
276 BOOST_LEAF_CONSTEXPR static Ex const * evaluate(std::exception const & ex) noexcept
277 {
278 return dynamic_cast<Ex const *>(&ex);
279 }
280
281 explicit catch_( std::exception const & ex ):
282 matched(*dynamic_cast<Ex const *>(&ex))
283 {
284 }
285 };
286
287 template <class... Ex>
288 struct is_predicate<catch_<Ex...>>: std::true_type
289 {
290 };
291
292 #endif
293
294 } }
295
296 #endif