Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:13

0001 #ifndef BOOST_LEAF_PRED_HPP_INCLUDED
0002 #define BOOST_LEAF_PRED_HPP_INCLUDED
0003 
0004 // Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc.
0005 
0006 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0007 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #include <boost/leaf/config.hpp>
0010 #include <boost/leaf/handle_errors.hpp>
0011 
0012 #if __cplusplus >= 201703L
0013 #   define BOOST_LEAF_MATCH_ARGS(et,v1,v) auto v1, auto... v
0014 #else
0015 #   define BOOST_LEAF_MATCH_ARGS(et,v1,v) typename leaf_detail::et::type v1, typename leaf_detail::et::type... v
0016 #endif
0017 #define BOOST_LEAF_ESC(...) __VA_ARGS__
0018 
0019 namespace boost { namespace leaf {
0020 
0021 namespace leaf_detail
0022 {
0023 #if __cplusplus >= 201703L
0024     template <class MatchType, class T>
0025     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) noexcept ) noexcept
0026     {
0027         BOOST_LEAF_ASSERT(P != nullptr);
0028         return P(e);
0029     }
0030 
0031     template <class MatchType, class T>
0032     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) )
0033     {
0034         BOOST_LEAF_ASSERT(P != nullptr);
0035         return P(e);
0036     }
0037 #endif
0038 
0039     template <class MatchType, class V>
0040     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, V v )
0041     {
0042         return e == v;
0043     }
0044 
0045     template <class MatchType, class VCar, class... VCdr>
0046     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, VCar car, VCdr ... cdr )
0047     {
0048         return cmp_value_pack(e, car) || cmp_value_pack(e, cdr...);
0049     }
0050 }
0051 
0052 ////////////////////////////////////////
0053 
0054 #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
0055 template <class E, class Enum = E>
0056 struct condition
0057 {
0058     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.");
0059 };
0060 
0061 template <class Enum>
0062 struct condition<Enum, Enum>
0063 {
0064     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.");
0065 };
0066 
0067 #if __cplusplus >= 201703L
0068 template <class ErrorCodeEnum>
0069 BOOST_LEAF_CONSTEXPR inline bool category( std::error_code const & ec )
0070 {
0071     static_assert(std::is_error_code_enum<ErrorCodeEnum>::value, "leaf::category requires an error code enum");
0072     return &ec.category() == &std::error_code(ErrorCodeEnum{}).category();
0073 }
0074 #endif
0075 #endif
0076 
0077 ////////////////////////////////////////
0078 
0079 namespace leaf_detail
0080 {
0081     template <class T>
0082     struct match_enum_type
0083     {
0084         using type = T;
0085     };
0086 
0087 #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
0088     template <class Enum>
0089     struct match_enum_type<condition<Enum, Enum>>
0090     {
0091         using type = Enum;
0092     };
0093 
0094     template <class E, class Enum>
0095     struct match_enum_type<condition<E, Enum>>
0096     {
0097         static_assert(sizeof(Enum) == 0, "leaf::condition<E, Enum> should be used with leaf::match_value<>, not with leaf::match<>");
0098     };
0099 #endif
0100 }
0101 
0102 template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
0103 struct match
0104 {
0105     using error_type = E;
0106     E matched;
0107 
0108     template <class T>
0109     BOOST_LEAF_CONSTEXPR static bool evaluate(T && x)
0110     {
0111         return leaf_detail::cmp_value_pack(std::forward<T>(x), V1, V...);
0112     }
0113 };
0114 
0115 #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
0116 template <class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_enum_type<condition<Enum, Enum>>), V1, V)>
0117 struct match<condition<Enum, Enum>, V1, V...>
0118 {
0119     using error_type = std::error_code;
0120     std::error_code const & matched;
0121 
0122     BOOST_LEAF_CONSTEXPR static bool evaluate(std::error_code const & e) noexcept
0123     {
0124         return leaf_detail::cmp_value_pack(e, V1, V...);
0125     }
0126 };
0127 #endif
0128 
0129 template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
0130 struct is_predicate<match<E, V1, V...>>: std::true_type
0131 {
0132 };
0133 
0134 ////////////////////////////////////////
0135 
0136 namespace leaf_detail
0137 {
0138     template <class E>
0139     struct match_value_enum_type
0140     {
0141         using type = typename std::remove_reference<decltype(std::declval<E>().value)>::type;
0142     };
0143 
0144 #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
0145     template <class E, class Enum>
0146     struct match_value_enum_type<condition<E, Enum>>
0147     {
0148         using type = Enum;
0149     };
0150 
0151     template <class Enum>
0152     struct match_value_enum_type<condition<Enum, Enum>>
0153     {
0154         static_assert(sizeof(Enum)==0, "leaf::condition<Enum> should be used with leaf::match<>, not with leaf::match_value<>");
0155     };
0156 #endif
0157 }
0158 
0159 template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
0160 struct match_value
0161 {
0162     using error_type = E;
0163     E const & matched;
0164 
0165     BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
0166     {
0167         return leaf_detail::cmp_value_pack(e.value, V1, V...);
0168     }
0169 };
0170 
0171 #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
0172 template <class E, class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_value_enum_type<condition<E, Enum>>), V1, V)>
0173 struct match_value<condition<E, Enum>, V1, V...>
0174 {
0175     using error_type = E;
0176     E const & matched;
0177 
0178     BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e)
0179     {
0180         return leaf_detail::cmp_value_pack(e.value, V1, V...);
0181     }
0182 };
0183 #endif
0184 
0185 template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
0186 struct is_predicate<match_value<E, V1, V...>>: std::true_type
0187 {
0188 };
0189 
0190 ////////////////////////////////////////
0191 
0192 #if __cplusplus >= 201703L
0193 template <auto, auto, auto...>
0194 struct match_member;
0195 
0196 template <class T, class E, T E::* P, auto V1, auto... V>
0197 struct match_member<P, V1, V...>
0198 {
0199     using error_type = E;
0200     E const & matched;
0201 
0202     BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
0203     {
0204         return leaf_detail::cmp_value_pack(e.*P, V1, V...);
0205     }
0206 };
0207 
0208 template <auto P, auto V1, auto... V>
0209 struct is_predicate<match_member<P, V1, V...>>: std::true_type
0210 {
0211 };
0212 #endif
0213 
0214 ////////////////////////////////////////
0215 
0216 template <class P>
0217 struct if_not
0218 {
0219     using error_type = typename P::error_type;
0220     decltype(std::declval<P>().matched) matched;
0221 
0222     template <class E>
0223     BOOST_LEAF_CONSTEXPR static bool evaluate(E && e) noexcept
0224     {
0225         return !P::evaluate(std::forward<E>(e));
0226     }
0227 };
0228 
0229 template <class P>
0230 struct is_predicate<if_not<P>>: std::true_type
0231 {
0232 };
0233 
0234 ////////////////////////////////////////
0235 
0236 
0237 #ifndef BOOST_LEAF_NO_EXCEPTIONS
0238 
0239 namespace leaf_detail
0240 {
0241     template <class Ex>
0242     BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const * ) noexcept
0243     {
0244         return dynamic_cast<Ex const *>(&ex)!=nullptr;
0245     }
0246 
0247     template <class Ex, class... ExRest>
0248     BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const *, ExRest const * ... ex_rest ) noexcept
0249     {
0250         return dynamic_cast<Ex const *>(&ex)!=nullptr || check_exception_pack(ex, ex_rest...);
0251     }
0252 
0253     BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ) noexcept
0254     {
0255         return true;
0256     }
0257 }
0258 
0259 template <class... Ex>
0260 struct catch_
0261 {
0262     using error_type = void;
0263     std::exception const & matched;
0264 
0265     BOOST_LEAF_CONSTEXPR static bool evaluate(std::exception const & ex) noexcept
0266     {
0267         return leaf_detail::check_exception_pack(ex, static_cast<Ex const *>(nullptr)...);
0268     }
0269 };
0270 
0271 template <class Ex>
0272 struct catch_<Ex>
0273 {
0274     using error_type = void;
0275     Ex const & matched;
0276 
0277     BOOST_LEAF_CONSTEXPR static Ex const * evaluate(std::exception const & ex) noexcept
0278     {
0279         return dynamic_cast<Ex const *>(&ex);
0280     }
0281 
0282     explicit catch_( std::exception const & ex ):
0283         matched(*dynamic_cast<Ex const *>(&ex))
0284     {
0285     }
0286 };
0287 
0288 template <class... Ex>
0289 struct is_predicate<catch_<Ex...>>: std::true_type
0290 {
0291 };
0292 
0293 #endif
0294 
0295 } }
0296 
0297 #endif