Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:52:05

0001 // Copyright (c) 2018-2025 Jean-Louis Leroy
0002 // Distributed under the Boost Software License, Version 1.0.
0003 // See accompanying file LICENSE_1_0.txt
0004 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_OPENMETHOD_MACROS_HPP
0007 #define BOOST_OPENMETHOD_MACROS_HPP
0008 
0009 #include <boost/preprocessor/cat.hpp>
0010 
0011 #include <boost/openmethod/core.hpp>
0012 
0013 namespace boost::openmethod::detail {
0014 
0015 template<typename, class Method, typename ReturnType, typename... Parameters>
0016 struct enable_forwarder;
0017 
0018 template<class Method, typename ReturnType, typename... Parameters>
0019 struct enable_forwarder<
0020     std::void_t<decltype(Method::fn(std::declval<Parameters>()...))>, Method,
0021     ReturnType, Parameters...> {
0022     using type = ReturnType;
0023 };
0024 
0025 template<class...>
0026 struct va_args;
0027 
0028 template<class ReturnType, class Registry>
0029 struct va_args<ReturnType, Registry> {
0030     using return_type = ReturnType;
0031     using registry = Registry;
0032 };
0033 
0034 template<class ReturnType>
0035 struct va_args<ReturnType> {
0036     using return_type = ReturnType;
0037     using registry = macro_default_registry;
0038 };
0039 
0040 } // namespace boost::openmethod::detail
0041 
0042 #define BOOST_OPENMETHOD_GENSYM BOOST_PP_CAT(openmethod_gensym_, __COUNTER__)
0043 
0044 #define BOOST_OPENMETHOD_REGISTER(...)                                         \
0045     static __VA_ARGS__ BOOST_OPENMETHOD_GENSYM
0046 
0047 #define BOOST_OPENMETHOD_ID(NAME) NAME##_boost_openmethod
0048 
0049 #define BOOST_OPENMETHOD_OVERRIDERS(NAME)                                      \
0050     BOOST_PP_CAT(BOOST_OPENMETHOD_ID(NAME), _overriders)
0051 
0052 #define BOOST_OPENMETHOD_OVERRIDER(NAME, ARGS, ...)                            \
0053     BOOST_OPENMETHOD_OVERRIDERS(NAME)<__VA_ARGS__ ARGS>
0054 
0055 #define BOOST_OPENMETHOD_GUIDE(NAME)                                           \
0056     BOOST_PP_CAT(BOOST_OPENMETHOD_ID(NAME), _guide)
0057 
0058 #define BOOST_OPENMETHOD_TYPE(NAME, ARGS, ...)                                 \
0059     ::boost::openmethod::method<                                               \
0060         BOOST_OPENMETHOD_ID(NAME),                                             \
0061         ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type ARGS,   \
0062         ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>
0063 
0064 #define BOOST_OPENMETHOD(NAME, ARGS, ...)                                      \
0065     template<typename...>                                                      \
0066     struct BOOST_OPENMETHOD_OVERRIDERS(NAME);                                  \
0067     struct BOOST_OPENMETHOD_ID(NAME);                                          \
0068     template<typename... ForwarderParameters>                                  \
0069     typename ::boost::openmethod::detail::enable_forwarder<                    \
0070         void, BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__),                  \
0071         typename BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__),               \
0072         ForwarderParameters...>::type                                          \
0073         BOOST_OPENMETHOD_GUIDE(NAME)(ForwarderParameters && ... args);         \
0074     template<typename... ForwarderParameters>                                  \
0075     inline auto NAME(ForwarderParameters&&... args) ->                         \
0076         typename ::boost::openmethod::detail::enable_forwarder<                \
0077             void, BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__),              \
0078             ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type,    \
0079             ForwarderParameters...>::type {                                    \
0080         return BOOST_OPENMETHOD_TYPE(NAME, ARGS, __VA_ARGS__)::fn(             \
0081             std::forward<ForwarderParameters>(args)...);                       \
0082     }
0083 
0084 #define BOOST_OPENMETHOD_DETAIL_LOCATE_METHOD(NAME, ARGS)                      \
0085     template<typename T>                                                       \
0086     struct boost_openmethod_detail_locate_method_aux;                          \
0087     template<typename... A>                                                    \
0088     struct boost_openmethod_detail_locate_method_aux<void(A...)> {             \
0089         using type =                                                           \
0090             decltype(BOOST_OPENMETHOD_GUIDE(NAME)(std::declval<A>()...));      \
0091     };
0092 
0093 #define BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, ...)                    \
0094     template<typename...>                                                      \
0095     struct BOOST_OPENMETHOD_OVERRIDERS(NAME);                                  \
0096     template<>                                                                 \
0097     struct BOOST_OPENMETHOD_OVERRIDERS(NAME)<__VA_ARGS__ ARGS> {               \
0098         BOOST_OPENMETHOD_DETAIL_LOCATE_METHOD(NAME, ARGS);                     \
0099         static auto fn ARGS->__VA_ARGS__;                                      \
0100         static auto has_next() -> bool;                                        \
0101         template<typename... Args>                                             \
0102         static auto next(Args&&... args) -> decltype(auto);                    \
0103     };                                                                         \
0104     inline auto BOOST_OPENMETHOD_OVERRIDERS(                                   \
0105         NAME)<__VA_ARGS__ ARGS>::has_next() -> bool {                          \
0106         return boost_openmethod_detail_locate_method_aux<                      \
0107             void ARGS>::type::has_next<fn>();                                  \
0108     }                                                                          \
0109     template<typename... Args>                                                 \
0110     inline auto BOOST_OPENMETHOD_OVERRIDERS(NAME)<__VA_ARGS__ ARGS>::next(     \
0111         Args&&... args) -> decltype(auto) {                                    \
0112         return boost_openmethod_detail_locate_method_aux<                      \
0113             void ARGS>::type::next<fn>(std::forward<Args>(args)...);           \
0114     }
0115 
0116 #define BOOST_OPENMETHOD_DETAIL_REGISTER_OVERRIDER(NAME, ARGS, ...)            \
0117     BOOST_OPENMETHOD_REGISTER(                                                 \
0118         BOOST_OPENMETHOD_OVERRIDERS(NAME) < __VA_ARGS__ ARGS >                 \
0119         ::boost_openmethod_detail_locate_method_aux<void ARGS>::type::         \
0120             override<                                                          \
0121                 BOOST_OPENMETHOD_OVERRIDERS(NAME) < __VA_ARGS__ ARGS>::fn >);
0122 
0123 #define BOOST_OPENMETHOD_DEFINE_OVERRIDER(NAME, ARGS, ...)                     \
0124     BOOST_OPENMETHOD_DETAIL_REGISTER_OVERRIDER(NAME, ARGS, __VA_ARGS__)        \
0125     auto BOOST_OPENMETHOD_OVERRIDER(NAME, ARGS, __VA_ARGS__)::fn ARGS          \
0126         -> boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
0127 
0128 #define BOOST_OPENMETHOD_OVERRIDE(NAME, ARGS, ...)                             \
0129     BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, __VA_ARGS__)                \
0130     BOOST_OPENMETHOD_DEFINE_OVERRIDER(NAME, ARGS, __VA_ARGS__)
0131 
0132 #define BOOST_OPENMETHOD_INLINE_OVERRIDE(NAME, ARGS, ...)                      \
0133     BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, ARGS, __VA_ARGS__)                \
0134     BOOST_OPENMETHOD_DETAIL_REGISTER_OVERRIDER(NAME, ARGS, __VA_ARGS__)        \
0135     inline auto BOOST_OPENMETHOD_OVERRIDER(NAME, ARGS, __VA_ARGS__)::fn ARGS   \
0136         -> boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
0137 
0138 #define BOOST_OPENMETHOD_CLASSES(...)                                          \
0139     BOOST_OPENMETHOD_REGISTER(::boost::openmethod::use_classes<__VA_ARGS__>);
0140 
0141 #endif