Skip to content

Commit

Permalink
rework next
Browse files Browse the repository at this point in the history
  • Loading branch information
jll63 committed Sep 28, 2024
1 parent 1ecf3aa commit e1356c4
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 78 deletions.
37 changes: 25 additions & 12 deletions docs.in/reference/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ make sense, see the example below.
#include <memory>
#include <string>

struct Animal { virtual ~Animal() {} };
struct Animal {
virtual ~Animal() {
}
};
struct Cat : Animal {};
struct Dog : Animal {};
struct Bulldog : Dog {};
Expand All @@ -194,33 +197,43 @@ YOMM2_REGISTER(yomm2::use_classes<Animal, Cat, Dog, Bulldog>);
struct kick_methods;
using kick = yomm2::method<kick_methods(virtual_<Animal&>), std::string>;

std::string kick_cat(Cat& dog) { return "hiss"; }
std::string kick_cat(Cat& dog) {
return "hiss";
}
YOMM2_REGISTER(kick::override_fn<kick_cat>);

std::string kick_dog(Dog& dog) { return "bark"; }
std::string kick_dog(Dog& dog) {
return "bark";
}
YOMM2_REGISTER(kick::override_fn<kick_dog>);

struct kick_bulldog : kick::with_next<kick_bulldog> {
static std::string fn(Bulldog& dog) { return next(dog) + " and bite"; }
struct kick_bulldog {
static std::string fn(Bulldog& dog) {
return kick::next<fn>(dog) + " and bite";
}
};
YOMM2_REGISTER(kick::override<kick_bulldog>);

struct YOMM2_METHOD_NAME(pet); // use obfuscated name
using pet = yomm2::method<YOMM2_METHOD_NAME(pet)(virtual_<Animal&>), std::string>;
using pet =
yomm2::method<YOMM2_METHOD_NAME(pet)(virtual_<Animal&>), std::string>;

std::string pet_cat(Cat& dog) { return "purr"; }
std::string pet_cat(Cat& dog) {
return "purr";
}
YOMM2_REGISTER(pet::override_fn<pet_cat>);

std::string pet_dog(Dog& dog) { return "wag tail"; }
std::string pet_dog(Dog& dog) {
return "wag tail";
}
YOMM2_REGISTER(pet::override_fn<pet_dog>);

BOOST_AUTO_TEST_CASE(ref_method_example) {
yomm2::initialize();

std::unique_ptr<Animal>
felix = std::make_unique<Cat>(),
snoopy = std::make_unique<Dog>(),
hector = std::make_unique<Bulldog>();
std::unique_ptr<Animal> felix = std::make_unique<Cat>(),
snoopy = std::make_unique<Dog>(),
hector = std::make_unique<Bulldog>();

BOOST_TEST(kick::fn(*felix) == "hiss");
BOOST_TEST(kick::fn(*snoopy) == "bark");
Expand Down
10 changes: 4 additions & 6 deletions docs.in/tutorials/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,11 @@ kick::override_fn<kick_dog> add_kick_dog;
// >

// code<
kick::next_type kick_bulldog_next;

std::string kick_bulldog(Bulldog& dog) {
return kick_bulldog_next(dog) + " and bite back";
return kick::next<kick_bulldog>(dog) + " and bite back";
}

kick::override_fn<kick_bulldog> add_kick_bulldog(&kick_bulldog_next);
kick::override_fn<kick_bulldog> add_kick_bulldog;
// >

// md<
Expand Down Expand Up @@ -281,9 +279,9 @@ YOMM2_REGISTER(kick::override<kick_dog>);
// >

// code<
struct kick_bulldog : kick::with_next<kick_bulldog> {
struct kick_bulldog {
static std::string fn(Bulldog& dog) {
return next(dog) + " and bite back";
return kick::next<fn>(dog) + " and bite back";
}
};

Expand Down
40 changes: 2 additions & 38 deletions include/yorel/yomm2/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,6 @@ using spec_polymorphic_types = boost::mp11::mp_remove<
MethodParameters, OverriderParameters>,
void>;

template<class Container, typename = void>
struct has_next : std::false_type {};

template<class Container>
struct has_next<Container, std::void_t<decltype(Container::next)>>
: std::true_type {};

template<class Method>
struct static_offsets;

Expand Down Expand Up @@ -637,11 +630,6 @@ class method<Name(Parameters...), Return, Policy> : public detail::method_info {

auto operator()(detail::remove_virtual<Parameters>... args) const -> Return;

template<class Container>
struct with_next {
static next_type next;
};

template<auto>
static FunctionPointer next;

Expand Down Expand Up @@ -669,7 +657,6 @@ class method<Name(Parameters...), Return, Policy> : public detail::method_info {
template<auto Function, typename FnReturnType, typename... FnParameters>
struct override_fn_aux<Function, FnReturnType (*)(FnParameters...)>
: override_fn_impl<Function> {
using override_fn_impl<Function>::override_fn_impl;
};

template<
Expand All @@ -695,39 +682,16 @@ class method<Name(Parameters...), Return, Policy> : public detail::method_info {
std::tuple<override_fn<F>...> fns;
};

private:
template<class Container, bool HasNext>
struct override_aux;

template<class Container>
struct override_aux<Container, false> : override_fn<Container::fn> {
override_aux() : override_fn<Container::fn>(nullptr) {
}
};

template<class Container>
struct override_aux<Container, true> : override_fn<Container::fn> {
override_aux() : override_fn<Container::fn>(&Container::next) {
}
};

public:
template<class Container>
struct override
: override_aux<Container, detail::has_next<Container>::value> {
using type = override; // make it a meta-function
struct override : override_fn<Container::fn> {
using type = override;
};
};

template<typename Name, typename Return, typename... Parameters, class Policy>
method<Name(Parameters...), Return, Policy>
method<Name(Parameters...), Return, Policy>::fn;

template<typename Name, typename Return, typename... Parameters, class Policy>
template<class Container>
typename method<Name(Parameters...), Return, Policy>::next_type
method<Name(Parameters...), Return, Policy>::with_next<Container>::next;

template<typename Name, typename Return, typename... Parameters, class Policy>
template<auto>
typename method<Name(Parameters...), Return, Policy>::FunctionPointer
Expand Down
16 changes: 10 additions & 6 deletions include/yorel/yomm2/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,20 @@
template<> \
struct OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) ARGS> { \
YOREL_YOMM2_DETAIL_LOCATE_METHOD(NAME, ARGS); \
static method_type::next_type next; \
static auto fn ARGS->YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__); \
static auto has_next() { \
return method_type::next<fn> != nullptr; \
} \
template<typename... Args> \
static decltype(auto) next(Args&&... args) { \
BOOST_ASSERT(has_next()); \
return method_type::next<fn>(std::forward<Args>(args)...); \
} \
}; \
INLINE OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) \
ARGS>::method_type::next_type \
OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) ARGS>::next; \
INLINE YOMM2_REGISTER( \
OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) ARGS>:: \
method_type::override<OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE( \
__VA_ARGS__) ARGS>>); \
method_type::override_fn<OVERRIDERS< \
YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) ARGS>::fn>); \
INLINE auto \
OVERRIDERS<YOREL_YOMM2_DETAIL_RETURN_TYPE(__VA_ARGS__) ARGS>::fn ARGS \
->boost::mp11::mp_back<boost::mp11::mp_list<__VA_ARGS__>>
Expand Down
16 changes: 0 additions & 16 deletions tests/test_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,22 +217,6 @@ static_assert(

} // namespace test_use_classes

namespace test_has_next {

struct with_next {
static int next;
};

static_assert(has_next<with_next>::value);

struct sans_next {
static int next;
};

static_assert(has_next<sans_next>::value);

}

namespace facets {

using namespace policies;
Expand Down

0 comments on commit e1356c4

Please sign in to comment.