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 @@
</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>
......
......@@ -94,7 +94,6 @@ queue_performances/blocking_cached_stack2.hpp
queue_performances/blocking_sutter_list.hpp
queue_performances/lockfree_list.hpp
queue_performances/intrusive_sutter_list.hpp
cppa/detail/cpp0x_thread_wrapper.hpp
src/context.cpp
cppa/scheduler.hpp
cppa/detail/mock_scheduler.hpp
......@@ -151,3 +150,6 @@ cppa/util/abstract_uniform_type_info.hpp
cppa/util/upgrade_lock_guard.hpp
cppa/exit_signal.hpp
src/exit_signal.cpp
cppa/to_string.hpp
src/string_serialization.cpp
cppa/from_string.hpp
......@@ -29,21 +29,119 @@
#ifndef CPPA_HPP
#define CPPA_HPP
#include <tuple>
#include <type_traits>
#include "cppa/tuple.hpp"
#include "cppa/actor.hpp"
#include "cppa/invoke.hpp"
#include "cppa/channel.hpp"
#include "cppa/context.hpp"
#include "cppa/message.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/actor_behavior.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 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>
actor_ptr spawn(scheduling_hint hint, F fun)
actor_ptr spawn(scheduling_hint hint, const F& fun)
{
struct fun_behavior : actor_behavior
{
......@@ -54,31 +152,22 @@ actor_ptr spawn(scheduling_hint hint, F 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>
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...);
return spawn(hint, [=]() { invoke(fun, arg_tuple); });
}
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...);
}
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()
{
......@@ -124,6 +213,12 @@ void reply(const Arg0& arg0, const Args&... 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()
{
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<>
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;
tdata<>& tail()
......@@ -47,14 +39,6 @@ struct tdata<Head, Tail...> : tdata<Tail...>
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;
inline tdata() : super(), head() { }
......@@ -99,8 +83,7 @@ template<size_t N, typename... ElementTypes>
const typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get(const tdata<ElementTypes...>& tv)
{
static_assert(N < util::type_list<ElementTypes...>::type_list_size,
"N < tv.size()");
static_assert(N < sizeof...(ElementTypes), "N >= tv.size()");
return static_cast<const typename tdata_upcast_helper<N, ElementTypes...>::type&>(tv).head;
}
......@@ -108,8 +91,7 @@ template<size_t N, typename... ElementTypes>
typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get_ref(tdata<ElementTypes...>& tv)
{
static_assert(N < util::type_list<ElementTypes...>::type_list_size,
"N >= tv.size()");
static_assert(N < sizeof...(ElementTypes), "N >= tv.size()");
return static_cast<typename tdata_upcast_helper<N, ElementTypes...>::type &>(tv).head;
}
......
......@@ -39,12 +39,6 @@ class tuple_vals : public abstract_tuple
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() : m_data() { }
......@@ -62,7 +56,7 @@ class tuple_vals : public abstract_tuple
virtual size_t size() const
{
return element_types::type_list_size;
return sizeof...(ElementTypes);
}
virtual tuple_vals* copy() const
......
......@@ -61,7 +61,7 @@ class exit_signal
* <tt>reason() == @p r</tt>.
* @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.
......@@ -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
#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
static_assert(std::is_convertible<tuple_val_type, back_type>::value,
"tuple element is not convertible to expected argument");
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...>
}
};
template<bool HasCallableTrait, typename Tuple, typename F>
struct invoke_impl
template<bool HasCallableTrati, typename F, class Tuple>
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;
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>
struct invoke_impl<false, Tuple, F>
template<typename F, template<typename...> class Tuple, typename... TTypes>
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
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>
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, Tuple, F>::_(what, args);
detail::invoke_impl<std::is_function<f_type>::value, F, Tuple>::_(what, args);
}
} // namespace cppa
......
......@@ -51,7 +51,7 @@ bool match(const any_tuple& what, const ValuesTuple& vals,
{
std::vector<size_t> tmp(mappings);
view_type view(what.vals(), std::move(tmp));
return compare_first_elements(view, vals);
return util::compare_first_elements(view, vals);
}
return false;
}
......
......@@ -40,8 +40,9 @@ struct invoke_rule_builder
{
typedef util::type_list<Arg0, Args...> arg_types;
static_assert(arg_types::type_list_size
<= filtered_types::type_list_size,
static constexpr size_t num_args = sizeof...(Args) + 1;
static_assert(num_args <= filtered_types::type_list_size,
"too much arguments");
class helper_impl : public irb_helper
......@@ -66,7 +67,7 @@ struct invoke_rule_builder
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,
arg_types,
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
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,
util::is_legal_tuple_type>::value,
......@@ -113,8 +113,6 @@ class tuple
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(const ElementTypes&... args) : m_vals(new vals_t(args...)) { }
......@@ -144,7 +142,7 @@ class tuple
template<typename... Args>
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");
return compare_vals(vals()->data(), other.vals()->data());
}
......
......@@ -29,7 +29,7 @@ class tuple_view
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");
typedef cow_ptr<detail::abstract_tuple> vals_t;
......@@ -51,21 +51,19 @@ class tuple_view
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; }
template<size_t N>
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));
}
template<size_t N>
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));
}
......@@ -82,14 +80,20 @@ template<size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
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>
typename util::type_at<N, util::type_list<Types...>>::type&
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>
......
......@@ -62,14 +62,13 @@ template<template<typename...> class LhsTuple, typename... LhsTypes,
bool compare_tuples(const LhsTuple<LhsTypes...>& lhs,
const RhsTuple<RhsTypes...>& rhs)
{
static_assert( LhsTuple<LhsTypes...>::type_list_size
== RhsTuple<RhsTypes...>::type_list_size,
static_assert(sizeof...(LhsTypes) == sizeof...(RhsTypes),
"could not compare tuples of different size");
static_assert(util::eval_type_lists<util::type_list<LhsTypes...>,
util::type_list<RhsTypes...>,
util::is_comparable>::value,
"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...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
}
......@@ -82,8 +81,8 @@ bool compare_first_elements(const LhsTuple<LhsTypes...>& lhs,
typedef util::type_list<LhsTypes...> lhs_types;
typedef util::type_list<RhsTypes...> rhs_types;
static_assert(util::eval_first_n<detail::min_<lhs_types::type_list_size,
rhs_types::type_list_size>
static_assert(util::eval_first_n<detail::min_<sizeof...(LhsTypes),
sizeof...(RhsTypes)>
::value,
lhs_types,
rhs_types,
......
......@@ -16,6 +16,9 @@ struct rm_ref<const T&> { typedef T type; };
template<typename T>
struct rm_ref<T&> { typedef T type; };
template<typename T>
struct rm_ref<T&&> { typedef T type; };
template<>
struct rm_ref<void> { };
......
......@@ -8,6 +8,7 @@
namespace cppa { namespace util {
/*
template<size_t N, typename TypeList>
struct type_at
{
......@@ -19,6 +20,31 @@ struct type_at<0, TypeList>
{
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
......
......@@ -70,7 +70,7 @@ struct type_list<Head, Tail...> : abstract_type_list
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()
{
......
This diff is collapsed.
......@@ -6,7 +6,16 @@
#include <stdexcept>
#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/detail/demangle.hpp"
#include "cppa/detail/to_uniform_name.hpp"
......@@ -51,6 +60,7 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
// all integer type names as uniform representation
static std::map<std::string, std::string> mapped_demangled_names =
{
// integer types
{ demangled<char>(), mapped_int_name<char>() },
{ demangled<signed char>(), mapped_int_name<signed char>() },
{ demangled<unsigned char>(), mapped_int_name<unsigned char>() },
......@@ -72,14 +82,21 @@ std::string to_uniform_name_impl(Iterator begin, Iterator end,
{ demangled<long long>(), mapped_int_name<long long>() },
{ demangled<signed long long>(), mapped_int_name<signed 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<char32_t>(), mapped_int_name<char32_t>() },
{ demangled<cppa::util::void_type>(), "@0" },
// { demangled<std::wstring>(), "@wstr" },
// string types
{ demangled<std::string>(), "@str" },
{ 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
......
This diff is collapsed.
include ../Makefile.rules
INCLUDE_FLAGS = $(INCLUDES) -I../ ./
INCLUDE_FLAGS = $(INCLUDES) -I../ -I./
LIB_FLAGS = $(LIBS) -L../ -lcppa
......
This diff is collapsed.
......@@ -19,16 +19,48 @@ void pong()
});
}
void echo(actor_ptr whom, int what)
{
send(whom, what);
}
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);
receive(on<int>() >> [&](int value) {
CPPA_CHECK_EQUAL(value, 42);
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);
}
{
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();
return CPPA_TEST_RESULT;
......
......@@ -87,12 +87,13 @@ size_t test__uniform_type()
"float", "double", // floating points
"@0", // cppa::util::void_type
// default announced cppa types
"cppa::any_type",
"cppa::any_tuple",
"cppa::exit_reason",
"cppa::intrusive_ptr<cppa::actor>",
"cppa::intrusive_ptr<cppa::group>",
"cppa::intrusive_ptr<cppa::channel>"
"@*", // cppa::any_type
"@<>", // cppa::any_tuple
"@msg", // cppa::message
"@exit", // cppa::exit_signal
"@actor", // cppa::actor_ptr
"@group", // cppa::group_ptr
"@channel" // cppa::channel_ptr
};
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