Commit 1d3cce57 authored by neverlord's avatar neverlord

type system

parent d0c322ae
......@@ -64,8 +64,6 @@ src/deserializer.cpp
cppa/util/eval_type_list.hpp
cppa/util/is_legal_tuple_type.hpp
cppa/util/replace_type.hpp
cppa/util/source.hpp
cppa/util/sink.hpp
src/untyped_tuple.cpp
cppa/util/abstract_type_list.hpp
cppa/detail/serialize_tuple.hpp
......@@ -143,3 +141,5 @@ src/binary_serializer.cpp
cppa/binary_deserializer.hpp
src/binary_deserializer.cpp
src/actor.cpp
cppa/announce.hpp
src/abstract_type_list.cpp
......@@ -8,9 +8,9 @@ class actor_behavior
public:
virtual void act() = 0;
virtual ~actor_behavior();
virtual void on_exit();
virtual void act() = 0;
};
......
#ifndef ANNOUNCE_HPP
#define ANNOUNCE_HPP
#include <typeinfo>
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/uniform_type_info_base.hpp"
#include "cppa/detail/default_uniform_type_info_impl.hpp"
namespace cppa {
template<class C, class Parent, typename... Args>
std::pair<C Parent::*, util::uniform_type_info_base<C>*>
compound_member(C Parent::*c_ptr, const Args&... args)
{
return { c_ptr, new detail::default_uniform_type_info_impl<C>(args...) };
}
/**
* @brief Add a new type mapping to the libCPPA internal type system.
* @return <code>true</code> if @p uniform_type was added as known
* instance (mapped to @p plain_type); otherwise @c false
* is returned and @p uniform_type was deleted.
*/
bool announce(const std::type_info& tinfo, uniform_type_info* utype);
template<typename T, typename... Args>
inline bool announce(const Args&... args)
{
return announce(typeid(T),
new detail::default_uniform_type_info_impl<T>(args...));
}
} // namespace cppa
#endif // ANNOUNCE_HPP
......@@ -5,6 +5,7 @@ namespace cppa {
struct any_type
{
constexpr any_type() { }
inline operator any_type*() { return 0; }
};
......@@ -25,9 +26,9 @@ template<typename T>
inline bool operator!=(const any_type&, const T&) { return false; }
#ifdef __GNUC__
static any_type any_val __attribute__ ((unused));
static constexpr any_type any_val __attribute__ ((unused));
#else
static any_type any_val;
static constexpr any_type any_val;
#endif
} // namespace cppa
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 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_HPP
#define CPPA_HPP
......@@ -98,7 +126,7 @@ void reply(const Arg0& arg0, const Args&... args)
inline void await_all_actors_done()
{
get_scheduler()->await_all_done();
get_scheduler()->await_others_done();
}
} // namespace cppa
......
......@@ -9,6 +9,8 @@
namespace cppa {
class object;
class deserializer
{
......@@ -42,6 +44,8 @@ class deserializer
};
deserializer& operator>>(deserializer& d, object& what);
} // namespace cppa
#endif // DESERIALIZER_HPP
......@@ -22,7 +22,7 @@ struct matcher<Head, Tail...>
auto head_uti = uniform_typeid<Head>();
if (begin != end)
{
if (*(*begin) == *head_uti)
if (*begin == *head_uti)
{
if (res)
{
......
......@@ -10,8 +10,10 @@ class mock_scheduler : public scheduler
public:
actor_ptr spawn(actor_behavior* behavior, scheduling_hint hint);
void await_all_done();
void await_others_done();
void register_converted_context(context*);
void unregister_converted_context(context*);
actor_ptr spawn(actor_behavior*, scheduling_hint);
};
......
#ifndef PRIMITIVE_MEMBER_HPP
#define 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"
......
......@@ -116,7 +116,7 @@ struct object_caster
} // namespace detail
template<typename T>
T& get(object& obj)
T& get_ref(object& obj)
{
static_assert(util::disjunction<std::is_pointer<T>,
std::is_reference<T>>::value == false,
......@@ -128,7 +128,7 @@ template<typename T>
const T& get(const object& obj)
{
static_assert(util::disjunction<std::is_pointer<T>,
std::is_reference<T>>::value,
std::is_reference<T>>::value == false,
"T is a reference a pointer type.");
return detail::object_caster<T>::_(obj);
}
......
......@@ -2,12 +2,13 @@
#define SCHEDULER_HPP
#include "cppa/actor.hpp"
#include "cppa/context.hpp"
#include "cppa/actor_behavior.hpp"
#include "cppa/scheduling_hint.hpp"
namespace cppa {
class context;
class actor_behavior;
class scheduler
{
......@@ -16,16 +17,30 @@ class scheduler
virtual ~scheduler();
/**
* @brief Spawn a new actor that executes <code>behavior->act()</code>
* @brief Spawns a new actor that executes <code>behavior->act()</code>
* with the scheduling policy @p hint if possible.
*/
virtual actor_ptr spawn(actor_behavior* behavior,
scheduling_hint hint) = 0;
/**
* @brief Wait until all (other) actors finished execution.
* @brief Informs the scheduler about a converted context
* (a thread that acts as actor).
*/
virtual void register_converted_context(context* what) = 0;
/**
* @brief Informs the scheduler that the convertex context @p what
* finished execution.
*/
virtual void unregister_converted_context(context* what) = 0;
/**
* @brief Wait until all other actors finished execution.
* @warning This function causes a deadlock if it's called from
* more than one actor.
*/
virtual void await_all_done() = 0;
virtual void await_others_done() = 0;
};
......
......@@ -4,6 +4,9 @@
#include <string>
#include <cstddef> // size_t
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/to_uniform_name.hpp"
namespace cppa {
// forward declaration
......@@ -36,6 +39,19 @@ class serializer
};
template<typename T>
serializer& operator<<(serializer& s, const T& what)
{
auto mtype = uniform_typeid<T>();
if (mtype == nullptr)
{
throw std::logic_error( "no uniform type info found for "
+ cppa::detail::to_uniform_name(typeid(T)));
}
mtype->serialize(&what, &s);
return s;
}
} // namespace cppa
#endif // SERIALIZER_HPP
......@@ -9,8 +9,6 @@
#include <type_traits>
#include "cppa/object.hpp"
#include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/util/comparable.hpp"
#include "cppa/util/disjunction.hpp"
......@@ -21,6 +19,8 @@
namespace cppa {
class serializer;
class deserializer;
class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&);
......@@ -68,7 +68,7 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
public:
// enable copy constructor
// enable copy constructor (only)
identifier(const identifier&) = default;
// needed by cppa::detail::comparable<identifier>
......@@ -136,29 +136,6 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
return id().compare(other.id());
}
/**
* @brief Add a new type mapping to the libCPPA internal type system.
* @return <code>true</code> if @p uniform_type was added as known
* instance (mapped to @p plain_type); otherwise @c false
* is returned and @p uniform_type was deleted.
*/
// static bool announce(const std::type_info& plain_type,
// uniform_type_info* uniform_type);
/**
* auto concept value_type<typename T>
* {
* T();
* T(const T&);
* bool operator==(const T&, const T&);
* }
*/
// template<typename T,
// class SerializeFun, class DeserializeFun,
// class ToStringFun, class FromStringFun>
// static bool announce(const SerializeFun& sf, const DeserializeFun& df,
// const ToStringFun& ts, const FromStringFun& fs);
/**
* @brief Creates an object of this type.
*/
......
......@@ -26,8 +26,6 @@
#include "cppa/util/reverse_type_list.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/sink.hpp"
#include "cppa/util/source.hpp"
#include "cppa/util/type_at.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_list_apply.hpp"
......
......@@ -18,8 +18,8 @@ struct amb_helper : util::conjunction<util::is_one_of<HeadA, HeadB, any_type>,
typename TailB::head_type,
typename TailB::tail_type>>
{
static_assert( !std::is_same<HeadB, any_type>::value
&& !std::is_same<HeadB, any_type*>::value,
static_assert( std::is_same<HeadB, any_type>::value == false
&& std::is_same<HeadB, any_type*>::value == false,
"any_type in right hand type list");
};
......@@ -49,7 +49,7 @@ struct amb_helper<any_type*, TailA, HeadB, TailB>
typename TailB::head_type,
typename TailB::tail_type>>
{
static_assert(!std::is_same<HeadB, any_type>::value,
static_assert(std::is_same<HeadB, any_type>::value == false,
"any_type in right hand type list");
};
......
......@@ -2,9 +2,9 @@
#define ABSTRACT_TYPE_LIST_HPP
#include <iterator>
#include "cppa/uniform_type_info.hpp"
namespace cppa { class serializer; }
// forward declaration
namespace cppa { class uniform_type_info; }
namespace cppa { namespace util {
......@@ -19,12 +19,10 @@ struct abstract_type_list
public:
inline const_iterator(const uniform_type_info* const* x = nullptr) : p(x) { }
inline const_iterator(const uniform_type_info* const* x = 0) : p(x) { }
const_iterator(const_iterator&&) = default;
const_iterator(const const_iterator&) = default;
const_iterator& operator=(const_iterator&&) = default;
const_iterator& operator=(const const_iterator&) = default;
inline bool operator==(const const_iterator& other) const
......@@ -37,14 +35,14 @@ struct abstract_type_list
return p != other.p;
}
inline const uniform_type_info* operator*()
inline const uniform_type_info& operator*() const
{
return *p;
return *(*p);
}
inline const uniform_type_info* const* operator->()
inline const uniform_type_info* operator->() const
{
return p;
return *p;
}
inline const_iterator& operator++()
......@@ -53,12 +51,7 @@ struct abstract_type_list
return *this;
}
inline const_iterator operator++(int)
{
const_iterator tmp(*this);
operator++();
return tmp;
}
const_iterator operator++(int);
inline const_iterator& operator--()
{
......@@ -66,15 +59,12 @@ struct abstract_type_list
return *this;
}
inline const_iterator operator--(int)
{
const_iterator tmp(*this);
operator--();
return tmp;
}
const_iterator operator--(int);
};
virtual ~abstract_type_list();
virtual abstract_type_list* copy() const = 0;
virtual const_iterator begin() const = 0;
......
......@@ -53,7 +53,6 @@ struct min_
static const std::size_t value = min_impl<(A < B), A, B>::value;
};
} } // namespace cppa::detail
namespace cppa { namespace util {
......
......@@ -8,8 +8,8 @@ namespace cppa { namespace util {
template<typename T>
struct is_legal_tuple_type
{
static const bool value = !std::is_pointer<T>::value
&& !std::is_reference<T>::value;
static const bool value = std::is_pointer<T>::value == false
&& std::is_reference<T>::value == false;
};
} } // namespace cppa::util
......
#ifndef SINK_HPP
#define SINK_HPP
#include <cstddef>
#include "cppa/ref_counted.hpp"
namespace cppa { namespace util {
struct sink : public virtual ref_counted
{
virtual void write(std::size_t buf_size, const void* buf) = 0;
virtual void flush() = 0;
};
} } // namespace cppa::util
#endif // SINK_HPP
#ifndef SOURCE_HPP
#define SOURCE_HPP
#include <cstddef>
#include "cppa/ref_counted.hpp"
namespace cppa { namespace util {
struct source : public virtual ref_counted
{
virtual std::size_t read_some(std::size_t buf_size, void* buf) = 0;
virtual void read(std::size_t buf_size, void* buf) = 0;
};
} } // namespace cppa::util
#endif // SOURCE_HPP
......@@ -3,7 +3,6 @@
#include <typeinfo>
#include "cppa/any_type.hpp"
//#include "cppa/uniform_type_info.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/util/abstract_type_list.hpp"
......@@ -38,7 +37,10 @@ struct type_list<Head, Tail...> : abstract_type_list
static const std::size_t type_list_size = tail_type::type_list_size + 1;
type_list() { init<type_list>(m_arr); }
type_list()
{
init<type_list>(m_arr);
}
virtual const_iterator begin() const
{
......@@ -69,14 +71,6 @@ struct type_list<Head, Tail...> : abstract_type_list
++what;
init<typename TypeList::tail_type>(what);
}
/*
what[0] = &uniform_type_info<typename TypeList::head_type>();
if (TypeList::type_list_size > 1)
{
++what;
init<typename TypeList::tail_type>(what);
}
*/
}
private:
......
......@@ -68,7 +68,8 @@ HEADERS = cppa/actor.hpp \
cppa/util/type_list_pop_back.hpp \
cppa/util/void_type.hpp
SOURCES = src/actor.cpp \
SOURCES = src/abstract_type_list.cpp \
src/actor.cpp \
src/actor_behavior.cpp \
src/binary_deserializer.cpp \
src/binary_serializer.cpp \
......
#include "cppa/util/abstract_type_list.hpp"
namespace cppa { namespace util {
abstract_type_list::~abstract_type_list()
{
}
abstract_type_list::const_iterator
abstract_type_list::const_iterator::operator++(int)
{
const_iterator tmp(*this);
operator++();
return tmp;
}
abstract_type_list::const_iterator
abstract_type_list::const_iterator::operator--(int)
{
const_iterator tmp(*this);
operator--();
return tmp;
}
} } // namespace cppa::util
......@@ -2,6 +2,12 @@
namespace cppa {
void actor_behavior::on_exit() { }
actor_behavior::~actor_behavior()
{
}
void actor_behavior::on_exit()
{
}
} // namespace cppa
......@@ -5,11 +5,16 @@
#include <boost/thread.hpp>
#include "cppa/scheduler.hpp"
namespace {
void cleanup_fun(cppa::context* what)
{
if (what && !what->deref()) delete what;
if (what && !what->deref())
{
delete what;
}
}
boost::thread_specific_ptr<cppa::context> m_this_context(cleanup_fun);
......@@ -30,6 +35,7 @@ context* self()
{
result = new detail::converted_thread_context;
result->ref();
get_scheduler()->register_converted_context(result);
m_this_context.reset(result);
}
return result;
......
#include <string>
#include "cppa/object.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/to_uniform_name.hpp"
namespace cppa {
......@@ -6,4 +11,16 @@ deserializer::~deserializer()
{
}
deserializer& operator>>(deserializer& d, object& what)
{
std::string tname = d.peek_object();
auto mtype = uniform_type_info::by_uniform_name(tname);
if (mtype == nullptr)
{
throw std::logic_error("no uniform type info found for " + tname);
}
what = std::move(mtype->deserialize(&d));
return d;
}
} // namespace cppa
......@@ -10,10 +10,10 @@
#include "cppa/message.hpp"
#include "cppa/context.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/actor_behavior.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/converted_thread_context.hpp"
namespace {
......@@ -28,14 +28,12 @@ void run_actor(cppa::intrusive_ptr<cppa::context> m_self,
cppa::set_self(m_self.get());
if (behavior)
{
try
{
behavior->act();
}
try { behavior->act(); }
catch(...) { }
try { behavior->on_exit(); }
catch(...) { }
behavior->on_exit();
}
if (--m_running_actors == 0)
if (--m_running_actors <= 1)
{
boost::mutex::scoped_lock lock(m_ra_mtx);
m_ra_cv.notify_all();
......@@ -54,10 +52,24 @@ actor_ptr mock_scheduler::spawn(actor_behavior* ab, scheduling_hint)
return ctx;
}
void mock_scheduler::await_all_done()
void mock_scheduler::register_converted_context(context*)
{
++m_running_actors;
}
void mock_scheduler::unregister_converted_context(context*)
{
if (--m_running_actors <= 1)
{
boost::mutex::scoped_lock lock(m_ra_mtx);
m_ra_cv.notify_all();
}
}
void mock_scheduler::await_others_done()
{
boost::mutex::scoped_lock lock(m_ra_mtx);
while (m_running_actors.load() > 0)
while (m_running_actors.load() > 1)
{
m_ra_cv.wait(lock);
}
......
......@@ -11,6 +11,7 @@
#include "cppa/config.hpp"
#include "cppa/actor.hpp"
#include "cppa/announce.hpp"
#include "cppa/any_type.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/uniform_type_info.hpp"
......@@ -48,8 +49,8 @@ inline const char* raw_name(const std::type_info& tinfo)
}
template<typename T>
struct is_signed : std::integral_constant<bool,
std::numeric_limits<T>::is_signed>
struct is_signed
: std::integral_constant<bool, std::numeric_limits<T>::is_signed>
{
};
......@@ -177,7 +178,6 @@ class uniform_type_info_map
insert<long double>();
}
insert<any_type>();
// insert<actor_ptr>();
// first: signed
// second: unsigned
std::map<int, std::pair<string_set, string_set>> ints;
......@@ -240,6 +240,7 @@ class uniform_type_info_map
{
if (m_by_uname.count(what->name()) > 0)
{
delete what;
return false;
}
m_by_uname.insert(std::make_pair(what->name(), what));
......@@ -287,6 +288,11 @@ inline int next_id() { return s_ids.fetch_add(1); }
namespace cppa {
bool announce(const std::type_info& tinfo, uniform_type_info* utype)
{
return detail::s_uniform_type_info_map().insert({ raw_name(tinfo) }, utype);
}
uniform_type_info::uniform_type_info(const std::string& uname)
: m_id(next_id()), m_name(uname)
{
......
......@@ -23,6 +23,7 @@
#include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/announce.hpp"
#include "cppa/serializer.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/deserializer.hpp"
......@@ -369,108 +370,11 @@ class string_deserializer : public deserializer
};
std::map<std::string, std::unique_ptr<uniform_type_info> > s_types;
void announce(uniform_type_info* utype)
{
const auto& uname = utype->name();
if (s_types.count(uname) == 0)
{
std::unique_ptr<uniform_type_info> uptr(utype);
s_types.insert(std::make_pair(uname, std::move(uptr)));
}
else
{
cerr << utype->name() << " already announced" << endl;
delete utype;
}
}
uniform_type_info* get_meta_type(const std::string& tname)
{
auto i = s_types.find(tname);
return (i != s_types.end()) ? i->second.get() : nullptr;
}
uniform_type_info* get_meta_type(const std::type_info& tinfo)
{
return get_meta_type(detail::to_uniform_name(tinfo));
}
template<typename T>
uniform_type_info* get_meta_type()
{
return get_meta_type(detail::to_uniform_name(typeid(T)));
}
template<int>
inline void _announce_all() { }
template<int, typename T0, typename... Tn>
inline void _announce_all()
{
announce(new detail::default_uniform_type_info_impl<T0>);
_announce_all<0, Tn...>();
}
template<typename... Tn>
void announce_all()
{
_announce_all<0, Tn...>();
}
namespace {
class root_object_type
{
public:
root_object_type()
{
announce_all<std::int8_t, std::int16_t, std::int32_t, std::int64_t,
std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t,
float, double, long double,
std::string, std::u16string, std::u32string>();
}
template<typename T>
void serialize(const T& what, serializer* where) const
{
uniform_type_info* mtype = get_meta_type(detail::to_uniform_name(typeid(T)));
if (!mtype)
{
throw std::logic_error("no meta found for "
+ cppa::detail::to_uniform_name(typeid(T)));
}
mtype->serialize(&what, where);
}
/**
* @brief Deserializes a new object from @p source and returns the
* new (deserialized) instance with its meta_type.
*/
object deserialize(deserializer* source) const
{
std::string tname = source->peek_object();
uniform_type_info* mtype = get_meta_type(tname);
if (!mtype)
{
throw std::logic_error("no meta object found for " + tname);
}
return mtype->deserialize(source);
}
}
root_object;
} // namespace <anonymous>
template<typename T>
std::string to_string(const T& what)
{
std::string tname = detail::to_uniform_name(typeid(T));
auto mobj = get_meta_type(tname);
auto mobj = uniform_typeid<T>();
if (!mobj) throw std::logic_error(tname + " not found");
std::ostringstream osstr;
string_serializer strs(osstr);
......@@ -478,25 +382,6 @@ std::string to_string(const T& what)
return osstr.str();
}
template<typename T, typename... Args>
uniform_type_info* meta_object(const Args&... args)
{
return new detail::default_uniform_type_info_impl<T>(args...);
}
template<class C, class Parent, typename... Args>
std::pair<C Parent::*, uniform_type_info_base<C>*>
compound_member(C Parent::*c_ptr, const Args&... args)
{
return std::make_pair(c_ptr, meta_object<C>(args...));
}
template<typename T, typename... Args>
void announce(const Args&... args)
{
announce(meta_object<T>(args...));
}
std::size_t test__serialization()
{
CPPA_TEST(test__serialization);
......@@ -508,17 +393,14 @@ std::size_t test__serialization()
CPPA_CHECK_EQUAL((is_iterable<std::map<int,int>>::value), true);
// test meta_object implementation for primitive types
{
auto meta_int = get_meta_type<std::uint32_t>();
auto meta_int = uniform_typeid<std::uint32_t>();
CPPA_CHECK(meta_int != nullptr);
if (meta_int)
{
/*
auto o = meta_int->create();
auto str = to_string(*i);
CPPA_CHECK_EQUAL(*i, 0);
CPPA_CHECK_EQUAL(str, "@u32 ( 0 )");
meta_int->delete_instance(i);
*/
get_ref<std::uint32_t>(o) = 42;
auto str = to_string(get<std::uint32_t>(o));
CPPA_CHECK_EQUAL(str, "@u32 ( 42 )");
}
}
// test serializers / deserializers with struct_b
......@@ -538,27 +420,25 @@ std::size_t test__serialization()
"{ 4, 5, 6, 7, 8, 9, 10 } )";
// verify
CPPA_CHECK_EQUAL((to_string(b1)), b1str);
// binary buffer
std::pair<size_t, char*> buf;
{
// serialize b1 to buf
binary_serializer bs;
root_object.serialize(b1, &bs);
bs << b1;
// deserialize b2 from buf
binary_deserializer bd(bs.data(), bs.size());
object res = root_object.deserialize(&bd);
object res;
bd >> res;
CPPA_CHECK_EQUAL(res.type().name(), "struct_b");
b2 = get<struct_b>(res);
}
// cleanup
delete buf.second;
// verify result of serialization / deserialization
CPPA_CHECK_EQUAL(b1, b2);
CPPA_CHECK_EQUAL(to_string(b2), b1str);
// deserialize b3 from string, using string_deserializer
{
string_deserializer strd(b1str);
auto res = root_object.deserialize(&strd);
object res;
strd >> res;
CPPA_CHECK_EQUAL(res.type().name(), "struct_b");
b3 = get<struct_b>(res);
}
......@@ -574,10 +454,11 @@ std::size_t test__serialization()
{
// serialize c1 to buf
binary_serializer bs;
root_object.serialize(c1, &bs);
bs << c1;
// serialize c2 from buf
binary_deserializer bd(bs.data(), bs.size());
auto res = root_object.deserialize(&bd);
object res;
bd >> res;
CPPA_CHECK_EQUAL(res.type().name(), "struct_c");
c2 = get<struct_c>(res);
}
......
......@@ -21,9 +21,7 @@ void pong()
std::size_t test__spawn()
{
CPPA_TEST(test__spawn);
{
auto sl = spawn(pong);
send(sl, 23.f);
......@@ -32,9 +30,6 @@ std::size_t test__spawn()
CPPA_CHECK_EQUAL(value, 42);
});
}
await_all_actors_done();
return CPPA_TEST_RESULT;
}
......@@ -44,13 +44,13 @@ std::size_t test__type_list()
type_list<std::int32_t, float, char> ifc;
auto i = ifc.begin();
CPPA_CHECK((i != ifc.end()));
CPPA_CHECK(((*i)->name() == "@i32"));
CPPA_CHECK((i->name() == "@i32"));
++i;
CPPA_CHECK((i != ifc.end()));
CPPA_CHECK(((*i)->name() == "float"));
CPPA_CHECK((i->name() == "float"));
++i;
CPPA_CHECK((i != ifc.end()));
CPPA_CHECK(((*i)->name() == "@i8"));
CPPA_CHECK((i->name() == "@i8"));
++i;
CPPA_CHECK((i == ifc.end()));
......
......@@ -15,6 +15,7 @@
#include "test.hpp"
#include "cppa/announce.hpp"
#include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp"
......@@ -33,106 +34,76 @@ struct foo
explicit foo(int val = 0) : value(val) { }
};
bool operator==(const foo& lhs, const foo& rhs)
inline bool operator==(const foo& lhs, const foo& rhs)
{
return lhs.value == rhs.value;
}
inline bool operator!=(const foo& lhs, const foo& rhs)
{
return !(lhs == rhs);
}
} // namespace <anonymous>
using namespace cppa;
namespace {
bool unused1 = true;
/*
bool unused1 =
uniform_type_info::announce<foo>(
[] (serializer& s, const foo& f) {
s << f.value;
},
[] (deserializer& d, foo& f) {
d >> f.value;
},
[] (const foo& f) -> std::string {
std::ostringstream ostr;
ostr << f.value;
return ostr.str();
},
[] (const std::string& str) -> foo* {
std::istringstream istr(str);
int tmp;
istr >> tmp;
return new foo(tmp);
}
);
*/
bool unused2 = false;// = uniform_type_info::announce(typeid(foo), new uti_impl<foo>);
bool unused3 = false;//= uniform_type_info::announce(typeid(foo), new uti_impl<foo>);
bool unused4 = false;//= uniform_type_info::announce(typeid(foo), new uti_impl<foo>);
bool announce1 = announce<foo>(&foo::value);
bool announce2 = announce<foo>(&foo::value);
bool announce3 = announce<foo>(&foo::value);
bool announce4 = announce<foo>(&foo::value);
} // namespace <anonymous>
std::size_t test__uniform_type()
{
CPPA_TEST(test__uniform_type);
/*
{
//bar.create_object();
object obj1 = uniform_typeid<foo>()->create();
object obj2(obj1);
CPPA_CHECK_EQUAL(obj1, obj2);
get<foo>(obj1).value = 42;
get_ref<foo>(obj1).value = 42;
CPPA_CHECK(obj1 != obj2);
CPPA_CHECK_EQUAL(get<foo>(obj1).value, 42);
CPPA_CHECK_EQUAL(get<foo>(obj2).value, 0);
}
*/
int successful_announces = (unused1 ? 1 : 0)
+ (unused2 ? 1 : 0)
+ (unused3 ? 1 : 0)
+ (unused4 ? 1 : 0);
int successful_announces = (announce1 ? 1 : 0)
+ (announce2 ? 1 : 0)
+ (announce3 ? 1 : 0)
+ (announce4 ? 1 : 0);
CPPA_CHECK_EQUAL(successful_announces, 1);
// these types (and only those) are present if
// the uniform_type_info implementation is correct
std::set<std::string> expected =
{
// "@_::foo", // name of <anonymous namespace>::foo
"@_::foo", // <anonymous namespace>::foo
"@i8", "@i16", "@i32", "@i64", // signed integer names
"@u8", "@u16", "@u32", "@u64", // unsigned integer names
"@str", "@u16str", "@u32str", // strings
"float", "double", // floating points
"@0", // util::void_type
// default announced cppa types
"cppa::any_type",
"cppa::intrusive_ptr<cppa::actor>"
"@0", // cppa::util::void_type
"cppa::any_type", // default announced cppa type
"cppa::intrusive_ptr<cppa::actor>" // default announced cppa type
};
if (sizeof(double) != sizeof(long double))
{
// long double is only present if it's not an alias for double
expected.insert("long double");
}
// holds the type names we see at runtime
std::set<std::string> found;
// fetch all available type names
// fetch all available type names
auto types = uniform_type_info::instances();
for (uniform_type_info* tinfo : types)
{
found.insert(tinfo->name());
}
// compare the two sets
CPPA_CHECK_EQUAL(expected.size(), found.size());
bool expected_equals_found = false;
if (expected.size() == found.size())
{
expected_equals_found = std::equal(found.begin(),
......
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