Commit 8a702203 authored by Neverlord's avatar Neverlord

GCC 4.7 compatibility / workarounds

parent 715e1999
...@@ -272,11 +272,13 @@ class proper_actor<Base, Policies,true> : public proper_actor_base<Base, ...@@ -272,11 +272,13 @@ class proper_actor<Base, Policies,true> : public proper_actor_base<Base,
has_timeout = true; has_timeout = true;
timeout_id = this->request_timeout(bhvr.timeout()); timeout_id = this->request_timeout(bhvr.timeout());
} }
// workaround for GCC 4.7 bug (const this when capturing refs)
auto& pending_timeouts = m_pending_timeouts;
auto guard = util::make_scope_guard([&] { auto guard = util::make_scope_guard([&] {
if (has_timeout) { if (has_timeout) {
auto e = m_pending_timeouts.end(); auto e = pending_timeouts.end();
auto i = std::find(m_pending_timeouts.begin(), e, timeout_id); auto i = std::find(pending_timeouts.begin(), e, timeout_id);
if (i != e) m_pending_timeouts.erase(i); if (i != e) pending_timeouts.erase(i);
} }
}); });
// read incoming messages // read incoming messages
......
...@@ -231,30 +231,24 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> { ...@@ -231,30 +231,24 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> {
typedef std::function<behavior_type (pointer)> one_arg_fun1; typedef std::function<behavior_type (pointer)> one_arg_fun1;
typedef std::function<void (pointer)> one_arg_fun2; typedef std::function<void (pointer)> one_arg_fun2;
functor_based_typed_actor(one_arg_fun1 fun) { template<typename F, typename... Ts>
set(std::move(fun)); functor_based_typed_actor(F fun, Ts&&... args) {
} typedef typename util::get_callable_trait<F>::type trait;
typedef typename trait::arg_types arg_types;
functor_based_typed_actor(one_arg_fun2 fun) { typedef typename trait::result_type result_type;
set(std::move(fun)); constexpr bool returns_behavior = std::is_same<
} result_type,
behavior_type
functor_based_typed_actor(no_arg_fun fun) { >::value;
set(std::move(fun));
}
template<typename F, typename T, typename... Ts>
functor_based_typed_actor(F fun, T&& arg, Ts&&... args) {
typedef typename util::get_callable_trait<F>::arg_types arg_types;
constexpr bool uses_first_arg = std::is_same< constexpr bool uses_first_arg = std::is_same<
typename util::tl_head< typename util::tl_head<
arg_types arg_types
>::type, >::type,
pointer pointer
>::value; >::value;
std::integral_constant<bool, uses_first_arg> token; std::integral_constant<bool, returns_behavior> token1;
bind_and_set(token, std::move(fun), std::integral_constant<bool, uses_first_arg> token2;
std::forward<T>(arg), std::forward<Ts>(args)...); set(token1, token2, std::move(fun), std::forward<Ts>(args)...);
} }
protected: protected:
...@@ -265,29 +259,40 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> { ...@@ -265,29 +259,40 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> {
private: private:
void set(one_arg_fun1 fun) { template<typename F>
m_fun = std::move(fun); void set(std::true_type, std::true_type, F&& fun) {
// behavior_type (pointer)
m_fun = std::forward<F>(fun);
} }
void set(one_arg_fun2 fun) { template<typename F>
void set(std::false_type, std::true_type, F fun) {
// void (pointer)
m_fun = [fun](pointer ptr) { m_fun = [fun](pointer ptr) {
fun(ptr); fun(ptr);
return behavior_type{}; return behavior_type{};
}; };
} }
void set(no_arg_fun fun) { template<typename F>
void set(std::true_type, std::false_type, F fun) {
// behavior_type ()
m_fun = [fun](pointer) { return fun(); }; m_fun = [fun](pointer) { return fun(); };
} }
template<typename F, typename... Ts> // (false_type, false_type) is an invalid functor for typed actors
void bind_and_set(std::true_type, F fun, Ts&&... args) {
set(std::bind(fun, std::placeholders::_1, std::forward<Ts>(args)...)); template<class Token, typename F, typename T0, typename... Ts>
void set(Token t1, std::true_type t2, F fun, T0&& arg0, Ts&&... args) {
set(t1, t2, std::bind(fun, std::placeholders::_1,
std::forward<T0>(arg0),
std::forward<Ts>(args)...));
} }
template<typename F, typename... Ts> template<class Token, typename F, typename T0, typename... Ts>
void bind_and_set(std::false_type, F fun, Ts&&... args) { void set(Token t1, std::false_type t2, F fun, T0&& arg0, Ts&&... args) {
set(std::bind(fun, std::forward<Ts>(args)...)); set(t1, t2, std::bind(fun, std::forward<T0>(arg0),
std::forward<Ts>(args)...));
} }
one_arg_fun1 m_fun; one_arg_fun1 m_fun;
......
...@@ -274,11 +274,15 @@ behavior echo_actor(event_based_actor* self) { ...@@ -274,11 +274,15 @@ behavior echo_actor(event_based_actor* self) {
struct simple_mirror : sb_actor<simple_mirror> { struct simple_mirror : sb_actor<simple_mirror> {
behavior init_state = ( behavior init_state;
others() >> [=] {
return last_dequeued(); simple_mirror() {
} init_state = (
); others() >> [=]() -> any_tuple {
return last_dequeued();
}
);
}
}; };
......
...@@ -6,9 +6,13 @@ using namespace cppa; ...@@ -6,9 +6,13 @@ using namespace cppa;
using namespace cppa::placeholders; using namespace cppa::placeholders;
struct sync_mirror : sb_actor<sync_mirror> { struct sync_mirror : sb_actor<sync_mirror> {
behavior init_state = ( behavior init_state;
others() >> [=] { return last_dequeued(); }
); sync_mirror() {
init_state = (
others() >> [=] { return last_dequeued(); }
);
}
}; };
// replies to 'f' with 0.0f and to 'i' with 0 // replies to 'f' with 0.0f and to 'i' with 0
...@@ -75,13 +79,16 @@ struct B : popular_actor { ...@@ -75,13 +79,16 @@ struct B : popular_actor {
}; };
struct C : sb_actor<C> { struct C : sb_actor<C> {
behavior init_state = ( behavior init_state;
on(atom("gogo")) >> [=]() -> atom_value { C() {
CPPA_CHECKPOINT(); init_state = (
quit(); on(atom("gogo")) >> [=]() -> atom_value {
return atom("gogogo"); CPPA_CHECKPOINT();
} quit();
); return atom("gogogo");
}
);
}
}; };
......
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