Commit f99c9526 authored by Dominik Charousset's avatar Dominik Charousset

Simplify implementation of composable behaviors

parent 22b1bc45
...@@ -31,7 +31,7 @@ class abstract_composable_behavior { ...@@ -31,7 +31,7 @@ class abstract_composable_behavior {
public: public:
virtual ~abstract_composable_behavior(); virtual ~abstract_composable_behavior();
virtual void init_behavior(behavior& x) = 0; virtual unit_t init_behavior(message_handler& x) = 0;
}; };
} // namespace caf } // namespace caf
......
...@@ -33,54 +33,30 @@ namespace caf { ...@@ -33,54 +33,30 @@ namespace caf {
/// of the apply operator is derived from the typed message passing interface /// of the apply operator is derived from the typed message passing interface
/// `MPI`. /// `MPI`.
template <class MPI> template <class MPI>
class abstract_composable_behavior_mixin; class composable_behavior_base;
template <class... Xs, class... Ys> template <class... Xs, class... Ys>
class abstract_composable_behavior_mixin<typed_mpi<detail::type_list<Xs...>, class composable_behavior_base<typed_mpi<detail::type_list<Xs...>,
detail::type_list<Ys...>>> { detail::type_list<Ys...>>> {
public: public:
virtual ~abstract_composable_behavior_mixin() noexcept { virtual ~composable_behavior_base() noexcept {
// nop // nop
} }
virtual result<Ys...> operator()(param_t<Xs>...) = 0; virtual result<Ys...> operator()(param_t<Xs>...) = 0;
};
// this class works around compiler issues on GCC
template <class... Ts>
struct abstract_composable_behavior_mixin_helper;
template <class T, class... Ts>
struct abstract_composable_behavior_mixin_helper<T, Ts...>
: public abstract_composable_behavior_mixin<T>,
public abstract_composable_behavior_mixin_helper<Ts...> {
using abstract_composable_behavior_mixin<T>::operator();
using abstract_composable_behavior_mixin_helper<Ts...>::operator();
};
template <class T> // C++14 and later
struct abstract_composable_behavior_mixin_helper<T> # if __cplusplus > 201103L
: public abstract_composable_behavior_mixin<T> { auto make_callback() {
using abstract_composable_behavior_mixin<T>::operator(); return [=](param_t<Xs>... xs) { return (*this)(std::move(xs)...); };
};
template <class T, class... Fs>
void init_behavior_impl(T*, detail::type_list<>, behavior& storage, Fs... fs) {
storage.assign(std::move(fs)...);
}
template <class T, class... Xs, class... Ys, class... Ts, class... Fs>
void init_behavior_impl(T* thisptr,
detail::type_list<typed_mpi<detail::type_list<Xs...>,
detail::type_list<Ys...>>,
Ts...>,
behavior& storage, Fs... fs) {
auto f = [=](param_t<Xs>... xs) {
return (*thisptr)(std::move(xs)...);
}; };
detail::type_list<Ts...> token; # else
init_behavior_impl(thisptr, token, storage, fs..., f); // C++11
} std::function<result<Ys...> (param_t<Xs>...)> make_callback() {
return [=](param_t<Xs>... xs) { return (*this)(std::move(xs)...); };
};
# endif
};
/// Base type for composable actor states. /// Base type for composable actor states.
template <class TypedActor> template <class TypedActor>
...@@ -89,7 +65,7 @@ class composable_behavior; ...@@ -89,7 +65,7 @@ class composable_behavior;
template <class... Clauses> template <class... Clauses>
class composable_behavior<typed_actor<Clauses...>> class composable_behavior<typed_actor<Clauses...>>
: virtual public abstract_composable_behavior, : virtual public abstract_composable_behavior,
public abstract_composable_behavior_mixin_helper<Clauses...> { public composable_behavior_base<Clauses>... {
public: public:
using signatures = detail::type_list<Clauses...>; using signatures = detail::type_list<Clauses...>;
...@@ -108,13 +84,17 @@ public: ...@@ -108,13 +84,17 @@ public:
} }
template <class SelfPointer> template <class SelfPointer>
void init_selfptr(SelfPointer selfptr) { unit_t init_selfptr(SelfPointer selfptr) {
self = selfptr; self = selfptr;
return unit;
} }
void init_behavior(behavior& x) override { unit_t init_behavior(message_handler& x) override {
signatures token; if (x)
init_behavior_impl(this, token, x); x = x.or_else(composable_behavior_base<Clauses>::make_callback()...);
else
x.assign(composable_behavior_base<Clauses>::make_callback()...);
return unit;
} }
typed_actor_pointer<Clauses...> self; typed_actor_pointer<Clauses...> self;
......
...@@ -42,7 +42,7 @@ class composable_behavior_based_actor : public stateful_actor<State, Base> { ...@@ -42,7 +42,7 @@ class composable_behavior_based_actor : public stateful_actor<State, Base> {
behavior_type make_behavior() override { behavior_type make_behavior() override {
this->state.init_selfptr(this); this->state.init_selfptr(this);
behavior tmp; message_handler tmp;
this->state.init_behavior(tmp); this->state.init_behavior(tmp);
return behavior_type{typename behavior_type::unsafe_init{}, std::move(tmp)}; return behavior_type{typename behavior_type::unsafe_init{}, std::move(tmp)};
} }
......
...@@ -26,67 +26,8 @@ ...@@ -26,67 +26,8 @@
namespace caf { namespace caf {
template <class InterfaceIntersection, class... States>
class composed_behavior_base;
template <class T>
class composed_behavior_base<detail::type_list<>, T> : public T {
public:
using T::operator();
// make this pure again, since the compiler can otherwise
// runs into a "multiple final overriders" error
virtual void init_behavior(behavior& x) override = 0;
};
template <class A, class B, class... Ts>
class composed_behavior_base<detail::type_list<>, A, B, Ts...>
: public A,
public composed_behavior_base<detail::type_list<>, B, Ts...> {
public:
using super = composed_behavior_base<detail::type_list<>, B, Ts...>;
using A::operator();
using super::operator();
template <class SelfPtr>
void init_selfptr(SelfPtr ptr) {
A::init_selfptr(ptr);
super::init_selfptr(ptr);
}
// make this pure again, since the compiler can otherwise
// runs into a "multiple final overriders" error
virtual void init_behavior(behavior& x) override = 0;
};
template <class... Xs, class... Ys, class... Ts, class... States>
class composed_behavior_base<detail::type_list<typed_mpi<detail::type_list<Xs...>,
detail::type_list<Ys...>>,
Ts...>,
States...>
: public composed_behavior_base<detail::type_list<Ts...>, States...> {
public:
using super = composed_behavior_base<detail::type_list<Ts...>, States...>;
using super::operator();
virtual result<Ys...> operator()(param_t<Xs>...) override = 0;
};
template <class... Ts> template <class... Ts>
class composed_behavior class composed_behavior : public Ts... {
: public composed_behavior_base<typename detail::tl_intersect<
typename Ts::signatures...
>::type,
Ts...> {
private:
using super =
composed_behavior_base<typename detail::tl_intersect<
typename Ts::signatures...
>::type,
Ts...>;
public: public:
using signatures = using signatures =
typename detail::tl_union<typename Ts::signatures...>::type; typename detail::tl_union<typename Ts::signatures...>::type;
...@@ -99,8 +40,6 @@ public: ...@@ -99,8 +40,6 @@ public:
using behavior_type = typename handle_type::behavior_type; using behavior_type = typename handle_type::behavior_type;
using combined_type = composed_behavior;
using actor_base = typename handle_type::base; using actor_base = typename handle_type::base;
using self_pointer = using self_pointer =
...@@ -113,17 +52,13 @@ public: ...@@ -113,17 +52,13 @@ public:
// nop // nop
} }
template <class SelfPtr> template <class SelfPointer>
void init_selfptr(SelfPtr ptr) { unit_t init_selfptr(SelfPointer x) {
self = ptr; return unit(Ts::init_selfptr(x)...);
super::init_selfptr(ptr);
} }
using super::operator(); unit_t init_behavior(message_handler& x) override {
return unit(Ts::init_behavior(x)...);
void init_behavior(behavior& x) override {
signatures token;
init_behavior_impl(this, token, x);
} }
protected: protected:
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define CAF_TYPED_BEHAVIOR_HPP #define CAF_TYPED_BEHAVIOR_HPP
#include "caf/behavior.hpp" #include "caf/behavior.hpp"
#include "caf/message_handler.hpp"
#include "caf/system_messages.hpp" #include "caf/system_messages.hpp"
#include "caf/typed_continue_helper.hpp" #include "caf/typed_continue_helper.hpp"
...@@ -169,7 +170,11 @@ public: ...@@ -169,7 +170,11 @@ public:
struct unsafe_init { }; struct unsafe_init { };
typed_behavior(unsafe_init, behavior bhvr) : bhvr_(std::move(bhvr)) { typed_behavior(unsafe_init, behavior x) : bhvr_(std::move(x)) {
// nop
}
typed_behavior(unsafe_init, message_handler x) : bhvr_(std::move(x)) {
// nop // nop
} }
......
...@@ -30,22 +30,27 @@ namespace caf { ...@@ -30,22 +30,27 @@ namespace caf {
/// to enable higher-order abstraction without cluttering code with /// to enable higher-order abstraction without cluttering code with
/// exceptions for `void` (which can't be stored, for example). /// exceptions for `void` (which can't be stored, for example).
struct unit_t : detail::comparable<unit_t> { struct unit_t : detail::comparable<unit_t> {
constexpr unit_t() { constexpr unit_t() noexcept {
// nop // nop
} }
constexpr unit_t(const unit_t&) { constexpr unit_t(const unit_t&) noexcept {
// nop // nop
} }
template <class T> template <class T>
explicit constexpr unit_t(T&&) { explicit constexpr unit_t(T&&) noexcept {
// nop // nop
} }
static constexpr int compare(const unit_t&) { static constexpr int compare(const unit_t&) noexcept {
return 0; return 0;
} }
template <class... Ts>
constexpr unit_t operator()(Ts&&...) const noexcept {
return {};
}
}; };
static constexpr unit_t unit = unit_t{}; static constexpr unit_t unit = unit_t{};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment