Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:47:49

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