Commit 1b4c24c2 authored by neverlord's avatar neverlord

send via operator<<

parent 8f59898e
......@@ -135,7 +135,7 @@
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{07fcd197-092d-45a0-8500-3be614e6ae31}</value>
<value type="QString">{23902c37-f07e-47cd-bb19-c366b9f708db}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
......
......@@ -155,3 +155,4 @@ cppa/util/element_at.hpp
cppa/util/if_else.hpp
cppa/util/pop_back.hpp
cppa/util/pt_dispatch.hpp
cppa/detail/get_behavior.hpp
......@@ -30,9 +30,7 @@ class any_tuple
template<typename... Args>
any_tuple(const tuple_view<Args...>& t) : m_vals(t.vals()) { }
any_tuple(vals_ptr&& vals);
any_tuple(const vals_ptr& vals);
explicit any_tuple(detail::abstract_tuple*);
any_tuple(any_tuple&&);
......@@ -48,7 +46,7 @@ class any_tuple
const void* at(size_t p) const;
const uniform_type_info& type_info_at(size_t p) const;
const uniform_type_info& utype_info_at(size_t p) const;
const util::abstract_type_list& types() const;
......
......@@ -47,85 +47,10 @@
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/detail/get_behavior.hpp"
namespace cppa {
namespace detail {
template<bool IsFunctionPtr, typename F>
class fun_behavior : public actor_behavior
{
F m_fun;
public:
fun_behavior(F ptr) : m_fun(ptr) { }
virtual void act()
{
m_fun();
}
};
template<typename F>
class fun_behavior<false, F> : public actor_behavior
{
F m_fun;
public:
fun_behavior(const F& arg) : m_fun(arg) { }
fun_behavior(F&& arg) : m_fun(std::move(arg)) { }
virtual void act()
{
m_fun();
}
};
template<typename R>
actor_behavior* get_behavior(std::integral_constant<bool,true>, R (*fptr)())
{
return new fun_behavior<true, R (*)()>(fptr);
}
template<typename F>
actor_behavior* get_behavior(std::integral_constant<bool,false>, F&& ftor)
{
typedef typename util::rm_ref<F>::type ftype;
return new fun_behavior<false, ftype>(std::forward<F>(ftor));
}
template<typename F, typename Arg0, typename... Args>
actor_behavior* get_behavior(std::integral_constant<bool,true>,
F fptr,
const Arg0& arg0,
const Args&... args)
{
detail::tdata<Arg0, Args...> arg_tuple(arg0, args...);
auto lambda = [fptr, arg_tuple]() { invoke(fptr, arg_tuple); };
return new fun_behavior<false, decltype(lambda)>(std::move(lambda));
}
template<typename F, typename Arg0, typename... Args>
actor_behavior* get_behavior(std::integral_constant<bool,false>,
F ftor,
const Arg0& arg0,
const Args&... args)
{
detail::tdata<Arg0, Args...> arg_tuple(arg0, args...);
auto lambda = [ftor, arg_tuple]() { invoke(ftor, arg_tuple); };
return new fun_behavior<false, decltype(lambda)>(std::move(lambda));
}
} // namespace detail
template<scheduling_hint Hint, typename F, typename... Args>
actor_ptr spawn(F&& what, const Args&... args)
{
......@@ -141,36 +66,6 @@ actor_ptr spawn(F&& what, const Args&... args)
return spawn<scheduled>(std::forward<F>(what), args...);
}
/*
template<typename F>
actor_ptr spawn(scheduling_hint hint, const F& fun)
{
struct fun_behavior : actor_behavior
{
F m_fun;
fun_behavior(const F& fun_arg) : m_fun(fun_arg) { }
virtual void act()
{
m_fun();
}
};
return spawn(hint, new fun_behavior(fun));
}
template<typename F, typename Arg0, typename... Args>
actor_ptr spawn(scheduling_hint hint, const F& fun, const Arg0& arg0, const Args&... args)
{
auto arg_tuple = make_tuple(arg0, args...);
return spawn(hint, [=]() { invoke(fun, arg_tuple); });
}
template<typename F, typename... Args>
inline actor_ptr spawn(const F& fun, const Args&... args)
{
return spawn(scheduled, fun, args...);
}
*/
inline const message& receive()
{
return self()->mailbox().dequeue();
......@@ -201,12 +96,52 @@ inline const message& last_received()
return self()->mailbox().last_dequeued();
}
template<typename Arg0, typename... Args>
void send(channel_ptr whom, const Arg0& arg0, const Args&... args)
template<class C, typename Arg0, typename... Args>
typename util::enable_if<std::is_base_of<channel, C>, void>::type
send(intrusive_ptr<C>& whom, const Arg0& arg0, const Args&... args)
{
if (whom) whom->enqueue(message(self(), whom, arg0, args...));
}
template<class C, typename Arg0, typename... Args>
typename util::enable_if<std::is_base_of<channel, C>, void>::type
send(intrusive_ptr<C>&& whom, const Arg0& arg0, const Args&... args)
{
if (whom) whom->enqueue(message(self(), whom, arg0, args...));
}
template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type
operator<<(intrusive_ptr<C>& whom, const any_tuple& what)
{
if (whom) whom->enqueue(message(self(), whom, what));
return whom;
}
template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&&>::type
operator<<(intrusive_ptr<C>&& whom, const any_tuple& what)
{
if (whom) whom->enqueue(message(self(), whom, what));
return std::move(whom);
}
template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type
operator<<(intrusive_ptr<C>& whom, any_tuple&& what)
{
if (whom) whom->enqueue(message(self(), whom, std::move(what)));
return whom;
}
template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&&>::type
operator<<(intrusive_ptr<C>&& whom, any_tuple&& what)
{
if (whom) whom->enqueue(message(self(), whom, std::move(what)));
return std::move(whom);
}
template<typename Arg0, typename... Args>
void reply(const Arg0& arg0, const Args&... args)
{
......
#ifndef GET_BEHAVIOR_HPP
#define GET_BEHAVIOR_HPP
#include "cppa/invoke.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/actor_behavior.hpp"
namespace cppa { namespace detail {
// default: <true, false, F>
template<bool IsFunctionPtr, bool HasArguments, typename F, typename... Args>
class ftor_behavior : public actor_behavior
{
F m_fun;
public:
ftor_behavior(F ptr) : m_fun(ptr) { }
virtual void act() { m_fun(); }
};
template<typename F, typename... Args>
class ftor_behavior<true, true, F, Args...> : public actor_behavior
{
static_assert(sizeof...(Args) > 0, "sizeof...(Args) == 0");
F m_fun;
tdata<Args...> m_args;
public:
ftor_behavior(F ptr, const Args&... args) : m_fun(ptr), m_args(args...) { }
virtual void act() { invoke(m_fun, m_args); }
};
template<typename F>
class ftor_behavior<false, false, F> : public actor_behavior
{
F m_fun;
public:
ftor_behavior(const F& arg) : m_fun(arg) { }
ftor_behavior(F&& arg) : m_fun(std::move(arg)) { }
virtual void act() { m_fun(); }
};
template<typename F, typename... Args>
class ftor_behavior<false, true, F, Args...> : public actor_behavior
{
static_assert(sizeof...(Args) > 0, "sizeof...(Args) == 0");
F m_fun;
tdata<Args...> m_args;
public:
ftor_behavior(const F& f, const Args&... args) : m_fun(f), m_args(args...)
{
}
ftor_behavior(F&& f,const Args&... args) : m_fun(std::move(f))
, m_args(args...)
{
}
virtual void act() { invoke(m_fun, m_args); }
};
template<typename R>
actor_behavior* get_behavior(std::integral_constant<bool,true>, R (*fptr)())
{
return new ftor_behavior<true, false, R (*)()>(fptr);
}
template<typename F>
actor_behavior* get_behavior(std::integral_constant<bool,false>, F&& ftor)
{
typedef typename util::rm_ref<F>::type ftype;
return new ftor_behavior<false, false, ftype>(std::forward<F>(ftor));
}
template<typename F, typename Arg0, typename... Args>
actor_behavior* get_behavior(std::integral_constant<bool,true>,
F fptr,
const Arg0& arg0,
const Args&... args)
{
typedef ftor_behavior<true, true, F, Arg0, Args...> impl;
return new impl(fptr, arg0, args...);
}
template<typename F, typename Arg0, typename... Args>
actor_behavior* get_behavior(std::integral_constant<bool,false>,
F ftor,
const Arg0& arg0,
const Args&... args)
{
typedef typename util::rm_ref<F>::type ftype;
typedef ftor_behavior<false, true, ftype, Arg0, Args...> impl;
return new impl(std::forward<F>(ftor), arg0, args...);
}
} } // namespace cppa::detail
#endif // GET_BEHAVIOR_HPP
......@@ -21,7 +21,8 @@ template<size_t N, typename F, class Tuple,
typename ArgTypeList, typename... Args>
struct invoke_helper
{
typedef typename util::reverse_type_list<ArgTypeList>::type::head_type back_type;
typedef typename util::reverse_type_list<ArgTypeList>::type rlist;
typedef typename rlist::head_type back_type;
typedef typename util::element_at<N, Tuple>::type tuple_val_type;
typedef typename util::pop_back<ArgTypeList>::type next_list;
inline static void _(F& f, const Tuple& t, const Args&... args)
......@@ -42,7 +43,7 @@ struct invoke_helper<N, F, Tuple, util::type_list<>, Args...>
}
};
template<bool HasCallableTrati, typename F, class Tuple>
template<bool HasCallableTrait, typename F, class Tuple>
struct invoke_impl;
template<typename F, template<typename...> class Tuple, typename... TTypes>
......@@ -88,7 +89,8 @@ template<typename F, class Tuple>
void invoke(F what, const Tuple& args)
{
typedef typename std::remove_pointer<F>::type f_type;
detail::invoke_impl<std::is_function<f_type>::value, F, Tuple>::_(what, args);
static constexpr bool is_fun = std::is_function<f_type>::value;
detail::invoke_impl<is_fun, F, Tuple>::_(what, args);
}
} // namespace cppa
......
......@@ -5,6 +5,7 @@
#include "cppa/tuple.hpp"
#include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp"
......@@ -26,6 +27,12 @@ class message
: ref_counted(), sender(s), receiver(r), data(ut)
{
}
inline msg_content(const actor_ptr& s,
const channel_ptr& r,
any_tuple&& ut)
: ref_counted(), sender(s), receiver(r), data(std::move(ut))
{
}
};
intrusive_ptr<msg_content> m_content;
......@@ -39,6 +46,10 @@ class message
const channel_ptr& to,
const any_tuple& ut);
message(const actor_ptr& from,
const channel_ptr& to,
any_tuple&& ut);
message();
message& operator=(const message&) = default;
......@@ -68,7 +79,7 @@ class message
template<typename... Args>
message::message(const actor_ptr& from, const channel_ptr& to, const Args&... args)
: m_content(new msg_content(from, to, any_tuple(tuple<Args...>(args...))))
: m_content(new msg_content(from, to, tuple<Args...>(args...)))
{
}
......
......@@ -72,7 +72,11 @@ template<typename... ElementTypes>
class tuple
{
friend class any_tuple;
//friend class any_tuple;
template<size_t N, typename... Types>
friend typename util::at<N, Types...>::type& get_ref(tuple<Types...>&);
public:
......@@ -109,39 +113,42 @@ class tuple
public:
// enable use of tuple as type_list
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
tuple() : m_vals(new vals_t) { }
tuple(const ElementTypes&... args) : m_vals(new vals_t(args...)) { }
/*
template<size_t N>
const typename util::at<N, ElementTypes...>::type& get() const
tuple() : m_vals(new vals_t)
{
return get<N>(m_vals->data());
}
template<size_t N>
typename util::at<N, ElementTypes...>::type& get_ref()
tuple(const ElementTypes&... args) : m_vals(new vals_t(args...))
{
return get_ref<N>(m_vals->data_ref());
}
*/
size_t size() const { return m_vals->size(); }
const void* at(size_t p) const { return m_vals->at(p); }
size_t size() const
{
return m_vals->size();
}
const uniform_type_info* utype_at(size_t p) const { return m_vals->utype_info_at(p); }
const void* at(size_t p) const
{
return m_vals->at(p);
}
const util::abstract_type_list& types() const { return m_vals->types(); }
const uniform_type_info* utype_at(size_t p) const
{
return m_vals->utype_info_at(p);
}
const cow_ptr<vals_t>& vals() const { return m_vals; }
const util::abstract_type_list& types() const
{
return m_vals->types();
}
cow_ptr<vals_t>& vals_ref() { return m_vals; }
const cow_ptr<vals_t>& vals() const
{
return m_vals;
}
template<typename... Args>
bool equal_to(const tuple<Args...>& other) const
......@@ -158,16 +165,13 @@ const typename util::at<N, Types...>::type&
get(const tuple<Types...>& t)
{
return get<N>(t.vals()->data());
//return get<N>(m_vals->data());
//return t.get<N>();
}
template<size_t N, typename... Types>
typename util::at<N, Types...>::type&
get_ref(tuple<Types...>& t)
{
return get_ref<N>(t.vals_ref()->data_ref());
//return t.get_ref<N>();
return get_ref<N>(t.m_vals->data_ref());
}
template<typename TypeList>
......
......@@ -3,6 +3,7 @@
#include <vector>
#include "cppa/get.hpp"
#include "cppa/tuple.hpp"
#include "cppa/util/at.hpp"
......@@ -14,11 +15,6 @@
namespace cppa {
// forward declaration
class any_tuple;
// needed to implement constructor
const cow_ptr<detail::abstract_tuple>& vals_of(const any_tuple&);
/**
* @brief Describes a view of an fixed-length tuple.
*/
......@@ -26,10 +22,17 @@ template<typename... ElementTypes>
class tuple_view
{
template<size_t N, typename... Types>
friend typename util::at<N, Types...>::type& get_ref(tuple_view<Types...>&);
public:
typedef util::type_list<ElementTypes...> element_types;
// enable use of tuple_view as type_list
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static_assert(sizeof...(ElementTypes) > 0,
"could not declare an empty tuple_view");
......@@ -42,38 +45,21 @@ class tuple_view
tuple_view(const tuple_view&) = default;
tuple_view(tuple_view&& other) : m_vals(std::move(other.m_vals))
inline const vals_t& vals() const
{
return m_vals;
}
const vals_t& vals() const { return m_vals; }
vals_t& vals_ref() { return m_vals; }
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
const element_types& types() const { return m_types; }
template<size_t N>
const typename util::at<N, ElementTypes...>::type& get() const
inline const element_types& types() const
{
static_assert(N < sizeof...(ElementTypes), "N >= size()");
typedef typename util::at<N, ElementTypes...>::type result_t;
return *reinterpret_cast<const result_t*>(m_vals->at(N));
return m_types;
}
template<size_t N>
typename util::at<N, ElementTypes...>::type& get_ref()
inline size_t size() const
{
static_assert(N < sizeof...(ElementTypes), "N >= size()");
typedef typename util::at<N, ElementTypes...>::type result_t;
return *reinterpret_cast<result_t*>(m_vals->mutable_at(N));
return m_vals->size();
}
size_t size() const { return m_vals->size(); }
private:
vals_t m_vals;
......@@ -88,7 +74,6 @@ get(const tuple_view<Types...>& t)
static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::at<N, Types...>::type result_t;
return *reinterpret_cast<const result_t*>(t.vals()->at(N));
//return t.get<N>();
}
template<size_t N, typename... Types>
......@@ -97,8 +82,7 @@ get_ref(tuple_view<Types...>& t)
{
static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::at<N, Types...>::type result_t;
return *reinterpret_cast<result_t*>(t.vals_ref()->mutable_at(N));
//return t.get_ref<N>();
return *reinterpret_cast<result_t*>(t.m_vals->mutable_at(N));
}
template<typename TypeList>
......
......@@ -62,35 +62,34 @@ struct empty_tuple : cppa::detail::abstract_tuple
return other.size() == 0;
}
virtual void serialize(cppa::serializer&) const
{
}
};
const cppa::cow_ptr<cppa::detail::abstract_tuple>& s_empty_tuple()
{
static cppa::cow_ptr<cppa::detail::abstract_tuple> ptr(new empty_tuple);
return ptr;
}
} // namespace <anonymous>
namespace cppa {
any_tuple::any_tuple() : m_vals(new empty_tuple)
{
}
any_tuple::any_tuple(const vals_ptr& vals) : m_vals(vals)
any_tuple::any_tuple() : m_vals(s_empty_tuple())
{
}
any_tuple::any_tuple(vals_ptr&& vals) : m_vals(std::move(vals))
any_tuple::any_tuple(detail::abstract_tuple* ptr) : m_vals(ptr)
{
}
any_tuple::any_tuple(any_tuple&& other) : m_vals(std::move(other.m_vals))
any_tuple::any_tuple(any_tuple&& other) : m_vals(s_empty_tuple())
{
m_vals.swap(other.m_vals);
}
any_tuple& any_tuple::operator=(any_tuple&& other)
{
m_vals = std::move(other.m_vals);
m_vals.swap(other.m_vals);
return *this;
}
......@@ -109,7 +108,7 @@ const void* any_tuple::at(size_t p) const
return m_vals->at(p);
}
const uniform_type_info& any_tuple::type_info_at(size_t p) const
const uniform_type_info& any_tuple::utype_info_at(size_t p) const
{
return m_vals->utype_info_at(p);
}
......
......@@ -9,6 +9,13 @@ message::message(const actor_ptr& from,
{
}
message::message(const actor_ptr& from,
const channel_ptr& to,
any_tuple&& ut)
: m_content(new msg_content(from, to, std::move(ut)))
{
}
message::message() : m_content(new msg_content(0, 0, tuple<int>(0)))
{
}
......
......@@ -360,7 +360,7 @@ class any_tuple_tinfo : public util::abstract_uniform_type_info<any_tuple>
sink->begin_sequence(atup.size());
for (size_t i = 0; i < atup.size(); ++i)
{
atup.type_info_at(i).serialize(atup.at(i), sink);
atup.utype_info_at(i).serialize(atup.at(i), sink);
}
sink->end_sequence();
sink->end_object();
......
......@@ -28,16 +28,31 @@ void worker()
});
}
struct baz_t
{
template<typename... Args>
baz_t& operator<<(const cppa::tuple<Args...>& tup)
{
cout << "baz { " << get<0>(tup) << ", ... }" << endl;
return *this;
}
}
baz;
size_t test__local_group()
{
CPPA_TEST(test__local_group);
baz << make_tuple(1, 2, 3);
auto foo_group = group::get("local", "foo");
for (int i = 0; i < 5; ++i)
{
// spawn workers and let them join local/foo
spawn(worker)->join(foo_group);
}
send(foo_group, 2);
foo_group << make_tuple(2);
//send(foo_group, 2);
int result = 0;
for (int i = 0; i < 5; ++i)
{
......
......@@ -29,10 +29,10 @@ size_t test__spawn()
CPPA_TEST(test__spawn);
actor_ptr self_ptr = self();
{
auto sl = spawn(pong);
spawn(echo, self_ptr, 1);
send(sl, 23.f);
send(sl, 2);
spawn(pong) << make_tuple(23.f) << make_tuple(2);
//send(sl, 23.f);
//send(sl, 2);
bool received_pong = false;
bool received_echo = false;
auto rules = (on<int>(42) >> [&]() { received_pong = true; },
......
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