Commit 68086d89 authored by neverlord's avatar neverlord

tuple -> cow_tuple + pattern tweaks

parent 964a41f5
......@@ -83,6 +83,7 @@ nobase_library_include_HEADERS = \
cppa/channel.hpp \
cppa/config.hpp \
cppa/cow_ptr.hpp \
cppa/cow_tuple.hpp \
cppa/cppa.hpp \
cppa/deserializer.hpp \
cppa/detail/abstract_scheduled_actor.hpp \
......@@ -172,7 +173,6 @@ nobase_library_include_HEADERS = \
cppa/serializer.hpp \
cppa/stacked_event_based_actor.hpp \
cppa/to_string.hpp \
cppa/tuple.hpp \
cppa/tuple_cast.hpp \
cppa/type_value_pair.hpp \
cppa/uniform_type_info.hpp \
......
......@@ -59,7 +59,7 @@ struct testee : fsm_actor<testee>
},
on(atom("spread"), arg_match) >> [=](int x)
{
any_tuple msg = make_tuple(atom("spread"), x - 1);
any_tuple msg = make_cow_tuple(atom("spread"), x - 1);
spawn(new testee(this)) << msg;
spawn(new testee(this)) << msg;
become
......@@ -91,7 +91,7 @@ void stacked_testee(actor_ptr parent)
},
on(atom("spread"), arg_match) >> [&](int x)
{
any_tuple msg = make_tuple(atom("spread"), x-1);
any_tuple msg = make_cow_tuple(atom("spread"), x-1);
spawn(stacked_testee, self) << msg;
spawn(stacked_testee, self) << msg;
receive
......
......@@ -79,7 +79,7 @@ void receiver(int64_t max)
void sender(actor_ptr whom, int64_t count)
{
any_tuple msg = make_tuple(atom("msg"));
any_tuple msg = make_cow_tuple(atom("msg"));
for (int64_t i = 0; i < count; ++i)
{
whom->enqueue(nullptr, msg);
......
......@@ -39,7 +39,7 @@
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/announce.hpp"
using std::cout;
......@@ -77,12 +77,12 @@ int main(int argc, char** argv)
return 1;
}
auto num_loops = rd<int64_t>(argv[1]);
any_tuple m1 = make_tuple(atom("msg1"), 0);
any_tuple m2 = make_tuple(atom("msg2"), 0.0);
any_tuple m3 = cppa::make_tuple(atom("msg3"), list<int>{0});
any_tuple m4 = make_tuple(atom("msg4"), 0, "0");
any_tuple m5 = make_tuple(atom("msg5"), 0, 0, 0);
any_tuple m6 = make_tuple(atom("msg6"), 0, 0.0, "0");
any_tuple m1 = make_cow_tuple(atom("msg1"), 0);
any_tuple m2 = make_cow_tuple(atom("msg2"), 0.0);
any_tuple m3 = cppa::make_cow_tuple(atom("msg3"), list<int>{0});
any_tuple m4 = make_cow_tuple(atom("msg4"), 0, "0");
any_tuple m5 = make_cow_tuple(atom("msg5"), 0, 0, 0);
any_tuple m6 = make_cow_tuple(atom("msg6"), 0, 0.0, "0");
int64_t m1matched = 0;
int64_t m2matched = 0;
int64_t m3matched = 0;
......
cppa/ref_counted.hpp
cppa/tuple.hpp
cppa/cow_tuple.hpp
unit_testing/main.cpp
cppa/util/void_type.hpp
cppa/util/type_list.hpp
......
......@@ -166,7 +166,7 @@ class abstract_actor : public Base
// send exit message without lock
if (reason != exit_reason::not_exited)
{
other->enqueue(this, make_tuple(atom(":Exit"), reason));
other->enqueue(this, make_cow_tuple(atom(":Exit"), reason));
}
return false;
}
......@@ -210,7 +210,7 @@ class abstract_actor : public Base
// send exit messages
for (actor_ptr& aptr : mlinks)
{
aptr->enqueue(this, make_tuple(atom(":Exit"), reason));
aptr->enqueue(this, make_cow_tuple(atom(":Exit"), reason));
}
for (attachable_ptr& ptr : mattachables)
{
......@@ -226,7 +226,7 @@ class abstract_actor : public Base
// send exit message if already exited
if (exited())
{
other->enqueue(this, make_tuple(atom(":Exit"),
other->enqueue(this, make_cow_tuple(atom(":Exit"),
m_exit_reason.load()));
}
// add link if not already linked to other
......
......@@ -33,7 +33,7 @@
#include <iostream>
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
......@@ -69,13 +69,13 @@ class any_tuple
* @brief Creates a tuple from @p t.
*/
template<typename... Args>
any_tuple(tuple<Args...> const& t) : m_vals(t.vals()) { }
any_tuple(cow_tuple<Args...> const& t) : m_vals(t.vals()) { }
/**
* @brief Creates a tuple and moves the content from @p t.
*/
template<typename... Args>
any_tuple(tuple<Args...>&& t) : m_vals(std::move(t.m_vals)) { }
any_tuple(cow_tuple<Args...>&& t) : m_vals(std::move(t.m_vals)) { }
explicit any_tuple(detail::abstract_tuple*);
......
......@@ -60,17 +60,17 @@ class local_actor;
/**
* @ingroup CopyOnWrite
* @brief A fixed-length copy-on-write tuple.
* @brief A fixed-length copy-on-write cow_tuple.
*/
template<typename... ElementTypes>
class tuple
class cow_tuple
{
static_assert(sizeof...(ElementTypes) > 0, "tuple is empty");
static_assert(util::tl_forall<util::type_list<ElementTypes...>,
util::is_legal_tuple_type>::value,
"illegal types in tuple definition: "
"illegal types in cow_tuple definition: "
"pointers and references are prohibited");
friend class any_tuple;
......@@ -82,7 +82,7 @@ class tuple
struct priv_ctor { };
tuple(priv_ctor, cow_ptr<detail::abstract_tuple>&& ptr) : m_vals(std::move(ptr)) { }
cow_tuple(priv_ctor, cow_ptr<detail::abstract_tuple>&& ptr) : m_vals(std::move(ptr)) { }
public:
......@@ -94,50 +94,50 @@ class tuple
/**
* @brief Initializes each element with its default constructor.
*/
tuple() : m_vals(new data_type)
cow_tuple() : m_vals(new data_type)
{
}
/**
* @brief Initializes the tuple with @p args.
* @brief Initializes the cow_tuple with @p args.
* @param args Initialization values.
*/
tuple(ElementTypes const&... args) : m_vals(new data_type(args...))
cow_tuple(ElementTypes const&... args) : m_vals(new data_type(args...))
{
}
/**
* @brief Initializes the tuple with @p args.
* @brief Initializes the cow_tuple with @p args.
* @param args Initialization values.
*/
tuple(ElementTypes&&... args) : m_vals(new data_type(std::move(args)...))
cow_tuple(ElementTypes&&... args) : m_vals(new data_type(std::move(args)...))
{
}
tuple(tuple&&) = default;
tuple(tuple const&) = default;
tuple& operator=(tuple&&) = default;
tuple& operator=(tuple const&) = default;
cow_tuple(cow_tuple&&) = default;
cow_tuple(cow_tuple const&) = default;
cow_tuple& operator=(cow_tuple&&) = default;
cow_tuple& operator=(cow_tuple const&) = default;
inline static tuple from(cow_ptr_type ptr)
inline static cow_tuple from(cow_ptr_type ptr)
{
return {priv_ctor{}, std::move(ptr)};
}
inline static tuple from(cow_ptr_type ptr,
inline static cow_tuple from(cow_ptr_type ptr,
util::fixed_vector<size_t, num_elements> const& mv)
{
return {priv_ctor{}, decorated_type::create(std::move(ptr), mv)};
}
inline static tuple offset_subtuple(cow_ptr_type ptr, size_t offset)
inline static cow_tuple offset_subtuple(cow_ptr_type ptr, size_t offset)
{
CPPA_REQUIRE(offset > 0);
return {priv_ctor{}, decorated_type::create(std::move(ptr), offset)};
}
/**
* @brief Gets the size of this tuple.
* @brief Gets the size of this cow_tuple.
*/
inline size_t size() const
{
......@@ -177,12 +177,12 @@ class tuple
};
template<typename TypeList>
struct tuple_from_type_list;
struct cow_tuple_from_type_list;
template<typename... Types>
struct tuple_from_type_list< util::type_list<Types...> >
struct cow_tuple_from_type_list< util::type_list<Types...> >
{
typedef tuple<Types...> type;
typedef cow_tuple<Types...> type;
};
#ifdef CPPA_DOCUMENTATION
......@@ -190,87 +190,85 @@ struct tuple_from_type_list< util::type_list<Types...> >
/**
* @ingroup CopyOnWrite
* @brief Gets a const-reference to the <tt>N</tt>th element of @p tup.
* @param tup The tuple object.
* @param tup The cow_tuple object.
* @returns A const-reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @relates tuple
* @relates cow_tuple
*/
template<size_t N, typename T>
T const& get(tuple<...> const& tup);
T const& get(cow_tuple<...> const& tup);
/**
* @ingroup CopyOnWrite
* @brief Gets a reference to the <tt>N</tt>th element of @p tup.
* @param tup The tuple object.
* @param tup The cow_tuple object.
* @returns A reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @note Detaches @p tup if there are two or more references to the tuple data.
* @relates tuple
* @note Detaches @p tup if there are two or more references to the cow_tuple data.
* @relates cow_tuple
*/
template<size_t N, typename T>
T& get_ref(tuple<...>& tup);
T& get_ref(cow_tuple<...>& tup);
/**
* @ingroup ImplicitConversion
* @brief Creates a new tuple from @p args.
* @param args Values for the tuple elements.
* @returns A tuple object containing the values @p args.
* @relates tuple
* @brief Creates a new cow_tuple from @p args.
* @param args Values for the cow_tuple elements.
* @returns A cow_tuple object containing the values @p args.
* @relates cow_tuple
*/
template<typename... Types>
tuple<Types...> make_tuple(Types const&... args);
template<typename... Args>
cow_tuple<Args...> make_cow_tuple(Args&&... args);
#else
template<size_t N, typename... Types>
const typename util::at<N, Types...>::type& get(tuple<Types...> const& tup)
const typename util::at<N, Types...>::type& get(cow_tuple<Types...> const& tup)
{
typedef typename util::at<N, Types...>::type result_type;
return *reinterpret_cast<result_type const*>(tup.at(N));
}
template<size_t N, typename... Types>
typename util::at<N, Types...>::type& get_ref(tuple<Types...>& tup)
typename util::at<N, Types...>::type& get_ref(cow_tuple<Types...>& tup)
{
typedef typename util::at<N, Types...>::type result_type;
return *reinterpret_cast<result_type*>(tup.mutable_at(N));
}
template<typename... Types>
typename tuple_from_type_list<
typename util::tl_apply<util::type_list<Types...>,
detail::implicit_conversions>::type>::type
make_tuple(Types const&... args)
template<typename... Args>
cow_tuple<typename detail::strip_and_convert<Args>::type...>
make_cow_tuple(Args&&... args)
{
return { args... };
return {std::forward<Args>(args)...};
}
#endif
/**
* @brief Compares two tuples.
* @param lhs First tuple object.
* @param rhs Second tuple object.
* @brief Compares two cow_tuples.
* @param lhs First cow_tuple object.
* @param rhs Second cow_tuple object.
* @returns @p true if @p lhs and @p rhs are equal; otherwise @p false.
* @relates tuple
* @relates cow_tuple
*/
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator==(tuple<LhsTypes...> const& lhs,
tuple<RhsTypes...> const& rhs)
inline bool operator==(cow_tuple<LhsTypes...> const& lhs,
cow_tuple<RhsTypes...> const& rhs)
{
return util::compare_tuples(lhs, rhs);
}
/**
* @brief Compares two tuples.
* @param lhs First tuple object.
* @param rhs Second tuple object.
* @brief Compares two cow_tuples.
* @param lhs First cow_tuple object.
* @param rhs Second cow_tuple object.
* @returns @p true if @p lhs and @p rhs are not equal; otherwise @p false.
* @relates tuple
* @relates cow_tuple
*/
template<typename... LhsTypes, typename... RhsTypes>
inline bool operator!=(tuple<LhsTypes...> const& lhs,
tuple<RhsTypes...> const& rhs)
inline bool operator!=(cow_tuple<LhsTypes...> const& lhs,
cow_tuple<RhsTypes...> const& rhs)
{
return !(lhs == rhs);
}
......
......@@ -38,7 +38,7 @@
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/self.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/actor.hpp"
#include "cppa/channel.hpp"
#include "cppa/receive.hpp"
......@@ -140,7 +140,7 @@
* tuple @p x and @p y, whereas @p y is a copy of @p x:
*
* @code
* auto x = make_tuple(1, 2, 3);
* auto x = make_cow_tuple(1, 2, 3);
* auto y = x;
* @endcode
*
......@@ -193,7 +193,7 @@
* send(a1, atom("hello"), "hello a1!");
*
* // send a message to a1, a2 and a3
* auto msg = make_tuple(atom("compute"), 1, 2, 3);
* auto msg = make_cow_tuple(atom("compute"), 1, 2, 3);
* auto s = self; // cache self pointer
* // note: this is more efficient then using send() three times because
* // send() would create a new tuple each time;
......@@ -385,7 +385,7 @@
* send(self, u"hello unicode world!");
*
* // x has the type cppa::tuple<std::string, std::string>
* auto x = make_tuple("hello", "tuple");
* auto x = make_cow_tuple("hello", "tuple");
*
* receive
* (
......@@ -551,7 +551,7 @@ void send(channel_ptr& whom, Arg0 const& arg0, Args const&... args);
*
* <b>Usage example:</b>
* @code
* self << make_tuple(1, 2, 3);
* self << make_cow_tuple(1, 2, 3);
* @endcode
* @returns @p whom.
*/
......@@ -563,7 +563,7 @@ template<class C, typename Arg0, typename... Args>
void send(intrusive_ptr<C>& whom, Arg0 const& arg0, Args const&... args)
{
static_assert(std::is_base_of<channel, C>::value, "C is not a channel");
if (whom) whom->enqueue(self, make_tuple(arg0, args...));
if (whom) whom->enqueue(self, make_cow_tuple(arg0, args...));
}
template<class C, typename Arg0, typename... Args>
......@@ -571,14 +571,14 @@ void send(intrusive_ptr<C>&& whom, Arg0 const& arg0, Args const&... args)
{
static_assert(std::is_base_of<channel, C>::value, "C is not a channel");
intrusive_ptr<C> tmp(std::move(whom));
if (tmp) tmp->enqueue(self, make_tuple(arg0, args...));
if (tmp) tmp->enqueue(self, make_cow_tuple(arg0, args...));
}
// matches "send(this, ...)" in event-based actors
template<typename Arg0, typename... Args>
void send(local_actor* whom, Arg0 const& arg0, Args const&... args)
{
whom->enqueue(whom, make_tuple(arg0, args...));
whom->enqueue(whom, make_cow_tuple(arg0, args...));
}
......
......@@ -173,21 +173,6 @@ class abstract_tuple : public ref_counted
};
inline bool full_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
{
return lhs.type() == rhs.first
&& ( rhs.second == nullptr
|| lhs.type()->equals(lhs.value(), rhs.second));
}
inline bool full_eq_v2(type_value_pair const& lhs,
abstract_tuple::const_iterator const& rhs)
{
return full_eq(rhs, lhs);
}
inline bool full_eq_v3(abstract_tuple::const_iterator const& lhs,
abstract_tuple::const_iterator const& rhs)
{
......@@ -195,29 +180,16 @@ inline bool full_eq_v3(abstract_tuple::const_iterator const& lhs,
&& lhs.type()->equals(lhs.value(), rhs.value());
}
inline bool values_only_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
{
return rhs.second == nullptr
|| lhs.type()->equals(lhs.value(), rhs.second);
}
inline bool values_only_eq_v2(type_value_pair const& lhs,
abstract_tuple::const_iterator const& rhs)
{
return values_only_eq(rhs, lhs);
}
inline bool types_only_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
uniform_type_info const* rhs)
{
return lhs.type() == rhs.first;
return lhs.type() == rhs;
}
inline bool types_only_eq_v2(type_value_pair const& lhs,
abstract_tuple::const_iterator const& rhs)
inline bool types_only_eq_v2(uniform_type_info const* lhs,
abstract_tuple::const_iterator const& rhs)
{
return lhs.first == rhs.type();
return lhs == rhs.type();
}
} } // namespace cppa::detail
......
......@@ -32,7 +32,7 @@
#define ADDRESSED_MESSAGE_HPP
#include "cppa/actor.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/ref_counted.hpp"
......
......@@ -146,10 +146,10 @@ class decorated_tuple : public abstract_tuple
};
template<typename TypeList>
struct decorated_tuple_from_type_list;
struct decorated_cow_tuple_from_type_list;
template<typename... Types>
struct decorated_tuple_from_type_list< util::type_list<Types...> >
struct decorated_cow_tuple_from_type_list< util::type_list<Types...> >
{
typedef decorated_tuple<Types...> type;
};
......
......@@ -37,6 +37,7 @@
#include "cppa/self.hpp"
#include "cppa/actor.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/is_array_of.hpp"
#include "cppa/util/replace_type.hpp"
......@@ -74,6 +75,13 @@ struct implicit_conversions
};
template<typename T>
struct strip_and_convert
{
typedef typename implicit_conversions<typename util::rm_ref<T>::type>::type
type;
};
} } // namespace cppa::detail
#endif // IMPLICIT_CONVERSIONS_HPP
......@@ -87,7 +87,7 @@ template<typename Fun, class FunArgs, class TupleTypes>
struct iimpl : intermediate
{
typedef Fun functor_type;
typedef typename tuple_from_type_list<TupleTypes>::type tuple_type;
typedef typename cow_tuple_from_type_list<TupleTypes>::type tuple_type;
functor_type m_fun;
tuple_type m_default_args;
tuple_type m_args;
......@@ -358,19 +358,20 @@ struct select_invokable_impl<Fun, pattern<anything> >
dummy_policy> type;
};
template<class Pattern, typename Fun, typename Data>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun, Data&& dt)
template<class Pattern, typename Fun>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun,
std::unique_ptr<value_matcher>&& vm)
{
typedef typename select_invokable_impl<Fun, Pattern>::type result;
return std::unique_ptr<invokable>(
new result(std::forward<Fun>(fun), std::forward<Data>(dt)));
return std::unique_ptr<invokable>{
new result(std::forward<Fun>(fun), std::move(vm))};
}
template<class Pattern, typename Fun>
std::unique_ptr<invokable> get_invokable_impl(Fun&& fun)
{
typedef typename select_invokable_impl<Fun, typename Pattern::types>::type result;
return std::unique_ptr<invokable>(new result(std::forward<Fun>(fun)));
return std::unique_ptr<invokable>{new result(std::forward<Fun>(fun))};
}
} } // namespace cppa::detail
......
......@@ -77,8 +77,7 @@ struct matcher<wildcard_position::nil, T...>
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
CPPA_REQUIRE(tup.size() == sizeof...(T));
return std::equal(ptrn.begin(), ptrn.vend(), tup.begin(),
detail::values_only_eq_v2);
return ptrn._matches_values(tup);
}
};
......@@ -113,8 +112,7 @@ struct matcher<wildcard_position::trailing, T...>
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
return std::equal(ptrn.begin(), ptrn.vend(), tup.begin(),
detail::values_only_eq_v2);
return ptrn._matches_values(tup);
}
};
......@@ -169,12 +167,7 @@ struct matcher<wildcard_position::leading, T...>
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
auto tbegin = tup.begin();
// skip unmatched elements
tbegin += (tup.size() - size);
// skip leading wildcard ++(ptr.begin())
return std::equal(++(ptrn.begin()), ptrn.vend(), tbegin,
detail::values_only_eq_v2);
return ptrn._matches_values(tup);
}
};
......@@ -231,19 +224,7 @@ struct matcher<wildcard_position::in_between, T...>
static inline bool vmatch(any_tuple const& tup, pattern<T...> const& ptrn)
{
// first range
auto tbegin = tup.begin();
auto tend = tbegin + wc_pos;
if (std::equal(tbegin, tend, ptrn.begin(), detail::values_only_eq))
{
// second range
tbegin = tend = tup.end();
tbegin -= (size - (wc_pos + 1));
auto pbegin = ptrn.begin();
pbegin += (wc_pos + 1);
return std::equal(tbegin, tend, pbegin, detail::values_only_eq);
}
return false;
return ptrn._matches_values(tup);
}
};
......@@ -335,19 +316,7 @@ struct matcher<wildcard_position::multiple, T...>
pattern<T...> const& ptrn,
typename pattern<T...>::mapping_vector const& mv)
{
auto i = mv.begin();
for (auto j = ptrn.begin(); j != ptrn.end(); ++j)
{
if (j.type() != nullptr)
{
if ( j.value() != nullptr
&& j.type()->equals(tup.at(*i), j.value()) == false)
{
return false;
}
++i;
}
}
return ptrn._matches_values(tup, &mv);
}
};
......
......@@ -42,6 +42,7 @@
#include "cppa/util/arg_match_t.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
class uniform_type_info;
......@@ -275,10 +276,11 @@ struct tdata_from_type_list<cppa::util::type_list<T...>>
namespace cppa {
template<typename... Tn>
inline detail::tdata<Tn...> make_tdata(Tn const&... args)
template<typename... Args>
detail::tdata<typename detail::implicit_conversions<typename util::rm_ref<Args>::type>::type...>
mk_tdata(Args&&... args)
{
return detail::tdata<Tn...>(args...);
return {std::forward<Args>(args)...};
}
template<size_t N, typename... Tn>
......
......@@ -62,23 +62,17 @@ struct types_array_impl
static constexpr bool builtin_only = true;
// all types are builtin, perform lookup on constuction
uniform_type_info const* data[sizeof...(T)];
type_value_pair pairs[sizeof...(T)];
types_array_impl()
: data{ta_util<cppa_tinf,util::is_builtin<T>::value,T>::get()...}
{
for (size_t i = 0; i < sizeof...(T); ++i)
{
pairs[i].first = data[i];
pairs[i].second = nullptr;
}
}
inline uniform_type_info const* operator[](size_t p) const
{
return data[p];
}
typedef type_value_pair_const_iterator const_iterator;
inline const_iterator begin() const { return pairs; }
inline const_iterator end() const { return pairs + sizeof...(T); }
typedef uniform_type_info const* const* const_iterator;
inline const_iterator begin() const { return std::begin(data); }
inline const_iterator end() const { return std::end(data); }
};
template<typename... T>
......@@ -90,7 +84,7 @@ struct types_array_impl<false, T...>
// contains uniform_type_infos for builtin types and lazy initializes
// non-builtin types at runtime
mutable std::atomic<uniform_type_info const*> data[sizeof...(T)];
mutable std::atomic<type_value_pair const*> pairs;
mutable std::atomic<uniform_type_info const* *> pairs;
// pairs[sizeof...(T)];
types_array_impl()
: tinfo_data{ta_util<std_tinf,util::is_builtin<T>::value,T>::get()...}
......@@ -120,17 +114,16 @@ struct types_array_impl<false, T...>
}
return result;
}
typedef type_value_pair_const_iterator const_iterator;
typedef uniform_type_info const* const* const_iterator;
inline const_iterator begin() const
{
auto result = pairs.load();
if (result == nullptr)
{
auto parr = new type_value_pair[sizeof...(T)];
auto parr = new uniform_type_info const*[sizeof...(T)];
for (size_t i = 0; i < sizeof...(T); ++i)
{
parr[i].first = (*this)[i];
parr[i].second = nullptr;
parr[i] = (*this)[i];
}
if (!pairs.compare_exchange_weak(result, parr, std::memory_order_relaxed))
{
......
......@@ -42,7 +42,7 @@ namespace cppa {
namespace detail { template<typename...> class tdata; }
// forward declaration of tuple
template<typename...> class tuple;
template<typename...> class cow_tuple;
// forward declaration of get(detail::tdata<...> const&)
template<size_t N, typename... Tn>
......@@ -50,7 +50,7 @@ const typename util::at<N, Tn...>::type& get(detail::tdata<Tn...> const&);
// forward declarations of get(tuple<...> const&)
template<size_t N, typename... Tn>
const typename util::at<N, Tn...>::type& get(tuple<Tn...> const&);
const typename util::at<N, Tn...>::type& get(cow_tuple<Tn...> const&);
// forward declarations of get_ref(detail::tdata<...>&)
template<size_t N, typename... Tn>
......@@ -58,7 +58,7 @@ typename util::at<N, Tn...>::type& get_ref(detail::tdata<Tn...>&);
// forward declarations of get_ref(tuple<...>&)
template<size_t N, typename... Tn>
typename util::at<N, Tn...>::type& get_ref(tuple<Tn...>&);
typename util::at<N, Tn...>::type& get_ref(cow_tuple<Tn...>&);
} // namespace cppa
......
......@@ -103,10 +103,10 @@ struct pmatch_each_helper
namespace cppa {
//inline detail::match_helper match(any_tuple t)
//{
// return std::move(t);
//}
inline detail::match_helper match(any_tuple t)
{
return std::move(t);
}
/**
* @brief Match expression.
......
......@@ -101,17 +101,13 @@ class rvalue_builder
typedef typename pattern_from_type_list<converted_types>::type
pattern_type;
typedef typename pattern_type::data_type pattern_data;
pattern_data m_data;
bool m_has_values;
std::unique_ptr<value_matcher> m_vm;
template<typename F>
partial_function cr_rvalue(F&& f, std::integral_constant<bool, true>)
{
return m_has_values ? get_invokable_impl<pattern_type>(std::forward<F>(f),
std::move(m_data))
: get_invokable_impl<pattern_type>(std::forward<F>(f));
return get_invokable_impl<pattern_type>(std::forward<F>(f),
std::move(m_vm));
}
template<typename F>
......@@ -124,22 +120,18 @@ class rvalue_builder
typedef typename tl_apply<raw_types,rm_ref>::type new_types;
typedef typename tl_concat<converted_types,new_types>::type types;
typedef typename pattern_from_type_list<types>::type epattern;
return m_has_values ? get_invokable_impl<epattern>(std::forward<F>(f),
std::move(m_data))
: get_invokable_impl<epattern>(std::forward<F>(f));
return get_invokable_impl<epattern>(std::forward<F>(f),
std::move(m_vm));
}
public:
template<typename... Args>
rvalue_builder(Args&&... args) : m_data(std::forward<Args>(args)...)
rvalue_builder(Args&&... args)
: m_vm(pattern_type::get_value_matcher(std::forward<Args>(args)...))
{
static constexpr bool all_boxed =
util::tl_forall<util::type_list<Args...>, is_boxed>::value;
m_has_values = !all_boxed;
}
template<typename F>
partial_function operator>>(F&& f)
{
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
#include "cppa/self.hpp"
#include "cppa/atom.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/actor.hpp"
#include "cppa/attachable.hpp"
#include "cppa/local_actor.hpp"
......@@ -112,8 +112,8 @@ class scheduler
Duration const& rel_time, Data const&... data)
{
static_assert(sizeof...(Data) > 0, "no message to send");
any_tuple data_tup = make_tuple(data...);
any_tuple tup = make_tuple(util::duration(rel_time), to, data_tup);
any_tuple data_tup = make_cow_tuple(data...);
any_tuple tup = make_cow_tuple(util::duration(rel_time), to, data_tup);
future_send_helper()->enqueue(self, std::move(tup));
}
......
......@@ -48,12 +48,12 @@ namespace cppa {
template<typename... T>
auto moving_tuple_cast(any_tuple& tup, pattern<T...> const& p)
-> option<
typename tuple_from_type_list<
typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type>
{
typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
typedef typename cow_tuple_from_type_list<filtered_types>::type tuple_type;
static constexpr auto impl =
get_wildcard_position<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::safe(tup, p);
......@@ -66,7 +66,7 @@ auto moving_tuple_cast(any_tuple& tup, pattern<T...> const& p)
template<typename... T>
auto moving_tuple_cast(any_tuple& tup)
-> option<
typename tuple_from_type_list<
typename cow_tuple_from_type_list<
typename util::tl_filter_not<util::type_list<T...>,
is_anything>::type
>::type>
......@@ -91,7 +91,7 @@ auto moving_tuple_cast(any_tuple& tup, util::type_list<T...> const&)
template<typename... T>
auto tuple_cast(any_tuple tup, pattern<T...> const& p)
-> option<
typename tuple_from_type_list<
typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type>
{
......@@ -104,7 +104,7 @@ auto tuple_cast(any_tuple tup, pattern<T...> const& p)
template<typename... T>
auto tuple_cast(any_tuple tup)
-> option<
typename tuple_from_type_list<
typename cow_tuple_from_type_list<
typename util::tl_filter_not<util::type_list<T...>,
is_anything>::type
>::type>
......@@ -125,12 +125,12 @@ auto tuple_cast(any_tuple tup, util::type_list<T...> const&)
template<typename... T>
auto unsafe_tuple_cast(any_tuple& tup, pattern<T...> const& p)
-> option<
typename tuple_from_type_list<
typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type>
{
typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
typedef typename cow_tuple_from_type_list<filtered_types>::type tuple_type;
static constexpr auto impl =
get_wildcard_position<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::unsafe(tup, p);
......@@ -146,12 +146,12 @@ auto unsafe_tuple_cast(any_tuple& tup, util::type_list<T...> const&)
// cast using a pattern; does neither perform type checking nor checks values
template<typename... T>
auto forced_tuple_cast(any_tuple& tup, pattern<T...> const& p)
-> typename tuple_from_type_list<
-> typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type
{
typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
typedef typename cow_tuple_from_type_list<filtered_types>::type tuple_type;
static constexpr auto impl =
get_wildcard_position<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::force(tup, p);
......
......@@ -103,6 +103,12 @@ class type_value_pair_const_iterator
return iter + offset;
}
inline type_value_pair_const_iterator& operator+=(size_t offset)
{
iter += offset;
return *this;
}
};
/**
......
......@@ -35,26 +35,48 @@
namespace cppa { namespace util {
/**
* @ingroup MetaProgramming
* @brief A for loop that can be used with tuples.
*/
template<size_t Begin, size_t End>
struct static_foreach
template<size_t Begin, size_t End, bool BeginGreaterEnd>
struct static_foreach_impl
{
template<typename Container, typename Fun>
static inline void _(Container const& c, Fun& f)
{
f(get<Begin>(c));
static_foreach<Begin+1, End>::_(c, f);
static_foreach_impl<Begin+1, End, (Begin+1 > End)>::_(c, f);
}
template<typename Container, typename Fun>
static inline bool eval(Container const& c, Fun& f)
{
return f(get<Begin>(c))
&& static_foreach_impl<Begin+1, End, (Begin+1 > End)>::eval(c, f);
}
};
template<size_t X>
struct static_foreach<X, X>
struct static_foreach_impl<X, X, false>
{
template<typename Container, typename Fun>
static inline void _(Container const&, Fun&) { }
template<typename Container, typename Fun>
static inline bool eval(Container const&, Fun&) { return true; }
};
template<size_t X, size_t Y>
struct static_foreach_impl<X, Y, true>
{
template<typename Container, typename Fun>
static inline void _(Container const&, Fun&) { }
template<typename Container, typename Fun>
static inline bool eval(Container const&, Fun&) { return true; }
};
/**
* @ingroup MetaProgramming
* @brief A for loop that can be used with tuples.
*/
template<size_t Begin, size_t End>
struct static_foreach : static_foreach_impl<Begin, End, (Begin > End)>
{
};
} } // namespace cppa::util
......
......@@ -86,7 +86,7 @@ void actor_proxy::link_to(intrusive_ptr<actor>& other)
// causes remote actor to link to (proxy of) other
forward_message(parent_process_ptr(),
other.get(),
make_tuple(atom(":Link"), other));
make_cow_tuple(atom(":Link"), other));
}
}
......@@ -102,7 +102,7 @@ void actor_proxy::unlink_from(intrusive_ptr<actor>& other)
// causes remote actor to unlink from (proxy of) other
forward_message(parent_process_ptr(),
other.get(),
make_tuple(atom(":Unlink"), other));
make_cow_tuple(atom(":Unlink"), other));
}
}
......@@ -119,7 +119,7 @@ bool actor_proxy::establish_backlink(intrusive_ptr<actor>& other)
// causes remote actor to unlink from (proxy of) other
forward_message(parent_process_ptr(),
other.get(),
make_tuple(atom(":Link"), other));
make_cow_tuple(atom(":Link"), other));
}
return result;
}
......@@ -131,7 +131,7 @@ bool actor_proxy::remove_backlink(intrusive_ptr<actor>& other)
{
forward_message(parent_process_ptr(),
nullptr,
make_tuple(atom(":Unlink"), actor_ptr(this)));
make_cow_tuple(atom(":Unlink"), actor_ptr(this)));
}
return result;
}
......
......@@ -52,7 +52,7 @@ std::string to_string(atom_value const& what)
read_chars = true;
}
}
return std::move(result);
return result;
}
} // namespace cppa
......@@ -135,4 +135,11 @@ void demonitor(actor_ptr& whom)
if (whom) whom->detach(mtoken);
}
value_matcher::~value_matcher() { }
bool dummy_matcher::operator()(any_tuple const&)
{
return true;
}
} // namespace cppa
......@@ -223,7 +223,7 @@ class po_peer
{
if (!m_children.empty())
{
auto msg = make_tuple(atom(":KillProxy"),
auto msg = make_cow_tuple(atom(":KillProxy"),
exit_reason::remote_link_unreachable);
for (actor_proxy_ptr& pptr : m_children)
{
......@@ -341,7 +341,7 @@ class po_peer
// this message was send from a proxy
receiver->attach_functor([=](std::uint32_t reason)
{
any_tuple kmsg = make_tuple(atom(":KillProxy"),
any_tuple kmsg = make_cow_tuple(atom(":KillProxy"),
reason);
auto mjob = new detail::mailman_job(m_peer,
receiver,
......@@ -540,7 +540,7 @@ void post_office_loop(int pipe_read_handle, int pipe_write_handle)
if (!pptr) DEBUG("pptr == nullptr");
throw std::logic_error("selected_peer == nullptr");
}
pptr->enqueue(nullptr, make_tuple(atom(":Monitor")));
pptr->enqueue(nullptr, make_cow_tuple(atom(":Monitor")));
selected_peer->add_child(pptr);
auto aid = pptr->id();
auto pptr_copy = pptr;
......
......@@ -84,7 +84,7 @@ struct scheduler_helper
void stop()
{
m_worker->enqueue(nullptr, make_tuple(atom(":_DIE")));
m_worker->enqueue(nullptr, make_cow_tuple(atom(":_DIE")));
m_thread.join();
}
......
......@@ -15,7 +15,7 @@
#include "test.hpp"
#include "cppa/cppa.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/match.hpp"
#include "cppa/config.hpp"
#include "cppa/anything.hpp"
......
......@@ -26,7 +26,7 @@ inline bool cppa_check_value_fun_eq(T1 value1, T2 value2,
}
template<typename T1, typename T2>
inline void cppa_check_value_fun(T1 const& value1, T2 const& value2,
inline bool cppa_check_value_fun(T1 const& value1, T2 const& value2,
char const* file_name,
int line_number,
size_t& error_count)
......@@ -38,6 +38,21 @@ inline void cppa_check_value_fun(T1 const& value1, T2 const& value2,
<< ", found: " << value2
<< std::endl;
++error_count;
return false;
}
return true;
}
template<typename T1, typename T2>
inline void cppa_check_value_verbose_fun(T1 const& value1, T2 const& value2,
char const* file_name,
int line_number,
size_t& error_count)
{
if (cppa_check_value_fun(value1, value2, file_name,
line_number, error_count))
{
std::cout << "line " << line_number << " passed" << std::endl;
}
}
......@@ -65,9 +80,13 @@ if (!(line_of_code)) \
} \
else \
{ \
std::cout << "line " << __LINE__ << " passed" << endl; \
std::cout << "line " << __LINE__ << " passed" << std::endl; \
} \
((void) 0)
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value_verbose_fun((lhs_loc), (rhs_loc), __FILE__, __LINE__, \
cppa_ts.error_count)
#else
#define CPPA_IF_VERBOSE(line_of_code) ((void) 0)
#define CPPA_CHECK(line_of_code) \
......@@ -77,16 +96,16 @@ if (!(line_of_code)) \
<< " => " << #line_of_code << std::endl; \
++cppa_ts.error_count; \
} ((void) 0)
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value_fun((lhs_loc), (rhs_loc), __FILE__, __LINE__, \
cppa_ts.error_count)
#endif
#define CPPA_ERROR(err_msg) \
std::cerr << err_msg << std::endl; \
++cppa_ts.error_count
#define CPPA_CHECK_EQUAL(lhs_loc, rhs_loc) \
cppa_check_value_fun((lhs_loc), (rhs_loc), __FILE__, __LINE__, \
cppa_ts.error_count)
#define CPPA_CHECK_NOT_EQUAL(lhs_loc, rhs_loc) CPPA_CHECK(((lhs_loc) != (rhs_loc)))
typedef std::pair<std::string, std::string> string_pair;
......
......@@ -45,12 +45,12 @@ size_t test__atom()
CPPA_CHECK_NOT_EQUAL(atom("abc"), atom(" abc"));
// check to_string impl.
CPPA_CHECK_EQUAL(to_string(s_foo), "FooBar");
self << make_tuple(atom("foo"), static_cast<std::uint32_t>(42))
<< make_tuple(atom(":Attach"), atom(":Baz"), "cstring")
<< make_tuple(atom("b"), atom("a"), atom("c"), 23.f)
<< make_tuple(atom("a"), atom("b"), atom("c"), 23.f);
self << make_cow_tuple(atom("foo"), static_cast<std::uint32_t>(42))
<< make_cow_tuple(atom(":Attach"), atom(":Baz"), "cstring")
<< make_cow_tuple(atom("b"), atom("a"), atom("c"), 23.f)
<< make_cow_tuple(atom("a"), atom("b"), atom("c"), 23.f);
int i = 0;
receive_while([&i]() { return ++i <= 3; })
receive_for(i, 3)
(
on<atom("foo"), std::uint32_t>() >> [&](std::uint32_t value)
{
......
......@@ -7,7 +7,7 @@
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/option.hpp"
#include "cppa/pattern.hpp"
#include "cppa/announce.hpp"
......@@ -26,10 +26,11 @@
#include <boost/progress.hpp>
using std::string;
using namespace cppa;
template<typename Arr>
std::string plot(Arr const& arr)
string plot(Arr const& arr)
{
std::ostringstream oss;
oss << "{ ";
......@@ -56,7 +57,7 @@ void match_test(T const& value)
{
cout << "(" << a << ", " << b << ", " << c << ")" << endl;
},
on_arg_match >> [&](std::string const& str)
on_arg_match >> [&](string const& str)
{
cout << str << endl;
}
......@@ -96,12 +97,12 @@ size_t test__pattern()
{
CPPA_TEST(test__pattern);
//match_test(make_tuple(1,2,3));
//match_test(make_cow_tuple(1,2,3));
//match_test(std::list<int>{1, 2, 3});
//match_test("abc");
pattern<int, anything, int> i3;
any_tuple i3_any_tup = make_tuple(1, 2, 3);
any_tuple i3_any_tup = make_cow_tuple(1, 2, 3);
/*
auto opt = tuple_cast(i3_any_tup, i3);
CPPA_CHECK(opt.valid());
......@@ -123,17 +124,72 @@ size_t test__pattern()
CPPA_CHECK_EQUAL(plot(arr2), arr2_as_string);
// some pattern objects to play with
pattern<atom_value, int, std::string> p0{util::wrapped<atom_value>()};
pattern<atom_value, int, std::string> p1(atom("FooBar"));
pattern<atom_value, int, std::string> p2(atom("FooBar"), 42);
pattern<atom_value, int, std::string> p3(atom("FooBar"), 42, "hello world");
pattern<atom_value, anything, std::string> p4(atom("FooBar"), anything(), "hello world");
pattern<atom_value, anything> p5(atom("FooBar"));
pattern<atom_value, int, string> p0{util::wrapped<atom_value>{}};
pattern<atom_value, int, string> p1{atom("FooBar")};
pattern<atom_value, int, string> p2{atom("FooBar"), 42};
pattern<atom_value, int, string> p3{atom("FooBar"), 42, "hello world"};
pattern<atom_value, anything, string> p4{atom("FooBar"), anything(), "hello world"};
pattern<atom_value, anything> p5{atom("FooBar")};
pattern<anything> p6;
pattern<atom_value, anything> p7;
pattern<atom_value, anything, std::string> p8;
// each one should accept x ...
auto x = make_tuple(atom("FooBar"), 42, "hello world");
pattern<anything, string> p8;
pattern<atom_value, int, string> p9{mk_tdata(atom("FooBar"), util::wrapped<int>(), "hello world")};
pattern<string, string, string> p10{"a", util::wrapped<string>{}, "c"};
// p0-p9 should accept t0
any_tuple t0 = make_cow_tuple(atom("FooBar"), 42, "hello world");
CPPA_CHECK((detail::matches(t0, p0)));
CPPA_CHECK((detail::matches(t0, p1)));
CPPA_CHECK((detail::matches(t0, p2)));
CPPA_CHECK((detail::matches(t0, p3)));
CPPA_CHECK((detail::matches(t0, p4)));
CPPA_CHECK((detail::matches(t0, p5)));
CPPA_CHECK((detail::matches(t0, p6)));
CPPA_CHECK((detail::matches(t0, p7)));
CPPA_CHECK((detail::matches(t0, p8)));
CPPA_CHECK((detail::matches(t0, p9)));
CPPA_CHECK(p0._matches_values(t0));
CPPA_CHECK(p1._matches_values(t0));
CPPA_CHECK(p2._matches_values(t0));
CPPA_CHECK(p3._matches_values(t0));
CPPA_CHECK(p4._matches_values(t0));
CPPA_CHECK(p5._matches_values(t0));
CPPA_CHECK(p6._matches_values(t0));
CPPA_CHECK(p7._matches_values(t0));
CPPA_CHECK(p8._matches_values(t0));
CPPA_CHECK(p9._matches_values(t0));
any_tuple t1 = make_cow_tuple("a", "b", "c");
CPPA_CHECK((detail::matches(t1, p8)));
CPPA_CHECK(p8._matches_values(t1));
CPPA_CHECK((detail::matches(t1, p10)));
CPPA_CHECK(p10._matches_values(t1));
std::vector<string> vec{"a", "b", "c"};
any_tuple t2 = any_tuple::view(vec);
CPPA_CHECK((detail::matches(t2, p8)));
CPPA_CHECK(p8._matches_values(t2));
CPPA_CHECK((detail::matches(t2, p10)));
CPPA_CHECK(p10._matches_values(t2));
pattern<atom_value, int> p11{atom("foo")};
any_tuple t3 = make_cow_tuple(atom("foo"), 42);
CPPA_CHECK((detail::matches(t3, p11)));
CPPA_CHECK(p11._matches_values(t3));
bool invoked = false;
match(t3)
(
on<atom("foo"), int>() >> [&](int i)
{
invoked = true;
CPPA_CHECK_EQUAL(42, i);
}
);
CPPA_CHECK_EQUAL(true, invoked);
/*
CPPA_CHECK(p0(x));
CPPA_CHECK(p1(x));
......@@ -145,7 +201,7 @@ size_t test__pattern()
CPPA_CHECK(p7(x));
CPPA_CHECK(p8(x));
// ... but p2 and p3 should reject y
auto y = make_tuple(atom("FooBar"), 24, "hello world");
auto y = make_cow_tuple(atom("FooBar"), 24, "hello world");
CPPA_CHECK_EQUAL(p0(y), true);
CPPA_CHECK_EQUAL(p1(y), true);
CPPA_CHECK_EQUAL(p2(y), false);
......@@ -174,7 +230,7 @@ size_t test__pattern()
CPPA_CHECK_EQUAL(v2, 3);
lambda_invoked[0] = true;
},
on<std::string>() >> [&](const std::string& str)
on<string>() >> [&](const string& str)
{
CPPA_CHECK_EQUAL(str, "hello foo");
lambda_invoked[1] = true;
......@@ -184,7 +240,7 @@ size_t test__pattern()
CPPA_CHECK_EQUAL(value, 2);
lambda_invoked[2] = true;
},
on(1, val<std::string>(), any_vals) >> [&](const std::string& str)
on(1, val<string>(), any_vals) >> [&](const string& str)
{
CPPA_CHECK_EQUAL(str, "2");
lambda_invoked[3] = true;
......@@ -202,27 +258,27 @@ size_t test__pattern()
}
);
// invokes lambda 0
patterns(make_tuple(1, "2", 3));
patterns(make_cow_tuple(1, "2", 3));
CPPA_CHECK(lambda_invoked[0]);
reset_invoke_states();
// invokes lambda 1
patterns(make_tuple("hello foo"));
patterns(make_cow_tuple("hello foo"));
CPPA_CHECK(lambda_invoked[1]);
reset_invoke_states();
// invokes lambda 2
patterns(make_tuple("1", 2, 3));
patterns(make_cow_tuple("1", 2, 3));
CPPA_CHECK(lambda_invoked[2]);
reset_invoke_states();
// invokes lambda 3
patterns(make_tuple(1, "2", "3"));
patterns(make_cow_tuple(1, "2", "3"));
CPPA_CHECK(lambda_invoked[3]);
reset_invoke_states();
// invokes lambda 4
patterns(make_tuple(atom("Foo"), 1));
patterns(make_cow_tuple(atom("Foo"), 1));
CPPA_CHECK(lambda_invoked[4]);
reset_invoke_states();
// invokes lambda 5
patterns(make_tuple(1.0, 2.0f));
patterns(make_cow_tuple(1.0, 2.0f));
CPPA_CHECK(lambda_invoked[5]);
reset_invoke_states();
......
......@@ -25,7 +25,7 @@
#include "test.hpp"
#include "cppa/self.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/announce.hpp"
#include "cppa/tuple_cast.hpp"
......@@ -140,7 +140,7 @@ size_t test__serialization()
}
{
any_tuple ttup = make_tuple(1, 2, actor_ptr(self));
any_tuple ttup = make_cow_tuple(1, 2, actor_ptr(self));
binary_serializer bs;
bs << ttup;
binary_deserializer bd(bs.data(), bs.size());
......@@ -176,7 +176,7 @@ size_t test__serialization()
}
{
any_tuple msg1 = cppa::make_tuple(42, std::string("Hello \"World\"!"));
any_tuple msg1 = cppa::make_cow_tuple(42, std::string("Hello \"World\"!"));
auto msg1_tostring = to_string(msg1);
if (msg1str != msg1_tostring)
{
......
......@@ -9,7 +9,7 @@
#include "test.hpp"
#include "cppa/on.hpp"
#include "cppa/tuple.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/to_string.hpp"
......@@ -28,9 +28,9 @@ using namespace cppa;
size_t test__tuple()
{
CPPA_TEST(test__tuple);
// check type correctness of make_tuple()
auto t0 = make_tuple("1", 2);
CPPA_CHECK((std::is_same<decltype(t0), cppa::tuple<std::string, int>>::value));
// check type correctness of make_cow_tuple()
auto t0 = make_cow_tuple("1", 2);
CPPA_CHECK((std::is_same<decltype(t0), cppa::cow_tuple<std::string, int>>::value));
auto t0_0 = get<0>(t0);
auto t0_1 = get<1>(t0);
// check implicit type conversion
......@@ -41,7 +41,7 @@ size_t test__tuple()
// use tuple cast to get a subtuple
any_tuple at0(t0);
auto v0opt = tuple_cast<std::string, anything>(at0);
CPPA_CHECK((std::is_same<decltype(v0opt), option<tuple<std::string>>>::value));
CPPA_CHECK((std::is_same<decltype(v0opt), option<cow_tuple<std::string>>>::value));
CPPA_CHECK((v0opt));
CPPA_CHECK( at0.size() == 2
&& at0.at(0) == &get<0>(t0)
......@@ -49,7 +49,7 @@ size_t test__tuple()
if (v0opt)
{
auto& v0 = *v0opt;
CPPA_CHECK((std::is_same<decltype(v0), tuple<std::string>&>::value));
CPPA_CHECK((std::is_same<decltype(v0), cow_tuple<std::string>&>::value));
CPPA_CHECK((std::is_same<decltype(get<0>(v0)), std::string const&>::value));
CPPA_CHECK_EQUAL(v0.size(), 1);
CPPA_CHECK_EQUAL(get<0>(v0), "1");
......@@ -61,19 +61,19 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(get<0>(v0), "1"); // v0 contains old value
CPPA_CHECK_NOT_EQUAL(&get<0>(t0), &get<0>(v0)); // no longer the same
// check operator==
auto lhs = make_tuple(1,2,3,4);
auto rhs = make_tuple(static_cast<std::uint8_t>(1), 2.0, 3, 4);
auto lhs = make_cow_tuple(1,2,3,4);
auto rhs = make_cow_tuple(static_cast<std::uint8_t>(1), 2.0, 3, 4);
CPPA_CHECK(lhs == rhs);
CPPA_CHECK(rhs == lhs);
}
any_tuple at1 = make_tuple("one", 2, 3.f, 4.0);
any_tuple at1 = make_cow_tuple("one", 2, 3.f, 4.0);
{
// perfect match
auto opt0 = tuple_cast<std::string, int, float, double>(at1);
CPPA_CHECK(opt0);
if (opt0)
{
CPPA_CHECK((*opt0 == make_tuple("one", 2, 3.f, 4.0)));
CPPA_CHECK((*opt0 == make_cow_tuple("one", 2, 3.f, 4.0)));
CPPA_CHECK_EQUAL(&get<0>(*opt0), at1.at(0));
CPPA_CHECK_EQUAL(&get<1>(*opt0), at1.at(1));
CPPA_CHECK_EQUAL(&get<2>(*opt0), at1.at(2));
......@@ -100,7 +100,7 @@ size_t test__tuple()
CPPA_CHECK(opt3);
if (opt3)
{
CPPA_CHECK((*opt3 == make_tuple("one", 4.0)));
CPPA_CHECK((*opt3 == make_cow_tuple("one", 4.0)));
CPPA_CHECK_EQUAL(get<0>(*opt3), "one");
CPPA_CHECK_EQUAL(get<1>(*opt3), 4.0);
CPPA_CHECK_EQUAL(&get<0>(*opt3), at1.at(0));
......
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