Commit 904adf60 authored by neverlord's avatar neverlord

any_tuple, serialization stuff and group modules

parent 767ab3f4
all: all:
./create_libcppa_Makefile.sh > libcppa.Makefile
make -f libcppa.Makefile make -f libcppa.Makefile
make -C unit_testing make -C unit_testing
make -C queue_performances make -C queue_performances
......
...@@ -17,7 +17,6 @@ cppa/config.hpp ...@@ -17,7 +17,6 @@ cppa/config.hpp
unit_testing/test__tuple.cpp unit_testing/test__tuple.cpp
cppa/detail/abstract_tuple.hpp cppa/detail/abstract_tuple.hpp
cppa/tuple_view.hpp cppa/tuple_view.hpp
cppa/untyped_tuple.hpp
cppa/any_type.hpp cppa/any_type.hpp
cppa/detail/matcher.hpp cppa/detail/matcher.hpp
cppa/detail/tuple_vals.hpp cppa/detail/tuple_vals.hpp
...@@ -64,15 +63,12 @@ src/deserializer.cpp ...@@ -64,15 +63,12 @@ src/deserializer.cpp
cppa/util/eval_type_list.hpp cppa/util/eval_type_list.hpp
cppa/util/is_legal_tuple_type.hpp cppa/util/is_legal_tuple_type.hpp
cppa/util/replace_type.hpp cppa/util/replace_type.hpp
src/untyped_tuple.cpp
cppa/util/abstract_type_list.hpp cppa/util/abstract_type_list.hpp
cppa/detail/serialize_tuple.hpp cppa/detail/serialize_tuple.hpp
unit_testing/test__atom.cpp unit_testing/test__atom.cpp
unit_testing/test__queue_performance.cpp unit_testing/test__queue_performance.cpp
cppa/detail/actor_public.hpp
cppa/util/single_reader_queue.hpp cppa/util/single_reader_queue.hpp
cppa/util/singly_linked_list.hpp cppa/util/singly_linked_list.hpp
cppa/detail/actor_private.hpp
unit_testing/test__local_group.cpp unit_testing/test__local_group.cpp
unit_testing/hash_of.cpp unit_testing/hash_of.cpp
unit_testing/hash_of.hpp unit_testing/hash_of.hpp
...@@ -128,7 +124,6 @@ cppa/util/is_primitive.hpp ...@@ -128,7 +124,6 @@ cppa/util/is_primitive.hpp
cppa/util/is_iterable.hpp cppa/util/is_iterable.hpp
src/primitive_variant.cpp src/primitive_variant.cpp
unit_testing/test__primitive_variant.cpp unit_testing/test__primitive_variant.cpp
cppa/util/uniform_type_info_base.hpp
cppa/detail/primitive_member.hpp cppa/detail/primitive_member.hpp
cppa/detail/list_member.hpp cppa/detail/list_member.hpp
cppa/detail/pair_member.hpp cppa/detail/pair_member.hpp
...@@ -147,3 +142,9 @@ src/message.cpp ...@@ -147,3 +142,9 @@ src/message.cpp
cppa/util/shared_spinlock.hpp cppa/util/shared_spinlock.hpp
src/shared_spinlock.cpp src/shared_spinlock.cpp
cppa/util/shared_lock_guard.hpp cppa/util/shared_lock_guard.hpp
cppa/get_view.hpp
cppa/detail/object_array.hpp
src/object_array.cpp
cppa/any_tuple.hpp
src/any_tuple.cpp
cppa/util/abstract_uniform_type_info.hpp
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
#include <typeinfo> #include <typeinfo>
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/default_uniform_type_info_impl.hpp" #include "cppa/detail/default_uniform_type_info_impl.hpp"
namespace cppa { namespace cppa {
template<class C, class Parent, typename... Args> template<class C, class Parent, typename... Args>
std::pair<C Parent::*, util::uniform_type_info_base<C>*> std::pair<C Parent::*, util::abstract_uniform_type_info<C>*>
compound_member(C Parent::*c_ptr, const Args&... args) compound_member(C Parent::*c_ptr, const Args&... args)
{ {
return { c_ptr, new detail::default_uniform_type_info_impl<C>(args...) }; return { c_ptr, new detail::default_uniform_type_info_impl<C>(args...) };
......
#ifndef ANY_TUPLE_HPP
#define ANY_TUPLE_HPP
#include "cppa/cow_ptr.hpp"
#include "cppa/tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa {
/**
* @brief Describes a fixed-length tuple (or tuple view)
* with elements of any type.
*/
class any_tuple
{
cow_ptr<detail::abstract_tuple> m_vals;
public:
typedef cow_ptr<detail::abstract_tuple> vals_ptr;
any_tuple();
template<typename... Args>
any_tuple(const tuple<Args...>& t) : m_vals(t.vals()) { }
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);
any_tuple(any_tuple&&);
any_tuple(const any_tuple&) = default;
any_tuple& operator=(any_tuple&&);
any_tuple& operator=(const any_tuple&) = default;
size_t size() const;
void* mutable_at(size_t p);
const void* at(size_t p) const;
const uniform_type_info& type_at(size_t p) const;
const util::abstract_type_list& types() const;
const cow_ptr<detail::abstract_tuple>& vals() const;
bool equal_to(const any_tuple& other) const;
};
inline bool operator==(const any_tuple& lhs, const any_tuple& rhs)
{
return lhs.equal_to(rhs);
}
inline bool operator!=(const any_tuple& lhs, const any_tuple& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa
#endif // ANY_TUPLE_HPP
...@@ -124,7 +124,7 @@ void reply(const Arg0& arg0, const Args&... args) ...@@ -124,7 +124,7 @@ 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...));
} }
inline void await_all_actors_done() inline void await_all_others_done()
{ {
get_scheduler()->await_others_done(); get_scheduler()->await_others_done();
} }
......
...@@ -12,15 +12,15 @@ struct abstract_tuple : ref_counted ...@@ -12,15 +12,15 @@ struct abstract_tuple : ref_counted
{ {
// mutators // mutators
virtual void* mutable_at(std::size_t pos) = 0; virtual void* mutable_at(size_t pos) = 0;
// accessors // accessors
virtual std::size_t size() const = 0; virtual size_t size() const = 0;
virtual abstract_tuple* copy() const = 0; virtual abstract_tuple* copy() const = 0;
virtual const void* at(std::size_t pos) const = 0; virtual const void* at(size_t pos) const = 0;
virtual const util::abstract_type_list& types() const = 0; virtual const util::abstract_type_list& types() const = 0;
virtual bool equal_to(const abstract_tuple& other) const = 0; virtual bool equal_to(const abstract_tuple& other) const = 0;
virtual const uniform_type_info* utype_at(std::size_t pos) const = 0; virtual const uniform_type_info& type_at(size_t pos) const = 0;
}; };
......
#ifndef ACTOR_PRIVATE_HPP
#define ACTOR_PRIVATE_HPP
/*
#include <boost/thread/thread.hpp>
#include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/detail/channel.hpp"
#include "cppa/detail/actor_public.hpp"
namespace cppa { class message; }
namespace cppa { namespace detail {
// private part of the actor interface (callable only from this_actor())
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& last_dequeued() const = 0;
virtual void receive(invoke_rules&) = 0;
virtual void send(channel* whom, untyped_tuple&& what) = 0;
};
} } // namespace cppa::detail
namespace cppa {
detail::actor_private* this_actor();
inline const message& receive()
{
return this_actor()->receive();
}
inline void receive(invoke_rules& rules)
{
this_actor()->receive(rules);
}
inline void receive(invoke_rules&& rules)
{
invoke_rules tmp(std::move(rules));
this_actor()->receive(tmp);
}
inline const message& last_dequeued()
{
return this_actor()->last_dequeued();
}
} // namespace cppa
*/
#endif // ACTOR_PRIVATE_HPP
#ifndef ACTOR_PUBLIC_HPP
#define ACTOR_PUBLIC_HPP
/*
#include "cppa/detail/channel.hpp"
namespace cppa { namespace detail {
// public part of the actor interface
struct actor_public : channel
{
virtual void enqueue_msg(const message& msg) = 0;
};
} } // namespace cppa::detail
*/
#endif // ACTOR_PUBLIC_HPP
...@@ -25,7 +25,7 @@ class converted_thread_context : public context ...@@ -25,7 +25,7 @@ class converted_thread_context : public context
bool m_exited; bool m_exited;
// manages group subscriptions // manages group subscriptions
std::map<group_ptr, intrusive_ptr<group::subscription>> m_subscriptions; std::map<group_ptr, group::subscription> m_subscriptions;
// manages actor links // manages actor links
std::set<actor_ptr> m_links; std::set<actor_ptr> m_links;
......
...@@ -25,17 +25,17 @@ class decorated_tuple : public abstract_tuple ...@@ -25,17 +25,17 @@ class decorated_tuple : public abstract_tuple
typedef cow_ptr<abstract_tuple> ptr_type; typedef cow_ptr<abstract_tuple> ptr_type;
decorated_tuple(const ptr_type& d, decorated_tuple(const ptr_type& d,
const std::vector<std::size_t>& v) const std::vector<size_t>& v)
: m_decorated(d), m_mappings(v) : m_decorated(d), m_mappings(v)
{ {
} }
virtual void* mutable_at(std::size_t pos) virtual void* mutable_at(size_t pos)
{ {
return m_decorated->mutable_at(m_mappings[pos]); return m_decorated->mutable_at(m_mappings[pos]);
} }
virtual std::size_t size() const virtual size_t size() const
{ {
return m_mappings.size(); return m_mappings.size();
} }
...@@ -45,14 +45,14 @@ class decorated_tuple : public abstract_tuple ...@@ -45,14 +45,14 @@ class decorated_tuple : public abstract_tuple
return new decorated_tuple(*this); return new decorated_tuple(*this);
} }
virtual const void* at(std::size_t pos) const virtual const void* at(size_t pos) const
{ {
return m_decorated->at(m_mappings[pos]); return m_decorated->at(m_mappings[pos]);
} }
virtual const uniform_type_info* utype_at(std::size_t pos) const virtual const uniform_type_info& type_at(size_t pos) const
{ {
return m_decorated->utype_at(m_mappings[pos]); return m_decorated->type_at(m_mappings[pos]);
} }
virtual const util::abstract_type_list& types() const virtual const util::abstract_type_list& types() const
...@@ -68,7 +68,7 @@ class decorated_tuple : public abstract_tuple ...@@ -68,7 +68,7 @@ class decorated_tuple : public abstract_tuple
private: private:
ptr_type m_decorated; ptr_type m_decorated;
std::vector<std::size_t> m_mappings; std::vector<size_t> m_mappings;
element_types m_types; element_types m_types;
decorated_tuple(const decorated_tuple& other) decorated_tuple(const decorated_tuple& other)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "cppa/util/is_iterable.hpp" #include "cppa/util/is_iterable.hpp"
#include "cppa/util/is_primitive.hpp" #include "cppa/util/is_primitive.hpp"
#include "cppa/util/is_forward_iterator.hpp" #include "cppa/util/is_forward_iterator.hpp"
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/map_member.hpp" #include "cppa/detail/map_member.hpp"
#include "cppa/detail/list_member.hpp" #include "cppa/detail/list_member.hpp"
...@@ -80,7 +80,7 @@ struct has_default_uniform_type_info_impl ...@@ -80,7 +80,7 @@ struct has_default_uniform_type_info_impl
}; };
template<typename T> template<typename T>
class default_uniform_type_info_impl : public util::uniform_type_info_base<T> class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T>
{ {
template<typename X> template<typename X>
...@@ -194,7 +194,7 @@ class default_uniform_type_info_impl : public util::uniform_type_info_base<T> ...@@ -194,7 +194,7 @@ class default_uniform_type_info_impl : public util::uniform_type_info_base<T>
// pr.first = member pointer // pr.first = member pointer
// pr.second = meta object to handle pr.first // pr.second = meta object to handle pr.first
template<typename R, class C, typename... Args> template<typename R, class C, typename... Args>
void push_back(std::pair<R C::*, util::uniform_type_info_base<R>*> pr, void push_back(std::pair<R C::*, util::abstract_uniform_type_info<R>*> pr,
const Args&... args) const Args&... args)
{ {
m_members.push_back({ pr.second, pr.first }); m_members.push_back({ pr.second, pr.first });
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
// intermediate is NOT thread safe // intermediate is NOT thread safe
class intermediate : public ref_counted_impl<std::size_t> class intermediate : public ref_counted_impl<size_t>
{ {
intermediate(const intermediate&) = delete; intermediate(const intermediate&) = delete;
......
...@@ -8,7 +8,7 @@ namespace cppa { namespace detail { ...@@ -8,7 +8,7 @@ namespace cppa { namespace detail {
class intermediate; class intermediate;
// invokable is NOT thread safe // invokable is NOT thread safe
class invokable : public ref_counted_impl<std::size_t> class invokable : public ref_counted_impl<size_t>
{ {
invokable(const invokable&) = delete; invokable(const invokable&) = delete;
...@@ -17,8 +17,8 @@ class invokable : public ref_counted_impl<std::size_t> ...@@ -17,8 +17,8 @@ class invokable : public ref_counted_impl<std::size_t>
public: public:
invokable() = default; invokable() = default;
virtual bool invoke(const untyped_tuple&) const = 0; virtual bool invoke(const any_tuple&) const = 0;
virtual intermediate* get_intermediate(const untyped_tuple&) const = 0; virtual intermediate* get_intermediate(const any_tuple&) const = 0;
}; };
...@@ -33,12 +33,12 @@ class invokable_impl : public invokable ...@@ -33,12 +33,12 @@ class invokable_impl : public invokable
invokable_impl(Invoker&& i, Getter&& g) : m_inv(i), m_get(g) { } invokable_impl(Invoker&& i, Getter&& g) : m_inv(i), m_get(g) { }
virtual bool invoke(const untyped_tuple& t) const virtual bool invoke(const any_tuple& t) const
{ {
return m_inv(t); return m_inv(t);
} }
virtual intermediate* get_intermediate(const untyped_tuple& t) const virtual intermediate* get_intermediate(const any_tuple& t) const
{ {
return m_get(t); return m_get(t);
} }
......
#ifndef LIST_MEMBER_HPP #ifndef LIST_MEMBER_HPP
#define LIST_MEMBER_HPP #define LIST_MEMBER_HPP
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename List> template<typename List>
class list_member : public util::uniform_type_info_base<List> class list_member : public util::abstract_uniform_type_info<List>
{ {
typedef typename List::value_type value_type; typedef typename List::value_type value_type;
......
#ifndef MAP_MEMBER_HPP #ifndef MAP_MEMBER_HPP
#define MAP_MEMBER_HPP #define MAP_MEMBER_HPP
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/primitive_member.hpp" #include "cppa/detail/primitive_member.hpp"
#include "cppa/detail/pair_member.hpp" #include "cppa/detail/pair_member.hpp"
...@@ -46,7 +46,7 @@ struct meta_value_type<std::pair<const T1, T2>> ...@@ -46,7 +46,7 @@ struct meta_value_type<std::pair<const T1, T2>>
}; };
template<typename Map> template<typename Map>
class map_member : public util::uniform_type_info_base<Map> class map_member : public util::abstract_uniform_type_info<Map>
{ {
typedef typename Map::key_type key_type; typedef typename Map::key_type key_type;
......
...@@ -16,8 +16,8 @@ struct matcher<Head, Tail...> ...@@ -16,8 +16,8 @@ struct matcher<Head, Tail...>
{ {
static bool match(util::abstract_type_list::const_iterator& begin, static bool match(util::abstract_type_list::const_iterator& begin,
util::abstract_type_list::const_iterator& end, util::abstract_type_list::const_iterator& end,
std::vector<std::size_t>* res = nullptr, std::vector<size_t>* res = nullptr,
std::size_t pos = 0) size_t pos = 0)
{ {
auto head_uti = uniform_typeid<Head>(); auto head_uti = uniform_typeid<Head>();
if (begin != end) if (begin != end)
...@@ -42,8 +42,8 @@ struct matcher<any_type, Tail...> ...@@ -42,8 +42,8 @@ struct matcher<any_type, Tail...>
{ {
static bool match(util::abstract_type_list::const_iterator& begin, static bool match(util::abstract_type_list::const_iterator& begin,
util::abstract_type_list::const_iterator& end, util::abstract_type_list::const_iterator& end,
std::vector<std::size_t>* res = nullptr, std::vector<size_t>* res = nullptr,
std::size_t pos = 0) size_t pos = 0)
{ {
if (begin != end) if (begin != end)
{ {
...@@ -60,8 +60,8 @@ struct matcher<any_type*, Next, Tail...> ...@@ -60,8 +60,8 @@ struct matcher<any_type*, Next, Tail...>
{ {
static bool match(util::abstract_type_list::const_iterator& begin, static bool match(util::abstract_type_list::const_iterator& begin,
util::abstract_type_list::const_iterator& end, util::abstract_type_list::const_iterator& end,
std::vector<std::size_t>* res = nullptr, std::vector<size_t>* res = nullptr,
std::size_t pos = 0) size_t pos = 0)
{ {
bool result = false; bool result = false;
while (!result) while (!result)
...@@ -90,8 +90,8 @@ struct matcher<any_type*> ...@@ -90,8 +90,8 @@ struct matcher<any_type*>
{ {
static bool match(util::abstract_type_list::const_iterator&, static bool match(util::abstract_type_list::const_iterator&,
util::abstract_type_list::const_iterator&, util::abstract_type_list::const_iterator&,
std::vector<std::size_t>* = nullptr, std::vector<size_t>* = nullptr,
std::size_t = 0) size_t = 0)
{ {
return true; return true;
} }
...@@ -102,8 +102,8 @@ struct matcher<> ...@@ -102,8 +102,8 @@ struct matcher<>
{ {
static bool match(util::abstract_type_list::const_iterator& begin, static bool match(util::abstract_type_list::const_iterator& begin,
util::abstract_type_list::const_iterator& end, util::abstract_type_list::const_iterator& end,
std::vector<std::size_t>* = nullptr, std::vector<size_t>* = nullptr,
std::size_t = 0) size_t = 0)
{ {
return begin == end; return begin == end;
} }
......
#ifndef OBJECT_ARRAY_HPP
#define OBJECT_ARRAY_HPP
#include <vector>
#include "cppa/object.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/util/abstract_type_list.hpp"
namespace cppa { namespace detail {
class object_array : public detail::abstract_tuple
, public util::abstract_type_list
{
std::vector<object> m_elements;
public:
object_array();
object_array(object_array&& other);
object_array(const object_array& other);
/**
* @pre
*/
void push_back(object&& what);
void push_back(const object& what);
void* mutable_at(size_t pos);
size_t size() const;
abstract_tuple* copy() const;
const void* at(size_t pos) const;
const util::abstract_type_list& types() const;
bool equal_to(const cppa::detail::abstract_tuple&) const;
const uniform_type_info& type_at(size_t pos) const;
util::abstract_type_list::const_iterator begin() const;
};
} } // namespace cppa::detail
#endif // OBJECT_ARRAY_HPP
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
#define PAIR_MEMBER_HPP #define PAIR_MEMBER_HPP
#include <utility> #include <utility>
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename T1, typename T2> template<typename T1, typename T2>
class pair_member : public util::uniform_type_info_base<std::pair<T1,T2>> class pair_member : public util::abstract_uniform_type_info<std::pair<T1,T2>>
{ {
static constexpr primitive_type ptype1 = type_to_ptype<T1>::ptype; static constexpr primitive_type ptype1 = type_to_ptype<T1>::ptype;
......
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
#include "cppa/primitive_type.hpp" #include "cppa/primitive_type.hpp"
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/detail/type_to_ptype.hpp" #include "cppa/detail/type_to_ptype.hpp"
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
// uniform_type_info implementation for primitive data types. // uniform_type_info implementation for primitive data types.
template<typename T> template<typename T>
class primitive_member : public util::uniform_type_info_base<T> class primitive_member : public util::abstract_uniform_type_info<T>
{ {
static constexpr primitive_type ptype = type_to_ptype<T>::ptype; static constexpr primitive_type ptype = type_to_ptype<T>::ptype;
......
...@@ -10,7 +10,7 @@ namespace cppa { class serializer; } ...@@ -10,7 +10,7 @@ namespace cppa { class serializer; }
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename List, std::size_t Pos = 0> template<typename List, size_t Pos = 0>
struct serialize_tuple struct serialize_tuple
{ {
template<typename T> template<typename T>
...@@ -22,7 +22,7 @@ struct serialize_tuple ...@@ -22,7 +22,7 @@ struct serialize_tuple
} }
}; };
template<std::size_t Pos> template<size_t Pos>
struct serialize_tuple<util::type_list<>, Pos> struct serialize_tuple<util::type_list<>, Pos>
{ {
template<typename T> template<typename T>
......
...@@ -16,14 +16,14 @@ struct byte_access ...@@ -16,14 +16,14 @@ struct byte_access
inline byte_access(T val = 0) : value(val) { } inline byte_access(T val = 0) : value(val) { }
}; };
template<std::size_t SizeOfT, typename T> template<size_t SizeOfT, typename T>
struct byte_swapper struct byte_swapper
{ {
static T _(byte_access<T> from) static T _(byte_access<T> from)
{ {
byte_access<T> to; byte_access<T> to;
auto i = SizeOfT - 1; auto i = SizeOfT - 1;
for (std::size_t j = 0 ; j < SizeOfT ; --i, ++j) for (size_t j = 0 ; j < SizeOfT ; --i, ++j)
{ {
to.bytes[i] = from.bytes[j]; to.bytes[i] = from.bytes[j];
} }
......
...@@ -20,7 +20,7 @@ struct tdata<> ...@@ -20,7 +20,7 @@ struct tdata<>
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size; static const size_t type_list_size = element_types::type_list_size;
util::void_type head; util::void_type head;
...@@ -53,7 +53,7 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -53,7 +53,7 @@ struct tdata<Head, Tail...> : tdata<Tail...>
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size; static const size_t type_list_size = element_types::type_list_size;
Head head; Head head;
...@@ -80,10 +80,10 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -80,10 +80,10 @@ struct tdata<Head, Tail...> : tdata<Tail...>
}; };
template<std::size_t N, typename... ElementTypes> template<size_t N, typename... ElementTypes>
struct tdata_upcast_helper; struct tdata_upcast_helper;
template<std::size_t N, typename Head, typename... Tail> template<size_t N, typename Head, typename... Tail>
struct tdata_upcast_helper<N, Head, Tail...> struct tdata_upcast_helper<N, Head, Tail...>
{ {
typedef typename tdata_upcast_helper<N-1, Tail...>::type type; typedef typename tdata_upcast_helper<N-1, Tail...>::type type;
...@@ -95,7 +95,7 @@ struct tdata_upcast_helper<0, Head, Tail...> ...@@ -95,7 +95,7 @@ struct tdata_upcast_helper<0, Head, Tail...>
typedef tdata<Head, Tail...> type; typedef tdata<Head, Tail...> type;
}; };
template<std::size_t N, typename... ElementTypes> 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)
{ {
...@@ -104,7 +104,7 @@ tdata_get(const tdata<ElementTypes...>& tv) ...@@ -104,7 +104,7 @@ tdata_get(const tdata<ElementTypes...>& tv)
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;
} }
template<std::size_t N, typename... ElementTypes> 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)
{ {
......
...@@ -26,13 +26,13 @@ class tuple_vals : public abstract_tuple ...@@ -26,13 +26,13 @@ class tuple_vals : public abstract_tuple
element_types m_types; element_types m_types;
template<typename... Types> template<typename... Types>
void* tdata_mutable_at(tdata<Types...>& d, std::size_t pos) void* tdata_mutable_at(tdata<Types...>& d, size_t pos)
{ {
return (pos == 0) ? &(d.head) : tdata_mutable_at(d.tail(), pos - 1); return (pos == 0) ? &(d.head) : tdata_mutable_at(d.tail(), pos - 1);
} }
template<typename... Types> template<typename... Types>
const void* tdata_at(const tdata<Types...>& d, std::size_t pos) const const void* tdata_at(const tdata<Types...>& d, size_t pos) const
{ {
return (pos == 0) ? &(d.head) : tdata_at(d.tail(), pos - 1); return (pos == 0) ? &(d.head) : tdata_at(d.tail(), pos - 1);
} }
...@@ -43,7 +43,7 @@ class tuple_vals : public abstract_tuple ...@@ -43,7 +43,7 @@ class tuple_vals : public abstract_tuple
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size; 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) { }
...@@ -55,12 +55,12 @@ class tuple_vals : public abstract_tuple ...@@ -55,12 +55,12 @@ class tuple_vals : public abstract_tuple
inline data_type& data_ref() { return m_data; } inline data_type& data_ref() { return m_data; }
virtual void* mutable_at(std::size_t pos) virtual void* mutable_at(size_t pos)
{ {
return tdata_mutable_at(m_data, pos); return tdata_mutable_at(m_data, pos);
} }
virtual std::size_t size() const virtual size_t size() const
{ {
return element_types::type_list_size; return element_types::type_list_size;
} }
...@@ -70,12 +70,12 @@ class tuple_vals : public abstract_tuple ...@@ -70,12 +70,12 @@ class tuple_vals : public abstract_tuple
return new tuple_vals(*this); return new tuple_vals(*this);
} }
virtual const void* at(std::size_t pos) const virtual const void* at(size_t pos) const
{ {
return tdata_at(m_data, pos); return tdata_at(m_data, pos);
} }
virtual const uniform_type_info* utype_at(std::size_t pos) const virtual const uniform_type_info& type_at(size_t pos) const
{ {
return m_types.at(pos); return m_types.at(pos);
} }
......
...@@ -16,21 +16,23 @@ class tuple; ...@@ -16,21 +16,23 @@ class tuple;
template<typename... ElementTypes> template<typename... ElementTypes>
class tuple_view; class tuple_view;
// forward declarations of get(...) // forward declarations of get(const tuple<...>&...)
template<std::size_t N, typename... Types> 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<Types...>& t); get(const tuple<Types...>& t);
template<std::size_t N, typename... Types> // forward declarations of get(const tuple_view<...>&...)
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);
// forward declarations of get_ref(...) // forward declarations of get_ref(tuple<...>&...)
template<std::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<Types...>& t); get_ref(tuple<Types...>& t);
template<std::size_t N, typename... Types> // forward declarations of get_ref(tuple_view<...>&...)
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);
......
#ifndef GET_VIEW_HPP
#define GET_VIEW_HPP
#include <vector>
#include <cstddef>
#include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/util/a_matches_b.hpp"
namespace cppa {
template<typename... MatchRules, template <typename...> class Tuple, typename... TupleTypes>
typename tuple_view_type_from_type_list<typename util::filter_type_list<any_type, util::type_list<MatchRules...>>::type>::type
get_view(const Tuple<TupleTypes...>& t)
{
static_assert(util::a_matches_b<util::type_list<MatchRules...>,
util::type_list<TupleTypes...>>::value,
"MatchRules does not match Tuple");
std::vector<size_t> mappings;
util::abstract_type_list::const_iterator begin = t.types().begin();
util::abstract_type_list::const_iterator end = t.types().end();
if (detail::matcher<MatchRules...>::match(begin, end, &mappings))
{
return { t.vals(), std::move(mappings) };
}
throw std::runtime_error("matcher did not return a valid mapping");
}
template<typename... MatchRules>
typename tuple_view_type_from_type_list<typename util::filter_type_list<any_type, util::type_list<MatchRules...>>::type>::type
get_view(const any_tuple& ut)
{
std::vector<size_t> mappings;
if (match<MatchRules...>(ut, mappings))
{
return { ut.vals(), std::move(mappings) };
}
// todo: throw nicer exception
throw std::runtime_error("doesn't match");
}
} // namespace cppa
#endif // GET_VIEW_HPP
#ifndef GROUP_HPP #ifndef GROUP_HPP
#define GROUP_HPP #define GROUP_HPP
#include <string>
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
...@@ -17,10 +19,9 @@ class group : public channel ...@@ -17,10 +19,9 @@ class group : public channel
class subscription; class subscription;
friend class group::subscription; friend class subscription;
// NOT thread safe class subscription
class subscription : public ref_counted
{ {
channel_ptr m_self; channel_ptr m_self;
...@@ -33,12 +34,27 @@ class group : public channel ...@@ -33,12 +34,27 @@ class group : public channel
public: public:
subscription(const channel_ptr& s, const intrusive_ptr<group>& g); subscription(const channel_ptr& s, const intrusive_ptr<group>& g);
subscription(subscription&& other);
~subscription();
virtual ~subscription(); };
class module
{
public:
virtual const std::string& name() = 0;
virtual intrusive_ptr<group> get(const std::string& group_name) = 0;
}; };
virtual intrusive_ptr<subscription> subscribe(const channel_ptr& who) = 0; virtual subscription subscribe(const channel_ptr& who) = 0;
static intrusive_ptr<group> get(const std::string& module_name,
const std::string& group_name);
static void add_module(module*);
}; };
......
...@@ -25,7 +25,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>, ...@@ -25,7 +25,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>,
public: public:
intrusive_ptr() : m_ptr(0) { } intrusive_ptr() : m_ptr(nullptr) { }
intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); } intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); }
...@@ -34,7 +34,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>, ...@@ -34,7 +34,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>,
set_ptr(other.m_ptr); set_ptr(other.m_ptr);
} }
intrusive_ptr(intrusive_ptr&& other) : m_ptr(0) intrusive_ptr(intrusive_ptr&& other) : m_ptr(nullptr)
{ {
swap(other); swap(other);
} }
...@@ -48,7 +48,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>, ...@@ -48,7 +48,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T*>,
} }
template<typename Y> template<typename Y>
intrusive_ptr(intrusive_ptr<Y>&& other) : m_ptr(0) intrusive_ptr(intrusive_ptr<Y>&& other) : m_ptr(nullptr)
{ {
swap(other); swap(other);
} }
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
#include <type_traits> #include <type_traits>
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp" #include "cppa/tuple_view.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/type_at.hpp" #include "cppa/util/type_at.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<std::size_t N, typename F, typename Tuple, template<size_t N, typename F, typename Tuple,
typename ArgTypeList, typename... Args> typename ArgTypeList, typename... Args>
struct invoke_helper struct invoke_helper
{ {
...@@ -31,7 +31,7 @@ struct invoke_helper ...@@ -31,7 +31,7 @@ struct invoke_helper
} }
}; };
template<std::size_t N, typename F, typename Tuple, typename... Args> template<size_t N, typename F, typename Tuple, typename... Args>
struct invoke_helper<N, F, Tuple, util::type_list<>, Args...> struct invoke_helper<N, F, Tuple, util::type_list<>, Args...>
{ {
inline static void _(F& f, const Tuple&, const Args&... args) inline static void _(F& f, const Tuple&, const Args&... args)
...@@ -46,7 +46,7 @@ struct invoke_impl ...@@ -46,7 +46,7 @@ struct invoke_impl
typedef typename util::callable_trait<F>::arg_types arg_types; typedef typename util::callable_trait<F>::arg_types arg_types;
static const std::size_t tuple_size = Tuple::type_list_size - 1; static const size_t tuple_size = Tuple::type_list_size - 1;
inline static void _(F& f, const Tuple& t) inline static void _(F& f, const Tuple& t)
{ {
...@@ -62,7 +62,7 @@ struct invoke_impl<false, Tuple, F> ...@@ -62,7 +62,7 @@ struct invoke_impl<false, Tuple, F>
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 std::size_t tuple_size = Tuple::type_list_size - 1; static const size_t tuple_size = Tuple::type_list_size - 1;
inline static void _(F& f, const Tuple& t) inline static void _(F& f, const Tuple& t)
{ {
......
...@@ -36,7 +36,7 @@ struct invoke_rules ...@@ -36,7 +36,7 @@ struct invoke_rules
if (arg) m_list.push_back(arg); if (arg) m_list.push_back(arg);
} }
bool operator()(const untyped_tuple& t) const bool operator()(const any_tuple& t) const
{ {
for (auto i = m_list.begin(); i != m_list.end(); ++i) for (auto i = m_list.begin(); i != m_list.end(); ++i)
{ {
...@@ -45,7 +45,7 @@ struct invoke_rules ...@@ -45,7 +45,7 @@ struct invoke_rules
return false; return false;
} }
intrusive_ptr<detail::intermediate> get_intermediate(const untyped_tuple& t) const intrusive_ptr<detail::intermediate> get_intermediate(const any_tuple& t) const
{ {
detail::intermediate* result; detail::intermediate* result;
for (auto i = m_list.begin(); i != m_list.end(); ++i) for (auto i = m_list.begin(); i != m_list.end(); ++i)
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include <stdexcept> #include <stdexcept>
#include "cppa/any_type.hpp" #include "cppa/any_type.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp" #include "cppa/tuple_view.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/compare_tuples.hpp" #include "cppa/util/compare_tuples.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
namespace cppa { namespace cppa {
template<typename... MatchRules> template<typename... MatchRules>
bool match(const untyped_tuple& what) bool match(const any_tuple& what)
{ {
util::abstract_type_list::const_iterator begin = what.types().begin(); util::abstract_type_list::const_iterator begin = what.types().begin();
util::abstract_type_list::const_iterator end = what.types().end(); util::abstract_type_list::const_iterator end = what.types().end();
...@@ -27,7 +27,7 @@ bool match(const untyped_tuple& what) ...@@ -27,7 +27,7 @@ bool match(const untyped_tuple& what)
} }
template<typename... MatchRules> template<typename... MatchRules>
bool match(const untyped_tuple& what, std::vector<std::size_t>& mappings) bool match(const any_tuple& what, std::vector<size_t>& mappings)
{ {
util::abstract_type_list::const_iterator begin = what.types().begin(); util::abstract_type_list::const_iterator begin = what.types().begin();
util::abstract_type_list::const_iterator end = what.types().end(); util::abstract_type_list::const_iterator end = what.types().end();
...@@ -35,8 +35,8 @@ bool match(const untyped_tuple& what, std::vector<std::size_t>& mappings) ...@@ -35,8 +35,8 @@ bool match(const untyped_tuple& what, std::vector<std::size_t>& mappings)
} }
template<typename... MatchRules, class ValuesTuple> template<typename... MatchRules, class ValuesTuple>
bool match(const untyped_tuple& what, const ValuesTuple& vals, bool match(const any_tuple& what, const ValuesTuple& vals,
std::vector<std::size_t>& mappings) std::vector<size_t>& mappings)
{ {
typedef util::type_list<MatchRules...> rules_list; typedef util::type_list<MatchRules...> rules_list;
typedef typename util::filter_type_list<any_type, rules_list>::type typedef typename util::filter_type_list<any_type, rules_list>::type
...@@ -49,7 +49,7 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals, ...@@ -49,7 +49,7 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals,
"given values are not comparable to matched types"); "given values are not comparable to matched types");
if (match<MatchRules...>(what, mappings)) if (match<MatchRules...>(what, mappings))
{ {
std::vector<std::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 compare_first_elements(view, vals);
} }
...@@ -57,42 +57,12 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals, ...@@ -57,42 +57,12 @@ bool match(const untyped_tuple& what, const ValuesTuple& vals,
} }
template<typename... MatchRules, class ValuesTuple> template<typename... MatchRules, class ValuesTuple>
bool match(const untyped_tuple& what, const ValuesTuple& vals) bool match(const any_tuple& what, const ValuesTuple& vals)
{ {
std::vector<std::size_t> mappings; std::vector<size_t> mappings;
return match<MatchRules...>(what, vals, mappings); return match<MatchRules...>(what, vals, mappings);
} }
template<typename... MatchRules, template <typename...> class Tuple, typename... TupleTypes>
typename tuple_view_type_from_type_list<typename util::filter_type_list<any_type, util::type_list<MatchRules...>>::type>::type
get_view(const Tuple<TupleTypes...>& t)
{
static_assert(util::a_matches_b<util::type_list<MatchRules...>,
util::type_list<TupleTypes...>>::value,
"MatchRules does not match Tuple");
std::vector<std::size_t> mappings;
util::abstract_type_list::const_iterator begin = t.types().begin();
util::abstract_type_list::const_iterator end = t.types().end();
if (detail::matcher<MatchRules...>::match(begin, end, &mappings))
{
return { t.vals(), std::move(mappings) };
}
throw std::runtime_error("matcher did not return a valid mapping");
}
template<typename... MatchRules>
typename tuple_view_type_from_type_list<typename util::filter_type_list<any_type, util::type_list<MatchRules...>>::type>::type
get_view(const untyped_tuple& t)
{
std::vector<std::size_t> mappings;
if (match<MatchRules...>(t, mappings))
{
return { t.vals(), std::move(mappings) };
}
// todo: throw nicer exception
throw std::runtime_error("doesn't match");
}
} // namespace cppa } // namespace cppa
#endif // MATCH_HPP #endif // MATCH_HPP
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/detail/channel.hpp" #include "cppa/detail/channel.hpp"
...@@ -14,32 +15,29 @@ namespace cppa { ...@@ -14,32 +15,29 @@ namespace cppa {
class message class message
{ {
struct content : ref_counted struct msg_content : ref_counted
{ {
const actor_ptr sender; const actor_ptr sender;
const channel_ptr receiver; const channel_ptr receiver;
const untyped_tuple data; const any_tuple data;
inline content(const actor_ptr& s, inline msg_content(const actor_ptr& s,
const channel_ptr& r, const channel_ptr& r,
const untyped_tuple& ut) const any_tuple& ut)
: ref_counted(), sender(s), receiver(r), data(ut) : ref_counted(), sender(s), receiver(r), data(ut)
{ {
} }
}; };
intrusive_ptr<content> m_content; intrusive_ptr<msg_content> m_content;
public: public:
template<typename... Args> template<typename... Args>
message(const actor_ptr& from, const channel_ptr& to, const Args&... args) message(const actor_ptr& from, const channel_ptr& to, const Args&... args);
: m_content(new content(from, to, tuple<Args...>(args...)))
{
}
message(const actor_ptr& from, message(const actor_ptr& from,
const channel_ptr& to, const channel_ptr& to,
const untyped_tuple& ut); const any_tuple& ut);
message(); message();
...@@ -61,13 +59,19 @@ class message ...@@ -61,13 +59,19 @@ class message
return m_content->receiver; return m_content->receiver;
} }
inline const untyped_tuple& data() const inline const any_tuple& content() const
{ {
return m_content->data; return m_content->data;
} }
}; };
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...))))
{
}
bool operator==(const message& lhs, const message& rhs); bool operator==(const message& lhs, const message& rhs);
inline bool operator!=(const message& lhs, const message& rhs) inline bool operator!=(const message& lhs, const message& rhs)
......
...@@ -13,9 +13,9 @@ namespace cppa { ...@@ -13,9 +13,9 @@ namespace cppa {
// forward declarations // forward declarations
class object; class object;
class uniform_type_info; class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&);
namespace detail { template<typename T> struct object_caster; } namespace detail { template<typename T> struct object_caster; }
bool operator==(const uniform_type_info& lhs, const std::type_info& rhs); bool operator==(const uniform_type_info& lhs, const std::type_info& rhs);
/** /**
* @brief foobar. * @brief foobar.
*/ */
...@@ -34,6 +34,9 @@ class object ...@@ -34,6 +34,9 @@ class object
object copy() const; object copy() const;
static void* new_instance(const uniform_type_info* type,
const void* from);
public: public:
/** /**
...@@ -44,21 +47,26 @@ public: ...@@ -44,21 +47,26 @@ public:
object(void* val, const uniform_type_info* utinfo); object(void* val, const uniform_type_info* utinfo);
/** /**
* @brief Create a void object. * @brief Create an empty object.
* @post {@code type() == uniform_typeid<util::void_type>()} * @post {@code empty() && type() == *uniform_typeid<util::void_type>()}
*/ */
object(); object();
template<typename T>
explicit object(const T& what);
~object(); ~object();
/** /**
* @brief Create an object and move type and value from @p other to this. * @brief Creates an object and moves type and value
* from @p other to @c this.
* @post {@code other.type() == uniform_typeid<util::void_type>()} * @post {@code other.type() == uniform_typeid<util::void_type>()}
*/ */
object(object&& other); object(object&& other);
/** /**
* @brief Create a copy of @p other. * @brief Creates a copy of @p other.
* @post {@code type() == other.type() && equal_to(other)}
*/ */
object(const object& other); object(const object& other);
...@@ -70,17 +78,34 @@ public: ...@@ -70,17 +78,34 @@ public:
object& operator=(const object& other); object& operator=(const object& other);
bool equal(const object& other) const; bool equal_to(const object& other) const;
const uniform_type_info& type() const; const uniform_type_info& type() const;
std::string to_string() const; std::string to_string() const;
const void* value() const;
void* mutable_value();
bool empty() const;
}; };
template<typename T>
object::object(const T& what)
{
m_type = uniform_typeid(typeid(T));
if (!m_type)
{
throw std::logic_error("unknown/unannounced type");
}
m_value = new_instance(m_type, &what);
}
inline bool operator==(const object& lhs, const object& rhs) inline bool operator==(const object& lhs, const object& rhs)
{ {
return lhs.equal(rhs); return lhs.equal_to(rhs);
} }
inline bool operator!=(const object& lhs, const object& rhs) inline bool operator!=(const object& lhs, const object& rhs)
...@@ -98,21 +123,6 @@ inline void assert_type(const object& obj, const std::type_info& tinfo) ...@@ -98,21 +123,6 @@ inline void assert_type(const object& obj, const std::type_info& tinfo)
} }
} }
template<typename T>
struct object_caster
{
static T& _(object& obj)
{
assert_type(obj, typeid(T));
return *reinterpret_cast<T*>(obj.m_value);
}
static const T& _(const object& obj)
{
assert_type(obj, typeid(T));
return *reinterpret_cast<const T*>(obj.m_value);
}
};
} // namespace detail } // namespace detail
template<typename T> template<typename T>
...@@ -121,7 +131,8 @@ T& get_ref(object& obj) ...@@ -121,7 +131,8 @@ T& get_ref(object& obj)
static_assert(util::disjunction<std::is_pointer<T>, static_assert(util::disjunction<std::is_pointer<T>,
std::is_reference<T>>::value == false, std::is_reference<T>>::value == false,
"T is a reference or a pointer type."); "T is a reference or a pointer type.");
return detail::object_caster<T>::_(obj); detail::assert_type(obj, typeid(T));
return *reinterpret_cast<T*>(obj.mutable_value());
} }
template<typename T> template<typename T>
...@@ -130,7 +141,8 @@ const T& get(const object& obj) ...@@ -130,7 +141,8 @@ const T& get(const object& obj)
static_assert(util::disjunction<std::is_pointer<T>, static_assert(util::disjunction<std::is_pointer<T>,
std::is_reference<T>>::value == false, std::is_reference<T>>::value == false,
"T is a reference a pointer type."); "T is a reference a pointer type.");
return detail::object_caster<T>::_(obj); detail::assert_type(obj, typeid(T));
return *reinterpret_cast<const T*>(obj.value());
} }
} // namespace cppa } // namespace cppa
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
#define ON_HPP #define ON_HPP
#include "cppa/match.hpp" #include "cppa/match.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/eval_first_n.hpp" #include "cppa/util/eval_first_n.hpp"
#include "cppa/util/filter_type_list.hpp" #include "cppa/util/filter_type_list.hpp"
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
// irb_helper is not thread safe // irb_helper is not thread safe
struct irb_helper : ref_counted_impl<std::size_t> struct irb_helper : ref_counted_impl<size_t>
{ {
virtual ~irb_helper() { } virtual ~irb_helper() { }
virtual bool value_cmp(const untyped_tuple&, virtual bool value_cmp(const any_tuple&,
std::vector<std::size_t>&) const = 0; std::vector<size_t>&) const = 0;
}; };
template<typename... Types> template<typename... Types>
...@@ -56,8 +56,8 @@ struct invoke_rule_builder ...@@ -56,8 +56,8 @@ struct invoke_rule_builder
{ {
} }
virtual bool value_cmp(const untyped_tuple& t, virtual bool value_cmp(const any_tuple& t,
std::vector<std::size_t>& v) const std::vector<size_t>& v) const
{ {
return match<Types...>(t, m_values, v); return match<Types...>(t, m_values, v);
} }
...@@ -85,9 +85,9 @@ struct invoke_rule_builder ...@@ -85,9 +85,9 @@ struct invoke_rule_builder
}; };
if (!m_helper) if (!m_helper)
{ {
auto inv = [f](const untyped_tuple& t) -> bool auto inv = [f](const any_tuple& t) -> bool
{ {
std::vector<std::size_t> mappings; std::vector<size_t> mappings;
if (match<Types...>(t, mappings)) if (match<Types...>(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
...@@ -96,9 +96,9 @@ struct invoke_rule_builder ...@@ -96,9 +96,9 @@ struct invoke_rule_builder
} }
return false; return false;
}; };
auto gt = [sub_inv](const untyped_tuple& t) -> detail::intermediate* auto gt = [sub_inv](const any_tuple& t) -> detail::intermediate*
{ {
std::vector<std::size_t> mappings; std::vector<size_t> mappings;
if (match<Types...>(t, mappings)) if (match<Types...>(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
...@@ -110,9 +110,9 @@ struct invoke_rule_builder ...@@ -110,9 +110,9 @@ struct invoke_rule_builder
} }
else else
{ {
auto inv = [f, m_helper](const untyped_tuple& t) -> bool auto inv = [f, m_helper](const any_tuple& t) -> bool
{ {
std::vector<std::size_t> mappings; std::vector<size_t> mappings;
if (m_helper->value_cmp(t, mappings)) if (m_helper->value_cmp(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
...@@ -121,9 +121,9 @@ struct invoke_rule_builder ...@@ -121,9 +121,9 @@ struct invoke_rule_builder
} }
return false; return false;
}; };
auto gt = [sub_inv, m_helper](const untyped_tuple& t) -> detail::intermediate* auto gt = [sub_inv, m_helper](const any_tuple& t) -> detail::intermediate*
{ {
std::vector<std::size_t> mappings; std::vector<size_t> mappings;
if (m_helper->value_cmp(t, mappings)) if (m_helper->value_cmp(t, mappings))
{ {
tuple_view_type tv(t.vals(), std::move(mappings)); tuple_view_type tv(t.vals(), std::move(mappings));
......
...@@ -12,7 +12,7 @@ namespace cppa { ...@@ -12,7 +12,7 @@ namespace cppa {
* @brief (Thread safe) base class for reference counted objects * @brief (Thread safe) base class for reference counted objects
* with an atomic reference count. * with an atomic reference count.
*/ */
typedef detail::ref_counted_impl< std::atomic<std::size_t> > ref_counted; typedef detail::ref_counted_impl< std::atomic<size_t> > ref_counted;
} // namespace cppa } // namespace cppa
......
...@@ -63,13 +63,16 @@ struct chars_to_string ...@@ -63,13 +63,16 @@ struct chars_to_string
namespace cppa { namespace cppa {
// forward declaration // forward declaration
class untyped_tuple; class any_tuple;
/**
* @brief Describes a fixed-length tuple.
*/
template<typename... ElementTypes> template<typename... ElementTypes>
class tuple class tuple
{ {
friend class untyped_tuple; friend class any_tuple;
public: public:
...@@ -110,29 +113,29 @@ class tuple ...@@ -110,29 +113,29 @@ class tuple
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size; 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...)) { }
template<std::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
{ {
return detail::tdata_get<N>(m_vals->data()); return detail::tdata_get<N>(m_vals->data());
} }
template<std::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()
{ {
return detail::tdata_get_ref<N>(m_vals->data_ref()); return detail::tdata_get_ref<N>(m_vals->data_ref());
} }
std::size_t size() const { return m_vals->size(); } size_t size() const { return m_vals->size(); }
const void* at(std::size_t p) const { return m_vals->at(p); } const void* at(size_t p) const { return m_vals->at(p); }
const uniform_type_info* utype_at(std::size_t p) const { return m_vals->utype_at(p); } const uniform_type_info* utype_at(size_t p) const { return m_vals->type_at(p); }
const util::abstract_type_list& types() const { return m_vals->types(); } const util::abstract_type_list& types() const { return m_vals->types(); }
...@@ -148,14 +151,14 @@ class tuple ...@@ -148,14 +151,14 @@ class tuple
}; };
template<std::size_t N, typename... Types> 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<Types...>& t) get(const tuple<Types...>& t)
{ {
return t.get<N>(); return t.get<N>();
} }
template<std::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<Types...>& t) get_ref(tuple<Types...>& t)
{ {
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <vector> #include <vector>
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/a_matches_b.hpp" #include "cppa/util/a_matches_b.hpp"
...@@ -14,6 +13,14 @@ ...@@ -14,6 +13,14 @@
namespace cppa { 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.
*/
template<typename... ElementTypes> template<typename... ElementTypes>
class tuple_view class tuple_view
{ {
...@@ -27,38 +34,42 @@ class tuple_view ...@@ -27,38 +34,42 @@ class tuple_view
typedef cow_ptr<detail::abstract_tuple> vals_t; typedef cow_ptr<detail::abstract_tuple> vals_t;
tuple_view(const vals_t& vals, std::vector<std::size_t>&& mappings) tuple_view(const vals_t& vals, std::vector<size_t>&& mappings)
: m_vals(new detail::decorated_tuple<ElementTypes...>(vals, mappings)) : m_vals(new detail::decorated_tuple<ElementTypes...>(vals, mappings))
{ {
} }
tuple_view(const tuple_view&) = default; tuple_view(const tuple_view&) = default;
tuple_view(tuple_view&& other) : m_vals(std::move(other.m_vals))
{
}
const vals_t& vals() const { return m_vals; } const vals_t& vals() const { return m_vals; }
typedef typename element_types::head_type head_type; typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type; typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size; 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<std::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 < element_types::type_list_size, "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<std::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 < element_types::type_list_size, "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));
} }
std::size_t size() const { return m_vals->size(); } size_t size() const { return m_vals->size(); }
private: private:
...@@ -67,14 +78,14 @@ class tuple_view ...@@ -67,14 +78,14 @@ class tuple_view
}; };
template<std::size_t N, typename... Types> 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>(); return t.get<N>();
} }
template<std::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)
{ {
......
...@@ -146,13 +146,18 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info> ...@@ -146,13 +146,18 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
*/ */
object deserialize(deserializer* source) const; object deserialize(deserializer* source) const;
protected:
/** /**
* @brief Compares two instances of this type. * @brief Compares two instances of this type.
*/ */
virtual bool equal(const void* instance1, const void* instance2) const = 0; virtual bool equal(const void* instance1, const void* instance2) const = 0;
protected:
/**
* @brief Cast @p instance to the native type and delete it.
*/
virtual void delete_instance(void* instance) const = 0;
/** /**
* @brief Creates an instance of this type, either as a copy of * @brief Creates an instance of this type, either as a copy of
* @p instance or initialized with the default constructor * @p instance or initialized with the default constructor
...@@ -160,11 +165,6 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info> ...@@ -160,11 +165,6 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
*/ */
virtual void* new_instance(const void* instance = nullptr) const = 0; virtual void* new_instance(const void* instance = nullptr) const = 0;
/**
* @brief Cast @p instance to the native type and delete it.
*/
virtual void delete_instance(void* instance) const = 0;
public: public:
/** /**
......
#ifndef UNTYPED_TUPLE_HPP
#define UNTYPED_TUPLE_HPP
#include "cppa/cow_ptr.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa {
class untyped_tuple
{
cow_ptr<detail::abstract_tuple> m_vals;
public:
untyped_tuple();
template<typename Tuple>
untyped_tuple(const Tuple& t) : m_vals(t.vals()) { }
inline untyped_tuple(const cow_ptr<detail::abstract_tuple>& vals)
: m_vals(vals)
{
}
std::size_t size() const { return m_vals->size(); }
void* mutable_at(size_t p) { return m_vals->mutable_at(p); }
const void* at(size_t p) const { return m_vals->at(p); }
const uniform_type_info* utype_at(std::size_t p) const { return m_vals->utype_at(p); }
const util::abstract_type_list& types() const { return m_vals->types(); }
const cow_ptr<detail::abstract_tuple>& vals() const
{
return m_vals;
}
};
} // namespace cppa
#endif // UNTYPED_TUPLE_HPP
#ifndef ABSTRACT_TYPE_LIST_HPP #ifndef ABSTRACT_TYPE_LIST_HPP
#define ABSTRACT_TYPE_LIST_HPP #define ABSTRACT_TYPE_LIST_HPP
#include <iterator> #include <memory>
// forward declaration // forward declaration
namespace cppa { class uniform_type_info; } namespace cppa { class uniform_type_info; }
...@@ -11,67 +11,101 @@ namespace cppa { namespace util { ...@@ -11,67 +11,101 @@ namespace cppa { namespace util {
struct abstract_type_list struct abstract_type_list
{ {
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, class abstract_iterator
const uniform_type_info*>
{ {
const uniform_type_info* const* p; public:
virtual ~abstract_iterator();
/**
* @brief
* @return @c false if the iterator is at the end; otherwise @c true.
*/
virtual bool next() = 0;
virtual const uniform_type_info& get() const = 0;
virtual abstract_iterator* copy() const = 0;
};
class const_iterator
{
abstract_iterator* m_iter;
public: public:
inline const_iterator(const uniform_type_info* const* x = 0) : p(x) { } const_iterator(abstract_iterator* x = 0) : m_iter(x) { }
const_iterator(const const_iterator&) = default; const_iterator(const const_iterator& other)
: m_iter((other.m_iter) ? other.m_iter->copy() : nullptr)
{
}
const_iterator& operator=(const const_iterator&) = default; const_iterator(const_iterator&& other) : m_iter(other.m_iter)
{
other.m_iter = nullptr;
}
inline bool operator==(const const_iterator& other) const const_iterator& operator=(const const_iterator& other)
{ {
return p == other.p; delete m_iter;
m_iter = (other.m_iter) ? other.m_iter->copy() : nullptr;
return *this;
} }
inline bool operator!=(const const_iterator& other) const const_iterator& operator=(const_iterator&& other)
{ {
return p != other.p; delete m_iter;
m_iter = other.m_iter;
other.m_iter = nullptr;
return *this;
} }
inline const uniform_type_info& operator*() const ~const_iterator()
{ {
return *(*p); delete m_iter;
} }
inline const uniform_type_info* operator->() const bool operator==(const const_iterator& other) const
{ {
return *p; return m_iter == other.m_iter;
} }
inline const_iterator& operator++() inline bool operator!=(const const_iterator& other) const
{ {
++p; return !(*this == other);
return *this;
} }
const_iterator operator++(int); const uniform_type_info& operator*() const
{
return m_iter->get();
}
inline const_iterator& operator--() const uniform_type_info* operator->() const
{ {
--p; return &(m_iter->get());
return *this;
} }
const_iterator operator--(int); const_iterator& operator++()
{
if (!m_iter->next())
{
delete m_iter;
m_iter = nullptr;
}
return *this;
}
}; };
virtual ~abstract_type_list(); virtual ~abstract_type_list();
virtual abstract_type_list* copy() const = 0;
virtual const_iterator begin() const = 0; virtual const_iterator begin() const = 0;
virtual const_iterator end() const = 0; virtual const_iterator end() const;
virtual const uniform_type_info* at(std::size_t pos) const = 0;
}; };
......
#ifndef UNIFORM_TYPE_INFO_BASE_HPP #ifndef ABSTRACT_UNIFORM_TYPE_INFO_HPP
#define UNIFORM_TYPE_INFO_BASE_HPP #define ABSTRACT_UNIFORM_TYPE_INFO_HPP
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
...@@ -11,7 +11,7 @@ namespace cppa { namespace util { ...@@ -11,7 +11,7 @@ namespace cppa { namespace util {
* except serialize() and deserialize(). * except serialize() and deserialize().
*/ */
template<typename T> template<typename T>
class uniform_type_info_base : public uniform_type_info class abstract_uniform_type_info : public uniform_type_info
{ {
inline static const T& deref(const void* ptr) inline static const T& deref(const void* ptr)
...@@ -26,7 +26,7 @@ class uniform_type_info_base : public uniform_type_info ...@@ -26,7 +26,7 @@ class uniform_type_info_base : public uniform_type_info
protected: protected:
uniform_type_info_base(const std::string& uname abstract_uniform_type_info(const std::string& uname
= detail::to_uniform_name(typeid(T))) = detail::to_uniform_name(typeid(T)))
: uniform_type_info(uname) : uniform_type_info(uname)
{ {
...@@ -58,4 +58,4 @@ class uniform_type_info_base : public uniform_type_info ...@@ -58,4 +58,4 @@ class uniform_type_info_base : public uniform_type_info
} } } }
#endif // UNIFORM_TYPE_INFO_BASE_HPP #endif // ABSTRACT_UNIFORM_TYPE_INFO_HPP
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<std::size_t N, template<typename...> class Tuple, typename... Types> template<size_t N, template<typename...> class Tuple, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type& const typename util::type_at<N, util::type_list<Types...>>::type&
do_get(const Tuple<Types...>& t) do_get(const Tuple<Types...>& t)
{ {
return ::cppa::get<N, Types...>(t); return ::cppa::get<N, Types...>(t);
} }
template<std::size_t N, typename LhsTuple, typename RhsTuple> template<size_t N, typename LhsTuple, typename RhsTuple>
struct cmp_helper struct cmp_helper
{ {
inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs) inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs)
...@@ -35,22 +35,22 @@ struct cmp_helper<0, LhsTuple, RhsTuple> ...@@ -35,22 +35,22 @@ struct cmp_helper<0, LhsTuple, RhsTuple>
} }
}; };
template<bool ALessB, std::size_t A, std::size_t B> template<bool ALessB, size_t A, size_t B>
struct min_impl struct min_impl
{ {
static const std::size_t value = A; static const size_t value = A;
}; };
template<std::size_t A, std::size_t B> template<size_t A, size_t B>
struct min_impl<false, A, B> struct min_impl<false, A, B>
{ {
static const std::size_t value = B; static const size_t value = B;
}; };
template<std::size_t A, std::size_t B> template<size_t A, size_t B>
struct min_ struct min_
{ {
static const std::size_t value = min_impl<(A < B), A, B>::value; static const size_t value = min_impl<(A < B), A, B>::value;
}; };
} } // namespace cppa::detail } } // namespace cppa::detail
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
namespace cppa { namespace util { namespace cppa { namespace util {
template <std::size_t N, template <size_t N,
class ListA, class ListB, class ListA, class ListB,
template <typename, typename> class What> template <typename, typename> class What>
struct eval_first_n; struct eval_first_n;
template <std::size_t N, typename... TypesA, typename... TypesB, template <size_t N, typename... TypesA, typename... TypesB,
template <typename, typename> class What> template <typename, typename> class What>
struct eval_first_n<N, type_list<TypesA...>, type_list<TypesB...>, What> struct eval_first_n<N, type_list<TypesA...>, type_list<TypesB...>, What>
{ {
......
...@@ -22,7 +22,7 @@ struct if_t<true, IfType, ElseType> ...@@ -22,7 +22,7 @@ struct if_t<true, IfType, ElseType>
typedef IfType type; typedef IfType type;
}; };
template<std::size_t N, typename List> template<size_t N, typename List>
struct n_ struct n_
{ {
...@@ -48,10 +48,10 @@ struct n_<0, List> ...@@ -48,10 +48,10 @@ struct n_<0, List>
namespace cppa { namespace util { namespace cppa { namespace util {
template<std::size_t N, typename List> template<size_t N, typename List>
struct first_n; struct first_n;
template<std::size_t N, typename... ListTypes> template<size_t N, typename... ListTypes>
struct first_n<N, util::type_list<ListTypes...>> struct first_n<N, util::type_list<ListTypes...>>
{ {
typedef typename detail::n_<N, util::type_list<ListTypes...>>::type type; typedef typename detail::n_<N, util::type_list<ListTypes...>>::type type;
......
#ifndef CPPA_UTIL_TYPE_AT_HPP #ifndef CPPA_UTIL_TYPE_AT_HPP
#define CPPA_UTIL_TYPE_AT_HPP #define CPPA_UTIL_TYPE_AT_HPP
// std::size_t // size_t
#include <cstddef> #include <cstddef>
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
template<std::size_t N, typename TypeList> template<size_t N, typename TypeList>
struct type_at struct type_at
{ {
typedef typename type_at<N-1, typename TypeList::tail_type>::type type; typedef typename type_at<N-1, typename TypeList::tail_type>::type type;
......
...@@ -17,6 +17,41 @@ const uniform_type_info* uniform_typeid(const std::type_info&); ...@@ -17,6 +17,41 @@ const uniform_type_info* uniform_typeid(const std::type_info&);
namespace cppa { namespace util { namespace cppa { namespace util {
class type_list_iterator : public abstract_type_list::abstract_iterator
{
public:
typedef const uniform_type_info* const* ptr_type;
type_list_iterator(ptr_type begin, ptr_type end) : m_pos(begin), m_end(end)
{
}
type_list_iterator(const type_list_iterator&) = default;
bool next()
{
return ++m_pos != m_end;
}
const uniform_type_info& get() const
{
return *(*m_pos);
}
abstract_type_list::abstract_iterator* copy() const
{
return new type_list_iterator(*this);
}
private:
const uniform_type_info* const* m_pos;
const uniform_type_info* const* m_end;
};
template<typename... Types> struct type_list; template<typename... Types> struct type_list;
template<> template<>
...@@ -24,7 +59,7 @@ struct type_list<> ...@@ -24,7 +59,7 @@ struct type_list<>
{ {
typedef void_type head_type; typedef void_type head_type;
typedef type_list<> tail_type; typedef type_list<> tail_type;
static const std::size_t type_list_size = 0; static const size_t type_list_size = 0;
}; };
template<typename Head, typename... Tail> template<typename Head, typename... Tail>
...@@ -35,7 +70,7 @@ struct type_list<Head, Tail...> : abstract_type_list ...@@ -35,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 std::size_t type_list_size = tail_type::type_list_size + 1; static const size_t type_list_size = tail_type::type_list_size + 1;
type_list() type_list()
{ {
...@@ -44,17 +79,12 @@ struct type_list<Head, Tail...> : abstract_type_list ...@@ -44,17 +79,12 @@ struct type_list<Head, Tail...> : abstract_type_list
virtual const_iterator begin() const virtual const_iterator begin() const
{ {
return m_arr; return new type_list_iterator(m_arr, m_arr + type_list_size);
}
virtual const_iterator end() const
{
return m_arr + type_list_size;
} }
virtual const uniform_type_info* at(std::size_t pos) const virtual const uniform_type_info& at(size_t pos) const
{ {
return m_arr[pos]; return *m_arr[pos];
} }
virtual type_list* copy() const virtual type_list* copy() const
......
#!/bin/bash
HEADERS=""
SOURCES=""
NLINE="\\n"
BSLASH="\\\\"
function append_hpp_from()
{
for i in "$1"/*.hpp ; do
HEADERS="$HEADERS ${BSLASH}${NLINE} $i"
done
}
function append_cpp_from()
{
for i in "$1/"*.cpp ; do
SOURCES="$SOURCES ${BSLASH}${NLINE} $i"
done
}
append_hpp_from "cppa"
append_hpp_from "cppa/detail"
append_hpp_from "cppa/util"
append_cpp_from "src"
echo "include Makefile.rules"
echo "INCLUDES = -I./"
echo
printf "%b\n" "HEADERS =$HEADERS"
echo
printf "%b\n" "SOURCES =$SOURCES"
echo
echo "OBJECTS = \$(SOURCES:.cpp=.o)"
echo
echo "LIB_NAME = libcppa.dylib"
echo
echo "%.o : %.cpp \$(HEADERS)"
printf "%b\n" "\t\$(CXX) \$(CXXFLAGS) \$(INCLUDES) -fPIC -c \$< -o \$@"
echo
echo "\$(LIB_NAME) : \$(OBJECTS) \$(HEADERS)"
printf "%b\n" "\t\$(CXX) \$(LIBS) -dynamiclib -o \$(LIB_NAME) \$(OBJECTS)"
echo
echo "all : \$(LIB_NAME) \$(OBJECTS)"
echo
echo "clean:"
printf "%b\n" "\trm -f \$(LIB_NAME) \$(OBJECTS)"
include Makefile.rules include Makefile.rules
INCLUDES = -I./ INCLUDES = -I./
#CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -O2 -I/opt/local/include/ -fPIC HEADERS = \
cppa/actor.hpp \
HEADERS = cppa/actor.hpp \ cppa/actor_behavior.hpp \
cppa/announce.hpp \
cppa/any_tuple.hpp \
cppa/any_type.hpp \ cppa/any_type.hpp \
cppa/binary_deserializer.hpp \ cppa/binary_deserializer.hpp \
cppa/binary_serializer.hpp \ cppa/binary_serializer.hpp \
...@@ -15,6 +16,7 @@ HEADERS = cppa/actor.hpp \ ...@@ -15,6 +16,7 @@ HEADERS = cppa/actor.hpp \
cppa/cppa.hpp \ cppa/cppa.hpp \
cppa/deserializer.hpp \ cppa/deserializer.hpp \
cppa/get.hpp \ cppa/get.hpp \
cppa/get_view.hpp \
cppa/group.hpp \ cppa/group.hpp \
cppa/intrusive_ptr.hpp \ cppa/intrusive_ptr.hpp \
cppa/invoke.hpp \ cppa/invoke.hpp \
...@@ -33,31 +35,58 @@ HEADERS = cppa/actor.hpp \ ...@@ -33,31 +35,58 @@ HEADERS = cppa/actor.hpp \
cppa/tuple.hpp \ cppa/tuple.hpp \
cppa/tuple_view.hpp \ cppa/tuple_view.hpp \
cppa/uniform_type_info.hpp \ cppa/uniform_type_info.hpp \
cppa/untyped_tuple.hpp \
cppa/util.hpp \ cppa/util.hpp \
cppa/detail/abstract_tuple.hpp \ cppa/detail/abstract_tuple.hpp \
cppa/detail/blocking_message_queue.hpp \ cppa/detail/blocking_message_queue.hpp \
cppa/detail/channel.hpp \
cppa/detail/converted_thread_context.hpp \ cppa/detail/converted_thread_context.hpp \
cppa/detail/cpp0x_thread_wrapper.hpp \
cppa/detail/decorated_tuple.hpp \ cppa/detail/decorated_tuple.hpp \
cppa/detail/channel.hpp \ cppa/detail/default_uniform_type_info_impl.hpp \
cppa/detail/demangle.hpp \
cppa/detail/intermediate.hpp \ cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \ cppa/detail/invokable.hpp \
cppa/detail/list_member.hpp \
cppa/detail/map_member.hpp \
cppa/detail/matcher.hpp \ cppa/detail/matcher.hpp \
cppa/detail/mock_scheduler.hpp \
cppa/detail/object_array.hpp \
cppa/detail/object_impl.hpp \
cppa/detail/pair_member.hpp \
cppa/detail/primitive_member.hpp \
cppa/detail/ptype_to_type.hpp \
cppa/detail/ref_counted_impl.hpp \ cppa/detail/ref_counted_impl.hpp \
cppa/detail/serialize_tuple.hpp \
cppa/detail/swap_bytes.hpp \
cppa/detail/tdata.hpp \ cppa/detail/tdata.hpp \
cppa/detail/to_uniform_name.hpp \
cppa/detail/tuple_vals.hpp \ cppa/detail/tuple_vals.hpp \
cppa/detail/type_to_ptype.hpp \
cppa/util/a_matches_b.hpp \ cppa/util/a_matches_b.hpp \
cppa/util/abstract_type_list.hpp \
cppa/util/abstract_uniform_type_info.hpp \
cppa/util/apply.hpp \
cppa/util/callable_trait.hpp \ cppa/util/callable_trait.hpp \
cppa/util/comparable.hpp \
cppa/util/compare_tuples.hpp \ cppa/util/compare_tuples.hpp \
cppa/util/concat_type_lists.hpp \ cppa/util/concat_type_lists.hpp \
cppa/util/conjunction.hpp \ cppa/util/conjunction.hpp \
cppa/util/detach.hpp \ cppa/util/detach.hpp \
cppa/util/disable_if.hpp \
cppa/util/disjunction.hpp \ cppa/util/disjunction.hpp \
cppa/util/enable_if.hpp \
cppa/util/eval_first_n.hpp \
cppa/util/eval_type_list.hpp \
cppa/util/eval_type_lists.hpp \ cppa/util/eval_type_lists.hpp \
cppa/util/filter_type_list.hpp \ cppa/util/filter_type_list.hpp \
cppa/util/first_n.hpp \
cppa/util/has_copy_member_fun.hpp \ cppa/util/has_copy_member_fun.hpp \
cppa/util/if_else_type.hpp \
cppa/util/is_comparable.hpp \ cppa/util/is_comparable.hpp \
cppa/util/is_copyable.hpp \ cppa/util/is_copyable.hpp \
cppa/util/is_forward_iterator.hpp \
cppa/util/is_iterable.hpp \
cppa/util/is_legal_tuple_type.hpp \
cppa/util/is_one_of.hpp \ cppa/util/is_one_of.hpp \
cppa/util/is_primitive.hpp \ cppa/util/is_primitive.hpp \
cppa/util/pt_token.hpp \ cppa/util/pt_token.hpp \
...@@ -65,17 +94,22 @@ HEADERS = cppa/actor.hpp \ ...@@ -65,17 +94,22 @@ HEADERS = cppa/actor.hpp \
cppa/util/replace_type.hpp \ cppa/util/replace_type.hpp \
cppa/util/reverse_type_list.hpp \ cppa/util/reverse_type_list.hpp \
cppa/util/rm_ref.hpp \ cppa/util/rm_ref.hpp \
cppa/util/shared_lock_guard.hpp \
cppa/util/shared_spinlock.hpp \ cppa/util/shared_spinlock.hpp \
cppa/util/single_reader_queue.hpp \ cppa/util/single_reader_queue.hpp \
cppa/util/singly_linked_list.hpp \
cppa/util/type_at.hpp \ cppa/util/type_at.hpp \
cppa/util/type_list.hpp \ cppa/util/type_list.hpp \
cppa/util/type_list_apply.hpp \ cppa/util/type_list_apply.hpp \
cppa/util/type_list_pop_back.hpp \ cppa/util/type_list_pop_back.hpp \
cppa/util/void_type.hpp cppa/util/void_type.hpp \
cppa/util/wrapped_type.hpp
SOURCES = src/abstract_type_list.cpp \ SOURCES = \
src/abstract_type_list.cpp \
src/actor.cpp \ src/actor.cpp \
src/actor_behavior.cpp \ src/actor_behavior.cpp \
src/any_tuple.cpp \
src/binary_deserializer.cpp \ src/binary_deserializer.cpp \
src/binary_serializer.cpp \ src/binary_serializer.cpp \
src/blocking_message_queue.cpp \ src/blocking_message_queue.cpp \
...@@ -88,13 +122,13 @@ SOURCES = src/abstract_type_list.cpp \ ...@@ -88,13 +122,13 @@ SOURCES = src/abstract_type_list.cpp \
src/message.cpp \ src/message.cpp \
src/mock_scheduler.cpp \ src/mock_scheduler.cpp \
src/object.cpp \ src/object.cpp \
src/object_array.cpp \
src/primitive_variant.cpp \ src/primitive_variant.cpp \
src/scheduler.cpp \ src/scheduler.cpp \
src/serializer.cpp \ src/serializer.cpp \
src/shared_spinlock.cpp \ src/shared_spinlock.cpp \
src/to_uniform_name.cpp \ src/to_uniform_name.cpp \
src/uniform_type_info.cpp \ src/uniform_type_info.cpp
src/untyped_tuple.cpp
OBJECTS = $(SOURCES:.cpp=.o) OBJECTS = $(SOURCES:.cpp=.o)
...@@ -110,4 +144,3 @@ all : $(LIB_NAME) $(OBJECTS) ...@@ -110,4 +144,3 @@ all : $(LIB_NAME) $(OBJECTS)
clean: clean:
rm -f $(LIB_NAME) $(OBJECTS) rm -f $(LIB_NAME) $(OBJECTS)
...@@ -6,20 +6,13 @@ abstract_type_list::~abstract_type_list() ...@@ -6,20 +6,13 @@ abstract_type_list::~abstract_type_list()
{ {
} }
abstract_type_list::const_iterator abstract_type_list::const_iterator abstract_type_list::end() const
abstract_type_list::const_iterator::operator++(int)
{ {
const_iterator tmp(*this); return const_iterator(nullptr);
operator++();
return tmp;
} }
abstract_type_list::const_iterator abstract_type_list::abstract_iterator::~abstract_iterator()
abstract_type_list::const_iterator::operator--(int)
{ {
const_iterator tmp(*this);
operator--();
return tmp;
} }
} } // namespace cppa::util } } // namespace cppa::util
#include "cppa/any_tuple.hpp"
namespace {
struct empty_type_list : cppa::util::abstract_type_list
{
virtual abstract_type_list* copy() const
{
return new empty_type_list;
}
virtual const_iterator begin() const
{
return 0;
}
virtual const cppa::uniform_type_info* at(size_t) const
{
throw std::range_error("empty_type_list::at()");
}
};
struct empty_tuple : cppa::detail::abstract_tuple
{
empty_type_list m_types;
virtual size_t size() const
{
return 0;
}
virtual abstract_tuple* copy() const
{
return new empty_tuple;
}
virtual void* mutable_at(size_t)
{
throw std::range_error("empty_tuple::mutable_at()");
}
virtual const void* at(size_t) const
{
throw std::range_error("empty_tuple::at()");
}
virtual const cppa::uniform_type_info& type_at(size_t) const
{
throw std::range_error("empty_tuple::type_at()");
}
virtual const cppa::util::abstract_type_list& types() const
{
return m_types;
}
virtual bool equal_to(const abstract_tuple& other) const
{
return other.size() == 0;
}
virtual void serialize(cppa::serializer&) const
{
}
};
} // 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(vals_ptr&& vals) : m_vals(std::move(vals))
{
}
any_tuple::any_tuple(any_tuple&& other) : m_vals(std::move(other.m_vals))
{
}
any_tuple& any_tuple::operator=(any_tuple&& other)
{
m_vals = std::move(other.m_vals);
return *this;
}
size_t any_tuple::size() const
{
return m_vals->size();
}
void* any_tuple::mutable_at(size_t p)
{
return m_vals->mutable_at(p);
}
const void* any_tuple::at(size_t p) const
{
return m_vals->at(p);
}
const uniform_type_info& any_tuple::type_at(size_t p) const
{
return m_vals->type_at(p);
}
const util::abstract_type_list& any_tuple::types() const
{
return m_vals->types();
}
const cow_ptr<detail::abstract_tuple>& any_tuple::vals() const
{
return m_vals;
}
bool any_tuple::equal_to(const any_tuple& other) const
{
return m_vals->equal_to(*other.vals());
}
} // namespace cppa
...@@ -25,7 +25,7 @@ void blocking_message_queue::dequeue(invoke_rules& rules) ...@@ -25,7 +25,7 @@ void blocking_message_queue::dequeue(invoke_rules& rules)
queue_node* amsg = m_queue.pop(); queue_node* amsg = m_queue.pop();
util::singly_linked_list<queue_node> buffer; util::singly_linked_list<queue_node> buffer;
intrusive_ptr<detail::intermediate> imd; intrusive_ptr<detail::intermediate> imd;
while (!(imd = rules.get_intermediate(amsg->msg.data()))) while (!(imd = rules.get_intermediate(amsg->msg.content())))
{ {
buffer.push_back(amsg); buffer.push_back(amsg);
amsg = m_queue.pop(); amsg = m_queue.pop();
......
...@@ -46,7 +46,8 @@ void converted_thread_context::join(group_ptr& what) ...@@ -46,7 +46,8 @@ void converted_thread_context::join(group_ptr& what)
std::lock_guard<std::mutex> guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
if (!m_exited && m_subscriptions.count(what) == 0) if (!m_exited && m_subscriptions.count(what) == 0)
{ {
m_subscriptions[what] = what->subscribe(this); m_subscriptions.insert(std::make_pair(what, what->subscribe(this)));
//m_subscriptions[what] = what->subscribe(this);
} }
} }
......
#include "cppa/config.hpp"
#include <map>
#include <mutex>
#include <memory>
#include <stdexcept>
#include "cppa/group.hpp" #include "cppa/group.hpp"
namespace cppa { namespace cppa {
group::subscription::subscription(const channel_ptr& s, const intrusive_ptr<group>& g) : m_self(s), m_group(g) namespace {
typedef std::map< std::string, std::unique_ptr<group::module> > modules_map;
std::mutex s_mtx;
modules_map s_mmap;
} // namespace <anonymous>
intrusive_ptr<group> group::get(const std::string& module_name,
const std::string& group_name)
{
std::lock_guard<std::mutex> guard(s_mtx);
auto i = s_mmap.find(module_name);
if (i != s_mmap.end())
{
return (i->second)->get(group_name);
}
std::string error_msg = "no module named \"";
error_msg += module_name;
error_msg += "\" found";
throw std::logic_error(error_msg);
}
void group::add_module(group::module* ptr)
{
auto mname = ptr->name();
std::unique_ptr<group::module> mptr(ptr);
// lifetime scope of guard
{
std::lock_guard<std::mutex> guard(s_mtx);
if (!s_mmap.insert(std::make_pair(mname, std::move(mptr))).second)
{
std::string error_msg = "module name \"";
error_msg += mname;
error_msg += "\" already defined";
throw std::logic_error(error_msg);
}
}
}
group::subscription::subscription(const channel_ptr& s,
const intrusive_ptr<group>& g)
: m_self(s), m_group(g)
{
}
group::subscription::subscription(group::subscription&& other)
: m_self(std::move(other.m_self)), m_group(std::move(other.m_group))
{ {
} }
group::subscription::~subscription() group::subscription::~subscription()
{ {
m_group->unsubscribe(m_self); if (m_group) m_group->unsubscribe(m_self);
} }
} // namespace cppa } // namespace cppa
...@@ -4,12 +4,12 @@ namespace cppa { ...@@ -4,12 +4,12 @@ namespace cppa {
message::message(const actor_ptr& from, message::message(const actor_ptr& from,
const channel_ptr& to, const channel_ptr& to,
const untyped_tuple& ut) const any_tuple& ut)
: m_content(new content(from, to, ut)) : m_content(new msg_content(from, to, ut))
{ {
} }
message::message() : m_content(new content(0, 0, tuple<int>(0))) message::message() : m_content(new msg_content(0, 0, tuple<int>(0)))
{ {
} }
...@@ -17,7 +17,7 @@ bool operator==(const message& lhs, const message& rhs) ...@@ -17,7 +17,7 @@ bool operator==(const message& lhs, const message& rhs)
{ {
return lhs.sender() == rhs.sender() return lhs.sender() == rhs.sender()
&& lhs.receiver() == rhs.receiver() && lhs.receiver() == rhs.receiver()
&& lhs.data().vals()->equal_to(*(rhs.data().vals())); && lhs.content().vals()->equal_to(*(rhs.content().vals()));
} }
} // namespace cppa } // namespace cppa
...@@ -19,13 +19,17 @@ void object::swap(object& other) ...@@ -19,13 +19,17 @@ void object::swap(object& other)
std::swap(m_type, other.m_type); std::swap(m_type, other.m_type);
} }
void* object::new_instance(const uniform_type_info* type, const void* from)
{
return type->new_instance(from);
}
object object::copy() const object object::copy() const
{ {
return (m_value != &s_void) ? object(m_type->new_instance(m_value), m_type) return (m_value != &s_void) ? object(m_type->new_instance(m_value), m_type)
: object(); : object();
} }
object::object(void* val, const uniform_type_info* utype) object::object(void* val, const uniform_type_info* utype)
: m_value(val), m_type(utype) : m_value(val), m_type(utype)
{ {
...@@ -70,7 +74,7 @@ object& object::operator=(const object& other) ...@@ -70,7 +74,7 @@ object& object::operator=(const object& other)
return *this; return *this;
} }
bool object::equal(const object& other) const bool object::equal_to(const object& other) const
{ {
if (m_type == other.m_type) if (m_type == other.m_type)
{ {
...@@ -90,4 +94,19 @@ std::string object::to_string() const ...@@ -90,4 +94,19 @@ std::string object::to_string() const
return ""; return "";
} }
bool object::empty() const
{
return m_value == &s_void;
}
const void* object::value() const
{
return m_value;
}
void* object::mutable_value()
{
return m_value;
}
} // namespace cppa } // namespace cppa
#include "cppa/detail/object_array.hpp"
namespace cppa { namespace detail {
object_array::object_array()
{
}
object_array::object_array(object_array&& other)
: m_elements(std::move(other.m_elements))
{
}
object_array::object_array(const object_array& other)
: m_elements(other.m_elements)
{
}
void object_array::push_back(const object& what)
{
m_elements.push_back(what);
}
void object_array::push_back(object&& what)
{
m_elements.push_back(std::move(what));
}
void* object_array::mutable_at(size_t pos)
{
return m_elements[pos].mutable_value();
}
size_t object_array::size() const
{
return m_elements.size();
}
abstract_tuple* object_array::copy() const
{
return new object_array(*this);
}
const void* object_array::at(size_t pos) const
{
return m_elements[pos].value();
}
const util::abstract_type_list& object_array::types() const
{
return *this;
}
bool object_array::equal_to(const cppa::detail::abstract_tuple& ut) const
{
if (size() == ut.size())
{
for (size_t i = 0; i < size(); ++i)
{
const uniform_type_info& utype = type_at(i);
if (utype == ut.type_at(i))
{
if (!utype.equal(at(i), ut.at(i))) return false;
}
else
{
return false;
}
}
return true;
}
return false;
}
const uniform_type_info& object_array::type_at(size_t pos) const
{
return m_elements[pos].type();
}
util::abstract_type_list::const_iterator object_array::begin() const
{
struct type_iterator : util::abstract_type_list::abstract_iterator
{
typedef std::vector<object>::const_iterator iterator_type;
iterator_type m_pos;
iterator_type m_end;
type_iterator(iterator_type begin, iterator_type end)
: m_pos(begin), m_end(end)
{
}
type_iterator(const type_iterator&) = default;
bool next()
{
return ++m_pos != m_end;
}
const uniform_type_info& get() const
{
return m_pos->type();
}
abstract_iterator* copy() const
{
return new type_iterator(*this);
}
};
return new type_iterator(m_elements.begin(), m_elements.end());
}
} } // namespace cppa::detail
...@@ -11,14 +11,17 @@ ...@@ -11,14 +11,17 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/object.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/any_type.hpp" #include "cppa/any_type.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.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/object_array.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
#include "cppa/detail/default_uniform_type_info_impl.hpp" #include "cppa/detail/default_uniform_type_info_impl.hpp"
...@@ -93,7 +96,7 @@ void push(std::map<int, std::pair<string_set, string_set>>& ints) ...@@ -93,7 +96,7 @@ void push(std::map<int, std::pair<string_set, string_set>>& ints)
namespace cppa { namespace detail { namespace { namespace cppa { namespace detail { namespace {
class actor_ptr_type_info_impl : public util::uniform_type_info_base<actor_ptr> class actor_ptr_type_info : public util::abstract_uniform_type_info<actor_ptr>
{ {
protected: protected:
...@@ -121,6 +124,44 @@ class actor_ptr_type_info_impl : public util::uniform_type_info_base<actor_ptr> ...@@ -121,6 +124,44 @@ class actor_ptr_type_info_impl : public util::uniform_type_info_base<actor_ptr>
}; };
class any_tuple_type_info : public util::abstract_uniform_type_info<any_tuple>
{
protected:
void serialize(const void* instance, serializer* sink) const
{
auto atup = reinterpret_cast<const any_tuple*>(instance);
sink->begin_object(name());
sink->begin_sequence(atup->size());
for (size_t i = 0; i < atup->size(); ++i)
{
atup->type_at(i).serialize(atup->at(i), sink);
}
sink->end_sequence();
sink->end_object();
}
void deserialize(void* instance, deserializer* source) const
{
auto result = new detail::object_array;
auto str = source->seek_object();
if (str != name()) throw std::logic_error("invalid type found: " + str);
source->begin_object(str);
size_t tuple_size = source->begin_sequence();
for (size_t i = 0; i < tuple_size; ++i)
{
auto tname = source->peek_object();
auto utype = uniform_type_info::by_uniform_name(tname);
result->push_back(utype->deserialize(source));
}
source->end_sequence();
source->end_object();
*reinterpret_cast<any_tuple*>(instance) = any_tuple(result);
}
};
class uniform_type_info_map class uniform_type_info_map
{ {
...@@ -164,7 +205,8 @@ class uniform_type_info_map ...@@ -164,7 +205,8 @@ class uniform_type_info_map
insert<std::string>(); insert<std::string>();
insert<std::u16string>(); insert<std::u16string>();
insert<std::u32string>(); insert<std::u32string>();
insert(new actor_ptr_type_info_impl, { raw_name<actor_ptr>() }); insert(new actor_ptr_type_info, { raw_name<actor_ptr>() });
insert(new any_tuple_type_info, { raw_name<any_tuple>() });
insert<float>(); insert<float>();
insert<cppa::util::void_type>(); insert<cppa::util::void_type>();
if (sizeof(double) == sizeof(long double)) if (sizeof(double) == sizeof(long double))
...@@ -236,7 +278,7 @@ class uniform_type_info_map ...@@ -236,7 +278,7 @@ class uniform_type_info_map
return nullptr; return nullptr;
} }
bool insert(std::set<std::string> plain_names, bool insert(std::set<std::string> raw_names,
uniform_type_info* what) uniform_type_info* what)
{ {
if (m_by_uname.count(what->name()) > 0) if (m_by_uname.count(what->name()) > 0)
...@@ -245,7 +287,7 @@ class uniform_type_info_map ...@@ -245,7 +287,7 @@ class uniform_type_info_map
return false; return false;
} }
m_by_uname.insert(std::make_pair(what->name(), what)); m_by_uname.insert(std::make_pair(what->name(), what));
for (const std::string& plain_name : plain_names) for (const std::string& plain_name : raw_names)
{ {
if (!m_by_rname.insert(std::make_pair(plain_name, what)).second) if (!m_by_rname.insert(std::make_pair(plain_name, what)).second)
{ {
...@@ -278,7 +320,6 @@ uniform_type_info_map& s_uniform_type_info_map() ...@@ -278,7 +320,6 @@ uniform_type_info_map& s_uniform_type_info_map()
} } } // namespace cppa::detail::<anonymous> } } } // namespace cppa::detail::<anonymous>
namespace { namespace {
std::atomic<int> s_ids; std::atomic<int> s_ids;
......
#include "cppa/untyped_tuple.hpp"
namespace {
struct empty_type_list : cppa::util::abstract_type_list
{
virtual abstract_type_list* copy() const
{
return new empty_type_list;
}
virtual const_iterator begin() const { return 0; }
virtual const_iterator end() const { return 0; }
virtual const cppa::uniform_type_info* at(std::size_t) const
{
throw std::range_error("empty_type_list::at()");
}
};
struct empty_tuple : cppa::detail::abstract_tuple
{
empty_type_list m_types;
virtual std::size_t size() const { return 0; }
virtual abstract_tuple* copy() const { return new empty_tuple; }
virtual void* mutable_at(std::size_t)
{
throw std::range_error("empty_tuple::mutable_at()");
}
virtual const void* at(std::size_t) const
{
throw std::range_error("empty_tuple::at()");
}
virtual const cppa::uniform_type_info* utype_at(std::size_t) const
{
throw std::range_error("empty_tuple::utype_at()");
}
virtual const cppa::util::abstract_type_list& types() const
{
return m_types;
}
virtual bool equal_to(const abstract_tuple& other) const
{
return other.size() == 0;
}
virtual void serialize(cppa::serializer&) const
{
}
};
} // namespace <anonymous>
namespace cppa {
untyped_tuple::untyped_tuple() : m_vals(new empty_tuple) { }
} // namespace cppa
...@@ -53,7 +53,7 @@ int main(int argc, char** c_argv) ...@@ -53,7 +53,7 @@ int main(int argc, char** c_argv)
else else
{ {
std::cout << std::boolalpha; std::cout << std::boolalpha;
std::size_t errors = 0; size_t errors = 0;
RUN_TEST(test__primitive_variant); RUN_TEST(test__primitive_variant);
RUN_TEST(test__uniform_type); RUN_TEST(test__uniform_type);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#define CPPA_TEST(name) \ #define CPPA_TEST(name) \
struct cppa_test_scope \ struct cppa_test_scope \
{ \ { \
std::size_t error_count; \ size_t error_count; \
cppa_test_scope() : error_count(0) { } \ cppa_test_scope() : error_count(0) { } \
~cppa_test_scope() \ ~cppa_test_scope() \
{ \ { \
...@@ -40,18 +40,22 @@ if (!(line_of_code)) \ ...@@ -40,18 +40,22 @@ if (!(line_of_code)) \
} ((void) 0) } ((void) 0)
#endif #endif
#define CPPA_ERROR(err_msg) \
std::cerr << err_msg << std::endl; \
++cppa_ts.error_count
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) == (rhs_loc))) #define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) == (rhs_loc)))
std::size_t test__uniform_type(); size_t test__uniform_type();
std::size_t test__type_list(); size_t test__type_list();
std::size_t test__a_matches_b(); size_t test__a_matches_b();
std::size_t test__atom(); size_t test__atom();
std::size_t test__tuple(); size_t test__tuple();
std::size_t test__spawn(); size_t test__spawn();
std::size_t test__intrusive_ptr(); size_t test__intrusive_ptr();
std::size_t test__serialization(); size_t test__serialization();
std::size_t test__local_group(); size_t test__local_group();
std::size_t test__primitive_variant(); size_t test__primitive_variant();
void test__queue_performance(); void test__queue_performance();
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
using namespace cppa; using namespace cppa;
using namespace cppa::util; using namespace cppa::util;
std::size_t test__a_matches_b() size_t test__a_matches_b()
{ {
CPPA_TEST(test__a_matches_b); CPPA_TEST(test__a_matches_b);
......
...@@ -101,7 +101,7 @@ class atom : public atom_base ...@@ -101,7 +101,7 @@ class atom : public atom_base
}; };
std::size_t test__atom() size_t test__atom()
{ {
CPPA_TEST(test__atom); CPPA_TEST(test__atom);
......
...@@ -15,7 +15,7 @@ int class1_instances = 0; ...@@ -15,7 +15,7 @@ int class1_instances = 0;
} }
struct class0 : cppa::detail::ref_counted_impl<std::size_t> struct class0 : cppa::detail::ref_counted_impl<size_t>
{ {
class0() { ++class0_instances; } class0() { ++class0_instances; }
...@@ -46,7 +46,7 @@ class0_ptr get_test_ptr() ...@@ -46,7 +46,7 @@ class0_ptr get_test_ptr()
return get_test_rc(); return get_test_rc();
} }
std::size_t test__intrusive_ptr() size_t test__intrusive_ptr()
{ {
CPPA_TEST(test__intrusive_ptr); CPPA_TEST(test__intrusive_ptr);
......
#include "cppa/config.hpp"
#include <map>
#include <list>
#include <mutex>
#include <iostream>
#include <algorithm>
#include "test.hpp" #include "test.hpp"
#include "hash_of.hpp" #include "hash_of.hpp"
...@@ -8,26 +16,17 @@ ...@@ -8,26 +16,17 @@
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include <map>
#include <list>
#include <iostream>
#include <algorithm>
#include <boost/thread/mutex.hpp>
using std::cout; using std::cout;
using std::endl; using std::endl;
/*
using namespace cppa; using namespace cppa;
namespace {
class local_group : public group class local_group : public group
{ {
boost::mutex m_mtx; friend class local_group_module;
std::mutex m_mtx;
std::list<channel_ptr> m_subscribers; std::list<channel_ptr> m_subscribers;
inline std::list<channel_ptr>::iterator find(const channel_ptr& what) inline std::list<channel_ptr>::iterator find(const channel_ptr& what)
...@@ -35,32 +34,34 @@ class local_group : public group ...@@ -35,32 +34,34 @@ class local_group : public group
return std::find(m_subscribers.begin(), m_subscribers.end(), what); return std::find(m_subscribers.begin(), m_subscribers.end(), what);
} }
local_group() = default;
public: public:
virtual void enqueue(const message& msg) virtual void enqueue(const message& msg)
{ {
boost::mutex::scoped_lock guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i) for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i)
{ {
(*i)->enqueue(msg); (*i)->enqueue(msg);
} }
} }
virtual intrusive_ptr<group::subscription> subscribe(const channel_ptr& who) virtual group::subscription subscribe(const channel_ptr& who)
{ {
boost::mutex::scoped_lock guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
auto i = find(who); auto i = find(who);
if (i == m_subscribers.end()) if (i == m_subscribers.end())
{ {
m_subscribers.push_back(who); m_subscribers.push_back(who);
return new group::subscription(who, this); return { who, this };
} }
return new group::subscription(0, 0); return { nullptr, nullptr };
} }
virtual void unsubscribe(const channel_ptr& who) virtual void unsubscribe(const channel_ptr& who)
{ {
boost::mutex::scoped_lock guard(m_mtx); std::lock_guard<std::mutex> guard(m_mtx);
auto i = find(who); auto i = find(who);
if (i != m_subscribers.end()) if (i != m_subscribers.end())
{ {
...@@ -70,102 +71,64 @@ class local_group : public group ...@@ -70,102 +71,64 @@ class local_group : public group
}; };
//local_group* m_local_group = new local_group; class local_group_module : public group::module
intrusive_ptr<local_group> m_local_group(new local_group);
intrusive_ptr<local_group> local(const char*)
{ {
return m_local_group;
}
} // namespace <anonymous> std::string m_name;
std::mutex m_mtx;
std::map<std::string, group_ptr> m_instances;
struct storage
{
std::map<std::string, intrusive_ptr<object>> m_map;
public: public:
template<typename T> local_group_module() : m_name("local")
T& get(const std::string& key)
{ {
auto uti = uniform_type_info::by_type_info(typeid(T)); }
auto i = m_map.find(key);
if (i == m_map.end()) const std::string& name()
{ {
i = m_map.insert(std::make_pair(key, uti->create())).first; return m_name;
} }
else if (uti != i->second->type())
group_ptr get(const std::string& group_name)
{ {
// todo: throw nicer exception std::lock_guard<std::mutex> guard(m_mtx);
throw std::runtime_error("invalid type"); auto i = m_instances.find(group_name);
if (i == m_instances.end())
{
group_ptr result(new local_group);
m_instances.insert(std::make_pair(group_name, result));
return result;
} }
return *reinterpret_cast<T*>(i->second->mutable_value()); else return i->second;
} }
}; };
void consumer(actor_ptr main_actor) void worker()
{
int result = 0;
for (int i = 0; i < 5; ++i)
{
receive(on<int>() >> [&](int x) {
result += x;
});
}
send(main_actor, result);
}
void producer(actor_ptr consume_actor)
{ {
receive(on<int>() >> [&](int i) { receive(on<int>() >> [](int value) {
send(consume_actor, i); reply(value);
}); });
} }
std::size_t test__local_group() size_t test__local_group()
{ {
CPPA_TEST(test__local_group); CPPA_TEST(test__local_group);
group::add_module(new local_group_module);
std::list<intrusive_ptr<group::subscription>> m_subscriptions; auto foo_group = group::get("local", "foo");
actor_ptr self_ptr = self();
auto consume_actor = spawn(consumer, self_ptr);
auto lg = local("foobar");
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
auto fa = spawn(producer, consume_actor); // spawn workers in group local:foo
auto sptr = lg->subscribe(fa); spawn(worker)->join(foo_group);
m_subscriptions.push_back(sptr);
} }
send(foo_group, 2);
send(lg, 1); int result = 0;
for (int i = 0; i < 5; ++i)
await_all_actors_done(); {
receive(on<int>() >> [&result](int value) { result += value; });
receive(on<int>() >> [&](int x) { }
CPPA_CHECK_EQUAL(x, 5); CPPA_CHECK_EQUAL(result, 10);
}); await_all_others_done();
return CPPA_TEST_RESULT;
}
*/
std::size_t test__local_group()
{
CPPA_TEST(test__local_group);
CPPA_CHECK_EQUAL(true, true);
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT;
} }
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
using namespace cppa; using namespace cppa;
std::size_t test__primitive_variant() size_t test__primitive_variant()
{ {
CPPA_TEST(test__primitive_variant); CPPA_TEST(test__primitive_variant);
std::uint32_t forty_two = 42; std::uint32_t forty_two = 42;
......
...@@ -18,8 +18,8 @@ using std::endl; ...@@ -18,8 +18,8 @@ using std::endl;
struct queue_element struct queue_element
{ {
queue_element* next; queue_element* next;
std::size_t value; size_t value;
queue_element(std::size_t val) : next(0), value(val) { } queue_element(size_t val) : next(0), value(val) { }
}; };
template<typename T> template<typename T>
...@@ -128,46 +128,46 @@ class locked_queue ...@@ -128,46 +128,46 @@ class locked_queue
namespace { namespace {
//const std::size_t num_slaves = 1000; //const size_t num_slaves = 1000;
//const std::size_t num_slave_msgs = 90000; //const size_t num_slave_msgs = 90000;
// 900 000 // 900 000
//const std::size_t num_msgs = (num_slaves) * (num_slave_msgs); //const size_t num_msgs = (num_slaves) * (num_slave_msgs);
// uint32::max = 4 294 967 296 // uint32::max = 4 294 967 296
// (n (n+1)) / 2 = 4 050 045 000 // (n (n+1)) / 2 = 4 050 045 000
//const std::size_t calc_result = ((num_msgs)*(num_msgs + 1)) / 2; //const size_t calc_result = ((num_msgs)*(num_msgs + 1)) / 2;
} // namespace <anonymous> } // namespace <anonymous>
template<typename Queue> template<typename Queue>
void slave(Queue& q, std::size_t from, std::size_t to) void slave(Queue& q, size_t from, size_t to)
{ {
for (std::size_t x = from; x < to; ++x) for (size_t x = from; x < to; ++x)
{ {
q.push_back(new queue_element(x)); q.push_back(new queue_element(x));
} }
} }
template<typename Queue, std::size_t num_slaves, std::size_t num_slave_msgs> template<typename Queue, size_t num_slaves, size_t num_slave_msgs>
void master(Queue& q) void master(Queue& q)
{ {
static const std::size_t num_msgs = (num_slaves) * (num_slave_msgs); static const size_t num_msgs = (num_slaves) * (num_slave_msgs);
static const std::size_t calc_result = ((num_msgs)*(num_msgs + 1)) / 2; static const size_t calc_result = ((num_msgs)*(num_msgs + 1)) / 2;
boost::timer t0; boost::timer t0;
for (std::size_t i = 0; i < num_slaves; ++i) for (size_t i = 0; i < num_slaves; ++i)
{ {
std::size_t from = (i * num_slave_msgs) + 1; size_t from = (i * num_slave_msgs) + 1;
std::size_t to = from + num_slave_msgs; size_t to = from + num_slave_msgs;
boost::thread(slave<Queue>, boost::ref(q), from, to).detach(); boost::thread(slave<Queue>, boost::ref(q), from, to).detach();
} }
std::size_t result = 0; size_t result = 0;
std::size_t min_val = calc_result; size_t min_val = calc_result;
std::size_t max_val = 0; size_t max_val = 0;
for (std::size_t i = 0; i < num_msgs; ++i) for (size_t i = 0; i < num_msgs; ++i)
{ {
queue_element* e = q.pop(); queue_element* e = q.pop();
result += e->value; result += e->value;
...@@ -185,10 +185,10 @@ void master(Queue& q) ...@@ -185,10 +185,10 @@ void master(Queue& q)
cout << t0.elapsed() << " " << num_slaves << endl; cout << t0.elapsed() << " " << num_slaves << endl;
} }
namespace { const std::size_t slave_messages = 1000000; } namespace { const size_t slave_messages = 1000000; }
template<std::size_t Pos, std::size_t Max, std::size_t Step, template<size_t Pos, size_t Max, size_t Step,
template<std::size_t> class Stmt> template<size_t> class Stmt>
struct static_for struct static_for
{ {
template<typename... Args> template<typename... Args>
...@@ -199,8 +199,8 @@ struct static_for ...@@ -199,8 +199,8 @@ struct static_for
} }
}; };
template<std::size_t Max, std::size_t Step, template<size_t Max, size_t Step,
template<std::size_t> class Stmt> template<size_t> class Stmt>
struct static_for<Max, Max, Step, Stmt> struct static_for<Max, Max, Step, Stmt>
{ {
template<typename... Args> template<typename... Args>
...@@ -216,7 +216,7 @@ struct type_token ...@@ -216,7 +216,7 @@ struct type_token
typedef What type; typedef What type;
}; };
template<std::size_t NumThreads> template<size_t NumThreads>
struct test_step struct test_step
{ {
template<typename QueueToken> template<typename QueueToken>
......
...@@ -25,10 +25,11 @@ ...@@ -25,10 +25,11 @@
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/message.hpp" #include "cppa/message.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/get_view.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/primitive_type.hpp" #include "cppa/primitive_type.hpp"
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/binary_serializer.hpp" #include "cppa/binary_serializer.hpp"
...@@ -42,8 +43,9 @@ ...@@ -42,8 +43,9 @@
#include "cppa/util/if_else_type.hpp" #include "cppa/util/if_else_type.hpp"
#include "cppa/util/wrapped_type.hpp" #include "cppa/util/wrapped_type.hpp"
#include "cppa/util/is_primitive.hpp" #include "cppa/util/is_primitive.hpp"
#include "cppa/util/uniform_type_info_base.hpp" #include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/type_to_ptype.hpp" #include "cppa/detail/type_to_ptype.hpp"
#include "cppa/detail/ptype_to_type.hpp" #include "cppa/detail/ptype_to_type.hpp"
#include "cppa/detail/default_uniform_type_info_impl.hpp" #include "cppa/detail/default_uniform_type_info_impl.hpp"
...@@ -372,7 +374,7 @@ class string_deserializer : public deserializer ...@@ -372,7 +374,7 @@ class string_deserializer : public deserializer
}; };
class message_uti : public util::uniform_type_info_base<message> class message_uti : public util::abstract_uniform_type_info<message>
{ {
public: public:
...@@ -380,20 +382,21 @@ class message_uti : public util::uniform_type_info_base<message> ...@@ -380,20 +382,21 @@ class message_uti : public util::uniform_type_info_base<message>
virtual void serialize(const void* instance, serializer* sink) const virtual void serialize(const void* instance, serializer* sink) const
{ {
const message& msg = *reinterpret_cast<const message*>(instance); const message& msg = *reinterpret_cast<const message*>(instance);
const untyped_tuple& data = msg.data(); const any_tuple& data = msg.content();
sink->begin_object("cppa::message"); sink->begin_object(name());
sink->begin_sequence(data.size()); uniform_typeid<any_tuple>()->serialize(&data, sink);
for (size_t i = 0; i < data.size(); ++i)
{
const uniform_type_info* ut = data.utype_at(i);
ut->serialize(data.at(i), sink);
}
sink->end_sequence();
sink->end_object(); sink->end_object();
} }
virtual void deserialize(void* instance, deserializer* source) const virtual void deserialize(void* instance, deserializer* source) const
{ {
auto tname = source->seek_object();
if (tname != name()) throw 42;
source->begin_object(tname);
any_tuple content;
uniform_typeid<any_tuple>()->deserialize(&content, source);
source->end_object();
*reinterpret_cast<message*>(instance) = message(0, 0, content);
} }
}; };
...@@ -413,13 +416,71 @@ std::string to_string(const T& what) ...@@ -413,13 +416,71 @@ std::string to_string(const T& what)
return osstr.str(); return osstr.str();
} }
std::size_t test__serialization() size_t test__serialization()
{ {
CPPA_TEST(test__serialization); CPPA_TEST(test__serialization);
announce(typeid(message), new message_uti); announce(typeid(message), new message_uti);
//message msg(0, 0, 42, std::string("Hello World"), 23.32);
//cout << to_string(msg) << endl; auto oarr = new detail::object_array;
oarr->push_back(object(static_cast<std::uint32_t>(42)));
oarr->push_back(object(std::string("foo")));
any_tuple atuple1(oarr);
try
{
auto tv1 = get_view<std::uint32_t, std::string>(atuple1);
CPPA_CHECK_EQUAL(tv1.size(), 2);
CPPA_CHECK_EQUAL(get<0>(tv1), 42);
CPPA_CHECK_EQUAL(get<1>(tv1), "foo");
}
catch (std::exception& e)
{
CPPA_ERROR("exception: " << e.what());
}
{
// serialize b1 to buf
binary_serializer bs;
bs << atuple1;
// deserialize b2 from buf
binary_deserializer bd(bs.data(), bs.size());
any_tuple atuple2;
uniform_typeid<any_tuple>()->deserialize(&atuple2, &bd);
try
{
auto tview = get_view<std::uint32_t, std::string>(atuple2);
CPPA_CHECK_EQUAL(tview.size(), 2);
CPPA_CHECK_EQUAL(get<0>(tview), 42);
CPPA_CHECK_EQUAL(get<1>(tview), "foo");
}
catch (std::exception& e)
{
CPPA_ERROR("exception: " << e.what());
}
}
{
message msg1(0, 0, 42, std::string("Hello World!"));
//cout << "msg = " << to_string(msg1) << endl;
binary_serializer bs;
bs << msg1;
binary_deserializer bd(bs.data(), bs.size());
object obj;
bd >> obj;
if (obj.type() == typeid(message))
{
auto& content = get<message>(obj).content();
auto cview = get_view<decltype(42), std::string>(content);
CPPA_CHECK_EQUAL(cview.size(), 2);
CPPA_CHECK_EQUAL(get<0>(cview), 42);
CPPA_CHECK_EQUAL(get<1>(cview), "Hello World!");
}
else
{
CPPA_ERROR("obj.type() != typeid(message)");
}
}
CPPA_CHECK_EQUAL((is_iterable<int>::value), false); CPPA_CHECK_EQUAL((is_iterable<int>::value), false);
// std::string is primitive and thus not identified by is_iterable // std::string is primitive and thus not identified by is_iterable
......
...@@ -19,7 +19,7 @@ void pong() ...@@ -19,7 +19,7 @@ void pong()
}); });
} }
std::size_t test__spawn() size_t test__spawn()
{ {
CPPA_TEST(test__spawn); CPPA_TEST(test__spawn);
{ {
...@@ -30,6 +30,6 @@ std::size_t test__spawn() ...@@ -30,6 +30,6 @@ std::size_t test__spawn()
CPPA_CHECK_EQUAL(value, 42); CPPA_CHECK_EQUAL(value, 42);
}); });
} }
await_all_actors_done(); await_all_others_done();
return CPPA_TEST_RESULT; return CPPA_TEST_RESULT;
} }
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/match.hpp" #include "cppa/match.hpp"
#include "cppa/invoke.hpp" #include "cppa/invoke.hpp"
#include "cppa/get_view.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp" #include "cppa/tuple_view.hpp"
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
...@@ -39,7 +40,7 @@ void fun(const std::string&) ...@@ -39,7 +40,7 @@ void fun(const std::string&)
} // namespace <anonymous> } // namespace <anonymous>
std::size_t test__tuple() size_t test__tuple()
{ {
CPPA_TEST(test__tuple); CPPA_TEST(test__tuple);
...@@ -58,14 +59,14 @@ std::size_t test__tuple() ...@@ -58,14 +59,14 @@ std::size_t test__tuple()
tuple<int, std::string, int> t5(42, "foo", 24); tuple<int, std::string, int> t5(42, "foo", 24);
tuple<int> t6; tuple<int> t6;
// untyped tuples under test // untyped tuples under test
untyped_tuple ut0 = t1; any_tuple ut0 = t1;
// tuple views under test // tuple views under test
auto tv0 = get_view<any_type*, float, any_type*, int, any_type>(t1); auto tv0 = get_view<any_type*, float, any_type*, int, any_type>(t1);
auto tv1 = get_view<any_type*, int, any_type*>(tv0); auto tv1 = get_view<any_type*, int, any_type*>(tv0);
auto tv2 = get_view<int, any_type*, std::string>(t1); auto tv2 = get_view<int, any_type*, std::string>(t1);
auto tv3 = get_view<any_type*, int, std::string>(t1); auto tv3 = get_view<any_type*, int, std::string>(t1);
// untyped_tuple ut1 = tv0; // any_tuple ut1 = tv0;
CPPA_CHECK(t6.get<0>() == 0); CPPA_CHECK(t6.get<0>() == 0);
CPPA_CHECK(tv2.get<0>() == t1.get<0>()); CPPA_CHECK(tv2.get<0>() == t1.get<0>());
...@@ -86,7 +87,7 @@ std::size_t test__tuple() ...@@ -86,7 +87,7 @@ std::size_t test__tuple()
} }
{ {
std::vector<std::size_t> tv3_mappings; std::vector<size_t> tv3_mappings;
match<any_type*, int, std::string>(t1, tv3_mappings); match<any_type*, int, std::string>(t1, tv3_mappings);
CPPA_CHECK_EQUAL(tv3_mappings.size(), 2); CPPA_CHECK_EQUAL(tv3_mappings.size(), 2);
CPPA_CHECK(tv3_mappings[0] == 2); CPPA_CHECK(tv3_mappings[0] == 2);
......
...@@ -14,7 +14,7 @@ using std::is_same; ...@@ -14,7 +14,7 @@ using std::is_same;
using namespace cppa::util; using namespace cppa::util;
std::size_t test__type_list() size_t test__type_list()
{ {
CPPA_TEST(test__type_list); CPPA_TEST(test__type_list);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "test.hpp" #include "test.hpp"
#include "cppa/get_view.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
...@@ -57,7 +58,7 @@ bool announce4 = announce<foo>(&foo::value); ...@@ -57,7 +58,7 @@ bool announce4 = announce<foo>(&foo::value);
} // namespace <anonymous> } // namespace <anonymous>
std::size_t test__uniform_type() size_t test__uniform_type()
{ {
CPPA_TEST(test__uniform_type); CPPA_TEST(test__uniform_type);
{ {
...@@ -85,8 +86,10 @@ std::size_t test__uniform_type() ...@@ -85,8 +86,10 @@ std::size_t test__uniform_type()
"@str", "@u16str", "@u32str", // strings "@str", "@u16str", "@u32str", // strings
"float", "double", // floating points "float", "double", // floating points
"@0", // cppa::util::void_type "@0", // cppa::util::void_type
"cppa::any_type", // default announced cppa type // default announced cppa types
"cppa::intrusive_ptr<cppa::actor>" // default announced cppa type "cppa::any_type",
"cppa::any_tuple",
"cppa::intrusive_ptr<cppa::actor>"
}; };
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