Commit b07c74d8 authored by neverlord's avatar neverlord

to_string, from_string, uniform name improvements, type_list stuff, etc

parent 4c840dac
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable> <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>
<data> <data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
......
...@@ -94,7 +94,6 @@ queue_performances/blocking_cached_stack2.hpp ...@@ -94,7 +94,6 @@ queue_performances/blocking_cached_stack2.hpp
queue_performances/blocking_sutter_list.hpp queue_performances/blocking_sutter_list.hpp
queue_performances/lockfree_list.hpp queue_performances/lockfree_list.hpp
queue_performances/intrusive_sutter_list.hpp queue_performances/intrusive_sutter_list.hpp
cppa/detail/cpp0x_thread_wrapper.hpp
src/context.cpp src/context.cpp
cppa/scheduler.hpp cppa/scheduler.hpp
cppa/detail/mock_scheduler.hpp cppa/detail/mock_scheduler.hpp
...@@ -151,3 +150,6 @@ cppa/util/abstract_uniform_type_info.hpp ...@@ -151,3 +150,6 @@ cppa/util/abstract_uniform_type_info.hpp
cppa/util/upgrade_lock_guard.hpp cppa/util/upgrade_lock_guard.hpp
cppa/exit_signal.hpp cppa/exit_signal.hpp
src/exit_signal.cpp src/exit_signal.cpp
cppa/to_string.hpp
src/string_serialization.cpp
cppa/from_string.hpp
...@@ -29,21 +29,119 @@ ...@@ -29,21 +29,119 @@
#ifndef CPPA_HPP #ifndef CPPA_HPP
#define CPPA_HPP #define CPPA_HPP
#include <tuple>
#include <type_traits>
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/invoke.hpp" #include "cppa/invoke.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/context.hpp" #include "cppa/context.hpp"
#include "cppa/message.hpp" #include "cppa/message.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/actor_behavior.hpp" #include "cppa/actor_behavior.hpp"
#include "cppa/scheduling_hint.hpp" #include "cppa/scheduling_hint.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
namespace cppa { 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)
{
auto arg_tuple = std::make_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)
{
auto arg_tuple = std::make_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)
{
typedef typename util::rm_ref<F>::type ftype;
std::integral_constant<bool, std::is_function<ftype>::value> is_fun;
auto ptr = detail::get_behavior(is_fun, std::forward<F>(what), args...);
return get_scheduler()->spawn(ptr, Hint);
}
template<typename F, typename... Args>
actor_ptr spawn(F&& what, const Args&... args)
{
return spawn<scheduled>(std::forward<F>(what), args...);
}
/*
template<typename F> template<typename F>
actor_ptr spawn(scheduling_hint hint, F fun) actor_ptr spawn(scheduling_hint hint, const F& fun)
{ {
struct fun_behavior : actor_behavior struct fun_behavior : actor_behavior
{ {
...@@ -54,31 +152,22 @@ actor_ptr spawn(scheduling_hint hint, F fun) ...@@ -54,31 +152,22 @@ actor_ptr spawn(scheduling_hint hint, F fun)
m_fun(); m_fun();
} }
}; };
return get_scheduler()->spawn(new fun_behavior(fun), hint); return spawn(hint, new fun_behavior(fun));
} }
template<typename F, typename Arg0, typename... Args> template<typename F, typename Arg0, typename... Args>
actor_ptr spawn(scheduling_hint hint, F fun, const Arg0& arg0, const Args&... args) actor_ptr spawn(scheduling_hint hint, const F& fun, const Arg0& arg0, const Args&... args)
{ {
auto arg_tuple = make_tuple(arg0, args...); auto arg_tuple = make_tuple(arg0, args...);
return spawn(hint, [=]() { invoke(fun, arg_tuple); }); return spawn(hint, [=]() { invoke(fun, arg_tuple); });
} }
template<typename F, typename... Args> template<typename F, typename... Args>
inline actor_ptr spawn(F fun, const Args&... args) inline actor_ptr spawn(const F& fun, const Args&... args)
{ {
return spawn(scheduled, fun, args...); return spawn(scheduled, fun, args...);
} }
*/
inline actor_ptr spawn(scheduling_hint hint, actor_behavior* ab)
{
return get_scheduler()->spawn(ab, hint);
}
inline actor_ptr spawn(actor_behavior* ab)
{
return get_scheduler()->spawn(ab, scheduled);
}
inline const message& receive() inline const message& receive()
{ {
...@@ -124,6 +213,12 @@ void reply(const Arg0& arg0, const Args&... args) ...@@ -124,6 +213,12 @@ void reply(const Arg0& arg0, const Args&... args)
if (whom) whom->enqueue(message(sptr, whom, arg0, args...)); if (whom) whom->enqueue(message(sptr, whom, arg0, args...));
} }
/**
* @brief Blocks execution of this actor until all
* other actors finished execution.
* @warning This function will cause a deadlock if
* called from multiple actors.
*/
inline void await_all_others_done() inline void await_all_others_done()
{ {
get_scheduler()->await_others_done(); get_scheduler()->await_others_done();
......
#ifndef CPPA_DETAIL_CPP0X_THREAD_WRAPPER_HPP
#define CPPA_DETAIL_CPP0X_THREAD_WRAPPER_HPP
// This header imports C++0x compatible parts of the boost threading library
// to the std namespace. It's a workaround to the missing stl threading
// library on GCC 4.6 under Mac OS X
#include <boost/thread.hpp>
namespace std {
using boost::mutex;
using boost::recursive_mutex;
using boost::timed_mutex;
using boost::recursive_timed_mutex;
using boost::adopt_lock;
using boost::defer_lock;
using boost::try_to_lock;
using boost::lock_guard;
using boost::unique_lock;
} // namespace std
#endif // CPPA_DETAIL_CPP0X_THREAD_WRAPPER_HPP
...@@ -14,14 +14,6 @@ template<> ...@@ -14,14 +14,6 @@ template<>
struct tdata<> struct tdata<>
{ {
typedef util::type_list<> element_types;
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const size_t type_list_size = element_types::type_list_size;
util::void_type head; util::void_type head;
tdata<>& tail() tdata<>& tail()
...@@ -47,14 +39,6 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -47,14 +39,6 @@ struct tdata<Head, Tail...> : tdata<Tail...>
typedef tdata<Tail...> super; typedef tdata<Tail...> super;
typedef util::type_list<Head, Tail...> element_types;
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const size_t type_list_size = element_types::type_list_size;
Head head; Head head;
inline tdata() : super(), head() { } inline tdata() : super(), head() { }
...@@ -99,8 +83,7 @@ template<size_t N, typename... ElementTypes> ...@@ -99,8 +83,7 @@ template<size_t N, typename... ElementTypes>
const typename util::type_at<N, util::type_list<ElementTypes...>>::type& const typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get(const tdata<ElementTypes...>& tv) tdata_get(const tdata<ElementTypes...>& tv)
{ {
static_assert(N < util::type_list<ElementTypes...>::type_list_size, static_assert(N < sizeof...(ElementTypes), "N >= tv.size()");
"N < tv.size()");
return static_cast<const typename tdata_upcast_helper<N, ElementTypes...>::type&>(tv).head; return static_cast<const typename tdata_upcast_helper<N, ElementTypes...>::type&>(tv).head;
} }
...@@ -108,8 +91,7 @@ template<size_t N, typename... ElementTypes> ...@@ -108,8 +91,7 @@ template<size_t N, typename... ElementTypes>
typename util::type_at<N, util::type_list<ElementTypes...>>::type& typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get_ref(tdata<ElementTypes...>& tv) tdata_get_ref(tdata<ElementTypes...>& tv)
{ {
static_assert(N < util::type_list<ElementTypes...>::type_list_size, static_assert(N < sizeof...(ElementTypes), "N >= tv.size()");
"N >= tv.size()");
return static_cast<typename tdata_upcast_helper<N, ElementTypes...>::type &>(tv).head; return static_cast<typename tdata_upcast_helper<N, ElementTypes...>::type &>(tv).head;
} }
......
...@@ -39,12 +39,6 @@ class tuple_vals : public abstract_tuple ...@@ -39,12 +39,6 @@ class tuple_vals : public abstract_tuple
public: public:
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const size_t type_list_size = element_types::type_list_size;
tuple_vals(const tuple_vals& other) : super(), m_data(other.m_data) { } tuple_vals(const tuple_vals& other) : super(), m_data(other.m_data) { }
tuple_vals() : m_data() { } tuple_vals() : m_data() { }
...@@ -62,7 +56,7 @@ class tuple_vals : public abstract_tuple ...@@ -62,7 +56,7 @@ class tuple_vals : public abstract_tuple
virtual size_t size() const virtual size_t size() const
{ {
return element_types::type_list_size; return sizeof...(ElementTypes);
} }
virtual tuple_vals* copy() const virtual tuple_vals* copy() const
......
...@@ -61,7 +61,7 @@ class exit_signal ...@@ -61,7 +61,7 @@ class exit_signal
* <tt>reason() == @p r</tt>. * <tt>reason() == @p r</tt>.
* @pre {@code r >= exit_reason::user_defined}. * @pre {@code r >= exit_reason::user_defined}.
*/ */
exit_signal(std::uint32_t r); explicit exit_signal(std::uint32_t r);
/** /**
* @brief Reads the exit reason. * @brief Reads the exit reason.
...@@ -86,6 +86,16 @@ class exit_signal ...@@ -86,6 +86,16 @@ class exit_signal
}; };
inline bool operator==(const exit_signal& lhs, const exit_signal& rhs)
{
return lhs.reason() == rhs.reason();
}
inline bool operator!=(const exit_signal& lhs, const exit_signal& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa } // namespace cppa
#endif // EXIT_SIGNAL_HPP #endif // EXIT_SIGNAL_HPP
#ifndef FROM_STRING_HPP
#define FROM_STRING_HPP
#include <string>
#include <typeinfo>
#include <exception>
#include "cppa/object.hpp"
#include "cppa/uniform_type_info.hpp"
namespace cppa {
object from_string(const std::string& what);
template<typename T>
T from_string(const std::string &what)
{
object o = from_string(what);
const std::type_info& tinfo = typeid(T);
if (o.type() == tinfo)
{
return std::move(get<T>(o));
}
else
{
std::string error_msg = "expected type name ";
error_msg += uniform_typeid(tinfo)->name();
error_msg += " found ";
error_msg += o.type().name();
throw std::logic_error(error_msg);
}
}
} // namespace cppa
#endif // FROM_STRING_HPP
...@@ -27,7 +27,8 @@ struct invoke_helper ...@@ -27,7 +27,8 @@ struct invoke_helper
static_assert(std::is_convertible<tuple_val_type, back_type>::value, static_assert(std::is_convertible<tuple_val_type, back_type>::value,
"tuple element is not convertible to expected argument"); "tuple element is not convertible to expected argument");
invoke_helper<N - 1, F, Tuple, next_list, tuple_val_type, Args...> invoke_helper<N - 1, F, Tuple, next_list, tuple_val_type, Args...>
::_(f, t, t.get<N>(), args...); //::_(f, t, t.get<N>(), args...);
::_(f, t, get<N>(t), args...);
} }
}; };
...@@ -40,33 +41,40 @@ struct invoke_helper<N, F, Tuple, util::type_list<>, Args...> ...@@ -40,33 +41,40 @@ struct invoke_helper<N, F, Tuple, util::type_list<>, Args...>
} }
}; };
template<bool HasCallableTrait, typename Tuple, typename F> template<bool HasCallableTrati, typename F, class Tuple>
struct invoke_impl struct invoke_impl;
template<typename F, template<typename...> class Tuple, typename... TTypes>
struct invoke_impl<true, F, Tuple<TTypes...> >
{ {
static_assert(sizeof...(TTypes) > 0, "empty tuple type");
typedef typename util::callable_trait<F>::arg_types arg_types; typedef typename util::callable_trait<F>::arg_types arg_types;
static const size_t tuple_size = Tuple::type_list_size - 1; typedef Tuple<TTypes...> tuple_type;
inline static void _(F& f, const Tuple& t) inline static void _(F& f, const tuple_type& t)
{ {
invoke_helper<tuple_size, F, Tuple, arg_types>::_(f, t); invoke_helper<sizeof...(TTypes) - 1, F, tuple_type, arg_types>::_(f, t);
} }
}; };
template<typename Tuple, typename F> template<typename F, template<typename...> class Tuple, typename... TTypes>
struct invoke_impl<false, Tuple, F> struct invoke_impl<false, F, Tuple<TTypes...> >
{ {
static_assert(sizeof...(TTypes) > 0, "empty tuple type");
typedef typename util::callable_trait<decltype(&F::operator())>::arg_types typedef typename util::callable_trait<decltype(&F::operator())>::arg_types
arg_types; arg_types;
static const size_t tuple_size = Tuple::type_list_size - 1; typedef Tuple<TTypes...> tuple_type;
inline static void _(F& f, const Tuple& t) inline static void _(F& f, const tuple_type& t)
{ {
invoke_helper<tuple_size, F, Tuple, arg_types>::_(f, t); invoke_helper<sizeof...(TTypes) - 1, F, tuple_type, arg_types>::_(f, t);
} }
}; };
...@@ -79,7 +87,7 @@ template<typename Tuple, typename F> ...@@ -79,7 +87,7 @@ template<typename Tuple, typename F>
void invoke(F what, const Tuple& args) void invoke(F what, const Tuple& args)
{ {
typedef typename std::remove_pointer<F>::type f_type; typedef typename std::remove_pointer<F>::type f_type;
detail::invoke_impl<std::is_function<f_type>::value, Tuple, F>::_(what, args); detail::invoke_impl<std::is_function<f_type>::value, F, Tuple>::_(what, args);
} }
} // namespace cppa } // namespace cppa
......
...@@ -51,7 +51,7 @@ bool match(const any_tuple& what, const ValuesTuple& vals, ...@@ -51,7 +51,7 @@ bool match(const any_tuple& what, const ValuesTuple& vals,
{ {
std::vector<size_t> tmp(mappings); std::vector<size_t> tmp(mappings);
view_type view(what.vals(), std::move(tmp)); view_type view(what.vals(), std::move(tmp));
return compare_first_elements(view, vals); return util::compare_first_elements(view, vals);
} }
return false; return false;
} }
......
...@@ -40,8 +40,9 @@ struct invoke_rule_builder ...@@ -40,8 +40,9 @@ struct invoke_rule_builder
{ {
typedef util::type_list<Arg0, Args...> arg_types; typedef util::type_list<Arg0, Args...> arg_types;
static_assert(arg_types::type_list_size static constexpr size_t num_args = sizeof...(Args) + 1;
<= filtered_types::type_list_size,
static_assert(num_args <= filtered_types::type_list_size,
"too much arguments"); "too much arguments");
class helper_impl : public irb_helper class helper_impl : public irb_helper
...@@ -66,7 +67,7 @@ struct invoke_rule_builder ...@@ -66,7 +67,7 @@ struct invoke_rule_builder
m_helper = new helper_impl(arg0, args...); m_helper = new helper_impl(arg0, args...);
static_assert(util::eval_first_n<arg_types::type_list_size, static_assert(util::eval_first_n<num_args,
filtered_types, filtered_types,
arg_types, arg_types,
util::is_comparable>::value, util::is_comparable>::value,
......
#ifndef TO_STRING_HPP
#define TO_STRING_HPP
#include "cppa/uniform_type_info.hpp"
namespace cppa {
namespace detail {
std::string to_string(const void* what, const uniform_type_info* utype);
} // namespace detail
template<typename T>
std::string to_string(const T& what)
{
auto utype = uniform_typeid<T>();
if (utype == nullptr)
{
throw std::logic_error( detail::to_uniform_name(typeid(T))
+ " is not announced");
}
return detail::to_string(&what, utype);
}
} // namespace cppa
#endif // TO_STRING_HPP
...@@ -80,7 +80,7 @@ class tuple ...@@ -80,7 +80,7 @@ class tuple
private: private:
static_assert(element_types::type_list_size > 0, "tuple is empty"); static_assert(sizeof...(ElementTypes) > 0, "tuple is empty");
static_assert(util::eval_type_list<element_types, static_assert(util::eval_type_list<element_types,
util::is_legal_tuple_type>::value, util::is_legal_tuple_type>::value,
...@@ -113,8 +113,6 @@ class tuple ...@@ -113,8 +113,6 @@ class tuple
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const size_t type_list_size = element_types::type_list_size;
tuple() : m_vals(new vals_t) { } tuple() : m_vals(new vals_t) { }
tuple(const ElementTypes&... args) : m_vals(new vals_t(args...)) { } tuple(const ElementTypes&... args) : m_vals(new vals_t(args...)) { }
...@@ -144,7 +142,7 @@ class tuple ...@@ -144,7 +142,7 @@ class tuple
template<typename... Args> template<typename... Args>
bool equal_to(const tuple<Args...>& other) const bool equal_to(const tuple<Args...>& other) const
{ {
static_assert(type_list_size == tuple<Args...>::type_list_size, static_assert(sizeof...(ElementTypes) == sizeof...(Args),
"Can't compare tuples of different size"); "Can't compare tuples of different size");
return compare_vals(vals()->data(), other.vals()->data()); return compare_vals(vals()->data(), other.vals()->data());
} }
......
...@@ -29,7 +29,7 @@ class tuple_view ...@@ -29,7 +29,7 @@ class tuple_view
typedef util::type_list<ElementTypes...> element_types; typedef util::type_list<ElementTypes...> element_types;
static_assert(element_types::type_list_size > 0, static_assert(sizeof...(ElementTypes) > 0,
"could not declare an empty tuple_view"); "could not declare an empty tuple_view");
typedef cow_ptr<detail::abstract_tuple> vals_t; typedef cow_ptr<detail::abstract_tuple> vals_t;
...@@ -51,21 +51,19 @@ class tuple_view ...@@ -51,21 +51,19 @@ class tuple_view
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const size_t type_list_size = element_types::type_list_size;
const element_types& types() const { return m_types; } const element_types& types() const { return m_types; }
template<size_t N> template<size_t N>
const typename util::type_at<N, element_types>::type& get() const const typename util::type_at<N, element_types>::type& get() const
{ {
static_assert(N < element_types::type_list_size, "N >= size()"); static_assert(N < sizeof...(ElementTypes), "N >= size()");
return *reinterpret_cast<const typename util::type_at<N, element_types>::type*>(m_vals->at(N)); return *reinterpret_cast<const typename util::type_at<N, element_types>::type*>(m_vals->at(N));
} }
template<size_t N> template<size_t N>
typename util::type_at<N, element_types>::type& get_ref() typename util::type_at<N, element_types>::type& get_ref()
{ {
static_assert(N < element_types::type_list_size, "N >= size()"); static_assert(N < sizeof...(ElementTypes), "N >= size()");
return *reinterpret_cast<typename util::type_at<N, element_types>::type*>(m_vals->mutable_at(N)); return *reinterpret_cast<typename util::type_at<N, element_types>::type*>(m_vals->mutable_at(N));
} }
...@@ -82,14 +80,20 @@ template<size_t N, typename... Types> ...@@ -82,14 +80,20 @@ template<size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type& const typename util::type_at<N, util::type_list<Types...>>::type&
get(const tuple_view<Types...>& t) get(const tuple_view<Types...>& t)
{ {
return t.get<N>(); static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::type_at<N, util::type_list<Types...>>::type result_t;
return *reinterpret_cast<const result_t*>(t.vals()->at(N));
//return t.get<N>();
} }
template<size_t N, typename... Types> template<size_t N, typename... Types>
typename util::type_at<N, util::type_list<Types...>>::type& typename util::type_at<N, util::type_list<Types...>>::type&
get_ref(tuple_view<Types...>& t) get_ref(tuple_view<Types...>& t)
{ {
return t.get_ref<N>(); static_assert(N < sizeof...(Types), "N >= t.size()");
typedef typename util::type_at<N, util::type_list<Types...>>::type result_t;
return *reinterpret_cast<result_t*>(t.vals()->mutable_at(N));
//return t.get_ref<N>();
} }
template<typename TypeList> template<typename TypeList>
......
...@@ -62,14 +62,13 @@ template<template<typename...> class LhsTuple, typename... LhsTypes, ...@@ -62,14 +62,13 @@ template<template<typename...> class LhsTuple, typename... LhsTypes,
bool compare_tuples(const LhsTuple<LhsTypes...>& lhs, bool compare_tuples(const LhsTuple<LhsTypes...>& lhs,
const RhsTuple<RhsTypes...>& rhs) const RhsTuple<RhsTypes...>& rhs)
{ {
static_assert( LhsTuple<LhsTypes...>::type_list_size static_assert(sizeof...(LhsTypes) == sizeof...(RhsTypes),
== RhsTuple<RhsTypes...>::type_list_size,
"could not compare tuples of different size"); "could not compare tuples of different size");
static_assert(util::eval_type_lists<util::type_list<LhsTypes...>, static_assert(util::eval_type_lists<util::type_list<LhsTypes...>,
util::type_list<RhsTypes...>, util::type_list<RhsTypes...>,
util::is_comparable>::value, util::is_comparable>::value,
"types of lhs are not comparable to the types of rhs"); "types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(LhsTuple<LhsTypes...>::type_list_size - 1), return detail::cmp_helper<(sizeof...(LhsTypes) - 1),
LhsTuple<LhsTypes...>, LhsTuple<LhsTypes...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs); RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
} }
...@@ -82,8 +81,8 @@ bool compare_first_elements(const LhsTuple<LhsTypes...>& lhs, ...@@ -82,8 +81,8 @@ bool compare_first_elements(const LhsTuple<LhsTypes...>& lhs,
typedef util::type_list<LhsTypes...> lhs_types; typedef util::type_list<LhsTypes...> lhs_types;
typedef util::type_list<RhsTypes...> rhs_types; typedef util::type_list<RhsTypes...> rhs_types;
static_assert(util::eval_first_n<detail::min_<lhs_types::type_list_size, static_assert(util::eval_first_n<detail::min_<sizeof...(LhsTypes),
rhs_types::type_list_size> sizeof...(RhsTypes)>
::value, ::value,
lhs_types, lhs_types,
rhs_types, rhs_types,
......
...@@ -16,6 +16,9 @@ struct rm_ref<const T&> { typedef T type; }; ...@@ -16,6 +16,9 @@ struct rm_ref<const T&> { typedef T type; };
template<typename T> template<typename T>
struct rm_ref<T&> { typedef T type; }; struct rm_ref<T&> { typedef T type; };
template<typename T>
struct rm_ref<T&&> { typedef T type; };
template<> template<>
struct rm_ref<void> { }; struct rm_ref<void> { };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace cppa { namespace util { namespace cppa { namespace util {
/*
template<size_t N, typename TypeList> template<size_t N, typename TypeList>
struct type_at struct type_at
{ {
...@@ -19,6 +20,31 @@ struct type_at<0, TypeList> ...@@ -19,6 +20,31 @@ struct type_at<0, TypeList>
{ {
typedef typename TypeList::head_type type; typedef typename TypeList::head_type type;
}; };
*/
template<size_t N, class TypeList>
struct type_at;
template<size_t N, template<typename...> class TypeList, typename T0, typename... Tn>
struct type_at< N, TypeList<T0,Tn...> >
{
// use type_list to avoid instantiations of TypeList parameter
typedef typename type_at< N-1, type_list<Tn...> >::type type;
};
template<template<typename...> class TypeList, typename T0, typename... Tn>
struct type_at< 0, TypeList<T0,Tn...> >
{
typedef T0 type;
};
template<size_t N, template<typename...> class TypeList>
struct type_at< N, TypeList<> >
{
typedef void_type type;
};
} } // namespace cppa::util } } // namespace cppa::util
......
...@@ -70,7 +70,7 @@ struct type_list<Head, Tail...> : abstract_type_list ...@@ -70,7 +70,7 @@ struct type_list<Head, Tail...> : abstract_type_list
typedef type_list<Tail...> tail_type; typedef type_list<Tail...> tail_type;
static const size_t type_list_size = tail_type::type_list_size + 1; static const size_t type_list_size = sizeof...(Tail) + 1;
type_list() type_list()
{ {
......
This diff is collapsed.
...@@ -6,7 +6,16 @@ ...@@ -6,7 +6,16 @@
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
#include "cppa/actor.hpp"
#include "cppa/group.hpp"
#include "cppa/channel.hpp"
#include "cppa/message.hpp"
#include "cppa/any_type.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/exit_signal.hpp"
#include "cppa/util/void_type.hpp" #include "cppa/util/void_type.hpp"
#include "cppa/detail/demangle.hpp" #include "cppa/detail/demangle.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
...@@ -51,6 +60,7 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -51,6 +60,7 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
// all integer type names as uniform representation // all integer type names as uniform representation
static std::map<std::string, std::string> mapped_demangled_names = static std::map<std::string, std::string> mapped_demangled_names =
{ {
// integer types
{ demangled<char>(), mapped_int_name<char>() }, { demangled<char>(), mapped_int_name<char>() },
{ demangled<signed char>(), mapped_int_name<signed char>() }, { demangled<signed char>(), mapped_int_name<signed char>() },
{ demangled<unsigned char>(), mapped_int_name<unsigned char>() }, { demangled<unsigned char>(), mapped_int_name<unsigned char>() },
...@@ -72,14 +82,21 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end, ...@@ -72,14 +82,21 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
{ demangled<long long>(), mapped_int_name<long long>() }, { demangled<long long>(), mapped_int_name<long long>() },
{ demangled<signed long long>(), mapped_int_name<signed long long>() }, { demangled<signed long long>(), mapped_int_name<signed long long>() },
{ demangled<unsigned long long>(), mapped_int_name<unsigned long long>()}, { demangled<unsigned long long>(), mapped_int_name<unsigned long long>()},
// { demangled<wchar_t>(), mapped_int_name<wchar_t>() },
{ demangled<char16_t>(), mapped_int_name<char16_t>() }, { demangled<char16_t>(), mapped_int_name<char16_t>() },
{ demangled<char32_t>(), mapped_int_name<char32_t>() }, { demangled<char32_t>(), mapped_int_name<char32_t>() },
{ demangled<cppa::util::void_type>(), "@0" }, // string types
// { demangled<std::wstring>(), "@wstr" },
{ demangled<std::string>(), "@str" }, { demangled<std::string>(), "@str" },
{ demangled<std::u16string>(), "@u16str" }, { demangled<std::u16string>(), "@u16str" },
{ demangled<std::u32string>(), "@u32str" } { demangled<std::u32string>(), "@u32str" },
// cppa types
{ demangled<cppa::any_type>(), "@*" },
{ demangled<cppa::util::void_type>(), "@0" },
{ demangled<cppa::any_tuple>(), "@<>" },
{ demangled<cppa::exit_signal>(), "@exit" },
{ demangled<cppa::actor_ptr>(), "@actor" },
{ demangled<cppa::group_ptr>(), "@group" },
{ demangled<cppa::channel_ptr>(), "@channel" },
{ demangled<cppa::message>(), "@msg" }
}; };
// check if we could find the whole string in our lookup map // check if we could find the whole string in our lookup map
......
This diff is collapsed.
include ../Makefile.rules include ../Makefile.rules
INCLUDE_FLAGS = $(INCLUDES) -I../ ./ INCLUDE_FLAGS = $(INCLUDES) -I../ -I./
LIB_FLAGS = $(LIBS) -L../ -lcppa LIB_FLAGS = $(LIBS) -L../ -lcppa
......
This diff is collapsed.
...@@ -19,16 +19,48 @@ void pong() ...@@ -19,16 +19,48 @@ void pong()
}); });
} }
void echo(actor_ptr whom, int what)
{
send(whom, what);
}
size_t test__spawn() size_t test__spawn()
{ {
CPPA_TEST(test__spawn); CPPA_TEST(test__spawn);
actor_ptr self_ptr = self();
{ {
auto sl = spawn(pong); auto sl = spawn(pong);
spawn(echo, self_ptr, 1);
send(sl, 23.f); send(sl, 23.f);
send(sl, 2); send(sl, 2);
receive(on<int>() >> [&](int value) { bool received_pong = false;
CPPA_CHECK_EQUAL(value, 42); bool received_echo = false;
auto rules = (on<int>(42) >> [&]() { received_pong = true; },
on<int>(1) >> [&]() { received_echo = true; });
receive(rules);
receive(rules);
CPPA_CHECK(received_pong);
CPPA_CHECK(received_echo);
}
{
auto sl = spawn([]() {
receive(on<int>() >> [](int value) {
reply((value * 20) + 2);
});
}); });
spawn([](actor_ptr whom, int what) { send(whom, what); },
self_ptr,
1);
send(sl, 23.f);
send(sl, 2);
bool received_pong = false;
bool received_echo = false;
auto rules = (on<int>(42) >> [&]() { received_pong = true; },
on<int>(1) >> [&]() { received_echo = true; });
receive(rules);
receive(rules);
CPPA_CHECK(received_pong);
CPPA_CHECK(received_echo);
} }
await_all_others_done(); await_all_others_done();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT;
......
...@@ -87,12 +87,13 @@ size_t test__uniform_type() ...@@ -87,12 +87,13 @@ size_t test__uniform_type()
"float", "double", // floating points "float", "double", // floating points
"@0", // cppa::util::void_type "@0", // cppa::util::void_type
// default announced cppa types // default announced cppa types
"cppa::any_type", "@*", // cppa::any_type
"cppa::any_tuple", "@<>", // cppa::any_tuple
"cppa::exit_reason", "@msg", // cppa::message
"cppa::intrusive_ptr<cppa::actor>", "@exit", // cppa::exit_signal
"cppa::intrusive_ptr<cppa::group>", "@actor", // cppa::actor_ptr
"cppa::intrusive_ptr<cppa::channel>" "@group", // cppa::group_ptr
"@channel" // cppa::channel_ptr
}; };
if (sizeof(double) != sizeof(long double)) if (sizeof(double) != sizeof(long double))
{ {
......
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