Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

improved announce interface, i.e., allow user-defined types as POD me…

…mbers and auto-detect recursive containers such as vector<vector<double>>
  • Loading branch information...
commit af0db37817f8a6e48e7c819ac7d8b1104c369830 1 parent cc998ba
@Neverlord Neverlord authored
View
6 ChangeLog → ChangeLog.md
@@ -1,8 +1,12 @@
Version 0.4.2
-2012-XX-XX
+2012-10-1
- Bugfix: evaluate `errno` whenever select() fails and handle errors properly
+- Refactored announce
+ * accept recursive containers, e.g., vector<vector<double>>
+ * allow user-defined types as members of announced types
+ * all-new, policy-based implementation
Version 0.4.1
View
3  cppa.files
@@ -54,14 +54,11 @@ cppa/detail/empty_tuple.hpp
cppa/detail/get_behavior.hpp
cppa/detail/group_manager.hpp
cppa/detail/implicit_conversions.hpp
-cppa/detail/list_member.hpp
-cppa/detail/map_member.hpp
cppa/detail/matches.hpp
cppa/detail/network_manager.hpp
cppa/detail/object_array.hpp
cppa/detail/object_impl.hpp
cppa/detail/pair_member.hpp
-cppa/detail/primitive_member.hpp
cppa/detail/projection.hpp
cppa/detail/pseudo_tuple.hpp
cppa/detail/ptype_to_type.hpp
View
2  cppa/detail/container_tuple_view.hpp
@@ -83,7 +83,7 @@ class container_tuple_view : public abstract_tuple {
private:
- std::unique_ptr<Container, disablable_delete<Container> > m_ptr;
+ std::unique_ptr<Container, disablable_delete> m_ptr;
};
View
476 cppa/detail/default_uniform_type_info_impl.hpp
@@ -31,6 +31,8 @@
#ifndef CPPA_DEFAULT_UNIFORM_TYPE_INFO_IMPL_HPP
#define CPPA_DEFAULT_UNIFORM_TYPE_INFO_IMPL_HPP
+#include <memory>
+
#include "cppa/anything.hpp"
#include "cppa/util/rm_ref.hpp"
@@ -41,13 +43,12 @@
#include "cppa/util/is_forward_iterator.hpp"
#include "cppa/util/abstract_uniform_type_info.hpp"
-#include "cppa/detail/map_member.hpp"
-#include "cppa/detail/list_member.hpp"
#include "cppa/detail/type_to_ptype.hpp"
-#include "cppa/detail/primitive_member.hpp"
namespace cppa { namespace detail {
+typedef std::unique_ptr<uniform_type_info> unique_uti;
+
template<typename T>
class is_stl_compliant_list {
@@ -93,11 +94,17 @@ class is_stl_compliant_map {
public:
static constexpr bool value = util::is_iterable<T>::value
- && std::is_same<bool, result_type>::value;
+ && std::is_same<bool, result_type>::value;
};
template<typename T>
+struct is_stl_pair : std::false_type { };
+
+template<typename F, typename S>
+struct is_stl_pair<std::pair<F,S> > : std::true_type { };
+
+template<typename T>
class builtin_member : public util::abstract_uniform_type_info<T> {
public:
@@ -118,211 +125,344 @@ class builtin_member : public util::abstract_uniform_type_info<T> {
};
+typedef std::integral_constant<int,0> primitive_impl;
+typedef std::integral_constant<int,1> list_impl;
+typedef std::integral_constant<int,2> map_impl;
+typedef std::integral_constant<int,3> pair_impl;
+typedef std::integral_constant<int,9> recursive_impl;
+
template<typename T>
-class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T> {
+constexpr int impl_id() {
+ return util::is_primitive<T>::value
+ ? 0
+ : (is_stl_compliant_list<T>::value
+ ? 1
+ : (is_stl_compliant_map<T>::value
+ ? 2
+ : (is_stl_pair<T>::value
+ ? 3
+ : 9)));
+}
- template<typename X>
- struct is_invalid {
- static constexpr bool value = !util::is_primitive<X>::value
- && !is_stl_compliant_map<X>::value
- && !is_stl_compliant_list<X>::value;
- };
+template<typename T>
+struct deconst_pair {
+ typedef T type;
+};
- class member {
+template<typename K, typename V>
+struct deconst_pair<std::pair<K,V> > {
+ typedef typename std::remove_const<K>::type first_type;
+ typedef typename std::remove_const<V>::type second_type;
+ typedef std::pair<first_type,second_type> type;
+};
- uniform_type_info* m_meta;
+class default_serialize_policy {
- std::function<void (const uniform_type_info*,
- const void*,
- serializer* )> m_serialize;
+ public:
- std::function<void (const uniform_type_info*,
- void*,
- deserializer* )> m_deserialize;
+ template<typename T>
+ void operator()(const T& val, serializer* s) const {
+ std::integral_constant<int,impl_id<T>()> token;
+ simpl(val, s, token);
+ }
- member(const member&) = delete;
- member& operator=(const member&) = delete;
+ template<typename T>
+ void operator()(T& val, deserializer* d) const {
+ std::integral_constant<int,impl_id<T>()> token;
+ dimpl(val, d, token);
+ //static_types_array<T>::arr[0]->deserialize(&val, d);
+ }
- void swap(member& other) {
- std::swap(m_meta, other.m_meta);
- std::swap(m_serialize, other.m_serialize);
- std::swap(m_deserialize, other.m_deserialize);
- }
+ private:
- template<typename S, class D>
- member(uniform_type_info* mtptr, S&& s, D&& d)
- : m_meta(mtptr)
- , m_serialize(std::forward<S>(s))
- , m_deserialize(std::forward<D>(d)) {
- }
+ template<typename T>
+ void simpl(const T& val, serializer* s, primitive_impl) const {
+ s->write_value(val);
+ }
- public:
-
- template<typename R, class C>
- member(uniform_type_info* mtptr, R C::*mem_ptr) : m_meta(mtptr) {
- m_serialize = [mem_ptr] (const uniform_type_info* mt,
- const void* obj,
- serializer* s) {
- mt->serialize(&(*reinterpret_cast<const C*>(obj).*mem_ptr), s);
- };
- m_deserialize = [mem_ptr] (const uniform_type_info* mt,
- void* obj,
- deserializer* d) {
- mt->deserialize(&(*reinterpret_cast<C*>(obj).*mem_ptr), d);
- };
+ template<typename T>
+ void simpl(const T& val, serializer* s, list_impl) const {
+ s->begin_sequence(val.size());
+ for (auto i = val.begin(); i != val.end(); ++i) {
+ (*this)(*i, s);
}
+ s->end_sequence();
+ }
- template<typename GRes, typename SRes, typename SArg, class C>
- member(uniform_type_info* mtptr,
- GRes (C::*getter)() const,
- SRes (C::*setter)(SArg)) : m_meta(mtptr) {
- typedef typename util::rm_ref<GRes>::type getter_result;
- typedef typename util::rm_ref<SArg>::type setter_arg;
- static_assert(std::is_same<getter_result, setter_arg>::value,
- "getter result doesn't match setter argument");
- m_serialize = [getter] (const uniform_type_info* mt,
- const void* obj,
- serializer* s) {
- GRes v = (*reinterpret_cast<const C*>(obj).*getter)();
- mt->serialize(&v, s);
- };
- m_deserialize = [setter] (const uniform_type_info* mt,
- void* obj,
- deserializer* d) {
- setter_arg value;
- mt->deserialize(&value, d); (*reinterpret_cast<C*>(obj).*setter)(value);
- };
- }
+ template<typename T>
+ void simpl(const T& val, serializer* s, map_impl) const {
+ // lists and maps share code for serialization
+ list_impl token;
+ simpl(val, s, token);
+ }
- member(member&& other) : m_meta(nullptr) {
- swap(other);
- }
+ template<typename T>
+ void simpl(const T& val, serializer* s, pair_impl) const {
+ (*this)(val.first, s);
+ (*this)(val.second, s);
+ }
- // a member that's not a member at all, but "forwards"
- // the 'self' pointer to make use of *_member implementations
- static member fake_member(uniform_type_info* mtptr) {
- return {
- mtptr,
- [] (const uniform_type_info* mt, const void* obj, serializer* s) {
- mt->serialize(obj, s);
- },
- [] (const uniform_type_info* mt, void* obj, deserializer* d) {
- mt->deserialize(obj, d);
- }
- };
- }
+ template<typename T>
+ void simpl(const T& val, serializer* s, recursive_impl) const {
+ static_types_array<T>::arr[0]->serialize(&val, s);
+ }
- ~member() {
- delete m_meta;
- }
+ template<typename T>
+ void dimpl(T& storage, deserializer* d, primitive_impl) const {
+ primitive_variant val = d->read_value(type_to_ptype<T>::ptype);
+ storage = std::move(get<T>(val));
+ }
- member& operator=(member&& other) {
- swap(other);
- return *this;
+ template<typename T>
+ void dimpl(T& storage, deserializer* d, list_impl) const {
+ typedef typename T::value_type value_type;
+ storage.clear();
+ size_t size = d->begin_sequence();
+ for (size_t i = 0; i < size; ++i) {
+ value_type tmp;
+ (*this)(tmp, d);
+ storage.push_back(std::move(tmp));
}
+ d->end_sequence();
+ }
- inline void serialize(const void* parent, serializer* s) const {
- m_serialize(m_meta, parent, s);
+ template<typename T>
+ void dimpl(T& storage, deserializer* d, map_impl) const {
+ storage.clear();
+ size_t size = d->begin_sequence();
+ for (size_t i = 0; i < size; ++i) {
+ typename deconst_pair<typename T::value_type>::type tmp;
+ (*this)(tmp, d);
+ storage.insert(tmp);
}
+ d->end_sequence();
+ }
- inline void deserialize(void* parent, deserializer* d) const {
- m_deserialize(m_meta, parent, d);
- }
+ template<typename T>
+ void dimpl(T& storage, deserializer* d, pair_impl) const {
+ (*this)(storage.first, d);
+ (*this)(storage.second, d);
+ }
- };
+ template<typename T>
+ void dimpl(T& storage, deserializer* d, recursive_impl) const {
+ static_types_array<T>::arr[0]->deserialize(&storage, d);
+ }
- std::vector<member> m_members;
+};
- // terminates recursion
- inline void push_back() { }
+class forwarding_serialize_policy {
- // pr.first = member pointer
- // pr.second = meta object to handle pr.first
- template<typename R, class C, typename... Args>
- void push_back(std::pair<R C::*, util::abstract_uniform_type_info<R>*> pr,
- Args&&... args) {
- m_members.push_back({ pr.second, pr.first });
- push_back(std::forward<Args>(args)...);
+ public:
+
+ forwarding_serialize_policy(const forwarding_serialize_policy&) = delete;
+ forwarding_serialize_policy& operator=(const forwarding_serialize_policy&) = delete;
+
+ forwarding_serialize_policy(forwarding_serialize_policy&&) = default;
+ forwarding_serialize_policy& operator=(forwarding_serialize_policy&&) = default;
+
+ inline forwarding_serialize_policy(unique_uti uti)
+ : m_uti(std::move(uti)) { }
+
+ template<typename T>
+ inline void operator()(const T& val, serializer* s) const {
+ m_uti->serialize(&val, s);
}
- // pr.first = getter / setter pair
- // pr.second = meta object to handle pr.first
- template<typename GRes, typename SRes, typename SArg, typename C, typename... Args>
- void push_back(const std::pair<std::pair<GRes (C::*)() const, SRes (C::*)(SArg)>, util::abstract_uniform_type_info<typename util::rm_ref<GRes>::type>*>& pr,
- Args&&... args) {
- m_members.push_back({ pr.second, pr.first.first, pr.first.second });
- push_back(std::forward<Args>(args)...);
+ template<typename T>
+ inline void operator()(T& val, deserializer* d) const {
+ m_uti->deserialize(&val, d);
}
- // pr.first = getter member const function pointer
- // pr.second = setter member function pointer
- template<typename GRes, typename SRes, typename SArg, class C, typename... Args>
- typename std::enable_if<util::is_primitive<typename util::rm_ref<GRes>::type>::value>::type
- push_back(const std::pair<GRes (C::*)() const, SRes (C::*)(SArg)>& pr,
- Args&&... args) {
- typedef typename util::rm_ref<GRes>::type memtype;
- m_members.push_back({ new primitive_member<memtype>(), pr.first, pr.second });
- push_back(std::forward<Args>(args)...);
+ private:
+
+ unique_uti m_uti;
+
+};
+
+template<typename T, class AccessPolicy, class SerializePolicy = default_serialize_policy>
+class member_tinfo : public util::abstract_uniform_type_info<T> {
+
+ public:
+
+ member_tinfo(AccessPolicy apol, SerializePolicy spol)
+ : m_apol(std::move(apol)), m_spol(std::move(spol)) { }
+
+ member_tinfo(AccessPolicy apol) : m_apol(std::move(apol)) { }
+
+ member_tinfo() { }
+
+ void serialize(const void* vptr, serializer* s) const {
+ m_spol(m_apol(vptr), s);
}
- template<typename R, class C, typename... Args>
- typename std::enable_if<util::is_primitive<R>::value>::type
- push_back(R C::*mem_ptr, Args&&... args) {
- m_members.push_back({ new primitive_member<R>(), mem_ptr });
- push_back(std::forward<Args>(args)...);
+ void deserialize(void* vptr, deserializer* d) const {
+ std::integral_constant<bool, AccessPolicy::grants_mutable_access> token;
+ ds(vptr, d, token);
}
- template< typename R, class C,typename... Args>
- typename std::enable_if<is_stl_compliant_list<R>::value>::type
- push_back(R C::*mem_ptr, Args&&... args) {
- m_members.push_back({ new list_member<R>(), mem_ptr });
- push_back(std::forward<Args>(args)...);
+ private:
+
+ void ds(void* p, deserializer* d, std::true_type) const {
+ m_spol(m_apol(p), d);
}
- template<typename R, class C, typename... Args>
- typename std::enable_if<is_stl_compliant_map<R>::value>::type
- push_back(R C::*mem_ptr, Args&&... args) {
- m_members.push_back({ new map_member<R>(), mem_ptr });
- push_back(std::forward<Args>(args)...);
+ void ds(void* p, deserializer* d, std::false_type) const {
+ T tmp;
+ m_spol(tmp, d);
+ m_apol(p, std::move(tmp));
}
- template<typename R, class C, typename... Args>
- typename std::enable_if<is_invalid<R>::value && util::is_builtin<R>::value>::type
- push_back(R C::* mem_ptr, Args&&... args) {
- m_members.push_back({new builtin_member<R>(), mem_ptr});
- push_back(std::forward<Args>(args)...);
+ AccessPolicy m_apol;
+ SerializePolicy m_spol;
+
+};
+
+template<typename T, class C>
+class memptr_access_policy {
+
+ public:
+
+ memptr_access_policy(const memptr_access_policy&) = default;
+ memptr_access_policy& operator=(const memptr_access_policy&) = default;
+
+ inline memptr_access_policy(T C::* memptr) : m_memptr(memptr) { }
+
+ inline T& operator()(void* vptr) const {
+ auto ptr = reinterpret_cast<C*>(vptr);
+ return *ptr.*m_memptr;
}
- template<typename R, class C, typename... Args>
- typename std::enable_if<is_invalid<R>::value && !util::is_builtin<R>::value>::type
- push_back(R C::*, Args&&...) {
- static_assert(util::is_primitive<R>::value,
- "T is neither a primitive type nor a "
- "stl-compliant list/map");
+ inline const T& operator()(const void* vptr) const {
+ auto ptr = reinterpret_cast<const C*>(vptr);
+ return *ptr.*m_memptr;
}
- template<typename P>
- void init_(typename std::enable_if<util::is_primitive<P>::value>::type* = 0) {
- m_members.push_back(member::fake_member(new primitive_member<P>()));
+ static constexpr bool grants_mutable_access = true;
+
+ private:
+
+ T C::* m_memptr;
+
+};
+
+template<class C, typename GRes, typename SRes, typename SArg>
+class getter_setter_access_policy {
+
+ public:
+
+ typedef GRes (C::*getter)() const;
+ typedef SRes (C::*setter)(SArg);
+
+ getter_setter_access_policy(const getter_setter_access_policy&) = default;
+ getter_setter_access_policy& operator=(const getter_setter_access_policy&) = default;
+
+ getter_setter_access_policy(getter g, setter s) : m_get(g), m_set(s) { }
+
+ inline GRes operator()(const void* vptr) const {
+ auto ptr = reinterpret_cast<const C*>(vptr);
+ return (*ptr.*m_get)();
}
- template<typename Map>
- void init_(typename std::enable_if<is_stl_compliant_map<Map>::value>::type* = 0) {
- m_members.push_back(member::fake_member(new map_member<Map>));
+ template<typename Arg>
+ inline void operator()(void* vptr, Arg&& value) const {
+ auto ptr = reinterpret_cast<C*>(vptr);
+ return (*ptr.*m_set)(std::forward<Arg>(value));
}
- template<typename List>
- void init_(typename std::enable_if<is_stl_compliant_list<List>::value>::type* = 0) {
- m_members.push_back(member::fake_member(new list_member<List>));
+ static constexpr bool grants_mutable_access = false;
+
+ private:
+
+ getter m_get;
+ setter m_set;
+
+};
+
+template<typename T>
+struct fake_access_policy {
+
+ inline T& operator()(void* vptr) const {
+ return *reinterpret_cast<T*>(vptr);
}
- template<typename X>
- void init_(typename std::enable_if<is_invalid<X>::value>::type* = 0) {
- // T is neither primitive nor a STL compliant list/map,
- // so it has to be an announced type
- static_assert(util::is_primitive<X>::value,
- "T is neither a primitive type nor a "
- "stl-compliant list/map");
+ inline const T& operator()(const void* vptr) const {
+ return *reinterpret_cast<const T*>(vptr);
+ }
+
+ static constexpr bool grants_mutable_access = true;
+
+};
+
+template<typename T, class C>
+unique_uti new_member_tinfo(T C::* memptr) {
+ typedef memptr_access_policy<T,C> access_policy;
+ typedef member_tinfo<T,access_policy> result_type;
+ return unique_uti(new result_type(memptr));
+}
+
+template<typename T, class C>
+unique_uti new_member_tinfo(T C::* memptr, std::unique_ptr<uniform_type_info> meminf) {
+ typedef memptr_access_policy<T,C> access_policy;
+ typedef member_tinfo<T,access_policy,forwarding_serialize_policy> result_type;
+ return unique_uti(new result_type(memptr, std::move(meminf)));
+}
+
+template<class C, typename GRes, typename SRes, typename SArg>
+unique_uti new_member_tinfo(GRes (C::*getter)() const, SRes (C::*setter)(SArg)) {
+ typedef getter_setter_access_policy<C, GRes, SRes, SArg> access_policy;
+ typedef typename util::rm_ref<GRes>::type value_type;
+ typedef member_tinfo<value_type,access_policy> result_type;
+ return unique_uti(new result_type(access_policy(getter, setter)));
+}
+
+template<class C, typename GRes, typename SRes, typename SArg>
+unique_uti new_member_tinfo(GRes (C::*getter)() const, SRes (C::*setter)(SArg), std::unique_ptr<uniform_type_info> meminf) {
+ typedef getter_setter_access_policy<C, GRes, SRes, SArg> access_policy;
+ typedef typename util::rm_ref<GRes>::type value_type;
+ typedef member_tinfo<value_type,access_policy,forwarding_serialize_policy> result_type;
+ return unique_uti(new result_type(access_policy(getter, setter), std::move(meminf)));
+}
+
+template<typename T>
+class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T> {
+
+ std::vector<unique_uti> m_members;
+
+ // terminates recursion
+ inline void push_back() { }
+
+ template<typename R, class C, typename... Args>
+ void push_back(R C::* memptr, Args&&... args) {
+ m_members.push_back(new_member_tinfo(memptr));
+ push_back(std::forward<Args>(args)...);
+ }
+
+ // pr.first = member pointer
+ // pr.second = meta object to handle pr.first
+ template<typename R, class C, typename... Args>
+ void push_back(const std::pair<R C::*, util::abstract_uniform_type_info<R>*>& pr,
+ Args&&... args) {
+ m_members.push_back(new_member_tinfo(pr.first, unique_uti(pr.second)));
+ push_back(std::forward<Args>(args)...);
+ }
+
+ // pr.first = getter / setter pair
+ // pr.second = meta object to handle pr.first
+ template<typename GRes, typename SRes, typename SArg, typename C, typename... Args>
+ void push_back(const std::pair<GRes (C::*)() const, SRes (C::*)(SArg)>& pr,
+ Args&&... args) {
+ m_members.push_back(new_member_tinfo(pr.first, pr.second));
+ push_back(std::forward<Args>(args)...);
+ }
+
+ // pr.first = getter / setter pair
+ // pr.second = meta object to handle pr.first
+ template<typename GRes, typename SRes, typename SArg, typename C, typename... Args>
+ void push_back(const std::pair<std::pair<GRes (C::*)() const, SRes (C::*)(SArg)>, util::abstract_uniform_type_info<typename util::rm_ref<GRes>::type>*>& pr,
+ Args&&... args) {
+ m_members.push_back(new_member_tinfo(pr.first.first, pr.first.second, unique_uti(pr.second)));
+ push_back(std::forward<Args>(args)...);
}
public:
@@ -333,16 +473,14 @@ class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T
}
default_uniform_type_info_impl() {
- init_<T>();
- if (m_members.size() != 1) {
- throw std::logic_error("no fake member added");
- }
+ typedef member_tinfo<T,fake_access_policy<T> > result_type;
+ m_members.push_back(unique_uti(new result_type));
}
void serialize(const void* obj, serializer* s) const {
s->begin_object(this->name());
for (auto& m : m_members) {
- m.serialize(obj, s);
+ m->serialize(obj, s);
}
s->end_object();
}
@@ -351,7 +489,7 @@ class default_uniform_type_info_impl : public util::abstract_uniform_type_info<T
this->assert_type_name(d);
d->begin_object(this->name());
for (auto& m : m_members) {
- m.deserialize(obj, d);
+ m->deserialize(obj, d);
}
d->end_object();
}
View
14 cppa/detail/disablable_delete.hpp
@@ -33,21 +33,25 @@
namespace cppa { namespace detail {
-template<typename T>
class disablable_delete {
- bool m_enabled;
-
public:
- disablable_delete() : m_enabled(true) { }
+ constexpr disablable_delete() : m_enabled(true) { }
- inline void disable() { m_enabled = false; }
+ inline void disable() {
+ m_enabled = false;
+ }
+ template<typename T>
inline void operator()(T* ptr) {
if (m_enabled) delete ptr;
}
+ private:
+
+ bool m_enabled;
+
};
} } // namespace cppa::detail
View
111 cppa/detail/list_member.hpp
@@ -1,111 +0,0 @@
-/******************************************************************************\
- * ___ __ *
- * /\_ \ __/\ \ *
- * \//\ \ /\_\ \ \____ ___ _____ _____ __ *
- * \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
- * \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
- * /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
- * \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
- * \ \_\ \ \_\ *
- * \/_/ \/_/ *
- * *
- * Copyright (C) 2011, 2012 *
- * Dominik Charousset <dominik.charousset@haw-hamburg.de> *
- * *
- * This file is part of libcppa. *
- * libcppa is free software: you can redistribute it and/or modify it under *
- * the terms of the GNU Lesser General Public License as published by the *
- * Free Software Foundation, either version 3 of the License *
- * or (at your option) any later version. *
- * *
- * libcppa is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
- * See the GNU Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public License *
- * along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
-\******************************************************************************/
-
-
-#ifndef CPPA_LIST_MEMBER_HPP
-#define CPPA_LIST_MEMBER_HPP
-
-#include "cppa/util/is_primitive.hpp"
-#include "cppa/util/abstract_uniform_type_info.hpp"
-
-namespace cppa { namespace detail {
-
-template<typename List, bool HasPrimitiveValues>
-struct list_member_util {
- typedef typename List::value_type value_type;
- static constexpr primitive_type vptype = type_to_ptype<value_type>::ptype;
- void operator()(const List& list, serializer* s) const {
- s->begin_sequence(list.size());
- for (auto i = list.begin(); i != list.end(); ++i) {
- s->write_value(*i);
- }
- s->end_sequence();
- }
- void operator()(List& list, deserializer* d) const {
- list.clear();
- auto size = d->begin_sequence();
- for (decltype(size) i = 0; i < size; ++i) {
- list.push_back(get<value_type>(d->read_value(vptype)));
- }
- d->end_sequence();
- }
-};
-
-template<typename List>
-struct list_member_util<List, false> {
- typedef typename List::value_type value_type;
-
- const uniform_type_info* m_value_type;
-
- list_member_util() : m_value_type(uniform_typeid<value_type>()) {
- }
-
- void operator()(const List& list, serializer* s) const {
- s->begin_sequence(list.size());
- for (auto i = list.begin(); i != list.end(); ++i) {
- m_value_type->serialize(&(*i), s);
- }
- s->end_sequence();
- }
-
- void operator()(List& list, deserializer* d) const {
- list.clear();
- value_type tmp;
- auto size = d->begin_sequence();
- for (decltype(size) i = 0; i < size; ++i) {
- m_value_type->deserialize(&tmp, d);
- list.push_back(tmp);
- }
- d->end_sequence();
- }
-};
-
-template<typename List>
-class list_member : public util::abstract_uniform_type_info<List> {
-
- typedef typename List::value_type value_type;
- list_member_util<List, util::is_primitive<value_type>::value> m_helper;
-
- public:
-
- void serialize(const void* obj, serializer* s) const {
- auto& list = *reinterpret_cast<const List*>(obj);
- m_helper(list, s);
- }
-
- void deserialize(void* obj, deserializer* d) const {
- auto& list = *reinterpret_cast<List*>(obj);
- m_helper(list, d);
- }
-
-};
-
-} } // namespace cppa::detail
-
-#endif // CPPA_LIST_MEMBER_HPP
View
150 cppa/detail/map_member.hpp
@@ -1,150 +0,0 @@
-/******************************************************************************\
- * ___ __ *
- * /\_ \ __/\ \ *
- * \//\ \ /\_\ \ \____ ___ _____ _____ __ *
- * \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
- * \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
- * /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
- * \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
- * \ \_\ \ \_\ *
- * \/_/ \/_/ *
- * *
- * Copyright (C) 2011, 2012 *
- * Dominik Charousset <dominik.charousset@haw-hamburg.de> *
- * *
- * This file is part of libcppa. *
- * libcppa is free software: you can redistribute it and/or modify it under *
- * the terms of the GNU Lesser General Public License as published by the *
- * Free Software Foundation, either version 3 of the License *
- * or (at your option) any later version. *
- * *
- * libcppa is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
- * See the GNU Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public License *
- * along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
-\******************************************************************************/
-
-
-#ifndef CPPA_MAP_MEMBER_HPP
-#define CPPA_MAP_MEMBER_HPP
-
-#include <type_traits>
-#include "cppa/detail/pair_member.hpp"
-#include "cppa/detail/primitive_member.hpp"
-#include "cppa/util/abstract_uniform_type_info.hpp"
-
-namespace cppa { namespace detail {
-
-template<typename T>
-struct is_pair { static constexpr bool value = false; };
-
-template<typename First, typename Second>
-struct is_pair< std::pair<First, Second> > { static constexpr bool value = true; };
-
-template<typename T, bool IsPair, bool IsPrimitive>
-struct map_member_util;
-
-// std::set with primitive value
-template<typename T>
-struct map_member_util<T, false, true> {
- primitive_member<T> impl;
-
- void serialize_value(const T& what, serializer* s) const {
- impl.serialize(&what, s);
- }
-
- template<typename M>
- void deserialize_and_insert(M& map, deserializer* d) const {
- T value;
- impl.deserialize(&value, d);
- map.insert(std::move(value));
- }
-};
-
-// std::set with non-primitive value
-template<typename T>
-struct map_member_util<T, false, false> {
- const uniform_type_info* m_type;
-
- map_member_util() : m_type(uniform_typeid<T>()) {
- }
-
- void serialize_value(const T& what, serializer* s) const {
- m_type->serialize(&what, s);
- }
-
- template<typename M>
- void deserialize_and_insert(M& map, deserializer* d) const {
- T value;
- m_type->deserialize(&value, d);
- map.insert(std::move(value));
- }
-};
-
-// std::map
-template<typename T>
-struct map_member_util<T, true, false> {
-
- // std::map defines its first half of value_type as const
- typedef typename std::remove_const<typename T::first_type>::type first_type;
- typedef typename T::second_type second_type;
-
- pair_member<first_type, second_type> impl;
-
-
- void serialize_value(const T& what, serializer* s) const {
- // impl needs a pair without const modifier
- std::pair<first_type, second_type> p(what.first, what.second);
- impl.serialize(&p, s);
- }
-
- template<typename M>
- void deserialize_and_insert(M& map, deserializer* d) const {
- std::pair<first_type, second_type> p;
- impl.deserialize(&p, d);
- std::pair<const first_type, second_type> v(std::move(p.first),
- std::move(p.second));
- map.insert(std::move(v));
- }
-
-};
-
-template<typename Map>
-class map_member : public util::abstract_uniform_type_info<Map> {
-
- typedef typename Map::key_type key_type;
- typedef typename Map::value_type value_type;
-
- map_member_util<value_type,
- is_pair<value_type>::value,
- util::is_primitive<value_type>::value> m_helper;
-
- public:
-
- void serialize(const void* obj, serializer* s) const {
- auto& mp = *reinterpret_cast<const Map*>(obj);
- s->begin_sequence(mp.size());
- for (const auto& val : mp) {
- m_helper.serialize_value(val, s);
- }
- s->end_sequence();
- }
-
- void deserialize(void* obj, deserializer* d) const {
- auto& mp = *reinterpret_cast<Map*>(obj);
- mp.clear();
- size_t mp_size = d->begin_sequence();
- for (size_t i = 0; i < mp_size; ++i) {
- m_helper.deserialize_and_insert(mp, d);
- }
- d->end_sequence();
- }
-
-};
-
-} } // namespace cppa::detail
-
-#endif // CPPA_MAP_MEMBER_HPP
View
66 cppa/detail/primitive_member.hpp
@@ -1,66 +0,0 @@
-/******************************************************************************\
- * ___ __ *
- * /\_ \ __/\ \ *
- * \//\ \ /\_\ \ \____ ___ _____ _____ __ *
- * \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
- * \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
- * /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
- * \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
- * \ \_\ \ \_\ *
- * \/_/ \/_/ *
- * *
- * Copyright (C) 2011, 2012 *
- * Dominik Charousset <dominik.charousset@haw-hamburg.de> *
- * *
- * This file is part of libcppa. *
- * libcppa is free software: you can redistribute it and/or modify it under *
- * the terms of the GNU Lesser General Public License as published by the *
- * Free Software Foundation, either version 3 of the License *
- * or (at your option) any later version. *
- * *
- * libcppa is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
- * See the GNU Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public License *
- * along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
-\******************************************************************************/
-
-
-#ifndef CPPA_PRIMITIVE_MEMBER_HPP
-#define CPPA_PRIMITIVE_MEMBER_HPP
-
-#include "cppa/serializer.hpp"
-#include "cppa/deserializer.hpp"
-#include "cppa/primitive_type.hpp"
-#include "cppa/primitive_variant.hpp"
-#include "cppa/detail/type_to_ptype.hpp"
-#include "cppa/util/abstract_uniform_type_info.hpp"
-
-namespace cppa { namespace detail {
-
-// uniform_type_info implementation for primitive data types.
-template<typename T>
-class primitive_member : public util::abstract_uniform_type_info<T> {
-
- static constexpr primitive_type ptype = type_to_ptype<T>::ptype;
-
- static_assert(ptype != pt_null, "T is not a primitive type");
-
- public:
-
- void serialize(const void* obj, serializer* s) const {
- s->write_value(*reinterpret_cast<const T*>(obj));
- }
-
- void deserialize(void* obj, deserializer* d) const {
- primitive_variant val(d->read_value(ptype));
- *reinterpret_cast<T*>(obj) = std::move(get<T>(val));
- }
-
-};
-
-} } // namespace cppa::detail
-
-#endif // CPPA_PRIMITIVE_MEMBER_HPP
View
33 examples/announce_example_1.cpp
@@ -4,10 +4,13 @@
#include <iostream>
#include "cppa/cppa.hpp"
+#include "cppa/binary_serializer.hpp"
+#include "cppa/binary_deserializer.hpp"
using std::cout;
using std::endl;
+using namespace std;
using namespace cppa;
// POD struct
@@ -28,11 +31,41 @@ typedef std::pair<int,int> foo_pair;
// another pair of two ints
typedef std::pair<int,int> foo_pair2;
+// a struct with member vector<vector<...>>
+struct foo2 {
+ int a;
+ vector<vector<double> > b;
+};
+
+bool operator==( const foo2& lhs, const foo2& rhs ) {
+ return lhs.a == rhs.a && lhs.b == rhs.b;
+}
+
int main(int, char**) {
+
// announces foo to the libcppa type system;
// the function expects member pointers to all elements of foo
assert(announce<foo>(&foo::a, &foo::b) == true);
+ // announce foo2 to the libcppa type system,
+ // note that recursive containers are managed automatically by libcppa
+ assert(announce<foo2>(&foo2::a, &foo2::b) == true);
+
+ foo2 vd;
+ vd.a = 5;
+ vd.b.resize(1);
+ vd.b.back().push_back(42);
+
+ util::buffer buf;
+ binary_serializer bs(&buf);
+ bs << vd;
+
+ binary_deserializer bd(buf.data(), buf.size());
+ foo2 vd2;
+ uniform_typeid<foo2>()->deserialize(&vd2, &bd);
+
+ assert(vd == vd2);
+
// announce std::pair<int,int> to the type system;
// NOTE: foo_pair is NOT distinguishable from foo_pair2!
assert(announce<foo_pair>(&foo_pair::first, &foo_pair::second) == true);
View
3  examples/type_plugins.hpp
@@ -24,6 +24,9 @@ inline void exec_plugin() {
}
}
}
+ else {
+ cerr << "*** plugin did not define symbol exec_plugin!" << endl;
+ }
}
}
View
4 unit_testing/test__serialization.cpp
@@ -1,3 +1,5 @@
+#define CPPA_VERBOSE_CHECK
+
#include "cppa/config.hpp"
#include <new>
@@ -185,7 +187,7 @@ int main() {
}
{
- any_tuple ttup = make_cow_tuple(1, 2, actor_ptr(self));
+ auto ttup = make_any_tuple(1, 2, actor_ptr(self));
util::buffer wr_buf;
binary_serializer bs(&wr_buf);
bs << ttup;
View
1  unit_testing/test__uniform_type.cpp
@@ -73,6 +73,7 @@ int main() {
"@i8", "@i16", "@i32", "@i64", // signed integer names
"@u8", "@u16", "@u32", "@u64", // unsigned integer names
"@str", "@u16str", "@u32str", // strings
+ "@strmap", // string containers
"float", "double", // floating points
"@0", // cppa::util::void_type
// default announced cppa types
Please sign in to comment.
Something went wrong with that request. Please try again.