Skip to content

Commit dbae215

Browse files
committed
rework overriders
1 parent 44003c2 commit dbae215

File tree

4 files changed

+123
-47
lines changed

4 files changed

+123
-47
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 = &next_fn<Function>) {
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...)> : override_fn_impl<Function>{
768+
using override_fn_impl<Function>::override_fn_impl;
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

include/yorel/yomm2/macros.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@
5151
YOMM2_SYMBOL(NAME), RETURN_TYPE ARGS, \
5252
::yorel::yomm2::detail::types<__VA_ARGS__>>::type
5353

54-
#define YOMM2_DECLARE(...) yOMM2_DECLARE(yOMM2_WHEN_NOT_STATIC, __VA_ARGS__)
55-
#define YOMM2_STATIC_DECLARE(...) yOMM2_DECLARE(yOMM2_WHEN_STATIC, __VA_ARGS__)
54+
#define YOMM2_DECLARE(RETURN_TYPE, NAME, ARGS, ...) \
55+
yOMM2_DECLARE(yOMM2_WHEN_NOT_STATIC, RETURN_TYPE, NAME, ARGS, __VA_ARGS__)
56+
#define YOMM2_STATIC_DECLARE(RETURN_TYPE, NAME, ARGS, ...) \
57+
yOMM2_DECLARE(yOMM2_WHEN_STATIC, RETURN_TYPE, NAME, ARGS, __VA_ARGS__)
5658

5759
#define yOMM2_DECLARE(IF_STATIC, RETURN_TYPE, NAME, ARGS, ...) \
5860
struct YOMM2_SYMBOL(NAME); \
@@ -112,7 +114,7 @@
112114
struct _yOMM2_spec { \
113115
static NS::_yOMM2_method::return_type yOMM2_body ARGS; \
114116
}; \
115-
_yOMM2_method::override_fn<_yOMM2_spec::yOMM2_body> YOMM2_GENSYM(&next); \
117+
_yOMM2_method::override_fn<_yOMM2_spec::yOMM2_body> YOMM2_GENSYM(&next); \
116118
} \
117119
} \
118120
NS::_yOMM2_method::return_type NS::_yOMM2_spec::yOMM2_body ARGS
@@ -165,7 +167,7 @@
165167
Inline NS::_yOMM2_method::next_type CONTAINER<RETURN_TYPE ARGS>::next; \
166168
namespace { \
167169
namespace NS { \
168-
Inline _yOMM2_method::override_fn<CONTAINER<RETURN_TYPE ARGS>::fn> \
170+
Inline _yOMM2_method::override_fn<CONTAINER<RETURN_TYPE ARGS>::fn> \
169171
YOMM2_GENSYM(&CONTAINER<RETURN_TYPE ARGS>::next); \
170172
} \
171173
} \

tests/test_blackbox.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,45 @@ BOOST_AUTO_TEST_CASE(simple) {
203203

204204
} // namespace matrices
205205

206+
namespace test_next_fn {
207+
208+
struct Animal {
209+
virtual ~Animal() {
210+
}
211+
};
212+
213+
struct Dog : Animal {};
214+
struct Bulldog : Dog {};
215+
216+
register_classes(Animal, Dog, Bulldog);
217+
218+
struct YOMM2_SYMBOL(kick);
219+
using kick = method<YOMM2_SYMBOL(kick), std::string(virtual_<Animal&>)>;
220+
221+
std::string kick_dog(Dog& dog) {
222+
return "bark";
223+
}
224+
225+
YOMM2_STATIC(kick::override_fn<kick_dog>);
226+
227+
std::string kick_bulldog(Bulldog& dog) {
228+
return kick::next_fn<kick_bulldog>(dog) + " and bite back";
229+
}
230+
231+
YOMM2_STATIC(kick::override_fn<kick_bulldog>);
232+
233+
BOOST_AUTO_TEST_CASE(test_next_fn) {
234+
update();
235+
236+
std::unique_ptr<Animal> snoopy = std::make_unique<Dog>();
237+
BOOST_TEST(kick::fn(*snoopy) == "bark");
238+
239+
std::unique_ptr<Animal> hector = std::make_unique<Bulldog>();
240+
BOOST_TEST(kick::fn(*hector) == "bark and bite back");
241+
}
242+
243+
} // namespace test_next_fn
244+
206245
namespace errors {
207246

208247
struct matrix {

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)