Commit dfea897e authored by neverlord's avatar neverlord

fixed conflict

parents 929da7cc 8021cd02
...@@ -60,15 +60,15 @@ ...@@ -60,15 +60,15 @@
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value> <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value>
<valuelist key="abstractProcess.Environment" type="QVariantList"> <valuelist key="abstractProcess.Environment" type="QVariantList">
<value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-gSC9AO/Render</value> <value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-Ii2KqP/Render</value>
<value type="QString">COMMAND_MODE=unix2003</value> <value type="QString">COMMAND_MODE=unix2003</value>
<value type="QString">DISPLAY=/tmp/launch-1vsPWG/org.x:0</value> <value type="QString">DISPLAY=/tmp/launch-6FAyZP/org.x:0</value>
<value type="QString">HOME=/Users/neverlord</value> <value type="QString">HOME=/Users/neverlord</value>
<value type="QString">LOGNAME=neverlord</value> <value type="QString">LOGNAME=neverlord</value>
<value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value> <value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value>
<value type="QString">SHELL=/bin/bash</value> <value type="QString">SHELL=/bin/bash</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-H5MBik/Listeners</value> <value type="QString">SSH_AUTH_SOCK=/tmp/launch-vifjfO/Listeners</value>
<value type="QString">TMPDIR=/var/folders/SE/SEReyCW0H-yDPCnNCe8mN++++TI/-Tmp-/</value> <value type="QString">TMPDIR=/var/folders/1p/1p6iuPgbH7GoDkrjrT20tU+++TI/-Tmp-/</value>
<value type="QString">USER=neverlord</value> <value type="QString">USER=neverlord</value>
<value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value> <value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value>
</valuelist> </valuelist>
......
...@@ -93,3 +93,6 @@ cppa/detail/channel.hpp ...@@ -93,3 +93,6 @@ cppa/detail/channel.hpp
cppa/message_receiver.hpp cppa/message_receiver.hpp
src/message_receiver.cpp src/message_receiver.cpp
src/actor.cpp src/actor.cpp
src/actor_private.cpp
cppa/util/eval_first_n.hpp
cppa/util/first_n.hpp
...@@ -15,11 +15,13 @@ class actor : public message_receiver ...@@ -15,11 +15,13 @@ class actor : public message_receiver
public: public:
typedef cppa::intrusive_ptr<detail::actor_public> ptr_type; typedef cppa::intrusive_ptr<detail::actor_private> ptr_type;
actor() = default; actor() = default;
inline actor(detail::actor_public* ptr) : super(ptr) { } ~actor();
inline actor(detail::actor_private* ptr) : super(ptr) { }
inline actor(const ptr_type& ptr) : super(ptr) { } inline actor(const ptr_type& ptr) : super(ptr) { }
......
#ifndef ACTOR_PRIVATE_HPP #ifndef ACTOR_PRIVATE_HPP
#define ACTOR_PRIVATE_HPP #define ACTOR_PRIVATE_HPP
#include <boost/thread/thread.hpp>
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/untyped_tuple.hpp"
...@@ -14,6 +16,9 @@ namespace cppa { namespace detail { ...@@ -14,6 +16,9 @@ namespace cppa { namespace detail {
// private part of the actor interface (callable only from this_actor()) // private part of the actor interface (callable only from this_actor())
struct actor_private : public actor_public struct actor_private : public actor_public
{ {
boost::thread* m_thread;
inline actor_private() : m_thread(0) { }
virtual ~actor_private();
virtual const message& receive() = 0; virtual const message& receive() = 0;
virtual const message& last_dequeued() const = 0; virtual const message& last_dequeued() const = 0;
virtual void receive(invoke_rules&) = 0; virtual void receive(invoke_rules&) = 0;
......
...@@ -21,9 +21,9 @@ class ref_counted_impl ...@@ -21,9 +21,9 @@ class ref_counted_impl
inline void ref() { ++m_rc; } inline void ref() { ++m_rc; }
inline bool deref() { return (--m_rc > 0); } inline bool deref() { return --m_rc > 0; }
inline bool unique() { return (m_rc == 1); } inline bool unique() { return m_rc == 1; }
}; };
......
...@@ -26,25 +26,39 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>, ...@@ -26,25 +26,39 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>,
intrusive_ptr() : m_ptr(0) { } intrusive_ptr() : m_ptr(0) { }
template<typename Y>
intrusive_ptr(Y* raw_ptr) { set_ptr(raw_ptr); }
intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); } intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); }
intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.m_ptr) intrusive_ptr(const intrusive_ptr& other)
{ {
other.m_ptr = 0; set_ptr(other.m_ptr);
} }
intrusive_ptr(const intrusive_ptr& other) { set_ptr(other.m_ptr); } intrusive_ptr(intrusive_ptr&& other) : m_ptr(0)
{
swap(other);
}
template<typename Y> template<typename Y>
intrusive_ptr(const intrusive_ptr<Y>& other) intrusive_ptr(const intrusive_ptr<Y>& other)
{ {
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
set_ptr(const_cast<Y*>(other.get())); set_ptr(const_cast<Y*>(other.get()));
} }
~intrusive_ptr() { if (m_ptr && !m_ptr->deref()) delete m_ptr; } template<typename Y>
intrusive_ptr(intrusive_ptr<Y>&& other) : m_ptr(0)
{
swap(other);
}
~intrusive_ptr()
{
if (m_ptr && !m_ptr->deref())
{
delete m_ptr;
}
}
T* get() { return m_ptr; } T* get() { return m_ptr; }
...@@ -91,6 +105,16 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>, ...@@ -91,6 +105,16 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>,
return *this; return *this;
} }
template<typename Y>
intrusive_ptr& operator=(intrusive_ptr<Y>&& other)
{
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
m_ptr = other.m_ptr;
other.m_ptr = 0;
return *this;
}
T* operator->() { return m_ptr; } T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; } T& operator*() { return *m_ptr; }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "cppa/tuple_view.hpp" #include "cppa/tuple_view.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/untyped_tuple.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/is_comparable.hpp" #include "cppa/util/is_comparable.hpp"
#include "cppa/util/utype_iterator.hpp" #include "cppa/util/utype_iterator.hpp"
...@@ -51,7 +52,8 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals, ...@@ -51,7 +52,8 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals,
{ {
std::vector<std::size_t> tmp(mappings); std::vector<std::size_t> tmp(mappings);
view_type view(what.vals(), std::move(tmp)); view_type view(what.vals(), std::move(tmp));
return view == vals; return compare_first_elements(view, vals);
// return view == vals;
} }
return false; return false;
} }
......
...@@ -23,7 +23,10 @@ class message ...@@ -23,7 +23,10 @@ class message
const untyped_tuple data; const untyped_tuple data;
content(const actor& s, const message_receiver& r, content(const actor& s, const message_receiver& r,
const untyped_tuple& ut) const untyped_tuple& ut)
: sender(s), receiver(r), data(ut) : ref_counted(), sender(s), receiver(r), data(ut)
{
}
~content()
{ {
} }
}; };
...@@ -41,8 +44,8 @@ class message ...@@ -41,8 +44,8 @@ class message
message(const actor& from, const message_receiver& to, const untyped_tuple& ut) message(const actor& from, const message_receiver& to, const untyped_tuple& ut)
: m_content(new content(from, to, ut)) { } : m_content(new content(from, to, ut)) { }
message(const actor& from, const message_receiver& to, untyped_tuple&& ut) // message(const actor& from, const message_receiver& to, untyped_tuple&& ut)
: m_content(new content(from, to, std::move(ut))) { } // : m_content(new content(from, to, std::move(ut))) { }
message() : m_content(new content(0, 0, tuple<int>(0))) { } message() : m_content(new content(0, 0, tuple<int>(0))) { }
......
...@@ -33,6 +33,8 @@ class message_receiver : ...@@ -33,6 +33,8 @@ class message_receiver :
{ {
} }
virtual ~message_receiver();
message_receiver() = default; message_receiver() = default;
message_receiver(message_receiver&&) = default; message_receiver(message_receiver&&) = default;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/untyped_tuple.hpp"
#include "cppa/util/eval_first_n.hpp"
#include "cppa/util/filter_type_list.hpp" #include "cppa/util/filter_type_list.hpp"
#include "cppa/detail/ref_counted_impl.hpp" #include "cppa/detail/ref_counted_impl.hpp"
...@@ -36,6 +37,12 @@ struct invoke_rule_builder ...@@ -36,6 +37,12 @@ struct invoke_rule_builder
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
invoke_rule_builder(const Arg0& arg0, const Args&... args) invoke_rule_builder(const Arg0& arg0, const Args&... args)
{ {
typedef util::type_list<Arg0, Args...> arg_types;
static_assert(arg_types::type_list_size
<= filtered_types::type_list_size,
"too much arguments");
class helper_impl : public irb_helper class helper_impl : public irb_helper
{ {
...@@ -44,7 +51,9 @@ struct invoke_rule_builder ...@@ -44,7 +51,9 @@ struct invoke_rule_builder
public: public:
helper_impl(const Arg0& arg0, const Args&... args) helper_impl(const Arg0& arg0, const Args&... args)
: m_values(arg0, args...) { } : m_values(arg0, args...)
{
}
virtual bool value_cmp(const untyped_tuple& t, virtual bool value_cmp(const untyped_tuple& t,
std::vector<std::size_t>& v) const std::vector<std::size_t>& v) const
...@@ -56,10 +65,11 @@ struct invoke_rule_builder ...@@ -56,10 +65,11 @@ struct invoke_rule_builder
m_helper = new helper_impl(arg0, args...); m_helper = new helper_impl(arg0, args...);
static_assert(util::eval_type_lists<filtered_types, static_assert(util::eval_first_n<arg_types::type_list_size,
util::type_list<Arg0, Args...>, filtered_types,
util::is_comparable>::value, arg_types,
"Wrong argument types"); util::is_comparable>::value,
"wrong argument types (not comparable)");
} }
typedef typename tuple_view_type_from_type_list<filtered_types>::type typedef typename tuple_view_type_from_type_list<filtered_types>::type
......
...@@ -61,7 +61,7 @@ CPPA_ANNOUNCE(std::uint64_t); ...@@ -61,7 +61,7 @@ CPPA_ANNOUNCE(std::uint64_t);
CPPA_ANNOUNCE(float); CPPA_ANNOUNCE(float);
CPPA_ANNOUNCE(double); CPPA_ANNOUNCE(double);
CPPA_ANNOUNCE(long double); CPPA_ANNOUNCE(long double);
*/
CPPA_ANNOUNCE(std::string); CPPA_ANNOUNCE(std::string);
*/
#endif // UNIFORM_TYPE_INFO_HPP #endif // UNIFORM_TYPE_INFO_HPP
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#include "cppa/util/detach.hpp" #include "cppa/util/detach.hpp"
#include "cppa/util/disjunction.hpp" #include "cppa/util/disjunction.hpp"
#include "cppa/util/enable_if.hpp" #include "cppa/util/enable_if.hpp"
#include "cppa/util/eval_first_n.hpp"
#include "cppa/util/eval_type_list.hpp" #include "cppa/util/eval_type_list.hpp"
#include "cppa/util/eval_type_lists.hpp" #include "cppa/util/eval_type_lists.hpp"
#include "cppa/util/filter_type_list.hpp" #include "cppa/util/filter_type_list.hpp"
#include "cppa/util/first_n.hpp"
#include "cppa/util/has_copy_member_fun.hpp" #include "cppa/util/has_copy_member_fun.hpp"
#include "cppa/util/is_comparable.hpp" #include "cppa/util/is_comparable.hpp"
#include "cppa/util/is_copyable.hpp" #include "cppa/util/is_copyable.hpp"
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "cppa/get.hpp" #include "cppa/get.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/eval_first_n.hpp"
#include "cppa/util/is_comparable.hpp" #include "cppa/util/is_comparable.hpp"
#include "cppa/util/eval_type_lists.hpp" #include "cppa/util/eval_type_lists.hpp"
...@@ -34,6 +35,25 @@ struct cmp_helper<0, LhsTuple, RhsTuple> ...@@ -34,6 +35,25 @@ struct cmp_helper<0, LhsTuple, RhsTuple>
} }
}; };
template<bool ALessB, std::size_t A, std::size_t B>
struct min_impl
{
static const std::size_t value = A;
};
template<std::size_t A, std::size_t B>
struct min_impl<false, A, B>
{
static const std::size_t value = B;
};
template<std::size_t A, std::size_t B>
struct min_
{
static const std::size_t value = min_impl<(A < B), A, B>::value;
};
} } // namespace cppa::detail } } // namespace cppa::detail
namespace cppa { namespace util { namespace cppa { namespace util {
...@@ -55,6 +75,29 @@ bool compare_tuples(const LhsTuple<LhsTypes...>& lhs, ...@@ -55,6 +75,29 @@ bool compare_tuples(const LhsTuple<LhsTypes...>& lhs,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs); RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
} }
template<template<typename...> class LhsTuple, typename... LhsTypes,
template<typename...> class RhsTuple, typename... RhsTypes>
bool compare_first_elements(const LhsTuple<LhsTypes...>& lhs,
const RhsTuple<RhsTypes...>& rhs)
{
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>
::value,
lhs_types,
rhs_types,
util::is_comparable>::value,
"types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(detail::min_<lhs_types::type_list_size,
rhs_types::type_list_size>
::value - 1),
LhsTuple<LhsTypes...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
}
} } // namespace cppa::util } } // namespace cppa::util
#endif // COMPARE_TUPLES_HPP #endif // COMPARE_TUPLES_HPP
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <type_traits> #include <type_traits>
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/concat_type_lists.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
...@@ -18,6 +17,7 @@ struct eval_type_lists ...@@ -18,6 +17,7 @@ struct eval_type_lists
typedef typename ListA::head_type head_type_a; typedef typename ListA::head_type head_type_a;
typedef typename ListA::tail_type tail_type_a; typedef typename ListA::tail_type tail_type_a;
typedef typename ListB::head_type head_type_b; typedef typename ListB::head_type head_type_b;
typedef typename ListB::tail_type tail_type_b; typedef typename ListB::tail_type tail_type_b;
......
...@@ -18,6 +18,16 @@ class singly_linked_list ...@@ -18,6 +18,16 @@ class singly_linked_list
singly_linked_list() : m_head(0), m_tail(0) { } singly_linked_list() : m_head(0), m_tail(0) { }
~singly_linked_list()
{
while (m_head)
{
T* next = m_head->next;
delete m_head;
m_head = next;
}
}
inline bool empty() const { return m_head == 0; } inline bool empty() const { return m_head == 0; }
void push_back(element_type* what) void push_back(element_type* what)
......
...@@ -55,6 +55,7 @@ HEADERS = cppa/actor.hpp \ ...@@ -55,6 +55,7 @@ HEADERS = cppa/actor.hpp \
cppa/util/void_type.hpp cppa/util/void_type.hpp
SOURCES = src/actor.cpp \ SOURCES = src/actor.cpp \
src/actor_private.cpp \
src/decorated_tuple.cpp \ src/decorated_tuple.cpp \
src/deserializer.cpp \ src/deserializer.cpp \
src/message_receiver.cpp \ src/message_receiver.cpp \
......
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include <boost/thread.hpp>
namespace cppa { namespace cppa {
actor& actor::operator=(const actor& other) actor& actor::operator=(const actor& other)
...@@ -14,4 +16,23 @@ actor& actor::operator=(actor&& other) ...@@ -14,4 +16,23 @@ actor& actor::operator=(actor&& other)
return *this; return *this;
} }
actor::~actor()
{
/*
if (m_channel && m_channel->unique())
{
detail::actor_private* ap = dynamic_cast<detail::actor_private*>(m_channel.get());
if (ap && ap->m_thread)
{
if (boost::this_thread::get_id() != ap->m_thread->get_id())
{
ap->m_thread->join();
delete ap->m_thread;
ap->m_thread = 0;
}
}
}
*/
}
} // namespace cppa } // namespace cppa
...@@ -18,6 +18,6 @@ cppa::deserializer& operator>>(cppa::deserializer& d, std::string& str) ...@@ -18,6 +18,6 @@ cppa::deserializer& operator>>(cppa::deserializer& d, std::string& str)
d.read(str_size, cbuf); d.read(str_size, cbuf);
cbuf[str_size] = 0; cbuf[str_size] = 0;
str = cbuf; str = cbuf;
delete cbuf; delete[] cbuf;
return d; return d;
} }
...@@ -22,4 +22,8 @@ message_receiver::operator=(intrusive_ptr<detail::channel>&& ch_ptr) ...@@ -22,4 +22,8 @@ message_receiver::operator=(intrusive_ptr<detail::channel>&& ch_ptr)
return *this; return *this;
} }
message_receiver::~message_receiver()
{
}
} // namespace cppa } // namespace cppa
...@@ -11,7 +11,7 @@ struct actor_message ...@@ -11,7 +11,7 @@ struct actor_message
{ {
actor_message* next; actor_message* next;
cppa::message msg; cppa::message msg;
actor_message(const cppa::message& from) : msg(from) { } actor_message(const cppa::message& from) : next(0), msg(from) { }
}; };
struct actor_impl; struct actor_impl;
...@@ -31,6 +31,11 @@ struct actor_impl : cppa::detail::actor_private ...@@ -31,6 +31,11 @@ struct actor_impl : cppa::detail::actor_private
actor_impl(cppa::detail::behavior* b = 0) : m_behavior(b) { } actor_impl(cppa::detail::behavior* b = 0) : m_behavior(b) { }
~actor_impl()
{
if (m_behavior) delete m_behavior;
}
virtual void enqueue_msg(const cppa::message& msg) virtual void enqueue_msg(const cppa::message& msg)
{ {
mailbox.push_back(new actor_message(msg)); mailbox.push_back(new actor_message(msg));
...@@ -98,7 +103,6 @@ struct actor_ptr ...@@ -98,7 +103,6 @@ struct actor_ptr
{ {
cppa::intrusive_ptr<actor_impl> m_impl; cppa::intrusive_ptr<actor_impl> m_impl;
actor_ptr(actor_impl* ai) : m_impl(ai) { } actor_ptr(actor_impl* ai) : m_impl(ai) { }
actor_ptr(actor_ptr&& other) : m_impl(std::move(other.m_impl)) { }
actor_ptr(const actor_ptr&) = default; actor_ptr(const actor_ptr&) = default;
void operator()() void operator()()
{ {
...@@ -130,8 +134,10 @@ namespace cppa { namespace detail { ...@@ -130,8 +134,10 @@ namespace cppa { namespace detail {
actor spawn_impl(behavior* actor_behavior) actor spawn_impl(behavior* actor_behavior)
{ {
actor_ptr aptr(new actor_impl(actor_behavior)); actor_ptr aptr(new actor_impl(actor_behavior));
boost::thread(aptr).detach(); aptr.m_impl->m_thread = new boost::thread(aptr);
return actor(std::move(aptr.m_impl)); // boost::thread(aptr).detach();
return actor(aptr.m_impl);
// return actor(std::move(aptr.m_impl));
} }
} } // namespace cppa::detail } } // namespace cppa::detail
#include <limits> #include <limits>
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory>
#include <cstdint> #include <cstdint>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <atomic>
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
...@@ -23,29 +27,53 @@ typedef std::map<std::string, std::string> string_map; ...@@ -23,29 +27,53 @@ typedef std::map<std::string, std::string> string_map;
template<int Size, bool IsSigned> template<int Size, bool IsSigned>
struct int_helper { }; struct int_helper { };
template<> struct int_helper<1,true> { static const char* name; }; template<>
const char* int_helper<1,true>::name = "int8_t"; struct int_helper<1, true>
{
static std::string name() { return "@i8"; }
};
template<> struct int_helper<2,true> { static const char* name; }; template<>
const char* int_helper<2,true>::name = "int16_t"; struct int_helper<2, true>
{
static std::string name() { return "@i16"; }
};
template<> struct int_helper<4,true> { static const char* name; }; template<>
const char* int_helper<4,true>::name = "int32_t"; struct int_helper<4, true>
{
static std::string name() { return "@i32"; }
};
template<> struct int_helper<8,true> { static const char* name; }; template<>
const char* int_helper<8,true>::name = "int64_t"; struct int_helper<8, true>
{
static std::string name() { return "@i64"; }
};
template<> struct int_helper<1,false> { static const char* name; }; template<>
const char* int_helper<1,false>::name = "uint8_t"; struct int_helper<1, false>
{
static std::string name() { return "@u8"; }
};
template<> struct int_helper<2,false> { static const char* name; }; template<>
const char* int_helper<2,false>::name = "uint16_t"; struct int_helper<2, false>
{
static std::string name() { return "@u16"; }
};
template<> struct int_helper<4,false> { static const char* name; }; template<>
const char* int_helper<4,false>::name = "uint32_t"; struct int_helper<4, false>
{
static std::string name() { return "@u32"; }
};
template<> struct int_helper<8,false> { static const char* name; }; template<>
const char* int_helper<8,false>::name = "uint64_t"; struct int_helper<8, false>
{
static std::string name() { return "@u64"; }
};
template<typename T> template<typename T>
struct uniform_int : int_helper<sizeof(T), std::numeric_limits<T>::is_signed>{}; struct uniform_int : int_helper<sizeof(T), std::numeric_limits<T>::is_signed>{};
...@@ -56,13 +84,12 @@ std::map<std::string, cppa::utype*>* ut_map = 0; ...@@ -56,13 +84,12 @@ std::map<std::string, cppa::utype*>* ut_map = 0;
template<typename T> template<typename T>
std::string raw_name() std::string raw_name()
{ {
std::string result;
size_t size; size_t size;
int status; int status;
char* undecorated = abi::__cxa_demangle(typeid(T).name(), char* undecorated = abi::__cxa_demangle(typeid(T).name(),
NULL, &size, &status); NULL, &size, &status);
assert(status == 0); assert(status == 0);
result = undecorated; std::string result(undecorated, size);
free(undecorated); free(undecorated);
return result; return result;
} }
...@@ -74,147 +101,120 @@ const char* raw_name() ...@@ -74,147 +101,120 @@ const char* raw_name()
} }
#endif #endif
string_map* btm_ptr = 0; //string_map* btm_ptr = 0;
std::unique_ptr<string_map> btm_ptr;
const string_map& builtin_type_mappings() const string_map& builtin_type_mappings()
{ {
if (!btm_ptr) if (!btm_ptr)
{ {
btm_ptr = new string_map string_map* value = new string_map
{ {
{ raw_name<char>(), { raw_name<char>(),
uniform_int<char>::name }, uniform_int<char>::name() },
{ raw_name<signed char>(), { raw_name<signed char>(),
uniform_int<signed char>::name }, uniform_int<signed char>::name() },
{ raw_name<unsigned char>(), { raw_name<unsigned char>(),
uniform_int<unsigned char>::name }, uniform_int<unsigned char>::name() },
{ raw_name<short>(), { raw_name<short>(),
uniform_int<short>::name }, uniform_int<short>::name() },
{ raw_name<signed short>(), { raw_name<signed short>(),
uniform_int<signed short>::name }, uniform_int<signed short>::name() },
{ raw_name<unsigned short>(), { raw_name<unsigned short>(),
uniform_int<unsigned short>::name }, uniform_int<unsigned short>::name() },
{ raw_name<short int>(), { raw_name<short int>(),
uniform_int<short int>::name }, uniform_int<short int>::name() },
{ raw_name<signed short int>(), { raw_name<signed short int>(),
uniform_int<signed short int>::name }, uniform_int<signed short int>::name() },
{ raw_name<unsigned short int>(), { raw_name<unsigned short int>(),
uniform_int<unsigned short int>::name }, uniform_int<unsigned short int>::name() },
{ raw_name<int>(), { raw_name<int>(),
uniform_int<int>::name }, uniform_int<int>::name() },
{ raw_name<signed int>(), { raw_name<signed int>(),
uniform_int<signed int>::name }, uniform_int<signed int>::name() },
{ raw_name<unsigned int>(), { raw_name<unsigned int>(),
uniform_int<unsigned int>::name }, uniform_int<unsigned int>::name() },
{ raw_name<long>(), { raw_name<long>(),
uniform_int<long>::name }, uniform_int<long>::name() },
{ raw_name<signed long>(), { raw_name<signed long>(),
uniform_int<signed long>::name }, uniform_int<signed long>::name() },
{ raw_name<unsigned long>(), { raw_name<unsigned long>(),
uniform_int<unsigned long>::name }, uniform_int<unsigned long>::name() },
{ raw_name<long int>(), { raw_name<long int>(),
uniform_int<long int>::name }, uniform_int<long int>::name() },
{ raw_name<signed long int>(), { raw_name<signed long int>(),
uniform_int<signed long int>::name }, uniform_int<signed long int>::name() },
{ raw_name<unsigned long int>(), { raw_name<unsigned long int>(),
uniform_int<unsigned long int>::name }, uniform_int<unsigned long int>::name() },
{ raw_name<long long>(), { raw_name<long long>(),
uniform_int<long long>::name }, uniform_int<long long>::name() },
{ raw_name<signed long long>(), { raw_name<signed long long>(),
uniform_int<signed long long>::name }, uniform_int<signed long long>::name() },
{ raw_name<unsigned long long>(), { raw_name<unsigned long long>(),
uniform_int<unsigned long long>::name }, uniform_int<unsigned long long>::name() },
// GCC dosn't return a standard compliant name for the std::string typedef { raw_name<std::string>(),
# ifdef CPPA_GCC "@str" },
{ raw_name<std::string>(), { raw_name<std::wstring>(),
"std::basic_string<char,std::char_traits<char>,std::allocator<char>>" } "@wstr" }
# endif // "std::basic_string<char,std::char_traits<char>,std::allocator<char>>" }
}; };
btm_ptr.reset(value);
return *btm_ptr;
}
else
{
return *btm_ptr;
} }
return *btm_ptr;
} }
} // namespace <anonymous> } // namespace <anonymous>
namespace cppa { namespace detail { namespace cppa { namespace detail {
std::string demangle(const char* type_name) std::string demangle_impl(const char* begin, const char* end, size_t size)
{ {
std::string result; // demangling of a template?
# ifdef CPPA_WINDOWS const char* pos = std::find(begin, end, '<');
result = type_name; if (pos == end)
std::vector<std::string> needles;
needles.push_back("class ");
needles.push_back("struct ");
// the VC++ compiler adds "class " and "struct " before a type names
for (size_t i = 0; i < needles.size(); ++i)
{ {
const std::string& needle = needles[i]; return std::string(begin, size);
bool string_changed = false;
do
{
// result is our haystack
size_t pos = result.find(needle);
if (pos != std::string::npos)
{
result.erase(pos, needle.size());
string_changed = true;
}
else string_changed = false;
}
while (string_changed);
} }
# elif defined(CPPA_GCC) else
size_t size;
int status;
char* undecorated = abi::__cxa_demangle(type_name,
NULL, &size, &status);
assert(status == 0);
result = undecorated;
free(undecorated);
# else
# error "Unsupported plattform"
# endif
// template class?
std::string::size_type pos = result.find('<');
if (pos != std::string::npos)
{ {
// map every single template argument to uniform names std::string processed(begin, pos);
// skip leading '<'
++pos;
std::string processed_name(result, 0, pos);
processed_name.reserve(result.size());
std::string tmp; std::string tmp;
// replace all simple type names // skip leading '<'
for (std::string::size_type p = pos; p < result.size(); ++p) for ( ++pos; pos != end; ++pos)
{ {
switch (result[p]) char c = *pos;
switch (c)
{ {
case ',': case ',':
case '>': case '>':
case '<': case '<':
{ {
// erase trailing whitespaces // erase trailing whitespaces
while (!tmp.empty() && tmp[tmp.size() - 1] == ' ') while (!tmp.empty() && (*(tmp.rbegin()) == ' '))
{ {
tmp.erase(tmp.size() - 1); tmp.resize(tmp.size() - 1);
} }
auto i = builtin_type_mappings().find(tmp); auto i = builtin_type_mappings().find(tmp);
if (i != builtin_type_mappings().end()) if (i != builtin_type_mappings().end())
{ {
processed_name += i->second; processed += i->second;
} }
else else
{ {
processed_name += tmp; processed += tmp;
} }
} }
processed_name += result[p]; processed += c;
tmp.clear(); tmp.clear();
break; break;
case ' ': case ' ':
if (tmp == "class" || tmp == "struct") if (tmp == "class" || tmp == "struct")
{ {
tmp.clear(); tmp.clear();
...@@ -226,38 +226,57 @@ std::string demangle(const char* type_name) ...@@ -226,38 +226,57 @@ std::string demangle(const char* type_name)
} }
break; break;
default: default:
tmp += result[p]; tmp += c;
break; break;
} }
} }
/* return processed;
if (!m_complex_mappings.empty()) }
}
std::string demangle(const char* decorated_type_name)
{
# ifdef CPPA_WINDOWS
result = type_name;
std::vector<std::string> needles;
needles.push_back("class ");
needles.push_back("struct ");
// the VC++ compiler adds "class " and "struct " before a type names
for (size_t i = 0; i < needles.size(); ++i)
{
const std::string& needle = needles[i];
bool string_changed = false;
do
{ {
// perform a lookup for complex types, such as template types // result is our haystack
for (string_map::const_iterator i = m_complex_mappings.begin(); size_t pos = result.find(needle);
i != m_complex_mappings.end(); if (pos != std::string::npos)
++i)
{ {
const std::string& needle = i->first; result.erase(pos, needle.size());
std::string::size_type x = processed_name.find(needle); string_changed = true;
if (x != std::string::npos)
{
processed_name.replace(x, needle.size(), i->second);
}
} }
else string_changed = false;
} }
*/ while (string_changed);
result = processed_name;
} }
else # elif defined(CPPA_GCC)
size_t size = 0;
int status = 0;
char* undecorated = abi::__cxa_demangle(decorated_type_name,
NULL, &size, &status);
assert(status == 0);
std::string result = demangle_impl(undecorated, undecorated + size, size);
free(undecorated);
# else
# error "Unsupported plattform"
# endif
// template class?
auto i = builtin_type_mappings().find(result);
if (i != builtin_type_mappings().end())
{ {
auto i = builtin_type_mappings().find(result); result = i->second;
if (i != builtin_type_mappings().end())
{
result = i->second;
}
} }
return result; return result;
} }
......
...@@ -26,6 +26,7 @@ using std::endl; ...@@ -26,6 +26,7 @@ using std::endl;
int main(int argc, char** c_argv) int main(int argc, char** c_argv)
{ {
std::vector<std::string> argv; std::vector<std::string> argv;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
......
...@@ -34,10 +34,6 @@ if ((lhs_loc) != (rhs_loc)) \ ...@@ -34,10 +34,6 @@ if ((lhs_loc) != (rhs_loc)) \
++error_count; \ ++error_count; \
} ((void) 0) } ((void) 0)
unsigned int hash_of(const char* what, int what_length);
unsigned int hash_of(const std::string& what);
std::size_t test__type_list(); std::size_t test__type_list();
std::size_t test__a_matches_b(); std::size_t test__a_matches_b();
std::size_t test__atom(); std::size_t test__atom();
......
...@@ -16,6 +16,8 @@ std::size_t test__a_matches_b() ...@@ -16,6 +16,8 @@ std::size_t test__a_matches_b()
typedef type_list<int, int, std::string> int_int_string; typedef type_list<int, int, std::string> int_int_string;
typedef type_list<int, int, const std::string&> int_int_const_string_ref; typedef type_list<int, int, const std::string&> int_int_const_string_ref;
typedef typename first_n<2, int_float_int>::type int_float;
typedef type_list_apply<int_int_const_string_ref, typedef type_list_apply<int_int_const_string_ref,
remove_const_reference>::type remove_const_reference>::type
int_int_string2; int_int_string2;
...@@ -29,8 +31,10 @@ std::size_t test__a_matches_b() ...@@ -29,8 +31,10 @@ std::size_t test__a_matches_b()
CPPA_CHECK((a_matches_b<int_int_string, int_int_string2>::value)); CPPA_CHECK((a_matches_b<int_int_string, int_int_string2>::value));
CPPA_CHECK(!(a_matches_b<int_int_string, int_int_const_string_ref>::value)); CPPA_CHECK(!(a_matches_b<int_int_string, int_int_const_string_ref>::value));
CPPA_CHECK_EQUAL((a_matches_b<type_list<float>, CPPA_CHECK(!(a_matches_b<type_list<float>,
type_list<int, float, int>>::value), false); type_list<int, float, int>>::value));
CPPA_CHECK((std::is_same<util::type_list<int, float>, int_float>::value));
CPPA_CHECK((a_matches_b<type_list<any_type*, float>, CPPA_CHECK((a_matches_b<type_list<any_type*, float>,
type_list<int, float, int>>::value) == false); type_list<int, float, int>>::value) == false);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
#include "test.hpp" #include "test.hpp"
#include "hash_of.hpp"
#include "cppa/util.hpp" #include "cppa/util.hpp"
using std::cout; using std::cout;
......
#include "test.hpp" #include "test.hpp"
#include "hash_of.hpp"
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/spawn.hpp" #include "cppa/spawn.hpp"
...@@ -19,119 +20,104 @@ using std::endl; ...@@ -19,119 +20,104 @@ using std::endl;
using namespace cppa; using namespace cppa;
class group : public detail::channel namespace {
{
boost::mutex m_mtx;
std::list<actor> m_subscribers;
public: struct group : detail::channel
{
struct subscription // NOT thread safe
class subscription : public detail::ref_counted_impl<std::size_t>
{ {
actor m_self; actor m_self;
intrusive_ptr<group> m_group; intrusive_ptr<group> m_group;
public:
subscription() = delete;
subscription(const subscription&) = delete;
subscription& operator=(const subscription&) = delete;
subscription(const actor& s, const intrusive_ptr<group>& g) subscription(const actor& s, const intrusive_ptr<group>& g)
: m_self(s), m_group(g) : m_self(s), m_group(g)
{ {
} }
~subscription() ~subscription()
{ {
m_group->unsubscribe(m_self); m_group->unsubscribe(m_self);
} }
}; };
subscription subscribe(const actor& who) virtual intrusive_ptr<subscription> subscribe(const actor& who) = 0;
{
boost::mutex::scoped_lock guard(m_mtx);
m_subscribers.push_back(who);
return { who, this };
}
void unsubscribe(const actor& who) virtual void unsubscribe(const actor& who) = 0;
{
boost::mutex::scoped_lock guard(m_mtx);
auto i = std::find(m_subscribers.begin(), m_subscribers.end(), who);
if (i != m_subscribers.end())
{
m_subscribers.erase(i);
}
}
void enqueue_msg(const message& msg)
{
boost::mutex::scoped_lock guard(m_mtx);
for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i)
{
i->enqueue_msg(msg);
}
}
template<typename... Args> template<typename... Args>
void send(const Args&... args) void send(const Args&... args)
{ {
message msg(this_actor(), this, args...); enqueue_msg(message(this_actor(), this, args...));
enqueue_msg(msg);
} }
}; };
namespace { class local_group : public group
class group_bucket
{ {
boost::mutex m_mtx; boost::mutex m_mtx;
std::map<std::string, intrusive_ptr<group>> m_groups; std::list<actor> m_subscribers;
inline std::list<actor>::iterator find(const actor& what)
{
return std::find(m_subscribers.begin(), m_subscribers.end(), what);
}
public: public:
intrusive_ptr<group> get(const std::string& group_name) virtual void enqueue_msg(const message& msg)
{ {
boost::mutex::scoped_lock guard(m_mtx); boost::mutex::scoped_lock guard(m_mtx);
intrusive_ptr<group>& result = m_groups[group_name]; for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i)
if (!result)
{ {
result.reset(new group); i->enqueue_msg(msg);
} }
return result;
} }
}; virtual intrusive_ptr<group::subscription> subscribe(const actor& who)
template<std::size_t NumBuckets>
class group_table
{
group_bucket m_buckets[NumBuckets];
group_bucket& bucket(const std::string& group_name)
{ {
unsigned int gn_hash = hash_of(group_name); boost::mutex::scoped_lock guard(m_mtx);
return m_buckets[gn_hash % NumBuckets]; auto i = find(who);
if (i == m_subscribers.end())
{
m_subscribers.push_back(who);
return new group::subscription(who, this);
}
return new group::subscription(0, 0);
} }
public: virtual void unsubscribe(const actor& who)
intrusive_ptr<group> operator[](const std::string& group_name)
{ {
return bucket(group_name).get(group_name); boost::mutex::scoped_lock guard(m_mtx);
auto i = find(who);
if (i != m_subscribers.end())
{
m_subscribers.erase(i);
}
} }
}; };
group_table<100> m_groups; //local_group* m_local_group = new local_group;
} // namespace <anonymous> local_group m_local_group;
struct group& local(const char*)
{ {
intrusive_ptr<group> operator/(const std::string& group_name) return m_local_group;
{
return m_groups[group_name];
}
} }
local;
} // namespace <anonymous>
struct storage struct storage
{ {
...@@ -159,12 +145,19 @@ struct storage ...@@ -159,12 +145,19 @@ struct storage
}; };
/*
template<typename... Args>
void send(std::list<actor>& actors, const Args&... args)
{
for (auto i = actors.begin(); i != actors.end(); ++i)
{
i->send(args...);
}
}
*/
void foo_actor() void foo_actor()
{ {
auto x = (local/"foobar")->subscribe(this_actor());
receive(on<int, int, int>() >> []() {
reply(23.f);
});
receive(on<int>() >> [](int i) { receive(on<int>() >> [](int i) {
reply(i); reply(i);
}); });
...@@ -175,42 +168,23 @@ std::size_t test__local_group() ...@@ -175,42 +168,23 @@ std::size_t test__local_group()
CPPA_TEST(test__local_group); CPPA_TEST(test__local_group);
/* std::list<intrusive_ptr<group::subscription>> m_subscriptions;
storage st;
st.get<int>("foobaz") = 42;
CPPA_CHECK_EQUAL(st.get<int>("foobaz"), 42);
st.get<std::string>("_s") = "Hello World!";
CPPA_CHECK_EQUAL(st.get<std::string>("_s"), "Hello World!");
*/
auto g = local/"foobar";
group& lg = local("foobar");
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
spawn(foo_actor).send(1, 2, 3); m_subscriptions.push_back(lg.subscribe(spawn(foo_actor)));
} }
for (int i = 0; i < 5; ++i) lg.send(1);
{
receive(on<float>() >> []() { });
}
g->send(1);
int result = 0; int result = 0;
auto rule = on<int>() >> [&result](int x) {
result += x;
};
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
receive(rule); receive(on<int>() >> [&result](int x) {
result += x;
});
} }
CPPA_CHECK_EQUAL(result, 5); CPPA_CHECK_EQUAL(result, 5);
......
...@@ -195,7 +195,7 @@ struct obj_types : util::abstract_type_list ...@@ -195,7 +195,7 @@ struct obj_types : util::abstract_type_list
~obj_types() ~obj_types()
{ {
delete m_arr; delete[] m_arr;
} }
virtual std::size_t size() const { return m_size; } virtual std::size_t size() const { return m_size; }
......
...@@ -73,6 +73,18 @@ std::size_t test__tuple() ...@@ -73,6 +73,18 @@ std::size_t test__tuple()
CPPA_CHECK(tv2.get<1>() == "Hello World"); CPPA_CHECK(tv2.get<1>() == "Hello World");
{
tuple<int> t1_sub1(42);
tuple<int, float> t1_sub2(42, .2f);
tuple<int, float, int> t1_sub3(42, .2f, 2);
CPPA_CHECK((util::compare_first_elements(t1, t1_sub1)));
CPPA_CHECK((match<int, any_type*>(t1, t1_sub1)));
CPPA_CHECK((util::compare_first_elements(t1, t1_sub2)));
CPPA_CHECK((match<int, any_type*, float, any_type*>(t1, t1_sub2)));
CPPA_CHECK((util::compare_first_elements(t1, t1_sub3)));
CPPA_CHECK((match<int, float, int, any_type>(t1, t1_sub3)));
}
{ {
std::vector<std::size_t> tv3_mappings; std::vector<std::size_t> tv3_mappings;
match<any_type*, int, std::string>(t1, tv3_mappings); match<any_type*, int, std::string>(t1, tv3_mappings);
......
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