From 12ca69e9b3b307c1da0fc096d2682bc4f99f792d Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Sat, 28 Sep 2024 09:17:42 -0400 Subject: [PATCH] rework 'override' --- docs.in/reference/method.cpp | 32 +++++++++++----------- docs.in/reference/use_definitions.cpp | 2 +- docs.in/tutorials/api.cpp | 26 ++++++++---------- docs.in/tutorials/templates_tutorial.cpp | 2 +- examples/slides.cpp | 12 ++++----- include/yorel/yomm2/core.hpp | 34 +++++++++--------------- include/yorel/yomm2/macros.hpp | 2 +- include/yorel/yomm2/templates.hpp | 4 +-- tests/benchmarks.cpp | 24 ++++++++--------- tests/test_blackbox.cpp | 22 +++++++-------- tests/test_generator_forward_decls.cpp | 4 +-- tests/test_member_method.cpp | 2 +- tests/test_templates.cpp | 25 +++++++++++------ tests/test_virtual_ptr_all.cpp | 10 +++---- tests/test_virtual_ptr_basic.cpp | 8 +++--- 15 files changed, 102 insertions(+), 107 deletions(-) diff --git a/docs.in/reference/method.cpp b/docs.in/reference/method.cpp index bc34f42e..5ec71daf 100644 --- a/docs.in/reference/method.cpp +++ b/docs.in/reference/method.cpp @@ -1,6 +1,6 @@ /*** entry: method -hrefs: method-fn, method-next_type, method-override_fn, method-override, method-use_next +hrefs: method-fn, method-next_type, method-override, method-override, method-use_next headers: yorel/yomm2/core.hpp, yorel/yomm2.hpp ```c++ @@ -16,7 +16,7 @@ struct method; `method` provides a static function object, `fn`, that takes a list of arguments of type `Args`, *minus* the `virtual_` decorator, and returns `ReturnType`. -Method definitions can be added with the [`method::override_fn`](#override_fn) +Method definitions can be added with the [`method::override`](#override) and [`method::override`](#override) class templates. ## Template parameters @@ -82,17 +82,17 @@ The single instance of `method`. Used to call the met | Name | Description | | --------------------------------- | --------------------------------------------------------- | -| [override_fn](#override_fn) | add a definition to the method | +| [override](#override) | add a definition to the method | | [override](#override) | add a definition container to the method | | [next_type](#next_type) | type of a pointer to the next most specialised definition | | [use_next](#use_next) | CRTP base for definitions that use `next` | -## override_fn +## override ```c++ template -struct override_fn { - explicit override_fn(next_type* next = nullptr); +struct override { + explicit override(next_type* next = nullptr); }; ``` @@ -200,18 +200,18 @@ using kick = yomm2::method), std::string>; std::string kick_cat(Cat& dog) { return "hiss"; } -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); std::string kick_dog(Dog& dog) { return "bark"; } -YOMM2_REGISTER(kick::override_fn); -struct kick_bulldog { - static std::string fn(Bulldog& dog) { - return kick::next(dog) + " and bite"; - } -}; +YOMM2_REGISTER(kick::override); + +std::string kick_bulldog(Bulldog& dog) { + return kick::next(dog) + " and bite"; +} + YOMM2_REGISTER(kick::override); struct YOMM2_METHOD_NAME(pet); // use obfuscated name @@ -221,12 +221,14 @@ using pet = std::string pet_cat(Cat& dog) { return "purr"; } -YOMM2_REGISTER(pet::override_fn); + +YOMM2_REGISTER(pet::override); std::string pet_dog(Dog& dog) { return "wag tail"; } -YOMM2_REGISTER(pet::override_fn); + +YOMM2_REGISTER(pet::override); BOOST_AUTO_TEST_CASE(ref_method_example) { yomm2::initialize(); diff --git a/docs.in/reference/use_definitions.cpp b/docs.in/reference/use_definitions.cpp index 07c6f7ea..156f0bb2 100644 --- a/docs.in/reference/use_definitions.cpp +++ b/docs.in/reference/use_definitions.cpp @@ -51,7 +51,7 @@ using same_type = method); +YOMM2_REGISTER(same_type::override); // 2 template diff --git a/docs.in/tutorials/api.cpp b/docs.in/tutorials/api.cpp index 6f337128..bcd57583 100644 --- a/docs.in/tutorials/api.cpp +++ b/docs.in/tutorials/api.cpp @@ -110,7 +110,7 @@ std::string kick_dog(Dog& dog) { return "bark"; } -kick::override_fn add_kick_dog; +kick::override add_kick_dog; // > // md< @@ -120,7 +120,7 @@ kick::override_fn add_kick_dog; // appropriate function. Function templates and explicit specialization can also // be used for this purpose. -// What about `next`? The constructor of `override_fn` can be passed a pointer +// What about `next`? The constructor of `override` can be passed a pointer // to a function that will be set to the function's next definition by // `update`. The pointer type is available in the method as `next_type`. @@ -131,7 +131,7 @@ std::string kick_bulldog(Bulldog& dog) { return kick::next(dog) + " and bite back"; } -kick::override_fn add_kick_bulldog; +kick::override add_kick_bulldog; // > // md< @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(test_synopsis_functions_no_macros) { // passing it `declval` arguments for the definition's parameter list. The // compiler performs overload resolution, and the macro uses `decltype` to // extract the result type, i.e the method's class, and registers the definition -// and the `next` pointer with `override_fn`. +// and the `next` pointer with `override`. // In the process, both macros need to create identifiers for the various static // objects, and the name of the function inside the definition wrapper class. @@ -247,7 +247,7 @@ using kick = method), std::string>; // md< -// `override_fn` is a workhorse that is intended to be used directly only by +// `override` is a workhorse that is intended to be used directly only by // `define_method`. YOMM2 has another mechanism that is a bit more high level: // *definition containers*. @@ -258,11 +258,9 @@ using kick = method), std::string>; // > // code< -struct kick_dog { - static std::string fn(Dog& dog) { - return "bark"; - } -}; +std::string kick_dog(Dog& dog) { + return "bark"; +} YOMM2_REGISTER(kick::override); // > @@ -279,11 +277,9 @@ YOMM2_REGISTER(kick::override); // > // code< -struct kick_bulldog { - static std::string fn(Bulldog& dog) { - return kick::next(dog) + " and bite back"; - } -}; +static std::string kick_bulldog(Bulldog& dog) { + return kick::next(dog) + " and bite back"; +} YOMM2_REGISTER(kick::override); // > diff --git a/docs.in/tutorials/templates_tutorial.cpp b/docs.in/tutorials/templates_tutorial.cpp index eca03a15..b8ae4645 100644 --- a/docs.in/tutorials/templates_tutorial.cpp +++ b/docs.in/tutorials/templates_tutorial.cpp @@ -282,7 +282,7 @@ inline bool operator==(const vector& a, const vector& b) { // Now we need to provide definitions for these methods. But which ones? // We could decide *for the user* that only (say) vectors of `double`s and -// `int`s are supported. We could use `override_fn` or `override` to +// `int`s are supported. We could use `override` or `override` to // define four specializations, covering all the possible combinations (i.e. the // Cartesian product): diff --git a/examples/slides.cpp b/examples/slides.cpp index db0b25e8..7145e07f 100644 --- a/examples/slides.cpp +++ b/examples/slides.cpp @@ -188,17 +188,15 @@ using value = method), int>; int number_value(const Number& node) { return node.val; } -value::override_fn add_number_value; +value::override add_number_value; template -struct binary_value { - static int fn(const NodeClass& expr) { +int binary_op(const NodeClass& expr) { return Op()(value::fn(expr.left), value::fn(expr.right)); - } -}; +} -YOMM2_REGISTER(value::override>>); -YOMM2_REGISTER(value::override>>); +YOMM2_REGISTER(value::override>>); +YOMM2_REGISTER(value::override>>); } diff --git a/include/yorel/yomm2/core.hpp b/include/yorel/yomm2/core.hpp index b7b16c5a..e2fd9b57 100644 --- a/include/yorel/yomm2/core.hpp +++ b/include/yorel/yomm2/core.hpp @@ -647,44 +647,34 @@ class method : public detail::method_info { }; template - struct override_fn_impl { - explicit override_fn_impl(FunctionPointer* next = nullptr); + struct override_impl { + explicit override_impl(FunctionPointer* next = nullptr); }; template - struct override_fn_aux; + struct override_aux; template - struct override_fn_aux - : override_fn_impl { + struct override_aux + : override_impl { }; template< auto Function, class FnClass, typename FnReturnType, typename... FnParameters> - struct override_fn_aux< + struct override_aux< Function, FnReturnType (FnClass::*)(FnParameters...)> { static auto fn(FnClass* this_, FnParameters&&... args) -> FnReturnType { return (this_->*Function)(std::forward(args)...); } - override_fn_impl impl{&next}; + override_impl impl{&next}; }; public: - template - struct override_fn : override_fn_aux { - using override_fn_aux::override_fn_aux; - }; - - template - struct override_fns { - std::tuple...> fns; - }; - - template - struct override : override_fn { - using type = override; + template + struct override { + std::tuple...> impl; }; }; @@ -988,8 +978,8 @@ auto method:: template template -method::override_fn_impl< - Function>::override_fn_impl(FunctionPointer* p_next) { +method::override_impl< + Function>::override_impl(FunctionPointer* p_next) { // Work around MSVC bug: using &next as a default value // for 'next' confuses it about Parameters not being expanded. if (!p_next) { diff --git a/include/yorel/yomm2/macros.hpp b/include/yorel/yomm2/macros.hpp index a1b6e06c..4abaf07c 100644 --- a/include/yorel/yomm2/macros.hpp +++ b/include/yorel/yomm2/macros.hpp @@ -69,7 +69,7 @@ }; \ INLINE YOMM2_REGISTER( \ OVERRIDERS:: \ - method_type::override_fn::fn>); \ INLINE auto \ OVERRIDERS::fn ARGS \ diff --git a/include/yorel/yomm2/templates.hpp b/include/yorel/yomm2/templates.hpp index c0edde88..4ad800aa 100644 --- a/include/yorel/yomm2/templates.hpp +++ b/include/yorel/yomm2/templates.hpp @@ -94,12 +94,12 @@ struct use_definition { template struct impl { - using type = typename T::method::template override; + using type = typename T::method::template override; }; template struct impl> { - using type = typename First::template override>; + using type = typename First::template override::fn>; }; template diff --git a/tests/benchmarks.cpp b/tests/benchmarks.cpp index 91b930a3..30c51311 100644 --- a/tests/benchmarks.cpp +++ b/tests/benchmarks.cpp @@ -377,24 +377,24 @@ struct population : abstract_population { template static void fn1(T&) { } - typename method1::template override_fn>> + typename method1::template override>> YOMM2_GENSYM; - typename method1::template override_fn>> + typename method1::template override>> YOMM2_GENSYM; template static void fn2(T&, U&) { } - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<0>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<1>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<0>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<1>>> YOMM2_GENSYM; }; @@ -416,24 +416,24 @@ struct population : abstract_population { template static void fn1(vptr) { } - typename method1::template override_fn>> + typename method1::template override>> YOMM2_GENSYM; - typename method1::template override_fn>> + typename method1::template override>> YOMM2_GENSYM; template static void fn2(vptr, vptr) { } - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<0>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<1>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<0>>> YOMM2_GENSYM; - typename method2::template override_fn< + typename method2::template override< fn2, intermediate<1>>> YOMM2_GENSYM; }; diff --git a/tests/test_blackbox.cpp b/tests/test_blackbox.cpp index 6ad06d10..a4716780 100644 --- a/tests/test_blackbox.cpp +++ b/tests/test_blackbox.cpp @@ -210,13 +210,13 @@ std::string kick_dog(Dog& dog) { return "bark"; } -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); std::string kick_bulldog(Bulldog& dog) { return kick::next(dog) + " and bite back"; } -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); BOOST_AUTO_TEST_CASE(test_next_fn) { initialize(); @@ -369,31 +369,31 @@ BOOST_AUTO_TEST_CASE(update_report) { // 'meet' dispatch table is one cell, containing 'not_implemented' BOOST_TEST(report.cells == 1); - YOMM2_REGISTER(kick::override_fn>); + YOMM2_REGISTER(kick::override>); report = initialize().report; BOOST_TEST(report.not_implemented == 2); - YOMM2_REGISTER(pet::override_fn>); - YOMM2_REGISTER(pet::override_fn>); + YOMM2_REGISTER(pet::override>); + YOMM2_REGISTER(pet::override>); report = initialize().report; BOOST_TEST(report.not_implemented == 2); // create ambiguity - YOMM2_REGISTER(meet::override_fn>); - YOMM2_REGISTER(meet::override_fn>); + YOMM2_REGISTER(meet::override>); + YOMM2_REGISTER(meet::override>); report = initialize().report; BOOST_TEST(report.cells == 4); BOOST_TEST(report.ambiguous == 1); - YOMM2_REGISTER(meet::override_fn>); + YOMM2_REGISTER(meet::override>); report = initialize().report; BOOST_TEST(report.cells == 6); BOOST_TEST(report.ambiguous == 1); // shadow ambiguity - YOMM2_REGISTER(meet::override_fn>); - YOMM2_REGISTER(meet::override_fn>); - YOMM2_REGISTER(meet::override_fn>); + YOMM2_REGISTER(meet::override>); + YOMM2_REGISTER(meet::override>); + YOMM2_REGISTER(meet::override>); report = initialize().report; BOOST_TEST(report.cells == 9); BOOST_TEST(report.ambiguous == 0); diff --git a/tests/test_generator_forward_decls.cpp b/tests/test_generator_forward_decls.cpp index 2c85adc7..837cc3b7 100644 --- a/tests/test_generator_forward_decls.cpp +++ b/tests/test_generator_forward_decls.cpp @@ -188,11 +188,11 @@ BOOST_AUTO_TEST_CASE(test_generate_offsets) { YOMM2_REGISTER(use_classes); using baz1 = method, int), void, policy>; - YOMM2_REGISTER(baz1::override_fn); + YOMM2_REGISTER(baz1::override); using baz2 = method, virtual_), void, policy>; - YOMM2_REGISTER(baz2::override_fn); + YOMM2_REGISTER(baz2::override); initialize(); diff --git a/tests/test_member_method.cpp b/tests/test_member_method.cpp index 590da373..21b7e8ca 100644 --- a/tests/test_member_method.cpp +++ b/tests/test_member_method.cpp @@ -45,7 +45,7 @@ struct Payroll { } public: - using pay_functions = Payroll::pay_method::override_fns< + using pay_functions = Payroll::pay_method::override< &Payroll::pay_employee, &Payroll::pay_manager>; }; diff --git a/tests/test_templates.cpp b/tests/test_templates.cpp index 5f1ebe01..5b9f6510 100644 --- a/tests/test_templates.cpp +++ b/tests/test_templates.cpp @@ -133,19 +133,28 @@ static_assert( namespace test_add_definition { -struct method { - using self_type = method; - template struct override; -}; +struct Number {}; +struct Fraction : Number {}; + +struct negate_; +using negate = method), Number>; + template -struct definition {}; +struct definition; -static_assert(std::is_same_v< - detail::use_definition::fn>, - method::override> +template +struct definition { + static auto fn(const Derived&) { + return Derived(); + } +}; +static_assert(std::is_same_v< + detail::use_definition::fn>, + negate::override::fn> >); + } int main() { diff --git a/tests/test_virtual_ptr_all.cpp b/tests/test_virtual_ptr_all.cpp index b23148df..3d0fd079 100644 --- a/tests/test_virtual_ptr_all.cpp +++ b/tests/test_virtual_ptr_all.cpp @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( static use_classes YOMM2_GENSYM; using kick = method< YOMM2_METHOD_NAME(kick)(virtual_ptr), std::string, Policy>; - static typename kick::template override_fn< + static typename kick::template override< kick_bear>> YOMM2_GENSYM; @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( using kick = method< YOMM2_METHOD_NAME(kick)(virtual_ptr), std::string, Policy>; - static typename kick::template override_fn< + static typename kick::template override< kick_bear>> YOMM2_GENSYM; @@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( virtual_ptr, virtual_ptr, virtual_ptr), std::string, Policy>; - static typename fight::template override_fn, virtual_ptr, virtual_ptr>> YOMM2_GENSYM; @@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( YOMM2_METHOD_NAME(kick)(virtual_shared_ptr), std::string, Policy>; - static typename kick::template override_fn< + static typename kick::template override< kick_bear>> YOMM2_GENSYM; @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( virtual_shared_ptr), std::string, Policy>; - static typename fight::template override_fn, virtual_shared_ptr, virtual_shared_ptr>> YOMM2_GENSYM; diff --git a/tests/test_virtual_ptr_basic.cpp b/tests/test_virtual_ptr_basic.cpp index b9f04958..c5c19e5c 100644 --- a/tests/test_virtual_ptr_basic.cpp +++ b/tests/test_virtual_ptr_basic.cpp @@ -78,7 +78,7 @@ void kick_dog(virtual_ptr, std::ostream& os) { struct YOMM2_METHOD_NAME(kick); using kick = method, std::ostream&), void>; -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); BOOST_AUTO_TEST_CASE(test_virtual_ptr_by_ref) { yorel::yomm2::initialize(); @@ -156,7 +156,7 @@ void kick_dog(virtual_shared_ptr, std::ostream& os) { struct YOMM2_METHOD_NAME(kick); using kick = method, std::ostream&), void>; -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); BOOST_AUTO_TEST_CASE(test_virtual_shared_by_value) { yorel::yomm2::initialize(); @@ -179,7 +179,7 @@ void kick_dog(const virtual_shared_ptr&, std::ostream& os) { struct YOMM2_METHOD_NAME(kick); using kick = method&, std::ostream&), void>; -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); BOOST_AUTO_TEST_CASE(test_virtual_shared_by_const_reference) { yorel::yomm2::initialize(); @@ -208,7 +208,7 @@ void kick_dog(virtual_ptr, std::ostream& os) { struct YOMM2_METHOD_NAME(kick); using kick = method, std::ostream&), void>; -YOMM2_REGISTER(kick::override_fn); +YOMM2_REGISTER(kick::override); BOOST_AUTO_TEST_CASE(test_virtual_ptr_non_polymorphic) { yorel::yomm2::initialize();