diff --git a/examples/core_api.cpp b/examples/core_api.cpp index 7cca48dc..e552cf62 100644 --- a/examples/core_api.cpp +++ b/examples/core_api.cpp @@ -27,7 +27,8 @@ using namespace boost::openmethod; class BOOST_OPENMETHOD_NAME(poke); using poke = method< - BOOST_OPENMETHOD_NAME(poke)(std::ostream&, virtual_ptr), void>; + BOOST_OPENMETHOD_NAME(poke), + auto(std::ostream&, virtual_ptr)->void>; // end::method[] // tag::poke_cat[] @@ -68,7 +69,7 @@ auto pet_dog(std::ostream& os, virtual_ptr dog) { } using pet = method< - BOOST_OPENMETHOD_NAME(pet)(std::ostream&, virtual_ptr), void>; + BOOST_OPENMETHOD_NAME(pet), auto(std::ostream&, virtual_ptr)->void>; BOOST_OPENMETHOD_REGISTER(pet::override); diff --git a/examples/slides.cpp b/examples/slides.cpp index e417b47e..a50f60ed 100644 --- a/examples/slides.cpp +++ b/examples/slides.cpp @@ -260,7 +260,7 @@ using namespace nodes; use_classes use_node_classes; struct value_id; -using value = method), int>; +using value = method)->int>; auto number_value(virtual_ptr node) -> int { return node->val; diff --git a/include/boost/openmethod/core.hpp b/include/boost/openmethod/core.hpp index a8d9f5ef..5e5c0df1 100644 --- a/include/boost/openmethod/core.hpp +++ b/include/boost/openmethod/core.hpp @@ -45,6 +45,8 @@ namespace detail { template constexpr bool is_polymorphic = Registry::rtti::template is_polymorphic; +using macro_default_registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY; + template struct extract_registry; @@ -962,10 +964,11 @@ class method; template< typename Name, typename... Parameters, typename ReturnType, class Registry> -class method +class methodReturnType, Registry> : public detail::method_info { // Aliases used in implementation only. Everything extracted from template // arguments is capitalized like the arguments themselves. + using RegistryType = Registry; using rtti = typename Registry::rtti; using DeclaredParameters = mp11::mp_list; using CallParameters = @@ -1107,21 +1110,22 @@ class method template< typename Name, typename... Parameters, typename ReturnType, class Registry> -method - method::fn; +methodReturnType, Registry> + methodReturnType, Registry>::fn; template< typename Name, typename... Parameters, typename ReturnType, class Registry> template -typename method::FunctionPointer - method::next; +typename method< + Name, auto(Parameters...)->ReturnType, Registry>::FunctionPointer + methodReturnType, Registry>::next; template constexpr bool is_method = std::is_base_of_v; template< typename Name, typename... Parameters, typename ReturnType, class Registry> -method::method() { +methodReturnType, Registry>::method() { method_info::slots_strides_ptr = slots_strides; using virtual_type_ids = detail::type_id_list< @@ -1140,20 +1144,21 @@ method::method() { template< typename Name, typename... Parameters, typename ReturnType, class Registry> -std::size_t method< - Name(Parameters...), ReturnType, Registry>::slots_strides[2 * Arity - 1]; +std::size_t methodReturnType, Registry>:: + slots_strides[2 * Arity - 1]; template< typename Name, typename... Parameters, typename ReturnType, class Registry> -method::~method() { +methodReturnType, Registry>::~method() { Registry::methods.remove(*this); } template< typename Name, typename... Parameters, typename ReturnType, class Registry> template -auto method::check_static_offset( - std::size_t actual, std::size_t expected) const -> void { +auto methodReturnType, Registry>:: + check_static_offset(std::size_t actual, std::size_t expected) const + -> void { using namespace detail; using error_handler = typename Registry::template policy; @@ -1177,7 +1182,7 @@ auto method::check_static_offset( template< typename Name, typename... Parameters, typename ReturnType, class Registry> BOOST_FORCEINLINE auto -method::operator()( +methodReturnType, Registry>::operator()( detail::remove_virtual... args) const -> ReturnType { using namespace detail; auto pf = resolve(parameter_traits::peek(args)...); @@ -1188,10 +1193,10 @@ method::operator()( template< typename Name, typename... Parameters, typename ReturnType, class Registry> template -BOOST_FORCEINLINE - typename method::FunctionPointer - method::resolve( - const ArgType&... args) const { +BOOST_FORCEINLINE typename method< + Name, auto(Parameters...)->ReturnType, Registry>::FunctionPointer +methodReturnType, Registry>::resolve( + const ArgType&... args) const { using namespace detail; std::uintptr_t pf; @@ -1209,7 +1214,8 @@ BOOST_FORCEINLINE template< typename Name, typename... Parameters, typename ReturnType, class Registry> template -BOOST_FORCEINLINE auto method::vptr( +BOOST_FORCEINLINE auto +methodReturnType, Registry>::vptr( const ArgType& arg) const -> vptr_type { if constexpr (detail::is_virtual_ptr) { return arg.vptr(); @@ -1222,7 +1228,7 @@ template< typename Name, typename... Parameters, typename ReturnType, class Registry> template BOOST_FORCEINLINE auto -method::resolve_uni( +methodReturnType, Registry>::resolve_uni( const ArgType& arg, const MoreArgTypes&... more_args) const -> std::uintptr_t { @@ -1251,7 +1257,7 @@ template< typename Name, typename... Parameters, typename ReturnType, class Registry> template BOOST_FORCEINLINE auto -method::resolve_multi_first( +methodReturnType, Registry>::resolve_multi_first( const ArgType& arg, const MoreArgTypes&... more_args) const -> std::uintptr_t { @@ -1292,7 +1298,7 @@ template< std::size_t VirtualArg, typename MethodArgList, typename ArgType, typename... MoreArgTypes> BOOST_FORCEINLINE auto -method::resolve_multi_next( +methodReturnType, Registry>::resolve_multi_next( vptr_type dispatch, const ArgType& arg, const MoreArgTypes&... more_args) const -> std::uintptr_t { @@ -1348,9 +1354,9 @@ auto error_type_id(const Class& obj) { template< typename Name, typename... Parameters, typename ReturnType, class Registry> -BOOST_NORETURN auto -method::not_implemented_handler( - detail::remove_virtual... args) -> ReturnType { +BOOST_NORETURN auto methodReturnType, Registry>:: + not_implemented_handler(detail::remove_virtual... args) + -> ReturnType { if constexpr (Registry::template has_policy) { not_implemented_error error; error.method = Registry::rtti::template static_type(); @@ -1383,7 +1389,7 @@ template< typename Name, typename... Parameters, typename ReturnType, class Registry> template< auto Overrider, typename OverriderReturn, typename... OverriderParameters> -auto method:: +auto methodReturnType, Registry>:: thunk::fn( detail::remove_virtual... arg) -> ReturnType { using namespace detail; @@ -1403,7 +1409,7 @@ auto method:: template< typename Name, typename... Parameters, typename ReturnType, class Registry> template -method::override_impl< +methodReturnType, Registry>::override_impl< Function, FnReturnType>::override_impl(FunctionPointer* p_next) { using namespace detail; diff --git a/include/boost/openmethod/macros.hpp b/include/boost/openmethod/macros.hpp index fd120aa0..f64352ba 100644 --- a/include/boost/openmethod/macros.hpp +++ b/include/boost/openmethod/macros.hpp @@ -22,6 +22,21 @@ struct enable_forwarder< using type = ReturnType; }; +template +struct va_args; + +template +struct va_args { + using return_type = ReturnType; + using registry = Registry; +}; + +template +struct va_args { + using return_type = ReturnType; + using registry = macro_default_registry; +}; + } // namespace boost::openmethod::detail #define BOOST_OPENMETHOD_GENSYM BOOST_PP_CAT(openmethod_gensym_, __COUNTER__) @@ -43,9 +58,15 @@ struct enable_forwarder< typename ::boost::openmethod::detail::enable_forwarder< \ void, \ ::boost::openmethod::method< \ - BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \ + BOOST_OPENMETHOD_NAME(NAME), \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \ + ARGS, \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \ typename ::boost::openmethod::method< \ - BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \ + BOOST_OPENMETHOD_NAME(NAME), \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \ + ARGS, \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \ ForwarderParameters...>::type \ BOOST_OPENMETHOD_GUIDE(NAME)(ForwarderParameters && ... args); \ template \ @@ -53,13 +74,23 @@ struct enable_forwarder< typename ::boost::openmethod::detail::enable_forwarder< \ void, \ ::boost::openmethod::method< \ - BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>, \ + BOOST_OPENMETHOD_NAME(NAME), \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \ + ARGS, \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>, \ typename ::boost::openmethod::method< \ - BOOST_OPENMETHOD_NAME(NAME) ARGS, __VA_ARGS__>::return_type, \ + BOOST_OPENMETHOD_NAME(NAME), \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \ + ARGS, \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>:: \ + return_type, \ ForwarderParameters...>::type { \ - return ::boost::openmethod:: \ - method::fn( \ - std::forward(args)...); \ + return ::boost::openmethod::method< \ + BOOST_OPENMETHOD_NAME(NAME), \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::return_type \ + ARGS, \ + ::boost::openmethod::detail::va_args<__VA_ARGS__>::registry>:: \ + fn(std::forward(args)...); \ } #define BOOST_OPENMETHOD_DETAIL_LOCATE_METHOD(NAME, ARGS) \ diff --git a/test/test_blackbox.cpp b/test/test_blackbox.cpp index 8962649e..16bba0d2 100644 --- a/test/test_blackbox.cpp +++ b/test/test_blackbox.cpp @@ -479,7 +479,7 @@ BOOST_OPENMETHOD_CLASSES(Animal, Dog, Bulldog); struct BOOST_OPENMETHOD_NAME(poke); using poke = - method), std::string>; + method)->std::string>; auto poke_dog(Dog&) -> std::string { return "bark"; @@ -637,10 +637,10 @@ void fn(Class&...) { BOOST_OPENMETHOD_CLASSES(Animal, Dog, Cat, test_registry); BOOST_AUTO_TEST_CASE(initialize_report) { - using poke = method), void, test_registry>; - using pet = method), void, test_registry>; + using poke = method)->void, test_registry>; + using pet = method)->void, test_registry>; using meet = method< - meet_(virtual_, virtual_), void, test_registry>; + meet_, auto(virtual_, virtual_)->void, test_registry>; auto report = initialize().report; BOOST_TEST(report.not_implemented == 3u); diff --git a/test/test_compiler.cpp b/test/test_compiler.cpp index 47a8ccdd..cb83ac79 100644 --- a/test/test_compiler.cpp +++ b/test/test_compiler.cpp @@ -216,11 +216,11 @@ struct M; #define ADD_METHOD(CLASS) \ auto& BOOST_PP_CAT(m_, CLASS) = \ - method), void, test_registry>::fn; + method)->void, test_registry>::fn; #define ADD_METHOD_N(CLASS, N) \ auto& BOOST_PP_CAT(BOOST_PP_CAT(m_, CLASS), N) = \ - method(virtual_), void, test_registry>::fn; + method, auto(virtual_)->void, test_registry>::fn; BOOST_AUTO_TEST_CASE(test_assign_slots_a_b1_c) { using test_registry = test_registry_<__COUNTER__>; diff --git a/test/test_member_method.cpp b/test/test_member_method.cpp index 131b9dda..43114126 100644 --- a/test/test_member_method.cpp +++ b/test/test_member_method.cpp @@ -34,7 +34,8 @@ struct Payroll { private: struct BOOST_OPENMETHOD_NAME(pay); using pay_method = method< - BOOST_OPENMETHOD_NAME(pay)(Payroll*, virtual_), void>; + BOOST_OPENMETHOD_NAME(pay), + auto(Payroll*, virtual_)->void>; void pay_employee(const Employee&) { balance -= 2000; diff --git a/test/test_virtual_ptr_dispatch.cpp b/test/test_virtual_ptr_dispatch.cpp index 2bb91a84..231df434 100644 --- a/test/test_virtual_ptr_dispatch.cpp +++ b/test/test_virtual_ptr_dispatch.cpp @@ -214,10 +214,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( BOOST_OPENMETHOD_REGISTER( use_classes); - ; using poke = method< - BOOST_OPENMETHOD_NAME(poke)(virtual_ptr), std::string, - Registry>; + BOOST_OPENMETHOD_NAME(poke), + auto(virtual_ptr)->std::string, Registry>; BOOST_OPENMETHOD_REGISTER( typename poke::template override< poke_bear>>); @@ -275,17 +274,19 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( use_classes); using poke = method< - BOOST_OPENMETHOD_NAME(poke)(virtual_ptr), std::string, - Registry>; + BOOST_OPENMETHOD_NAME(poke), + auto(virtual_ptr)->std::string, Registry>; BOOST_OPENMETHOD_REGISTER( typename poke::template override< poke_bear>>); using fight = method< - BOOST_OPENMETHOD_NAME(fight)( + BOOST_OPENMETHOD_NAME(fight), + auto( virtual_ptr, virtual_ptr, - virtual_ptr), - std::string, Registry>; + virtual_ptr) + ->std::string, + Registry>; BOOST_OPENMETHOD_REGISTER( typename fight::template override, virtual_ptr, @@ -316,19 +317,21 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( use_classes); using poke = method< - BOOST_OPENMETHOD_NAME(poke)(shared_virtual_ptr), - std::string, Registry>; + BOOST_OPENMETHOD_NAME(poke), + auto(shared_virtual_ptr)->std::string, Registry>; BOOST_OPENMETHOD_REGISTER( typename poke::template override< poke_bear>>); using fight = method< - BOOST_OPENMETHOD_NAME(fight)( + BOOST_OPENMETHOD_NAME(fight), + auto( shared_virtual_ptr, shared_virtual_ptr, - shared_virtual_ptr), - std::string, Registry>; + shared_virtual_ptr) + ->std::string, + Registry>; BOOST_OPENMETHOD_REGISTER( typename fight::template override void init_test() { BOOST_OPENMETHOD_REGISTER(use_classes); struct id; - (void)&method), void, Registry>::fn; + (void)&method)->void, Registry>::fn; boost::openmethod::initialize(); }