Skip to content

Commit 48bf623

Browse files
committed
rework overriders
1 parent 44003c2 commit 48bf623

File tree

2 files changed

+78
-43
lines changed

2 files changed

+78
-43
lines changed

include/yorel/yomm2/core.hpp

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -703,38 +703,8 @@ class method<Name, Return(Parameters...), Options...>
703703
template<auto, typename>
704704
struct thunk;
705705

706-
template<
707-
auto Overrider, typename OverriderReturn,
708-
typename... OverriderParameters>
709-
struct thunk<Overrider, OverriderReturn (*)(OverriderParameters...)> {
710-
static auto fn(detail::remove_virtual<Parameters>... arg) -> Return;
711-
using OverriderParameterTypeIds = detail::type_id_list<
712-
Policy,
713-
detail::spec_polymorphic_types<
714-
Policy, DeclaredParameters,
715-
detail::types<OverriderParameters...>>>;
716-
};
717-
718-
template<class Container, bool has_next>
719-
struct override_;
720-
721706
friend class generator;
722707

723-
public:
724-
template<auto Function>
725-
struct override_fn;
726-
727-
private:
728-
template<class Container>
729-
struct override_<Container, false> {
730-
override_fn<Container::fn> override_{nullptr};
731-
};
732-
733-
template<class Container>
734-
struct override_<Container, true> {
735-
override_fn<Container::fn> add{&Container::next};
736-
};
737-
738708
public:
739709
// Public aliases.
740710
using return_type = Return;
@@ -753,9 +723,25 @@ class method<Name, Return(Parameters...), Options...>
753723
template<class Container>
754724
using next = detail::next_aux<method, Container>;
755725

726+
template<auto>
727+
static Next next_fn;
728+
729+
private:
730+
template<
731+
auto Overrider, typename OverriderReturn,
732+
typename... OverriderParameters>
733+
struct thunk<Overrider, OverriderReturn (*)(OverriderParameters...)> {
734+
static auto fn(detail::remove_virtual<Parameters>... arg) -> Return;
735+
using OverriderParameterTypeIds = detail::type_id_list<
736+
Policy,
737+
detail::spec_polymorphic_types<
738+
Policy, DeclaredParameters,
739+
detail::types<OverriderParameters...>>>;
740+
};
741+
756742
template<auto Function>
757-
struct override_fn {
758-
explicit override_fn(Next* next = nullptr) {
743+
struct override_fn_impl {
744+
explicit override_fn_impl(Next* next) {
759745
static detail::definition_info info;
760746

761747
if (info.method) {
@@ -774,25 +760,72 @@ class method<Name, Return(Parameters...), Options...>
774760
}
775761
};
776762

777-
template<class Container>
778-
struct override
779-
: override_<Container, detail::has_next<Container>::value> {
780-
using type = override; // make it a meta-function
763+
template<auto Function, typename FunctionType>
764+
struct override_fn_aux;
765+
766+
template<auto Function, typename FnReturnType, typename... FnParameters>
767+
struct override_fn_aux<Function, FnReturnType (*)(FnParameters...)> {
768+
override_fn_impl<Function> impl{&next_fn<Function>};
781769
};
782770

783-
template<auto F>
784-
struct add_member_function
785-
: override_fn<detail::member_function_thunk<F, decltype(F)>::fn> {};
771+
template<
772+
auto Function, class FnClass, typename FnReturnType,
773+
typename... FnParameters>
774+
struct override_fn_aux<
775+
Function, FnReturnType (FnClass::*)(FnParameters...)> {
776+
static auto fn(FnClass* this_, FnParameters&&... args) -> FnReturnType {
777+
return (this_->*Function)(std::forward<FnParameters>(args)...);
778+
}
779+
780+
override_fn_impl<fn> impl{&next_fn<Function>};
781+
};
782+
783+
public:
784+
template<auto Function>
785+
struct override_fn : override_fn_aux<Function, decltype(Function)> {
786+
using override_fn_aux<Function, decltype(Function)>::override_fn_aux;
787+
};
786788

787789
template<auto... F>
788-
struct add_member_functions : std::tuple<add_member_function<F>...> {};
790+
struct override_fns {
791+
std::tuple<override_fn<F>...> fns;
792+
};
793+
794+
private:
795+
template<class Container, bool HasNext>
796+
struct override_aux;
797+
798+
template<class Container>
799+
struct override_aux<Container, false> : override_fn<Container::fn> {
800+
override_aux() : override_fn<Container::fn>(nullptr) {
801+
}
802+
};
803+
804+
template<class Container>
805+
struct override_aux<Container, true> : override_fn<Container::fn> {
806+
override_aux() : override_fn<Container::fn>(&Container::next) {
807+
}
808+
};
809+
810+
public:
811+
template<class Container>
812+
struct override
813+
: override_aux<Container, detail::has_next<Container>::value> {
814+
using type = override; // make it a meta-function
815+
};
789816
};
790817

791818
template<
792819
typename Name, typename Return, typename... Parameters, class... Options>
793820
method<Name, Return(Parameters...), Options...>
794821
method<Name, Return(Parameters...), Options...>::fn;
795822

823+
template<
824+
typename Name, typename Return, typename... Parameters, class... Options>
825+
template<auto>
826+
typename method<Name, Return(Parameters...), Options...>::Next
827+
method<Name, Return(Parameters...), Options...>::next_fn;
828+
796829
template<typename T>
797830
constexpr bool is_method = std::is_base_of_v<detail::method_info, T>;
798831

tests/test_member_method.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ struct Payroll {
3939
void pay_employee(const Employee&) {
4040
balance -= 2000;
4141
}
42-
void pay_manager(const Manager&) {
43-
balance -= 3000;
42+
void pay_manager(const Manager& manager) {
43+
auto pf = &pay_method::next_fn<&Payroll::pay_manager>;
44+
pay_method::next_fn<&Payroll::pay_manager>(this, manager);
45+
balance -= 1000;
4446
}
4547

4648
public:
47-
using pay_functions = Payroll::pay_method::add_member_functions<
49+
using pay_functions = Payroll::pay_method::override_fns<
4850
&Payroll::pay_employee, &Payroll::pay_manager>;
4951
};
5052

0 commit comments

Comments
 (0)