Commit 53f29a60 authored by neverlord's avatar neverlord

first commit

parents
.DS_Store
*.o
test
#all:
# /opt/local/bin/g++-mp-4.5 -std=c++0x -g -O0 main.cpp
CXX = /opt/local/bin/g++-mp-4.5
#CXX = /opt/local/bin/g++-mp-4.6
CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -g -O0
LIBS =
INCLUDES = -I./
HEADERS = cppa/actor.hpp \
cppa/any_type.hpp \
cppa/config.hpp \
cppa/cow_ptr.hpp \
cppa/get.hpp \
cppa/intrusive_ptr.hpp \
cppa/invoke.hpp \
cppa/invoke_rules.hpp \
cppa/match.hpp \
cppa/message.hpp \
cppa/on.hpp \
cppa/ref_counted.hpp \
cppa/test.hpp \
cppa/tuple.hpp \
cppa/tuple_view.hpp \
cppa/uniform_type_info.hpp \
cppa/untyped_tuple.hpp \
cppa/util.hpp \
cppa/detail/abstract_tuple.hpp \
cppa/detail/decorated_tuple.hpp \
cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \
cppa/detail/matcher.hpp \
cppa/detail/ref_counted_impl.hpp \
cppa/detail/scheduler.hpp \
cppa/detail/tdata.hpp \
cppa/detail/tuple_vals.hpp \
cppa/util/a_matches_b.hpp \
cppa/util/callable_trait.hpp \
cppa/util/compare_tuples.hpp \
cppa/util/concat_type_lists.hpp \
cppa/util/conjunction.hpp \
cppa/util/detach.hpp \
cppa/util/disjunction.hpp \
cppa/util/eval_type_lists.hpp \
cppa/util/filter_type_list.hpp \
cppa/util/has_copy_member_fun.hpp \
cppa/util/is_comparable.hpp \
cppa/util/is_copyable.hpp \
cppa/util/is_one_of.hpp \
cppa/util/remove_const_reference.hpp \
cppa/util/reverse_type_list.hpp \
cppa/util/type_at.hpp \
cppa/util/type_list.hpp \
cppa/util/type_list_apply.hpp \
cppa/util/type_list_pop_back.hpp \
cppa/util/utype_iterator.hpp \
cppa/util/void_type.hpp
SOURCES = src/decorated_tuple.cpp \
src/deserializer.cpp \
src/main.cpp \
src/ref_counted.cpp \
src/serializer.cpp \
src/test__a_matches_b.cpp \
src/test__atom.cpp \
src/test__intrusive_ptr.cpp \
src/test__serialization.cpp \
src/test__spawn.cpp \
src/test__tuple.cpp \
src/test__type_list.cpp \
src/uniform_type_info.cpp \
src/untyped_tuple.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = test
%.o : %.cpp $(HEADERS)
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
$(EXECUTABLE) : $(OBJECTS) $(HEADERS)
$(CXX) $(LIBS) $(OBJECTS) -o $(EXECUTABLE)
all : $(SOURCES) $(EXECUTABLE)
clean:
rm -f $(OBJECTS) $(EXECUTABLE)
// ADD PREDEFINED MACROS HERE!
<!DOCTYPE QtCreatorProject>
<qtcreator>
<data>
<variable>RunConfiguration0-Arguments</variable>
<valuelist type="QVariantList"/>
</data>
<data>
<variable>RunConfiguration0-BaseEnvironmentBase</variable>
<value type="int">2</value>
</data>
<data>
<variable>RunConfiguration0-Executable</variable>
<value type="QString">/Users/neverlord/Desktop/libcppa/test</value>
</data>
<data>
<variable>RunConfiguration0-RunConfiguration.name</variable>
<value type="QString">test</value>
</data>
<data>
<variable>RunConfiguration0-UseTerminal</variable>
<value type="bool">false</value>
</data>
<data>
<variable>RunConfiguration0-UserEnvironmentChanges</variable>
<valuelist type="QVariantList"/>
</data>
<data>
<variable>RunConfiguration0-UserName</variable>
<value type="QString">test</value>
</data>
<data>
<variable>RunConfiguration0-UserSetName</variable>
<value type="bool">true</value>
</data>
<data>
<variable>RunConfiguration0-WorkingDirectory</variable>
<value type="QString">$BUILDDIR</value>
</data>
<data>
<variable>RunConfiguration0-type</variable>
<value type="QString">ProjectExplorer.CustomExecutableRunConfiguration</value>
</data>
<data>
<variable>activeRunConfiguration</variable>
<value type="int">0</value>
</data>
<data>
<variable>activebuildconfiguration</variable>
<value type="QString">all</value>
</data>
<data>
<variable>buildConfiguration-all</variable>
<valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value>
<value key="buildDirectory" type="QString">/Users/neverlord/Desktop/libcppa</value>
</valuemap>
</data>
<data>
<variable>buildconfiguration-all-buildstep0</variable>
<valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value>
<valuelist key="abstractProcess.Environment" type="QVariantList">
<value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-Ii2KqP/Render</value>
<value type="QString">COMMAND_MODE=unix2003</value>
<value type="QString">DISPLAY=/tmp/launch-6FAyZP/org.x:0</value>
<value type="QString">HOME=/Users/neverlord</value>
<value type="QString">LOGNAME=neverlord</value>
<value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value>
<value type="QString">SHELL=/bin/bash</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-vifjfO/Listeners</value>
<value type="QString">TMPDIR=/var/folders/1p/1p6iuPgbH7GoDkrjrT20tU+++TI/-Tmp-/</value>
<value type="QString">USER=neverlord</value>
<value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value>
</valuelist>
<valuelist key="abstractProcess.arguments" type="QVariantList">
<value type="QString">all</value>
</valuelist>
<value key="abstractProcess.command" type="QString">make</value>
<value key="abstractProcess.enabled" type="bool">true</value>
<value key="abstractProcess.workingDirectory" type="QString">/Users/neverlord/Desktop/libcppa</value>
<valuelist key="buildTargets" type="QVariantList">
<value type="QString">all</value>
</valuelist>
</valuemap>
</data>
<data>
<variable>buildconfigurations</variable>
<valuelist type="QVariantList">
<value type="QString">all</value>
</valuelist>
</data>
<data>
<variable>buildstep0</variable>
<valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString"></value>
</valuemap>
</data>
<data>
<variable>buildsteps</variable>
<valuelist type="QVariantList">
<value type="QString">GenericProjectManager.MakeStep</value>
</valuelist>
</data>
<data>
<variable>cleansteps</variable>
<valuelist type="QVariantList"/>
</data>
<data>
<variable>defaultFileEncoding</variable>
<value type="QByteArray">System</value>
</data>
<data>
<variable>includePaths</variable>
<valuelist type="QVariantList"/>
</data>
<data>
<variable>project</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>toolChain</variable>
<value type="int">0</value>
</data>
</qtcreator>
cppa/ref_counted.hpp
cppa/tuple.hpp
src/main.cpp
src/ref_counted.cpp
cppa/util/void_type.hpp
cppa/util/type_list.hpp
cppa/util/type_at.hpp
cppa/util/a_matches_b.hpp
cppa/util.hpp
cppa/util/is_one_of.hpp
cppa/util/conjunction.hpp
cppa/util/disjunction.hpp
cppa/test.hpp
src/test__a_matches_b.cpp
cppa/uniform_type_info.hpp
src/uniform_type_info.cpp
cppa/config.hpp
src/test__tuple.cpp
cppa/detail/abstract_tuple.hpp
cppa/tuple_view.hpp
cppa/untyped_tuple.hpp
cppa/any_type.hpp
cppa/util/utype_iterator.hpp
cppa/detail/matcher.hpp
cppa/detail/tuple_vals.hpp
cppa/match.hpp
src/decorated_tuple.cpp
cppa/detail/decorated_tuple.hpp
cppa/cow_ptr.hpp
cppa/util/detach.hpp
cppa/detail/ref_counted_impl.hpp
cppa/intrusive_ptr.hpp
cppa/detail/scheduler.hpp
src/test__spawn.cpp
src/mock_scheduler.cpp
cppa/actor.hpp
cppa/message.hpp
src/test__intrusive_ptr.cpp
cppa/util/concat_type_lists.hpp
cppa/util/filter_type_list.hpp
cppa/util/is_comparable.hpp
cppa/util/callable_trait.hpp
cppa/util/reverse_type_list.hpp
src/test__type_list.cpp
cppa/util/remove_const_reference.hpp
cppa/util/type_list_apply.hpp
cppa/util/eval_type_lists.hpp
cppa/util/compare_tuples.hpp
cppa/get.hpp
cppa/detail/tdata.hpp
cppa/util/is_copyable.hpp
cppa/util/has_copy_member_fun.hpp
cppa/detail/intermediate.hpp
cppa/detail/invokable.hpp
cppa/invoke_rules.hpp
cppa/util/type_list_pop_back.hpp
cppa/invoke.hpp
cppa/on.hpp
src/test__serialization.cpp
cppa/serializer.hpp
cppa/deserializer.hpp
cppa/util/is_serializable.hpp
cppa/util/enable_if.hpp
cppa/object.hpp
cppa/utype.hpp
cppa/detail/utype_impl.hpp
cppa/detail/object_impl.hpp
cppa/detail/swap_bytes.hpp
src/serializer.cpp
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
src/test__atom.cpp
/Users/neverlord/libcppa
#ifndef ACTOR_HPP
#define ACTOR_HPP
namespace cppa {
struct actor
{
template<typename... Args>
void send(const Args&...)
{
}
};
} // namespace cppa
#endif // ACTOR_HPP
#ifndef LIBCPPA_ANY_TYPE_HPP
#define LIBCPPA_ANY_TYPE_HPP
namespace cppa {
struct any_type
{
inline operator any_type*() { return 0; }
};
inline bool operator==(const any_type&, const any_type&) { return true; }
template<typename T>
inline bool operator==(const T&, const any_type&) { return true; }
template<typename T>
inline bool operator==(const any_type&, const T&) { return true; }
inline bool operator!=(const any_type&, const any_type&) { return false; }
template<typename T>
inline bool operator!=(const T&, const any_type&) { return false; }
template<typename T>
inline bool operator!=(const any_type&, const T&) { return false; }
#ifdef __GNUC__
static any_type any_val __attribute__ ((unused));
#else
static any_type any_val;
#endif
} // namespace cppa
#endif // LIBCPPA_ANY_TYPE_HPP
#ifndef CPPA_CONFIG_HPP
#define CPPA_CONFIG_HPP
#if defined(__GNUC__)
# define CPPA_GCC
#endif
#if defined(__APPLE__)
# define CPPA_MACOS
#elif defined(__GNUC__) && defined(__linux__)
# define CPPA_LINUX
#elif defined(WIN32)
# define CPPA_WINDOWS
#else
# error Plattform and/or compiler not supportet
#endif
#if defined(__amd64__) || defined(__LP64__)
# define CPPA_64BIT
#endif
#endif // CPPA_CONFIG_HPP
#ifndef COW_PTR_HPP
#define COW_PTR_HPP
#include <stdexcept>
#include "cppa/util/detach.hpp"
#include "cppa/intrusive_ptr.hpp"
namespace cppa {
template<typename T>
class cow_ptr
{
intrusive_ptr<T> m_ptr;
T* do_detach()
{
T* ptr = m_ptr.get();
if (!ptr->unique())
{
T* new_ptr = util::detach(ptr);
cow_ptr tmp(new_ptr);
swap(tmp);
return new_ptr;
}
return ptr;
}
public:
template<typename Y>
cow_ptr(Y* raw_ptr) : m_ptr(raw_ptr) { }
cow_ptr(T* raw_ptr) : m_ptr(raw_ptr) { }
cow_ptr(const cow_ptr& other) : m_ptr(other.m_ptr) { }
template<typename Y>
cow_ptr(const cow_ptr<Y>& other) : m_ptr(const_cast<Y*>(other.get())) { }
const T* get() const { return m_ptr.get(); }
inline void swap(cow_ptr& other)
{
m_ptr.swap(other.m_ptr);
}
cow_ptr& operator=(const cow_ptr& other)
{
cow_ptr tmp(other);
swap(tmp);
return *this;
}
template<typename Y>
cow_ptr& operator=(const cow_ptr<Y>& other)
{
cow_ptr tmp(other);
swap(tmp);
return *this;
}
T* operator->() { return do_detach(); }
T& operator*() { return do_detach(); }
const T* operator->() const { return m_ptr.get(); }
const T& operator*() const { return *m_ptr.get(); }
explicit operator bool() const { return m_ptr.get() != 0; }
};
} // namespace cppa
#endif // COW_PTR_HPP
#ifndef DESERIALIZER_HPP
#define DESERIALIZER_HPP
#include <string>
#include <cstddef>
#include <type_traits>
#include "cppa/any_type.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/util/source.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/detail/swap_bytes.hpp"
namespace cppa { namespace util {
struct void_type;
} } // namespace cppa::util
namespace cppa {
class deserializer
{
intrusive_ptr<util::source> m_src;
public:
deserializer(const intrusive_ptr<util::source>& data_source);
inline void read(std::size_t buf_size, void* buf)
{
m_src->read(buf_size, buf);
}
};
} // namespace cppa
cppa::deserializer& operator>>(cppa::deserializer&, std::string&);
template<typename T>
typename cppa::util::enable_if<std::is_integral<T>, cppa::deserializer&>::type
operator>>(cppa::deserializer& d, T& value)
{
d.read(sizeof(T), &value);
value = cppa::detail::swap_bytes(value);
return d;
}
template<typename T>
typename cppa::util::enable_if<std::is_floating_point<T>,
cppa::deserializer&>::type
operator>>(cppa::deserializer& d, T& value)
{
d.read(sizeof(T), &value);
return d;
}
inline cppa::deserializer& operator>>(cppa::deserializer& d,
cppa::util::void_type&)
{
return d;
}
inline cppa::deserializer& operator>>(cppa::deserializer& d, cppa::any_type&)
{
return d;
}
#endif // DESERIALIZER_HPP
#ifndef ABSTRACT_TUPLE_HPP
#define ABSTRACT_TUPLE_HPP
#include "cppa/ref_counted.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
namespace cppa { namespace detail {
struct abstract_tuple : ref_counted
{
// mutators
virtual void* mutable_at(std::size_t pos) = 0;
// accessors
virtual std::size_t size() const = 0;
virtual abstract_tuple* copy() const = 0;
virtual const void* at(std::size_t pos) const = 0;
virtual const utype& utype_at(std::size_t pos) const = 0;
virtual const util::abstract_type_list& types() const = 0;
virtual bool equal_to(const abstract_tuple& other) const = 0;
virtual void serialize(serializer&) const = 0;
};
} } // namespace cppa::detail
#endif // ABSTRACT_TUPLE_HPP
#ifndef DECORATED_TUPLE_HPP
#define DECORATED_TUPLE_HPP
#include <vector>
#include "cppa/cow_ptr.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/serialize_tuple.hpp"
namespace cppa { namespace detail {
template<typename... ElementTypes>
class decorated_tuple : public abstract_tuple
{
public:
typedef util::type_list<ElementTypes...> element_types;
typedef cow_ptr<abstract_tuple> ptr_type;
decorated_tuple(const ptr_type& d,
const std::vector<std::size_t>& v)
: m_decorated(d), m_mappings(v)
{
}
virtual void* mutable_at(std::size_t pos)
{
return m_decorated->mutable_at(m_mappings[pos]);
}
virtual std::size_t size() const
{
return m_mappings.size();
}
virtual decorated_tuple* copy() const
{
return new decorated_tuple(*this);
}
virtual const void* at(std::size_t pos) const
{
return m_decorated->at(m_mappings[pos]);
}
virtual const utype& utype_at(std::size_t pos) const
{
return m_decorated->utype_at(m_mappings[pos]);
}
virtual const util::abstract_type_list& types() const
{
return m_types;
}
virtual bool equal_to(const abstract_tuple&) const
{
return false;
}
virtual void serialize(serializer& s) const
{
s << static_cast<std::uint8_t>(element_types::type_list_size);
serialize_tuple<element_types>::_(s, this);
}
private:
ptr_type m_decorated;
std::vector<std::size_t> m_mappings;
element_types m_types;
decorated_tuple(const decorated_tuple& other)
: abstract_tuple()
, m_decorated(other.m_decorated)
, m_mappings(other.m_mappings)
{
}
decorated_tuple& operator=(const decorated_tuple&) = delete;
};
} } // namespace cppa::detail
#endif // DECORATED_TUPLE_HPP
#ifndef INTERMEDIATE_HPP
#define INTERMEDIATE_HPP
#include "cppa/detail/ref_counted_impl.hpp"
namespace cppa { namespace detail {
// intermediate is NOT thread safe
class intermediate : public ref_counted_impl<std::size_t>
{
intermediate(const intermediate&) = delete;
intermediate& operator=(const intermediate&) = delete;
public:
intermediate() = default;
virtual void invoke() = 0;
};
template<typename Impl, typename View>
class intermediate_impl : public intermediate
{
Impl m_impl;
View m_view;
public:
intermediate_impl(const Impl& impl, const View& view)
: intermediate(), m_impl(impl), m_view(view)
{
}
virtual void invoke()
{
m_impl(m_view);
}
};
} } // namespace cppa::detail
#endif // INTERMEDIATE_HPP
#ifndef INVOKABLE_HPP
#define INVOKABLE_HPP
#include "cppa/detail/ref_counted_impl.hpp"
namespace cppa { namespace detail {
class intermediate;
// invokable is NOT thread safe
class invokable : public ref_counted_impl<std::size_t>
{
invokable(const invokable&) = delete;
invokable& operator=(const invokable&) = delete;
public:
invokable() = default;
virtual bool invoke(const untyped_tuple&) const = 0;
virtual intermediate* get_intermediate(const untyped_tuple&) const = 0;
};
template<typename Invoker, typename Getter>
class invokable_impl : public invokable
{
Invoker m_inv;
Getter m_get;
public:
invokable_impl(Invoker&& i, Getter&& g) : m_inv(i), m_get(g) { }
virtual bool invoke(const untyped_tuple& t) const
{
return m_inv(t);
}
virtual intermediate* get_intermediate(const untyped_tuple& t) const
{
return m_get(t);
}
};
} } // namespace cppa::detail
#endif // INVOKABLE_HPP
#ifndef MATCHER_HPP
#define MATCHER_HPP
#include <vector>
#include "cppa/any_type.hpp"
#include "cppa/util/utype_iterator.hpp"
namespace cppa { namespace detail {
template<typename... Types> struct matcher;
template<typename Head, typename... Tail>
struct matcher<Head, Tail...>
{
static bool match(util::utype_iterator& begin,
util::utype_iterator& end,
std::vector<std::size_t>* res = 0,
std::size_t pos = 0)
{
if (begin != end)
{
if (begin->native() == typeid(Head))
{
if (res)
{
res->push_back(pos);
}
++begin;
++pos;
return matcher<Tail...>::match(begin, end, res, pos);
}
}
return false;
}
};
template<typename... Tail>
struct matcher<any_type, Tail...>
{
static bool match(util::utype_iterator &begin,
util::utype_iterator &end,
std::vector<std::size_t>* res = 0,
std::size_t pos = 0)
{
if (begin != end)
{
++begin;
++pos;
return matcher<Tail...>::match(begin, end, res, pos);
}
return false;
}
};
template<typename Next, typename... Tail>
struct matcher<any_type*, Next, Tail...>
{
static bool match(util::utype_iterator &begin,
util::utype_iterator &end,
std::vector<std::size_t>* res = 0,
std::size_t pos = 0)
{
bool result = false;
while (!result)
{
util::utype_iterator begin_cpy = begin;
result = matcher<Next, Tail...>::match(begin_cpy, end, 0, pos);
if (!result)
{
++begin;
++pos;
if (begin == end) return false;
}
else if (res)
{
// one more iteration to store mappings
begin_cpy = begin;
(void) matcher<Next, Tail...>::match(begin_cpy, end, res, pos);
}
}
return result;
}
};
template<>
struct matcher<any_type*>
{
static bool match(util::utype_iterator&,
util::utype_iterator&,
std::vector<std::size_t>* = 0,
std::size_t = 0)
{
return true;
}
};
template<>
struct matcher<>
{
static bool match(util::utype_iterator& begin,
util::utype_iterator& end,
std::vector<std::size_t>* = 0,
std::size_t = 0)
{
return begin == end;
}
};
} } // namespace cppa::detail
#endif // MATCHER_HPP
#ifndef OBJECT_IMPL_HPP
#define OBJECT_IMPL_HPP
#include "cppa/object.hpp"
namespace cppa {
template<typename T>
const utype& uniform_type_info();
}
namespace cppa { namespace detail {
template<typename T>
struct obj_impl : object
{
T m_value;
obj_impl() : m_value() { }
obj_impl(const T& v) : m_value(v) { }
virtual object* copy() const { return new obj_impl(m_value); }
virtual const utype& type() const { return uniform_type_info<T>(); }
virtual void* mutable_value() { return &m_value; }
virtual const void* value() const { return &m_value; }
virtual void serialize(serializer& s) const
{
s << m_value;
}
virtual void deserialize(deserializer& d)
{
d >> m_value;
}
};
} } // namespace cppa::detail
#endif // OBJECT_IMPL_HPP
#ifndef REF_COUNTED_IMPL_HPP
#define REF_COUNTED_IMPL_HPP
namespace cppa { namespace detail {
template<typename T>
class ref_counted_impl
{
T m_rc;
ref_counted_impl(const ref_counted_impl&) = delete;
ref_counted_impl& operator=(const ref_counted_impl&) = delete;
public:
virtual ~ref_counted_impl() { }
inline ref_counted_impl() : m_rc(0) { }
inline void ref() { ++m_rc; }
inline bool deref() { return (--m_rc > 0); }
inline bool unique() { return (m_rc == 0); }
};
} } // namespace cppa::detail
#endif // REF_COUNTED_IMPL_HPP
#ifndef SCHEDULER_HPP
#define SCHEDULER_HPP
#include "cppa/actor.hpp"
#include "cppa/message.hpp"
namespace cppa { namespace detail {
// public part of the actor interface (callable from other actors)
struct actor_public
{
virtual void enqueue_msg(const message& msg) = 0;
};
// private part of the actor interface (callable only from this_actor())
struct actor_private : public actor_public
{
virtual message dequeue_msg() = 0;
};
actor_private* this_actor();
actor spawn_impl();
} } // namespace cppa::detail
#endif // SCHEDULER_HPP
#ifndef SERIALIZE_TUPLE_HPP
#define SERIALIZE_TUPLE_HPP
#include <cstddef>
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
namespace cppa { class serializer; }
namespace cppa { namespace detail {
template<typename List, std::size_t Pos = 0>
struct serialize_tuple
{
template<typename T>
inline static void _(serializer& s, const T* self)
{
s << uniform_type_info<typename List::head_type>().name()
<< *reinterpret_cast<const typename List::head_type*>(self->at(Pos));
serialize_tuple<typename List::tail_type, Pos + 1>::_(s, self);
}
};
template<std::size_t Pos>
struct serialize_tuple<util::type_list<>, Pos>
{
template<typename T>
inline static void _(serializer&, const T*) { }
};
} } // namespace cppa::detail
#endif // SERIALIZE_TUPLE_HPP
#ifndef SWAP_BYTES_HPP
#define SWAP_BYTES_HPP
#include <cstddef>
namespace cppa { namespace detail {
template<typename T>
struct byte_access
{
union
{
T value;
unsigned char bytes[sizeof(T)];
};
inline byte_access(T val = 0) : value(val) { }
};
template<std::size_t SizeOfT, typename T>
struct byte_swapper
{
static T _(byte_access<T> from)
{
byte_access<T> to;
auto i = SizeOfT - 1;
for (std::size_t j = 0 ; j < SizeOfT ; --i, ++j)
{
to.bytes[i] = from.bytes[j];
}
return to.value;
}
};
template<typename T>
struct byte_swapper<1, T>
{
inline static T _(T what) { return what; }
};
template<typename T>
inline T swap_bytes(T what)
{
return byte_swapper<sizeof(T), T>::_(what);
}
} } // namespace cppa::detail
#endif // SWAP_BYTES_HPP
#ifndef TDATA_HPP
#define TDATA_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace detail {
template<typename... ElementTypes>
struct tdata;
template<>
struct tdata<>
{
typedef util::type_list<> element_types;
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size;
util::void_type head;
tdata<>& tail()
{
throw std::out_of_range("");
}
const tdata<>& tail() const
{
throw std::out_of_range("");
}
inline bool operator==(const tdata&) const
{
return true;
}
};
template<typename Head, typename... Tail>
struct tdata<Head, Tail...> : tdata<Tail...>
{
typedef tdata<Tail...> super;
typedef util::type_list<Head, Tail...> element_types;
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size;
Head head;
inline tdata() : super(), head() { }
tdata(const Head& v0, const Tail&... vals) : super(vals...), head(v0) { }
inline tdata<Tail...>& tail()
{
// upcast
return *this;
}
inline const tdata<Tail...>& tail() const
{
// upcast
return *this;
}
inline bool operator==(const tdata& other) const
{
return head == other.head && tail() == other.tail();
}
};
template<std::size_t N, typename... ElementTypes>
struct tdata_upcast_helper;
template<std::size_t N, typename Head, typename... Tail>
struct tdata_upcast_helper<N, Head, Tail...>
{
typedef typename tdata_upcast_helper<N-1, Tail...>::type type;
};
template<typename Head, typename... Tail>
struct tdata_upcast_helper<0, Head, Tail...>
{
typedef tdata<Head, Tail...> type;
};
template<std::size_t N, typename... ElementTypes>
const typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get(const tdata<ElementTypes...>& tv)
{
static_assert(N < util::type_list<ElementTypes...>::type_list_size,
"N < tv.size()");
return static_cast<const typename tdata_upcast_helper<N, ElementTypes...>::type&>(tv).head;
}
template<std::size_t N, typename... ElementTypes>
typename util::type_at<N, util::type_list<ElementTypes...>>::type&
tdata_get_ref(tdata<ElementTypes...>& tv)
{
static_assert(N < util::type_list<ElementTypes...>::type_list_size,
"N >= tv.size()");
return static_cast<typename tdata_upcast_helper<N, ElementTypes...>::type &>(tv).head;
}
} } // namespace cppa::detail
#endif // TDATA_HPP
#ifndef TUPLE_VALS_HPP
#define TUPLE_VALS_HPP
#include <stdexcept>
#include "cppa/util/type_list.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/serialize_tuple.hpp"
namespace cppa { namespace detail {
template<typename... ElementTypes>
class tuple_vals : public abstract_tuple
{
typedef abstract_tuple super;
typedef tdata<ElementTypes...> data_type;
typedef util::type_list<ElementTypes...> element_types;
data_type m_data;
element_types m_types;
template<typename... Types>
void* tdata_mutable_at(tdata<Types...>& d, std::size_t pos)
{
return (pos == 0) ? &(d.head) : tdata_mutable_at(d.tail(), pos - 1);
}
template<typename... Types>
const void* tdata_at(const tdata<Types...>& d, std::size_t pos) const
{
return (pos == 0) ? &(d.head) : tdata_at(d.tail(), pos - 1);
}
public:
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size;
tuple_vals(const tuple_vals& other) : super(), m_data(other.m_data) { }
tuple_vals() : m_data() { }
tuple_vals(const ElementTypes&... args) : m_data(args...) { }
inline const data_type& data() const { return m_data; }
inline data_type& data_ref() { return m_data; }
virtual void* mutable_at(std::size_t pos)
{
return tdata_mutable_at(m_data, pos);
}
virtual std::size_t size() const
{
return element_types::type_list_size;
}
virtual tuple_vals* copy() const
{
return new tuple_vals(*this);
}
virtual const void* at(std::size_t pos) const
{
return tdata_at(m_data, pos);
}
virtual const utype& utype_at(std::size_t pos) const
{
return m_types.at(pos);
}
virtual const util::abstract_type_list& types() const
{
return m_types;
}
virtual bool equal_to(const abstract_tuple& other) const
{
const tuple_vals* o = dynamic_cast<const tuple_vals*>(&other);
if (o)
{
return m_data == (o->m_data);
}
return false;
}
virtual void serialize(serializer& s) const
{
s << static_cast<std::uint8_t>(element_types::type_list_size);
serialize_tuple<element_types>::_(s, this);
}
};
} } // namespace cppa::detail
#endif // TUPLE_VALS_HPP
#ifndef UTYPE_IMPL_HPP
#define UTYPE_IMPL_HPP
#include <map>
#include <string>
#include "cppa/utype.hpp"
#include "cppa/detail/object_impl.hpp"
namespace cppa { namespace detail {
std::string demangle(const char*);
std::map<std::string, utype*>& uniform_types();
template<typename T>
class utype_impl : public utype
{
const std::string m_name;
const std::type_info& m_native;
utype_impl() : m_name(demangle(typeid(T).name())), m_native(typeid(T))
{
(uniform_types())[m_name] = this;
}
public:
static const utype_impl instance;
std::uint8_t announce_helper() const { return 42; }
virtual object* create() const
{
return new obj_impl<T>;
}
virtual const std::string& name() const
{
return m_name;
}
virtual const std::type_info& native() const
{
return m_native;
}
};
template<typename A> const utype_impl<A> utype_impl<A>::instance;
} } // namespace cppa::detail
#endif // UTYPE_IMPL_HPP
#ifndef GET_HPP
#define GET_HPP
#include <cstddef>
#include "cppa/util/type_at.hpp"
#include "cppa/util/type_list.hpp"
namespace cppa {
// forward declaration of tuple
template<typename... ElementTypes>
class tuple;
// forward declaration of tuple_view
template<typename... ElementTypes>
class tuple_view;
// forward declarations of get(...)
template<std::size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
get(const tuple<Types...>& t);
template<std::size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
get(const tuple_view<Types...>& t);
// forward declarations of get(...)
template<std::size_t N, typename... Types>
typename util::type_at<N, util::type_list<Types...>>::type&
get_ref(tuple<Types...>& t);
template<std::size_t N, typename... Types>
typename util::type_at<N, util::type_list<Types...>>::type&
get_ref(tuple_view<Types...>& t);
} // namespace cppa
#endif // GET_HPP
#ifndef INTRUSIVE_PTR_HPP
#define INTRUSIVE_PTR_HPP
#include <algorithm>
#include <stdexcept>
namespace cppa {
template<typename T>
class intrusive_ptr
{
T* m_ptr;
inline void init(T* raw_ptr)
{
m_ptr = raw_ptr;
if (raw_ptr) raw_ptr->ref();
}
public:
intrusive_ptr() : m_ptr(0) { }
template<typename Y>
intrusive_ptr(Y* raw_ptr) { init(raw_ptr); }
intrusive_ptr(T* raw_ptr) { init(raw_ptr); }
intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.m_ptr)
{
other.m_ptr = 0;
}
intrusive_ptr(const intrusive_ptr& other) { init(other.m_ptr); }
template<typename Y>
intrusive_ptr(const intrusive_ptr<Y>& other)
{
init(const_cast<Y*>(other.get()));
}
~intrusive_ptr() { if (m_ptr && !m_ptr->deref()) delete m_ptr; }
T* get() { return m_ptr; }
const T* get() const { return m_ptr; }
void swap(intrusive_ptr& other)
{
std::swap(m_ptr, other.m_ptr);
}
intrusive_ptr& operator=(const intrusive_ptr& other)
{
intrusive_ptr tmp(other);
swap(tmp);
return *this;
}
template<typename Y>
intrusive_ptr& operator=(const intrusive_ptr<Y>& other)
{
intrusive_ptr tmp(other);
swap(tmp);
return *this;
}
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }
const T* operator->() const { return m_ptr; }
const T& operator*() const { return *m_ptr; }
inline explicit operator bool() const { return m_ptr != 0; }
};
template<typename X, typename Y>
bool operator==(const intrusive_ptr<X>& lhs, const Y* rhs)
{
return lhs.get() == rhs;
}
template<typename X, typename Y>
bool operator==(const X* lhs, const intrusive_ptr<Y>& rhs)
{
return lhs == rhs.get();
}
template<typename X, typename Y>
bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs)
{
return lhs.get() == rhs.get();
}
template<typename X, typename Y>
bool operator!=(const intrusive_ptr<X>& lhs, const Y* rhs)
{
return !(lhs == rhs);
}
template<typename X, typename Y>
bool operator!=(const X* lhs, const intrusive_ptr<Y>& rhs)
{
return !(lhs == rhs);
}
template<typename X, typename Y>
bool operator!=(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs)
{
return !(lhs == rhs);
}
template<typename X>
bool operator==(const intrusive_ptr<X>& lhs, const X* rhs)
{
return lhs.get() == rhs;
}
template<typename X>
bool operator==(const X* lhs, const intrusive_ptr<X>& rhs)
{
return lhs == rhs.get();
}
template<typename X>
bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<X>& rhs)
{
return lhs.get() == rhs.get();
}
template<typename X>
bool operator!=(const intrusive_ptr<X>& lhs, const X* rhs)
{
return !(lhs == rhs);
}
template<typename X>
bool operator!=(const X* lhs, const intrusive_ptr<X>& rhs)
{
return !(lhs == rhs);
}
template<typename X>
bool operator!=(const intrusive_ptr<X>& lhs, const intrusive_ptr<X>& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa
#endif // INTRUSIVE_PTR_HPP
#ifndef INVOKE_HPP
#define INVOKE_HPP
#include <type_traits>
#include "cppa/tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/type_at.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/reverse_type_list.hpp"
#include "cppa/util/type_list_pop_back.hpp"
namespace cppa { namespace detail {
template<std::size_t N, typename F, typename Tuple,
typename ArgTypeList, typename... Args>
struct invoke_helper
{
typedef typename util::reverse_type_list<ArgTypeList>::type::head_type back_type;
typedef typename util::type_at<N, Tuple>::type tuple_val_type;
typedef typename util::type_list_pop_back<ArgTypeList>::type next_list;
inline static void _(F& f, const Tuple& t, const Args&... args)
{
static_assert(std::is_convertible<tuple_val_type, back_type>::value,
"tuple element is not convertible to expected argument");
invoke_helper<N - 1, F, Tuple, next_list, tuple_val_type, Args...>
::_(f, t, t.get<N>(), args...);
}
};
template<std::size_t N, typename F, typename Tuple, typename... Args>
struct invoke_helper<N, F, Tuple, util::type_list<>, Args...>
{
inline static void _(F& f, const Tuple&, const Args&... args)
{
f(args...);
}
};
template<bool HasCallableTrait, typename Tuple, typename F>
struct invoke_impl
{
typedef typename util::callable_trait<F>::arg_types arg_types;
static const std::size_t tuple_size = Tuple::type_list_size - 1;
inline static void _(F& f, const Tuple& t)
{
invoke_helper<tuple_size, F, Tuple, arg_types>::_(f, t);
}
};
template<typename Tuple, typename F>
struct invoke_impl<false, Tuple, F>
{
typedef typename util::callable_trait<decltype(&F::operator())>::arg_types
arg_types;
static const std::size_t tuple_size = Tuple::type_list_size - 1;
inline static void _(F& f, const Tuple& t)
{
invoke_helper<tuple_size, F, Tuple, arg_types>::_(f, t);
}
};
} } // namespace cppa::detail
namespace cppa {
template<typename Tuple, typename F>
void invoke(F what, const Tuple& args)
{
typedef typename std::remove_pointer<F>::type f_type;
detail::invoke_impl<std::is_function<f_type>::value, Tuple, F>::_(what, args);
}
} // namespace cppa
#endif // INVOKE_HPP
#ifndef INVOKE_RULES_HPP
#define INVOKE_RULES_HPP
#include "cppa/invoke.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp"
namespace cppa {
struct invoke_rules
{
std::list<intrusive_ptr<detail::invokable>> m_list;
public:
invoke_rules() { }
invoke_rules(intrusive_ptr<detail::invokable>&& arg)
{
if (arg) m_list.push_back(arg);
}
bool operator()(const untyped_tuple& t) const
{
for (auto i = m_list.begin(); i != m_list.end(); ++i)
{
if ((*i)->invoke(t)) return true;
}
return false;
}
intrusive_ptr<detail::intermediate> get_intermediate(const untyped_tuple& t) const
{
detail::intermediate* result;
for (auto i = m_list.begin(); i != m_list.end(); ++i)
{
result = (*i)->get_intermediate(t);
if (result) return result;
}
return 0;
}
invoke_rules& operator,(invoke_rules&& other)
{
for (auto i = other.m_list.begin(); i != other.m_list.end(); ++i)
{
if (*i) m_list.push_back(std::move(*i));
}
other.m_list.clear();
return *this;
}
};
} // namespace cppa
#endif // INVOKE_RULES_HPP
#ifndef MATCH_HPP
#define MATCH_HPP
#include <utility>
#include <stdexcept>
#include "cppa/any_type.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_comparable.hpp"
#include "cppa/util/utype_iterator.hpp"
#include "cppa/util/eval_type_lists.hpp"
#include "cppa/util/filter_type_list.hpp"
#include "cppa/detail/matcher.hpp"
namespace cppa {
template<typename... MatchRules>
bool match(const untyped_tuple& what)
{
util::utype_iterator begin = what.types().begin();
util::utype_iterator end = what.types().end();
return detail::matcher<MatchRules...>::match(begin, end);
}
template<typename... MatchRules>
bool match(const untyped_tuple& what, std::vector<std::size_t>& mappings)
{
util::utype_iterator begin = what.types().begin();
util::utype_iterator end = what.types().end();
return detail::matcher<MatchRules...>::match(begin, end, &mappings);
}
template<typename... MatchRules, class ValuesTuple>
bool match(const untyped_tuple& what, const ValuesTuple& vals,
std::vector<std::size_t>& mappings)
{
typedef util::type_list<MatchRules...> rules_list;
typedef typename util::filter_type_list<any_type, rules_list>::type
filtered_rules;
typedef typename tuple_view_type_from_type_list<filtered_rules>::type
view_type;
static_assert(util::eval_type_lists<filtered_rules,
ValuesTuple,
util::is_comparable>::value,
"given values are not comparable to matched types");
if (match<MatchRules...>(what, mappings))
{
std::vector<std::size_t> tmp(mappings);
view_type view(what.vals(), std::move(tmp));
return view == vals;
}
return false;
}
template<typename... MatchRules, class ValuesTuple>
bool match(const untyped_tuple& what, const ValuesTuple& vals)
{
std::vector<std::size_t> 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::utype_iterator begin = t.types().begin();
util::utype_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");
}
} // namespace cppa
#endif // MATCH_HPP
#ifndef MESSAGE_HPP
#define MESSAGE_HPP
namespace cppa {
class message
{
};
} // namespace cppa
#endif // MESSAGE_HPP
#ifndef OBJECT_HPP
#define OBJECT_HPP
#include "cppa/ref_counted.hpp"
namespace cppa {
struct utype;
class serializer;
class deserializer;
struct object : public ref_counted
{
// mutators
virtual void* mutable_value() = 0;
virtual void deserialize(deserializer&) = 0;
// accessors
virtual object* copy() const = 0;
virtual const utype& type() const = 0;
virtual const void* value() const = 0;
virtual void serialize(serializer&) const = 0;
};
} // namespace cppa
#endif // OBJECT_HPP
#ifndef ON_HPP
#define ON_HPP
#include "cppa/match.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/filter_type_list.hpp"
#include "cppa/detail/ref_counted_impl.hpp"
namespace cppa { namespace detail {
struct irb_helper : ref_counted_impl<std::size_t>
{
virtual ~irb_helper() { }
virtual bool value_cmp(const untyped_tuple&,
std::vector<std::size_t>&) const = 0;
};
template<typename... Types>
struct invoke_rule_builder
{
typedef util::type_list<Types...> types_list;
typedef typename util::filter_type_list<any_type, types_list>::type
filtered_types;
intrusive_ptr<irb_helper> m_helper;
public:
invoke_rule_builder() { }
template<typename Arg0, typename... Args>
invoke_rule_builder(const Arg0& arg0, const Args&... args)
{
class helper_impl : public irb_helper
{
tuple<Arg0, Args...> m_values;
public:
helper_impl(const Arg0& arg0, const Args&... args)
: m_values(arg0, args...) { }
virtual bool value_cmp(const untyped_tuple& t,
std::vector<std::size_t>& v) const
{
return match<Types...>(t, m_values, v);
}
};
m_helper = new helper_impl(arg0, args...);
static_assert(util::eval_type_lists<filtered_types,
util::type_list<Arg0, Args...>,
util::is_comparable>::value,
"Wrong argument types");
}
typedef typename tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type;
template<typename F>
invoke_rules operator>>(F f)
{
auto sub_inv = [f](const tuple_view_type& tv)
{
invoke(f, tv);
};
if (!m_helper)
{
auto inv = [f](const untyped_tuple& t) -> bool
{
std::vector<std::size_t> mappings;
if (match<Types...>(t, mappings))
{
tuple_view_type tv(t.vals(), std::move(mappings));
invoke(f, tv);
return true;
}
return false;
};
auto gt = [sub_inv](const untyped_tuple& t) -> detail::intermediate*
{
std::vector<std::size_t> mappings;
if (match<Types...>(t, mappings))
{
tuple_view_type tv(t.vals(), std::move(mappings));
return new detail::intermediate_impl<decltype(sub_inv), tuple_view_type>(sub_inv, tv);
}
return 0;
};
return invoke_rules(new detail::invokable_impl<decltype(inv), decltype(gt)>(std::move(inv), std::move(gt)));
}
else
{
auto inv = [f, m_helper](const untyped_tuple& t) -> bool
{
std::vector<std::size_t> mappings;
if (m_helper->value_cmp(t, mappings))
{
tuple_view_type tv(t.vals(), std::move(mappings));
invoke(f, tv);
return true;
}
return false;
};
auto gt = [sub_inv, m_helper](const untyped_tuple& t) -> detail::intermediate*
{
std::vector<std::size_t> mappings;
if (m_helper->value_cmp(t, mappings))
{
tuple_view_type tv(t.vals(), std::move(mappings));
return new detail::intermediate_impl<decltype(sub_inv), tuple_view_type>(sub_inv, tv);
}
return 0;
};
return invoke_rules(new detail::invokable_impl<decltype(inv), decltype(gt)>(std::move(inv), std::move(gt)));
}
}
};
} } // cppa::detail
namespace cppa {
template<typename... Types>
inline detail::invoke_rule_builder<Types...> on()
{
return detail::invoke_rule_builder<Types...>();
}
template<typename... Types, typename Arg0, typename... Args>
inline detail::invoke_rule_builder<Types...> on(const Arg0& arg0, const Args&... args)
{
return detail::invoke_rule_builder<Types...>(arg0, args...);
}
} // namespace cppa
#endif // ON_HPP
#ifndef LIBCPPA_REF_COUNTED_HPP
#define LIBCPPA_REF_COUNTED_HPP
#include <atomic>
#include <cstddef>
#include "cppa/detail/ref_counted_impl.hpp"
namespace cppa {
/**
* @brief (Thread safe) base class for reference counted objects
* with an atomic reference count.
*/
typedef detail::ref_counted_impl<std::atomic<std::size_t>> ref_counted;
} // namespace cppa
#endif // LIBCPPA_REF_COUNTED_HPP
#ifndef SERIALIZER_HPP
#define SERIALIZER_HPP
#include <string>
#include <cstddef>
#include <type_traits>
#include "cppa/any_type.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/util/sink.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/detail/swap_bytes.hpp"
namespace cppa { namespace util {
struct void_type;
} } // namespace cppa::util
namespace cppa {
class serializer
{
intrusive_ptr<util::sink> m_sink;
public:
serializer(const intrusive_ptr<util::sink>& data_sink);
inline void write(std::size_t buf_size, const void* buf)
{
m_sink->write(buf_size, buf);
}
};
} // namespace cppa
cppa::serializer& operator<<(cppa::serializer&, const std::string&);
template<typename T>
typename cppa::util::enable_if<std::is_integral<T>, cppa::serializer&>::type
operator<<(cppa::serializer& s, const T& value)
{
T tmp = cppa::detail::swap_bytes(value);
s.write(sizeof(T), &tmp);
return s;
}
template<typename T>
typename cppa::util::enable_if<std::is_floating_point<T>,
cppa::serializer&>::type
operator<<(cppa::serializer& s, const T& value)
{
s.write(sizeof(T), &value);
return s;
}
inline cppa::serializer& operator<<(cppa::serializer& s,
const cppa::util::void_type&)
{
return s;
}
inline cppa::serializer& operator<<(cppa::serializer& s, const cppa::any_type&)
{
return s;
}
#endif // SERIALIZER_HPP
#ifndef TEST_HPP
#define TEST_HPP
#include <cstddef>
#include <iostream>
#define CPPA_TEST(name) \
struct cppa_test_scope \
{ \
std::size_t error_count; \
cppa_test_scope() : error_count(0) { } \
~cppa_test_scope() \
{ \
std::cout << error_count << " error(s) detected" << std::endl; \
} \
} cppa_ts; \
std::size_t& error_count = cppa_ts.error_count
#define CPPA_CHECK(line_of_code) \
if (!(line_of_code)) \
{ \
std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \
<< " => " << #line_of_code << std::endl; \
++error_count; \
} ((void) 0)
#define CPPA_CHECK_EQUAL(line_of_code, expected) \
if ((line_of_code) != expected) \
{ \
std::cerr << "ERROR in file " << __FILE__ << " on line " << __LINE__ \
<< " => " << #line_of_code << " != " << expected << std::endl; \
++error_count; \
} ((void) 0)
void test__type_list();
void test__a_matches_b();
void test__atom();
void test__tuple();
void test__spawn();
void test__intrusive_ptr();
void test__serialization();
#endif // TEST_HPP
#ifndef CPPA_TUPLE_HPP
#define CPPA_TUPLE_HPP
#include <cstddef>
#include <string>
#include <typeinfo>
#include <type_traits>
#include "cppa/get.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/util/type_at.hpp"
#include "cppa/util/replace_type.hpp"
#include "cppa/util/is_comparable.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/util/eval_type_list.hpp"
#include "cppa/util/type_list_apply.hpp"
#include "cppa/util/is_serializable.hpp"
#include "cppa/util/is_legal_tuple_type.hpp"
#include "cppa/detail/tuple_vals.hpp"
namespace cppa { namespace detail {
template<typename T>
struct is_char_array
{
typedef typename std::remove_all_extents<T>::type step1_type;
typedef typename std::remove_cv<step1_type>::type step2_type;
static const bool value = std::is_array<T>::value
&& std::is_same<step2_type, char>::value;
};
template<typename T>
struct chars_to_string
{
typedef typename util::replace_type<T, std::string,
std::is_same<T, const char*>,
std::is_same<T, char*>,
is_char_array<T>>::type
type;
};
} } // namespace cppa::detail
namespace cppa {
// forward declaration
class untyped_tuple;
template<typename... ElementTypes>
class tuple
{
friend class untyped_tuple;
public:
typedef util::type_list<ElementTypes...> element_types;
private:
static_assert(element_types::type_list_size > 0, "tuple is empty");
static_assert(util::eval_type_list<element_types,
util::is_legal_tuple_type>::value,
"illegal types in tuple definition: "
"pointers and references are prohibited");
static_assert(util::eval_type_list<element_types,
util::is_serializable>::value,
"illegal types in tuple definition: "
"only serializable types are allowed");
typedef detail::tuple_vals<ElementTypes...> vals_t;
cow_ptr<vals_t> m_vals;
static bool compare_vals(const detail::tdata<>& v0,
const detail::tdata<>& v1)
{
return true;
}
template<typename Vals0, typename Vals1>
static bool compare_vals(const Vals0& v0, const Vals1& v1)
{
typedef typename Vals0::head_type lhs_type;
typedef typename Vals1::head_type rhs_type;
static_assert(util::is_comparable<lhs_type, rhs_type>::value,
"Types are not comparable");
return v0.head == v1.head && compare_vals(v0.tail(), v1.tail());
}
public:
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size;
tuple() : m_vals(new vals_t) { }
tuple(const ElementTypes&... args) : m_vals(new vals_t(args...)) { }
template<std::size_t N>
const typename util::type_at<N, element_types>::type& get() const
{
return detail::tdata_get<N>(m_vals->data());
}
template<std::size_t N>
typename util::type_at<N, element_types>::type& get_ref()
{
return detail::tdata_get_ref<N>(m_vals->data_ref());
}
std::size_t size() const { return m_vals->size(); }
const void* at(std::size_t p) const { return m_vals->at(p); }
const utype& utype_at(std::size_t p) const { return m_vals->utype_at(p); }
const util::abstract_type_list& types() const { return m_vals->types(); }
cow_ptr<vals_t> vals() const { return m_vals; }
template<typename... Args>
bool equal_to(const tuple<Args...>& other) const
{
static_assert(type_list_size == tuple<Args...>::type_list_size,
"Can't compare tuples of different size");
return compare_vals(vals()->data(), other.vals()->data());
}
};
template<std::size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
get(const tuple<Types...>& t)
{
return t.get<N>();
}
template<std::size_t N, typename... Types>
typename util::type_at<N, util::type_list<Types...>>::type&
get_ref(tuple<Types...>& t)
{
return t.get_ref<N>();
}
template<typename TypeList>
struct tuple_type_from_type_list;
template<typename... Types>
struct tuple_type_from_type_list<util::type_list<Types...>>
{
typedef tuple<Types...> type;
};
template<typename... Types>
typename tuple_type_from_type_list<
typename util::type_list_apply<util::type_list<Types...>,
detail::chars_to_string>::type>::type
make_tuple(const Types&... args)
{
return { args... };
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator==(const tuple<LhsTypes...>& lhs,
const tuple<RhsTypes...>& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator!=(const tuple<LhsTypes...>& lhs,
const tuple<RhsTypes...>& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa
#endif
#ifndef TUPLE_VIEW_HPP
#define TUPLE_VIEW_HPP
#include <vector>
#include "cppa/tuple.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/a_matches_b.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/detail/decorated_tuple.hpp"
namespace cppa {
template<typename... ElementTypes>
class tuple_view
{
public:
typedef util::type_list<ElementTypes...> element_types;
static_assert(element_types::type_list_size > 0,
"could not declare an empty tuple_view");
typedef cow_ptr<detail::abstract_tuple> vals_t;
tuple_view(const vals_t& vals, std::vector<std::size_t>&& mappings)
: m_vals(new detail::decorated_tuple<ElementTypes...>(vals, mappings))
{
}
tuple_view(const tuple_view&) = default;
const vals_t& vals() const { return m_vals; }
typedef typename element_types::head_type head_type;
typedef typename element_types::tail_type tail_type;
static const std::size_t type_list_size = element_types::type_list_size;
const element_types& types() const { return m_types; }
template<std::size_t N>
const typename util::type_at<N, element_types>::type& get() const
{
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));
}
template<std::size_t N>
typename util::type_at<N, element_types>::type& get_ref()
{
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));
}
std::size_t size() const { return m_vals->size(); }
private:
vals_t m_vals;
element_types m_types;
};
template<std::size_t N, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
get(const tuple_view<Types...>& t)
{
return t.get<N>();
}
template<std::size_t N, typename... Types>
typename util::type_at<N, util::type_list<Types...>>::type&
get_ref(tuple_view<Types...>& t)
{
return t.get_ref<N>();
}
template<typename TypeList>
struct tuple_view_type_from_type_list;
template<typename... Types>
struct tuple_view_type_from_type_list<util::type_list<Types...>>
{
typedef tuple_view<Types...> type;
};
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator==(const tuple_view<LhsTypes...>& lhs,
const tuple_view<RhsTypes...>& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator==(const tuple<LhsTypes...>& lhs,
const tuple_view<RhsTypes...>& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator==(const tuple_view<LhsTypes...>& lhs,
const tuple<RhsTypes...>& rhs)
{
return util::compare_tuples(lhs, rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator!=(const tuple_view<LhsTypes...>& lhs,
const tuple_view<RhsTypes...>& rhs)
{
return !(lhs == rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator!=(const tuple<LhsTypes...>& lhs,
const tuple_view<RhsTypes...>& rhs)
{
return !(lhs == rhs);
}
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator!=(const tuple_view<LhsTypes...>& lhs,
const tuple<RhsTypes...>& rhs)
{
return !(lhs == rhs);
}
} // namespace cppa
#endif // TUPLE_VIEW_HPP
#ifndef UNIFORM_TYPE_INFO_HPP
#define UNIFORM_TYPE_INFO_HPP
#include <map>
#include <string>
#include <cstdint>
#include <typeinfo>
#include "cppa/utype.hpp"
#include "cppa/object.hpp"
#include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/detail/utype_impl.hpp"
#include "cppa/detail/object_impl.hpp"
namespace cppa {
/**
* @brief Get the uniform type information for @p T.
*/
template<typename T>
const utype& uniform_type_info()
{
return detail::utype_impl<T>::instance;
}
/**
* @brief Get the uniform type information associated with the name
* @p uniform_type_name.
*/
const utype& uniform_type_info(const std::string& uniform_type_name);
} // namespace cppa
#define CPPA_CONCAT_II(res) res
#define CPPA_CONCAT_I(lhs, rhs) CPPA_CONCAT_II(lhs ## rhs)
#define CPPA_CONCAT(lhs, rhs) CPPA_CONCAT_I( lhs, rhs )
#ifdef __GNUC__
# define CPPA_ANNOUNCE(what) \
static const std::uint8_t CPPA_CONCAT( __unused_val , __LINE__ ) \
__attribute__ ((unused)) \
= cppa::detail::utype_impl< what >::instance.announce_helper()
#else
# define CPPA_ANNOUNCE(what) \
static const std::uint8_t CPPA_CONCAT( __unused_val , __LINE__ ) \
= cppa::detail::utype_impl< what >::instance.announce_helper()
#endif
/*
CPPA_ANNOUNCE(char);
CPPA_ANNOUNCE(std::int8_t);
CPPA_ANNOUNCE(std::uint8_t);
CPPA_ANNOUNCE(std::int16_t);
CPPA_ANNOUNCE(std::uint16_t);
CPPA_ANNOUNCE(std::int32_t);
CPPA_ANNOUNCE(std::uint32_t);
CPPA_ANNOUNCE(std::int64_t);
CPPA_ANNOUNCE(std::uint64_t);
CPPA_ANNOUNCE(float);
CPPA_ANNOUNCE(double);
CPPA_ANNOUNCE(long double);
*/
CPPA_ANNOUNCE(std::string);
#endif // UNIFORM_TYPE_INFO_HPP
#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(); }
const void* at(std::size_t p) const { return m_vals->at(p); }
const utype& 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 UTIL_HPP
#define UTIL_HPP
#include "cppa/util/a_matches_b.hpp"
#include "cppa/util/callable_trait.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/util/concat_type_lists.hpp"
#include "cppa/util/conjunction.hpp"
#include "cppa/util/detach.hpp"
#include "cppa/util/disjunction.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/eval_type_list.hpp"
#include "cppa/util/eval_type_lists.hpp"
#include "cppa/util/filter_type_list.hpp"
#include "cppa/util/has_copy_member_fun.hpp"
#include "cppa/util/is_comparable.hpp"
#include "cppa/util/is_copyable.hpp"
#include "cppa/util/is_legal_tuple_type.hpp"
#include "cppa/util/is_one_of.hpp"
#include "cppa/util/is_serializable.hpp"
#include "cppa/util/remove_const_reference.hpp"
#include "cppa/util/replace_type.hpp"
#include "cppa/util/reverse_type_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"
#include "cppa/util/type_list_pop_back.hpp"
#include "cppa/util/utype_iterator.hpp"
#include "cppa/util/void_type.hpp"
#endif // UTIL_HPP
#ifndef CPPA_UTIL_A_MATCHES_B_HPP
#define CPPA_UTIL_A_MATCHES_B_HPP
#include <type_traits>
#include "cppa/any_type.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_one_of.hpp"
#include "cppa/util/conjunction.hpp"
namespace cppa { namespace detail {
template<typename HeadA, typename TailA, typename HeadB, typename TailB>
struct amb_helper : util::conjunction<util::is_one_of<HeadA, HeadB, any_type>,
amb_helper<typename TailA::head_type,
typename TailA::tail_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,
"any_type in right hand type list");
};
template<>
struct amb_helper<util::void_type, util::type_list<>,
util::void_type, util::type_list<>> : std::true_type
{
};
template<typename TailA>
struct amb_helper<any_type*, TailA, util::void_type, util::type_list<>>
: amb_helper<typename TailA::head_type,
typename TailA::tail_type,
util::void_type,
util::type_list<>>
{
};
template<typename TailA, typename HeadB, typename TailB>
struct amb_helper<any_type*, TailA, HeadB, TailB>
: util::disjunction<amb_helper<typename TailA::head_type,
typename TailA::tail_type,
HeadB,
TailB>,
amb_helper<any_type*,
TailA,
typename TailB::head_type,
typename TailB::tail_type>>
{
static_assert(!std::is_same<HeadB, any_type>::value,
"any_type in right hand type list");
};
} } // namespace cppa::detail
namespace cppa { namespace util {
template<typename ListA, typename ListB>
struct a_matches_b : detail::amb_helper<typename ListA::head_type,
typename ListA::tail_type,
typename ListB::head_type,
typename ListB::tail_type>
{
};
} } // namespace cppa::util
#endif // CPPA_UTIL_A_MATCHES_B_HPP
#ifndef ABSTRACT_TYPE_LIST_HPP
#define ABSTRACT_TYPE_LIST_HPP
#include "cppa/util/utype_iterator.hpp"
namespace cppa { class serializer; }
namespace cppa { namespace util {
struct abstract_type_list
{
typedef utype_iterator iterator;
typedef utype_iterator const_iterator;
virtual abstract_type_list* copy() const = 0;
virtual const_iterator begin() const = 0;
virtual const_iterator end() const = 0;
virtual const utype& at(std::size_t pos) const = 0;
};
} } // namespace cppa::util
#endif // ABSTRACT_TYPE_LIST_HPP
#ifndef CPPA_UTIL_CALLABLE_TRAIT
#define CPPA_UTIL_CALLABLE_TRAIT
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
template<typename Signature>
struct callable_trait;
template<class C, typename Result, typename... Args>
struct callable_trait<Result (C::*)(Args...) const>
{
typedef Result result_type;
typedef util::type_list<Args...> arg_types;
};
template<class C, typename Result, typename... Args>
struct callable_trait<Result (C::*)(Args...)>
{
typedef Result result_type;
typedef util::type_list<Args...> arg_types;
};
template<typename Result, typename... Args>
struct callable_trait<Result (Args...)>
{
typedef Result result_type;
typedef util::type_list<Args...> arg_types;
};
template<typename Result, typename... Args>
struct callable_trait<Result (*)(Args...)>
{
typedef Result result_type;
typedef util::type_list<Args...> arg_types;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_CALLABLE_TRAIT
#ifndef COMPARE_TUPLES_HPP
#define COMPARE_TUPLES_HPP
#include "cppa/get.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_comparable.hpp"
#include "cppa/util/eval_type_lists.hpp"
namespace cppa { namespace detail {
template<std::size_t N, template<typename...> class Tuple, typename... Types>
const typename util::type_at<N, util::type_list<Types...>>::type&
do_get(const Tuple<Types...>& t)
{
return ::cppa::get<N, Types...>(t);
}
template<std::size_t N, typename LhsTuple, typename RhsTuple>
struct cmp_helper
{
inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs)
{
return do_get<N>(lhs) == do_get<N>(rhs)
&& cmp_helper<N-1, LhsTuple, RhsTuple>::cmp(lhs, rhs);
}
};
template<typename LhsTuple, typename RhsTuple>
struct cmp_helper<0, LhsTuple, RhsTuple>
{
inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs)
{
return do_get<0>(lhs) == do_get<0>(rhs);
}
};
} } // namespace cppa::detail
namespace cppa { namespace util {
template<template<typename...> class LhsTuple, typename... LhsTypes,
template<typename...> class RhsTuple, typename... RhsTypes>
bool compare_tuples(const LhsTuple<LhsTypes...>& lhs,
const RhsTuple<RhsTypes...>& rhs)
{
static_assert( LhsTuple<LhsTypes...>::type_list_size
== RhsTuple<RhsTypes...>::type_list_size,
"could not compare tuples of different size");
static_assert(util::eval_type_lists<util::type_list<LhsTypes...>,
util::type_list<RhsTypes...>,
util::is_comparable>::value,
"types of lhs are not comparable to the types of rhs");
return detail::cmp_helper<(LhsTuple<LhsTypes...>::type_list_size - 1),
LhsTuple<LhsTypes...>,
RhsTuple<RhsTypes...>>::cmp(lhs, rhs);
}
} } // namespace cppa::util
#endif // COMPARE_TUPLES_HPP
#ifndef CONCAT_TYPE_LISTS_HPP
#define CONCAT_TYPE_LISTS_HPP
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
template<typename ListA, typename ListB>
struct concat_type_lists;
template<typename... ListATypes, typename... ListBTypes>
struct concat_type_lists<util::type_list<ListATypes...>, util::type_list<ListBTypes...>>
{
typedef util::type_list<ListATypes..., ListBTypes...> type;
};
} } // namespace cppa::util
#endif // CONCAT_TYPE_LISTS_HPP
#ifndef CONJUNCTION_HPP
#define CONJUNCTION_HPP
#include <type_traits>
namespace cppa { namespace util {
template<typename... BooleanConstants>
struct conjunction;
template<typename Head, typename... Tail>
struct conjunction<Head, Tail...>
: std::integral_constant<bool, Head::value && conjunction<Tail...>::value>
{
};
template<>
struct conjunction<> : std::true_type { };
} } // namespace cppa::util
#endif // CONJUNCTION_HPP
#ifndef DETACH_HPP
#define DETACH_HPP
#include "cppa/util/is_copyable.hpp"
#include "cppa/util/has_copy_member_fun.hpp"
namespace cppa { namespace detail {
template<bool IsCopyable, bool HasCpyMemFun>
struct detach_;
template<bool HasCpyMemFun>
struct detach_<true, HasCpyMemFun>
{
template<typename T>
inline static T* cpy(const T* what)
{
return new T(*what);
}
};
template<>
struct detach_<false, true>
{
template<typename T>
inline static T* cpy(const T* what)
{
return what->copy();
}
};
} } // namespace cppa::detail
namespace cppa { namespace util {
template<typename T>
inline T* detach(const T* what)
{
return detail::detach_<is_copyable<T>::value,
has_copy_member_fun<T>::value>::cpy(what);
}
} } // namespace cppa::util
#endif // DETACH_HPP
#ifndef DISJUNCTION_HPP
#define DISJUNCTION_HPP
#include <type_traits>
namespace cppa { namespace util {
template<typename... BooleanConstants>
struct disjunction;
template<typename Head, typename... Tail>
struct disjunction<Head, Tail...>
: std::integral_constant<bool, Head::value || disjunction<Tail...>::value>
{
};
template<>
struct disjunction<> : std::false_type { };
} } // namespace cppa::util
#endif // DISJUNCTION_HPP
#ifndef ENABLE_IF_HPP
#define ENABLE_IF_HPP
namespace cppa { namespace util {
template<bool Stmt, typename T>
struct enable_if_c { };
template<typename T>
struct enable_if_c<true, T>
{
typedef T type;
};
template<class Trait, typename T>
struct enable_if : enable_if_c<Trait::value, T>
{
};
} } // namespace cppa::util
#endif // ENABLE_IF_HPP
#ifndef EVAL_TYPE_LIST_HPP
#define EVAL_TYPE_LIST_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/concat_type_lists.hpp"
namespace cppa { namespace util {
/**
* @brief Apply @p What to each element of @p List.
*/
template <class List, template <typename> class What>
struct eval_type_list
{
typedef typename List::head_type head_type;
typedef typename List::tail_type tail_type;
static const bool value =
What<head_type>::value
&& eval_type_list<tail_type, What>::value;
};
template <template <typename> class What>
struct eval_type_list<type_list<>, What>
{
static const bool value = true;
};
} } // namespace cppa::util
#endif // EVAL_TYPE_LIST_HPP
#ifndef EVAL_TYPE_LISTS_HPP
#define EVAL_TYPE_LISTS_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/concat_type_lists.hpp"
namespace cppa { namespace util {
/**
* @brief Apply @p What to each element of @p List.
*/
template <class ListA, class ListB,
template <typename, typename> class What>
struct eval_type_lists
{
typedef typename ListA::head_type head_type_a;
typedef typename ListA::tail_type tail_type_a;
typedef typename ListB::head_type head_type_b;
typedef typename ListB::tail_type tail_type_b;
static const bool value =
What<head_type_a, head_type_b>::value
&& eval_type_lists<tail_type_a, tail_type_b, What>::value;
};
template <template <typename, typename> class What>
struct eval_type_lists<type_list<>, type_list<>, What>
{
static const bool value = true;
};
} } // namespace cppa::util
#endif // EVAL_TYPE_LISTS_HPP
#ifndef FILTER_TYPE_LIST_HPP
#define FILTER_TYPE_LIST_HPP
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
template<typename Needle, typename Haystack>
struct filter_type_list;
template<typename Needle, typename... Tail>
struct filter_type_list<Needle, util::type_list<Needle, Tail...>>
{
typedef typename filter_type_list<Needle, util::type_list<Tail...>>::type type;
};
template<typename Needle, typename... Tail>
struct filter_type_list<Needle, util::type_list<Needle*, Tail...>>
{
typedef typename filter_type_list<Needle, util::type_list<Tail...>>::type type;
};
template<typename Needle, typename Head, typename... Tail>
struct filter_type_list<Needle, util::type_list<Head, Tail...>>
{
typedef typename concat_type_lists<util::type_list<Head>, typename filter_type_list<Needle, util::type_list<Tail...>>::type>::type type;
};
template<typename Needle>
struct filter_type_list<Needle, util::type_list<>>
{
typedef util::type_list<> type;
};
} } // namespace cppa::util
#endif // FILTER_TYPE_LIST_HPP
#ifndef HAS_COPY_MEMBER_FUN_HPP
#define HAS_COPY_MEMBER_FUN_HPP
#include <type_traits>
namespace cppa { namespace util {
template<typename T>
class has_copy_member_fun
{
template<typename A>
static bool hc_help_fun(const A* arg0, decltype(arg0->copy()) = 0)
{
return true;
}
template<typename A>
static void hc_help_fun(const A*, void* = 0) { }
typedef decltype(hc_help_fun((T*) 0, (T*) 0)) result_type;
public:
static const bool value = std::is_same<bool, result_type>::value;
};
} } // namespace cppa::util
#endif // HAS_COPY_MEMBER_FUN_HPP
#ifndef IS_COMPARABLE_HPP
#define IS_COMPARABLE_HPP
#include <type_traits>
namespace cppa { namespace util {
template<typename T1, typename T2>
class is_comparable
{
// SFINAE: If you pass a "bool*" as third argument, then
// decltype(cmp_help_fun(...)) is bool if there's an
// operator==(A,B) because
// cmp_help_fun(A*, B*, bool*) is a better match than
// cmp_help_fun(A*, B*, void*). If there's no operator==(A,B)
// available, then cmp_help_fun(A*, B*, void*) is the only
// candidate and thus decltype(cmp_help_fun(...)) is void.
template<typename A, typename B>
static bool cmp_help_fun(const A* arg0, const B* arg1,
decltype(*arg0 == *arg1)* = 0)
{
return true;
}
template<typename A, typename B>
static void cmp_help_fun(const A*, const B*, void* = 0) { }
typedef decltype(cmp_help_fun((T1*) 0, (T2*) 0, (bool*) 0)) result_type;
public:
static const bool value = std::is_same<bool, result_type>::value;
};
} } // namespace cppa::util
#endif // IS_COMPARABLE_HPP
#ifndef IS_COPYABLE_HPP
#define IS_COPYABLE_HPP
#include <type_traits>
namespace cppa { namespace detail {
template<bool IsAbstract, typename T>
class is_copyable_
{
template<typename A>
static bool cpy_help_fun(const A* arg0, decltype(new A(*arg0)) = 0)
{
return true;
}
template<typename A>
static void cpy_help_fun(const A*, void* = 0) { }
typedef decltype(cpy_help_fun((T*) 0, (T*) 0)) result_type;
public:
static const bool value = std::is_same<bool, result_type>::value;
};
template<typename T>
class is_copyable_<true, T>
{
public:
static const bool value = false;
};
} } // namespace cppa::detail
namespace cppa { namespace util {
template<typename T>
struct is_copyable
{
public:
static const bool value = detail::is_copyable_<std::is_abstract<T>::value, T>::value;
};
} } // namespace cppa::util
#endif // IS_COPYABLE_HPP
#ifndef IS_LEGAL_TUPLE_TYPE_HPP
#define IS_LEGAL_TUPLE_TYPE_HPP
#include <type_traits>
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;
};
} } // namespace cppa::util
#endif // IS_LEGAL_TUPLE_TYPE_HPP
#ifndef IS_ONE_OF_HPP
#define IS_ONE_OF_HPP
#include <type_traits>
#include "cppa/util/disjunction.hpp"
namespace cppa { namespace util {
template<typename T, typename... Types>
struct is_one_of;
template<typename T, typename X, typename... Types>
struct is_one_of<T, X, Types...>
: disjunction<std::is_same<T, X>, is_one_of<T, Types...>>
{
};
template<typename T>
struct is_one_of<T> : std::false_type { };
} } // namespace cppa::util
#endif // IS_ONE_OF_HPP
#ifndef IS_SERIALIZABLE_HPP
#define IS_SERIALIZABLE_HPP
namespace cppa {
struct serializer;
struct deserializer;
} // namespace cppa
namespace cppa { namespace util {
template<typename T>
class is_serializable
{
template<typename A>
static auto help_fun1(A* arg, serializer* s) -> decltype((*s) << (*arg))
{
return true;
}
template<typename A>
static void help_fun1(A*, void*) { }
typedef decltype(help_fun1((T*) 0, (serializer*) 0)) type1;
template<typename A>
static auto help_fun2(A* arg, deserializer* d) -> decltype((*d) >> (*arg))
{
return true;
}
template<typename A>
static void help_fun2(A*, void*) { }
typedef decltype(help_fun2((T*) 0, (deserializer*) 0)) type2;
public:
static const bool value = std::is_same< serializer&, type1>::value
&& std::is_same<deserializer&, type2>::value;
};
} } // namespace cppa::util
#endif // IS_SERIALIZABLE_HPP
#ifndef REMOVE_CONST_REFERENCE_HPP
#define REMOVE_CONST_REFERENCE_HPP
namespace cppa { namespace util {
template<typename T>
struct remove_const_reference
{
typedef T type;
};
template<typename T>
struct remove_const_reference<const T&>
{
typedef T type;
};
} } // namespace cppa::util
#endif // REMOVE_CONST_REFERENCE_HPP
#ifndef REPLACE_TYPE_HPP
#define REPLACE_TYPE_HPP
#include <type_traits>
#include "cppa/util/disjunction.hpp"
namespace cppa { namespace detail {
template<bool DoReplace, typename T, typename ReplaceType>
struct replace_type
{
typedef T type;
};
template<typename T, typename ReplaceType>
struct replace_type<true, T, ReplaceType>
{
typedef ReplaceType type;
};
} } // namespace cppa::detail
namespace cppa { namespace util {
template<typename What, typename With, typename... IfStmt>
struct replace_type
{
static const bool do_replace = disjunction<IfStmt...>::value;
typedef typename detail::replace_type<do_replace, What, With>::type
type;
};
} } // namespace cppa::util
#endif // REPLACE_TYPE_HPP
#ifndef CPPA_UTIL_REVERSE_TYPE_LIST_HPP
#define CPPA_UTIL_REVERSE_TYPE_LIST_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/concat_type_lists.hpp"
namespace cppa { namespace util {
template<typename ListFrom, typename ListTo = type_list<>>
struct reverse_type_list;
template<typename HeadA, typename... TailA, typename... ListB>
struct reverse_type_list<type_list<HeadA, TailA...>, type_list<ListB...>>
{
typedef typename reverse_type_list<type_list<TailA...>,
type_list<HeadA, ListB...>>::type
type;
};
template<typename... Types>
struct reverse_type_list<type_list<>, type_list<Types...>>
{
typedef type_list<Types...> type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_REVERSE_TYPE_LIST_HPP
#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
#ifndef CPPA_UTIL_TYPE_AT_HPP
#define CPPA_UTIL_TYPE_AT_HPP
// std::size_t
#include <cstddef>
#include "cppa/util/type_list.hpp"
namespace cppa { namespace util {
template<std::size_t N, typename TypeList>
struct type_at
{
typedef typename type_at<N-1, typename TypeList::tail_type>::type type;
};
template<typename TypeList>
struct type_at<0, TypeList>
{
typedef typename TypeList::head_type type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_TYPE_AT_HPP
#ifndef LIBCPPA_UTIL_TYPE_LIST_HPP
#define LIBCPPA_UTIL_TYPE_LIST_HPP
#include "cppa/any_type.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/util/abstract_type_list.hpp"
namespace cppa { namespace util {
template<typename... Types> struct type_list;
template<>
struct type_list<>
{
typedef void_type head_type;
typedef type_list<> tail_type;
static const std::size_t type_list_size = 0;
};
template<typename Head, typename... Tail>
struct type_list<Head, Tail...> : abstract_type_list
{
typedef Head head_type;
typedef type_list<Tail...> tail_type;
static const std::size_t type_list_size = tail_type::type_list_size + 1;
type_list() { init<type_list>(m_arr); }
virtual const_iterator begin() const
{
return m_arr;
}
virtual const_iterator end() const
{
return m_arr + type_list_size;
}
const utype& operator[](std::size_t pos) const
{
return *m_arr[pos];
}
virtual const utype& at(std::size_t pos) const
{
return *m_arr[pos];
}
virtual type_list* copy() const
{
return new type_list;
}
template<typename TypeList>
static void init(const utype** what)
{
what[0] = &uniform_type_info<typename TypeList::head_type>();
if (TypeList::type_list_size > 1)
{
++what;
init<typename TypeList::tail_type>(what);
}
}
private:
const utype* m_arr[type_list_size];
};
} } // namespace cppa::util
#endif // LIBCPPA_UTIL_TYPE_LIST_HPP
#ifndef TYPE_LIST_APPLY_HPP
#define TYPE_LIST_APPLY_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/concat_type_lists.hpp"
namespace cppa { namespace util {
/**
* @brief Apply @p What to each element of @p List.
*/
template <typename List, template <typename> class What>
struct type_list_apply
{
typedef typename What<typename List::head_type>::type head_type;
typedef typename concat_type_lists<
type_list<head_type>,
typename type_list_apply<typename List::tail_type, What>::type>::type
type;
};
template<template <typename> class What>
struct type_list_apply<type_list<>, What>
{
typedef type_list<> type;
};
} } // namespace cppa::util
#endif // TYPE_LIST_APPLY_HPP
#ifndef CPPA_UTIL_TYPE_LIST_POP_BACK_HPP
#define CPPA_UTIL_TYPE_LIST_POP_BACK_HPP
#include "cppa/util/type_list.hpp"
#include "cppa/util/reverse_type_list.hpp"
namespace cppa { namespace util {
template<typename List>
struct type_list_pop_back
{
typedef typename reverse_type_list<List>::type rlist;
typedef typename reverse_type_list<typename rlist::tail_type>::type type;
};
} } // namespace cppa::util
#endif // CPPA_UTIL_TYPE_LIST_POP_BACK_HPP
#ifndef UTYPE_ITERATOR_HPP
#define UTYPE_ITERATOR_HPP
#include "cppa/uniform_type_info.hpp"
namespace cppa { namespace util {
struct utype_iterator
{
typedef const utype* const* arr_ptr;
arr_ptr m_pos;
public:
utype_iterator(arr_ptr p) : m_pos(p) { }
inline utype_iterator& operator++()
{
++m_pos;
return *this;
}
inline bool operator==(const utype_iterator& other) const
{
return m_pos == other.m_pos;
}
inline bool operator!=(const utype_iterator& other) const
{
return !(*this == other);
}
inline const utype& operator*()
{
return *m_pos[0];
}
inline const utype* operator->()
{
return m_pos[0];
}
};
} } // namespace cppa::util
#endif // UTYPE_ITERATOR_HPP
#ifndef LIBCPPA_UTIL_VOID_TYPE_HPP
#define LIBCPPA_UTIL_VOID_TYPE_HPP
namespace cppa { namespace util {
// forward declaration
template<typename... Types> struct type_list;
struct void_type
{
typedef void_type head_type;
typedef type_list<> tail_type;
};
} } // namespace cppa::util
#endif // LIBCPPA_UTIL_VOID_TYPE_HPP
#ifndef UTYPE_HPP
#define UTYPE_HPP
#include <string>
#include <typeinfo>
#include "cppa/object.hpp"
namespace cppa {
/**
* @brief Uniform type information.
*/
struct utype
{
/**
* @brief Create an object of this type, initialized with
* the default constructor.
*/
virtual object* create() const = 0;
/**
* @brief Get the uniform type name (equal on all supported plattforms).
*/
virtual const std::string& name() const = 0;
/**
* @brief Get the result of typeid(T) where T is the native type.
*/
virtual const std::type_info& native() const = 0;
};
} // namespace cppa
#endif // UTYPE_HPP
#include <stdexcept>
#include "cppa/detail/decorated_tuple.hpp"
/*
namespace cppa { namespace detail {
decorated_tuple::decorated_tuple(const decorated_tuple::ptr_type& d,
const std::vector<std::size_t>& v,
util::abstract_type_list* tlist)
: m_decorated(d), m_mappings(v), m_types(tlist)
{
if (!tlist)
{
throw std::invalid_argument("tlist == nullpr");
}
}
decorated_tuple::decorated_tuple(const decorated_tuple& other)
: abstract_tuple()
, m_decorated(other.m_decorated)
, m_mappings(other.m_mappings)
, m_types(other.m_types->copy())
{
}
decorated_tuple::~decorated_tuple()
{
delete m_types;
}
void* decorated_tuple::mutable_at(std::size_t pos)
{
return m_decorated->mutable_at(m_mappings[pos]);
}
std::size_t decorated_tuple::size() const
{
return m_mappings.size();
}
decorated_tuple* decorated_tuple::copy() const
{
return new decorated_tuple(*this);
}
const void* decorated_tuple::at(std::size_t pos) const
{
return m_decorated->at(m_mappings[pos]);
}
const utype& decorated_tuple::utype_at(std::size_t pos) const
{
return m_decorated->utype_at(m_mappings[pos]);
}
const util::abstract_type_list& decorated_tuple::types() const
{
return *m_types;
// throw std::runtime_error("not implemented yet");
}
bool decorated_tuple::equal_to(const abstract_tuple&) const
{
return false;
}
} } // namespace cppa::detail
*/
#include <cstdint>
#include "cppa/deserializer.hpp"
namespace cppa {
deserializer::deserializer(const intrusive_ptr<util::source>& src) : m_src(src)
{
}
} // namespace cppa
cppa::deserializer& operator>>(cppa::deserializer& d, std::string& str)
{
std::uint32_t str_size;
d >> str_size;
char* cbuf = new char[str_size + 1];
d.read(str_size, cbuf);
cbuf[str_size] = 0;
str = cbuf;
delete cbuf;
return d;
}
#include <map>
#include <string>
#include <limits>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <typeinfo>
#include <iostream>
#include "cppa/test.hpp"
#include "cppa/tuple.hpp"
#include "cppa/config.hpp"
#include "cppa/uniform_type_info.hpp"
#ifdef CPPA_GCC
#include <cxxabi.h>
#endif
#define RUN_TEST(fun_name) \
std::cout << "run " << #fun_name << " ..." << std::endl; \
fun_name (); \
std::cout << std::endl
using std::cout;
using std::endl;
typedef std::map<std::string, std::pair<std::string, std::string>> str3_map;
int main()
{
std::cout << std::boolalpha;
RUN_TEST(test__a_matches_b);
RUN_TEST(test__intrusive_ptr);
RUN_TEST(test__spawn);
RUN_TEST(test__tuple);
RUN_TEST(test__type_list);
RUN_TEST(test__serialization);
RUN_TEST(test__atom);
return 0;
}
#include "cppa/detail/scheduler.hpp"
#include "cppa/ref_counted.hpp"
namespace cppa {
//ref_counted::~ref_counted() { }
} // namespace cppa
#include <cstdint>
#include "cppa/serializer.hpp"
namespace cppa {
serializer::serializer(const intrusive_ptr<util::sink>& dsink) : m_sink(dsink)
{
}
} // namespace cppa
cppa::serializer& operator<<(cppa::serializer& s, const std::string& str)
{
auto str_size = static_cast<std::uint32_t>(str.size());
s << str_size;
s.write(str.size(), str.c_str());
return s;
}
#include <string>
#include <typeinfo>
#include "cppa/test.hpp"
#include "cppa/util.hpp"
using namespace cppa;
using namespace cppa::util;
void test__a_matches_b()
{
CPPA_TEST(test__a_matches_b);
typedef type_list<int, any_type*> int_star;
typedef type_list<int, float, int> int_float_int;
typedef type_list<int, int, std::string> int_int_string;
typedef type_list<int, int, const std::string&> int_int_const_string_ref;
typedef type_list_apply<int_int_const_string_ref,
remove_const_reference>::type
int_int_string2;
CPPA_CHECK((std::is_same<int, remove_const_reference<const int&>::type>::value));
CPPA_CHECK((a_matches_b<int_star, int_float_int>::value));
CPPA_CHECK((a_matches_b<int_float_int, int_float_int>::value));
CPPA_CHECK((a_matches_b<int_int_string, int_int_string>::value));
CPPA_CHECK((a_matches_b<int_int_string, int_int_string2>::value));
CPPA_CHECK(!(a_matches_b<int_int_string, int_int_const_string_ref>::value));
CPPA_CHECK_EQUAL((a_matches_b<type_list<float>,
type_list<int, float, int>>::value), false);
CPPA_CHECK((a_matches_b<type_list<any_type*, float>,
type_list<int, float, int>>::value) == false);
CPPA_CHECK((a_matches_b<type_list<any_type*, float>,
type_list<int, int, float>>::value));
}
#include <string>
#include <typeinfo>
#include <iostream>
#include "cppa/test.hpp"
#include "cppa/util.hpp"
using std::cout;
using std::endl;
using namespace cppa;
using namespace cppa::util;
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
static_assert(sizeof(int) == 4,
"MurmurHash2 requires sizeof(int) == 4");
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
const unsigned int m = 0x5bd1e995;
const int r = 24;
// Initialize the hash to a 'random' value
unsigned int h = seed ^ len;
// Mix 4 bytes at a time into the hash
const unsigned char * data = (const unsigned char *)key;
while(len >= 4)
{
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
// Handle the last few bytes of the input array
switch(len)
{
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
h *= m;
};
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
unsigned int hash_of(const char* what, int what_length)
{
return MurmurHash2(what, what_length, 0xDEADC0DE);
}
unsigned int hash_of(const std::string& what)
{
return MurmurHash2(what.c_str(), what.size(), 0xDEADC0DE);
}
template<char... Str>
struct _tostring;
template<char C0, char... Str>
struct _tostring<C0, Str...>
{
inline static void _(std::string& s)
{
s += C0;
_tostring<Str...>::_(s);
}
};
template<>
struct _tostring<>
{
inline static void _(std::string&) { }
};
class atom_base
{
std::string m_str;
unsigned int m_hash;
public:
atom_base(std::string&& str) : m_str(str), m_hash(hash_of(m_str))
{
}
unsigned int hash() const
{
return m_hash;
}
const std::string& value() const
{
return m_str;
}
};
/*
template<char... Str>
class atom : atom_base
{
static std::string to_string()
{
std::string result;
_tostring<Str...>::_(result);
return result;
}
public:
atom() : atom_base(to_string()) { }
};
*/
/*
bool operator==(const atom& lhs, const atom& rhs)
{
return (lhs.hash() == rhs.hash()) && (lhs.value() == rhs.value());
}
bool operator!=(const atom& lhs, const atom& rhs)
{
return !(lhs == rhs);
}
bool operator!=(const atom& lhs, const std::string& rhs)
{
return lhs.value() == rhs;
}
bool operator!=(const std::string& lhs, const atom& rhs)
{
return lhs == rhs.value();
}
*/
// template<char...>
// atom<Str...> operator "" _atom();
template<char... Str>
class atom : public atom_base
{
static std::string to_string()
{
std::string result;
_tostring<Str...>::_(result);
return result;
}
public:
atom() : atom_base(to_string()) { }
};
void test__atom()
{
CPPA_TEST(test__atom);
atom<'f','o','o'> a1;
cout << "a1 = " << a1.value() << endl;
// atom<"foobar"> a1;
// CPPA_CHECK(a1 == a3);
}
#include <list>
#include <cstddef>
#include "cppa/test.hpp"
#include "cppa/intrusive_ptr.hpp"
using namespace cppa;
namespace { int rc_instances = 0; }
class test_rc
{
std::size_t m_rc;
public:
test_rc() : m_rc(0) { ++rc_instances; }
void ref() { ++m_rc; }
bool deref() { return --m_rc > 0; }
std::size_t rc() const { return m_rc; }
virtual ~test_rc() { --rc_instances; }
test_rc* create() { return new test_rc; }
};
typedef intrusive_ptr<test_rc> test_ptr;
test_rc* get_test_rc()
{
return new test_rc;
}
test_ptr get_test_ptr()
{
return get_test_rc();
}
void test__intrusive_ptr()
{
CPPA_TEST(test__intrusive_ptr);
{
test_ptr p(new test_rc);
CPPA_CHECK_EQUAL(rc_instances, 1);
CPPA_CHECK_EQUAL(p->rc(), 1);
}
CPPA_CHECK_EQUAL(rc_instances, 0);
{
test_ptr p;
p = new test_rc;
CPPA_CHECK_EQUAL(rc_instances, 1);
CPPA_CHECK_EQUAL(p->rc(), 1);
}
CPPA_CHECK_EQUAL(rc_instances, 0);
{
test_ptr p1;
p1 = get_test_rc();
test_ptr p2 = p1;
CPPA_CHECK_EQUAL(rc_instances, 1);
CPPA_CHECK_EQUAL(p1->rc(), 2);
}
CPPA_CHECK_EQUAL(rc_instances, 0);
{
std::list<test_ptr> pl;
pl.push_back(get_test_ptr());
pl.push_back(get_test_rc());
pl.push_back(pl.front()->create());
CPPA_CHECK_EQUAL(pl.front()->rc(), 1);
CPPA_CHECK_EQUAL(rc_instances, 3);
}
CPPA_CHECK_EQUAL(rc_instances, 0);
}
This diff is collapsed.
#include "cppa/test.hpp"
#include "cppa/actor.hpp"
//#include "cppa/spawn.hpp"
using cppa::actor;
template<typename F>
actor spawn(F)
{
return actor();
}
void test__spawn()
{
CPPA_TEST(test__spawn);
actor a0 = spawn([](){
// receive(on<int>() >> [](int i){
// reply(i + 2);
// });
});
a0.send(42);
CPPA_CHECK(true);
}
#include <list>
#include <string>
#include <utility>
#include <iostream>
#include <typeinfo>
#include <functional>
#include "cppa/on.hpp"
#include "cppa/util.hpp"
#include "cppa/test.hpp"
#include "cppa/tuple.hpp"
#include "cppa/match.hpp"
#include "cppa/invoke.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp"
using std::cout;
using std::endl;
using namespace cppa;
using namespace cppa::util;
namespace {
bool function_called = false;
void fun(const std::string&)
{
function_called = true;
// CPPA_CHECK((s == "Hello World"));
}
} // namespace <anonymous>
void test__tuple()
{
CPPA_TEST(test__tuple);
// test of filter_type_list
typedef filter_type_list<any_type,
util::type_list<any_type*, float,
any_type*, int, any_type>>::type
tv_float_int;
// tuples under test
tuple<int, float, int, std::string> t1(42, .2f, 2, "Hello World");
tuple<std::string> t2("foo");
auto t3 = make_tuple(42, .2f, 2, "Hello World", 0);
tuple<int, float, int, std::string> t4(42, .2f, 2, "Hello World");
tuple<int, std::string, int> t5(42, "foo", 24);
tuple<int> t6;
// untyped tuples under test
untyped_tuple ut0 = t1;
// tuple views under test
auto tv0 = get_view<any_type*, float, any_type*, int, any_type>(t1);
auto tv1 = get_view<any_type*, int, any_type*>(tv0);
auto tv2 = get_view<int, any_type*, std::string>(t1);
auto tv3 = get_view<any_type*, int, std::string>(t1);
// untyped_tuple ut1 = tv0;
CPPA_CHECK(t6.get<0>() == 0);
CPPA_CHECK(tv2.get<0>() == t1.get<0>());
CPPA_CHECK(tv2.get<1>() == t1.get<3>());
CPPA_CHECK(tv2.get<1>() == "Hello World");
{
std::vector<std::size_t> tv3_mappings;
match<any_type*, int, std::string>(t1, tv3_mappings);
CPPA_CHECK_EQUAL(tv3_mappings.size(), 2);
CPPA_CHECK(tv3_mappings[0] == 2);
CPPA_CHECK(tv3_mappings[1] == 3);
}
CPPA_CHECK(tv3.get<0>() == t1.get<2>());
CPPA_CHECK(tv3.get<1>() == t1.get<3>());
CPPA_CHECK(!(tv2 == tv3));
{
int* foo_int = new int(42);
decltype(new int(*foo_int)) foo_int_2 = new int(*foo_int);
CPPA_CHECK_EQUAL(*foo_int, *foo_int_2);
delete foo_int_2;
delete foo_int;
}
CPPA_CHECK((match<int, any_type*, std::string>(ut0)));
// CPPA_CHECK(ut0 == t1);
CPPA_CHECK(tv0.get<0>() == .2f);
CPPA_CHECK(tv0.get<1>() == 2);
CPPA_CHECK(tv1.get<0>() == 2);
CPPA_CHECK((tv1.get<0>() == tv0.get<1>()));
CPPA_CHECK((&(tv1.get<0>()) == &(tv0.get<1>())));
// force detaching of tv1 from tv0 (and t1)
tv1.get_ref<0>() = 20;
CPPA_CHECK(tv0.get<1>() == 2);
CPPA_CHECK(tv1.get<0>() == 20);
CPPA_CHECK((&(tv1.get<0>()) != &(tv0.get<1>())));
CPPA_CHECK((&(t1.get<1>()) == &(tv0.get<0>())));
bool l1_invoked = false;
bool l2_invoked = false;
bool l3_invoked = false;
auto reset_invoke_states = [&]() {
l1_invoked = l2_invoked = l3_invoked = false;
};
auto l1 = [&](int v0, float v1, int v2, const std::string& v3) {
l1_invoked = true;
CPPA_CHECK((t1.get<0>() == v0));
CPPA_CHECK((t1.get<1>() == v1));
CPPA_CHECK((t1.get<2>() == v2));
CPPA_CHECK((t1.get<3>() == v3));
};
auto l2 = [&](float v0, int v1) {
l2_invoked = true;
CPPA_CHECK((tv0.get<0>() == v0));
CPPA_CHECK((tv0.get<1>() == v1));
};
auto l3 = [&](const std::string& v0) {
l3_invoked = true;
CPPA_CHECK((t2.get<0>() == v0));
};
invoke(l1, t1);
CPPA_CHECK(l1_invoked);
reset_invoke_states();
invoke(l2, tv0);
CPPA_CHECK(l2_invoked);
reset_invoke_states();
invoke(l3, t2);
CPPA_CHECK(l3_invoked);
reset_invoke_states();
auto inv = ( on<any_type*, float, any_type*, int, any_type>() >> l2
, on<int, float, int, std::string, any_type*>() >> l1
, on<any_type*, int, std::string, any_type*>() >> l3);
CPPA_CHECK(inv(t1));
CPPA_CHECK(!l1_invoked && l2_invoked && !l3_invoked);
reset_invoke_states();
CPPA_CHECK(inv(t5));
CPPA_CHECK(!l1_invoked && !l2_invoked && l3_invoked);
reset_invoke_states();
CPPA_CHECK(inv(t3));
CPPA_CHECK(l1_invoked && !l2_invoked && !l3_invoked);
reset_invoke_states();
auto intmd = inv.get_intermediate(t1);
CPPA_CHECK(intmd != (reinterpret_cast<detail::intermediate*>(0)));
if (intmd) intmd->invoke();
CPPA_CHECK(!l1_invoked && l2_invoked && !l3_invoked);
reset_invoke_states();
(on<any_type*, std::string, any_type*>() >> fun)(t2);
CPPA_CHECK(function_called);
reset_invoke_states();
bool l4_invoked = false;
auto l4 = [&]() {
l4_invoked = true;
};
auto inv2 = (
on<any_type*, float, any_type*, int, any_type>(.1f, 2) >> l4,
on<any_type*, float, any_type*, int, any_type>(any_val, 2) >> l2
);
CPPA_CHECK((match<any_type*, float, any_type*, int, any_type>(t1, tv0)));
CPPA_CHECK(inv2(t1));
CPPA_CHECK(!l4_invoked);
CPPA_CHECK(l2_invoked);
reset_invoke_states();
{
any_type* x = 0;
CPPA_CHECK(x == any_val);
CPPA_CHECK(any_val == x);
CPPA_CHECK(any_val == 42);
CPPA_CHECK(any_val == 24);
}
// test detaching of tuples
auto t1_copy = t1;
CPPA_CHECK((&(t1_copy.get<0>()) == &(t1.get<0>())));
t1_copy.get_ref<0>() = 24; // this detaches t4 from t1
CPPA_CHECK((&(t1_copy.get<0>()) != &(t1.get<0>())));
CPPA_CHECK(t1_copy.get<0>() != t1.get<0>());
CPPA_CHECK(t1_copy.get<1>() == t1.get<1>());
CPPA_CHECK(t1_copy.get<2>() == t1.get<2>());
CPPA_CHECK(t1_copy.get<3>() == t1.get<3>());
CPPA_CHECK(t1 == t4);
}
#include <string>
#include <typeinfo>
#include <type_traits>
#include "cppa/util.hpp"
#include "cppa/test.hpp"
#include "cppa/uniform_type_info.hpp"
using std::cout;
using std::endl;
using std::is_same;
using namespace cppa::util;
template <typename T, template <typename> class What>
struct apply
{
typedef typename What<T>::type type;
};
void test__type_list()
{
CPPA_TEST(test__type_list);
typedef apply<const int&, remove_const_reference>::type int_typedef;
CPPA_CHECK((is_same<int, int_typedef>::value));
typedef type_list<int, float, std::string> l1;
typedef reverse_type_list<l1>::type r1;
CPPA_CHECK((is_same<int, type_at<0, l1>::type>::value));
CPPA_CHECK((is_same<float, type_at<1, l1>::type>::value));
CPPA_CHECK((is_same<std::string, type_at<2, l1>::type>::value));
CPPA_CHECK_EQUAL(l1::type_list_size, 3);
CPPA_CHECK_EQUAL(l1::type_list_size, r1::type_list_size);
CPPA_CHECK((is_same<type_at<0, l1>::type, type_at<2, r1>::type>::value));
CPPA_CHECK((is_same<type_at<1, l1>::type, type_at<1, r1>::type>::value));
CPPA_CHECK((is_same<type_at<2, l1>::type, type_at<0, r1>::type>::value));
typedef concat_type_lists<type_list<int>, l1>::type l2;
CPPA_CHECK((is_same<int, l2::head_type>::value));
CPPA_CHECK((is_same<l1, l2::tail_type>::value));
}
This diff is collapsed.
#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::utype& 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::utype& 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
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