Commit ada8fbb3 authored by neverlord's avatar neverlord

pattern matching improvements

parent e41694da
...@@ -198,6 +198,7 @@ nobase_library_include_HEADERS = \ ...@@ -198,6 +198,7 @@ nobase_library_include_HEADERS = \
cppa/util/is_legal_tuple_type.hpp \ cppa/util/is_legal_tuple_type.hpp \
cppa/util/is_one_of.hpp \ cppa/util/is_one_of.hpp \
cppa/util/is_primitive.hpp \ cppa/util/is_primitive.hpp \
cppa/util/option.hpp \
cppa/util/producer_consumer_list.hpp \ cppa/util/producer_consumer_list.hpp \
cppa/util/pt_dispatch.hpp \ cppa/util/pt_dispatch.hpp \
cppa/util/pt_token.hpp \ cppa/util/pt_token.hpp \
......
...@@ -250,3 +250,4 @@ cppa/detail/types_array.hpp ...@@ -250,3 +250,4 @@ cppa/detail/types_array.hpp
cppa/util/is_builtin.hpp cppa/util/is_builtin.hpp
cppa/util/type_pair.hpp cppa/util/type_pair.hpp
cppa/util/tbind.hpp cppa/util/tbind.hpp
cppa/util/option.hpp
...@@ -39,8 +39,8 @@ ...@@ -39,8 +39,8 @@
namespace cppa { namespace cppa {
template<typename... Types> //template<typename... Types>
tuple_view<Types...> tuple_cast(any_tuple&& tup); //tuple_view<Types...> tuple_cast(any_tuple&& tup);
/** /**
* @brief Describes a fixed-length tuple with elements of any type. * @brief Describes a fixed-length tuple with elements of any type.
...@@ -48,8 +48,8 @@ tuple_view<Types...> tuple_cast(any_tuple&& tup); ...@@ -48,8 +48,8 @@ tuple_view<Types...> tuple_cast(any_tuple&& tup);
class any_tuple class any_tuple
{ {
template<typename... Types> //template<typename... Types>
friend tuple_view<Types...> tuple_cast(any_tuple&& tup); //friend tuple_view<Types...> tuple_cast(any_tuple&& tup);
cow_ptr<detail::abstract_tuple> m_vals; cow_ptr<detail::abstract_tuple> m_vals;
...@@ -57,8 +57,6 @@ class any_tuple ...@@ -57,8 +57,6 @@ class any_tuple
public: public:
//typedef cow_ptr<detail::abstract_tuple> vals_ptr;
any_tuple(); any_tuple();
template<typename... Args> template<typename... Args>
...@@ -102,6 +100,8 @@ class any_tuple ...@@ -102,6 +100,8 @@ class any_tuple
template<typename T> template<typename T>
inline T& get_mutable_as(size_t p); inline T& get_mutable_as(size_t p);
}; };
inline bool operator==(any_tuple const& lhs, any_tuple const& rhs) inline bool operator==(any_tuple const& lhs, any_tuple const& rhs)
...@@ -126,6 +126,7 @@ inline T& any_tuple::get_mutable_as(size_t p) ...@@ -126,6 +126,7 @@ inline T& any_tuple::get_mutable_as(size_t p)
return *reinterpret_cast<T*>(mutable_at(p)); return *reinterpret_cast<T*>(mutable_at(p));
} }
/*
template<typename... Types> template<typename... Types>
tuple_view<Types...> tuple_cast(any_tuple const& tup) tuple_view<Types...> tuple_cast(any_tuple const& tup)
{ {
...@@ -137,6 +138,7 @@ tuple_view<Types...> tuple_cast(any_tuple&& tup) ...@@ -137,6 +138,7 @@ tuple_view<Types...> tuple_cast(any_tuple&& tup)
{ {
return tuple_view<Types...>::from(std::move(tup.m_vals)); return tuple_view<Types...>::from(std::move(tup.m_vals));
} }
*/
} // namespace cppa } // namespace cppa
......
...@@ -101,6 +101,8 @@ class cow_ptr ...@@ -101,6 +101,8 @@ class cow_ptr
cow_ptr(T* raw_ptr) : m_ptr(raw_ptr) { } cow_ptr(T* raw_ptr) : m_ptr(raw_ptr) { }
cow_ptr(cow_ptr&& other) : m_ptr(std::move(other.m_ptr)) { }
cow_ptr(cow_ptr const& other) : m_ptr(other.m_ptr) { } cow_ptr(cow_ptr const& other) : m_ptr(other.m_ptr) { }
template<typename Y> template<typename Y>
...@@ -111,6 +113,12 @@ class cow_ptr ...@@ -111,6 +113,12 @@ class cow_ptr
m_ptr.swap(other.m_ptr); m_ptr.swap(other.m_ptr);
} }
cow_ptr& operator=(cow_ptr&& other)
{
swap(other);
return *this;
}
cow_ptr& operator=(cow_ptr const& other) cow_ptr& operator=(cow_ptr const& other)
{ {
cow_ptr tmp(other); cow_ptr tmp(other);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
......
...@@ -45,18 +45,21 @@ ...@@ -45,18 +45,21 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename... ElementTypes> template<size_t VectorSize>
class decorated_tuple : public abstract_tuple class decorated_tuple : public abstract_tuple
{ {
public: public:
typedef util::fixed_vector<size_t, sizeof...(ElementTypes)> vector_type; typedef util::fixed_vector<size_t, VectorSize> vector_type;
typedef util::type_list<ElementTypes...> element_types;
typedef cow_ptr<abstract_tuple> ptr_type; typedef cow_ptr<abstract_tuple> ptr_type;
decorated_tuple(ptr_type&& d, vector_type const& v)
: m_decorated(std::move(d)), m_mappings(v)
{
}
decorated_tuple(ptr_type const& d, vector_type const& v) decorated_tuple(ptr_type const& d, vector_type const& v)
: m_decorated(d), m_mappings(v) : m_decorated(d), m_mappings(v)
{ {
......
...@@ -43,79 +43,6 @@ ...@@ -43,79 +43,6 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
template<typename OutputIterator, typename T0>
void fill_uti_vec(OutputIterator& ii)
{
typedef typename unboxed<T0>::type real_type;
*ii = std::is_same<real_type,anything>::value ? nullptr
: uniform_typeid<real_type>();
}
template<typename OutputIterator, typename T0, typename T1, typename... Tn>
void fill_uti_vec(OutputIterator& ii)
{
fill_uti_vec<OutputIterator, T0>(ii);
fill_uti_vec<OutputIterator, T1, Tn...>(++ii);
}
template<typename T0>
struct fill_vecs_util
{
template<typename DataTuple>
inline static void _(size_t pos,
size_t dt_size,
bool* dt_is_invalid,
DataTuple const& dt,
cppa::uniform_type_info const* * utis,
void const* * data_ptrs)
{
utis[pos] = uniform_typeid<T0>();
data_ptrs[pos] = (pos < dt_size && !(dt_is_invalid[pos])) ? dt.at(pos)
: nullptr;
}
};
template<>
struct fill_vecs_util<anything>
{
template<typename DataTuple>
inline static void _(size_t pos,
size_t,
bool*,
DataTuple const&,
cppa::uniform_type_info const* * utis,
void const* * data_ptrs)
{
utis[pos] = nullptr;
data_ptrs[pos] = nullptr;
}
};
template<typename DataTuple, typename T0>
void fill_vecs(size_t pos,
size_t dt_size,
bool* dt_invalids,
DataTuple const& dt,
cppa::uniform_type_info const* * utis,
void const* * data_ptrs)
{
fill_vecs_util<T0>::_(pos, dt_size, dt_invalids, dt, utis, data_ptrs);
}
template<typename DataTuple, typename T0, typename T1, typename... Tn>
void fill_vecs(size_t pos,
size_t dt_size,
bool* dt_invalids,
DataTuple const& dt,
cppa::uniform_type_info const* * utis,
void const* * data_ptrs)
{
fill_vecs_util<T0>::_(pos, dt_size, dt_invalids,
dt, utis, data_ptrs);
fill_vecs<DataTuple, T1, Tn...>(pos + 1, dt_size, dt_invalids,
dt, utis, data_ptrs);
}
template<class TypesArray> template<class TypesArray>
class pattern_iterator class pattern_iterator
{ {
......
...@@ -99,7 +99,7 @@ class invoke_rule_builder ...@@ -99,7 +99,7 @@ class invoke_rule_builder
detail::implicit_conversions>::type detail::implicit_conversions>::type
converted_types; converted_types;
typedef typename pattern_type_from_type_list<converted_types>::type typedef typename pattern_from_type_list<converted_types>::type
pattern_type; pattern_type;
std::unique_ptr<pattern_type> m_ptr; std::unique_ptr<pattern_type> m_ptr;
...@@ -122,7 +122,7 @@ class invoke_rule_builder ...@@ -122,7 +122,7 @@ class invoke_rule_builder
static_assert(raw_types::size > 0, "functor has no arguments"); static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_types,rm_ref>::type new_types; typedef typename tl_apply<raw_types,rm_ref>::type new_types;
typedef typename concat_type_lists<converted_types,new_types>::type types; typedef typename concat_type_lists<converted_types,new_types>::type types;
typedef typename pattern_type_from_type_list<types>::type epattern; typedef typename pattern_from_type_list<types>::type epattern;
typedef typename epattern::tuple_view_type tuple_view_type; typedef typename epattern::tuple_view_type tuple_view_type;
typedef invokable_impl<tuple_view_type, epattern, F> impl; typedef invokable_impl<tuple_view_type, epattern, F> impl;
std::unique_ptr<epattern> pptr(extend_pattern<epattern>(m_ptr.get())); std::unique_ptr<epattern> pptr(extend_pattern<epattern>(m_ptr.get()));
...@@ -164,7 +164,7 @@ class on_the_fly_invoke_rule_builder ...@@ -164,7 +164,7 @@ class on_the_fly_invoke_rule_builder
typedef typename ctrait::arg_types raw_types; typedef typename ctrait::arg_types raw_types;
static_assert(raw_types::size > 0, "functor has no arguments"); static_assert(raw_types::size > 0, "functor has no arguments");
typedef typename tl_apply<raw_types,rm_ref>::type types; typedef typename tl_apply<raw_types,rm_ref>::type types;
typedef typename pattern_type_from_type_list<types>::type pattern_type; typedef typename pattern_from_type_list<types>::type pattern_type;
typedef typename pattern_type::tuple_view_type tuple_view_type; typedef typename pattern_type::tuple_view_type tuple_view_type;
typedef invokable_impl<tuple_view_type, pattern_type, F> impl; typedef invokable_impl<tuple_view_type, pattern_type, F> impl;
std::unique_ptr<pattern_type> pptr(new pattern_type); std::unique_ptr<pattern_type> pptr(new pattern_type);
......
...@@ -51,12 +51,11 @@ namespace cppa { ...@@ -51,12 +51,11 @@ namespace cppa {
struct dont_initialize_pattern { }; struct dont_initialize_pattern { };
template<typename... Types> template<typename... Types>
class pattern; class pattern
template<typename T0, typename... Tn>
class pattern<T0, Tn...>
{ {
static_assert(sizeof...(Types) > 0, "empty pattern");
pattern(pattern const&) = delete; pattern(pattern const&) = delete;
pattern& operator=(pattern const&) = delete; pattern& operator=(pattern const&) = delete;
...@@ -64,14 +63,14 @@ class pattern<T0, Tn...> ...@@ -64,14 +63,14 @@ class pattern<T0, Tn...>
pattern(dont_initialize_pattern const&) { } pattern(dont_initialize_pattern const&) { }
static constexpr size_t size = sizeof...(Tn) + 1; static constexpr size_t size = sizeof...(Types);
typedef util::type_list<T0, Tn...> tpl_args; typedef util::type_list<Types...> types;
typedef typename util::lt_filter_not<tpl_args, util::tbind<std::is_same, anything>::type>::type typedef typename util::lt_filter_not<types, util::tbind<std::is_same, anything>::type>::type
filtered_tpl_args; filtered_types;
typedef typename tuple_view_type_from_type_list<filtered_tpl_args>::type typedef typename tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type; tuple_view_type;
typedef typename tuple_view_type::mapping_vector mapping_vector; typedef typename tuple_view_type::mapping_vector mapping_vector;
...@@ -109,15 +108,15 @@ class pattern<T0, Tn...> ...@@ -109,15 +108,15 @@ class pattern<T0, Tn...>
// private: // private:
detail::tdata<T0, Tn...> m_data; detail::tdata<Types...> m_data;
//cppa::uniform_type_info const* m_utis[size]; //cppa::uniform_type_info const* m_utis[size];
static detail::types_array<T0, Tn...> m_utis; static detail::types_array<Types...> m_utis;
void const* m_data_ptr[size]; void const* m_data_ptr[size];
}; };
template<typename T0, typename... Tn> template<typename... Types>
detail::types_array<T0, Tn...> pattern<T0, Tn...>::m_utis; detail::types_array<Types...> pattern<Types...>::m_utis;
template<class ExtendedType, class BasicType> template<class ExtendedType, class BasicType>
ExtendedType* extend_pattern(BasicType* p) ExtendedType* extend_pattern(BasicType* p)
...@@ -126,23 +125,21 @@ ExtendedType* extend_pattern(BasicType* p) ...@@ -126,23 +125,21 @@ ExtendedType* extend_pattern(BasicType* p)
et->m_data = p->m_data; et->m_data = p->m_data;
for (size_t i = 0; i < BasicType::size; ++i) for (size_t i = 0; i < BasicType::size; ++i)
{ {
//et->m_utis[i] = p->m_utis[i];
et->m_data_ptr[i] = (p->m_data_ptr[i]) ? et->m_data.at(i) et->m_data_ptr[i] = (p->m_data_ptr[i]) ? et->m_data.at(i)
: nullptr; : nullptr;
} }
for (size_t i = BasicType::size; i < ExtendedType::size; ++i) for (size_t i = BasicType::size; i < ExtendedType::size; ++i)
{ {
et->m_data_ptr[i] = nullptr; et->m_data_ptr[i] = nullptr;
//et->m_utis[i] = et->m_data.type_at(i);
} }
return et; return et;
} }
template<typename TypeList> template<typename TypeList>
struct pattern_type_from_type_list; struct pattern_from_type_list;
template<typename... Types> template<typename... Types>
struct pattern_type_from_type_list<util::type_list<Types...>> struct pattern_from_type_list<util::type_list<Types...>>
{ {
typedef pattern<Types...> type; typedef pattern<Types...> type;
}; };
......
...@@ -64,34 +64,38 @@ template<typename... ElementTypes> ...@@ -64,34 +64,38 @@ template<typename... ElementTypes>
class tuple class tuple
{ {
template<size_t N, typename... Types>
friend typename util::at<N, Types...>::type& get_ref(tuple<Types...>&);
public:
typedef util::type_list<ElementTypes...> element_types;
private:
static_assert(sizeof...(ElementTypes) > 0, "tuple is empty"); static_assert(sizeof...(ElementTypes) > 0, "tuple is empty");
static_assert(util::tl_forall<element_types, util::is_legal_tuple_type>::value, static_assert(util::tl_forall<util::type_list<ElementTypes...>,
util::is_legal_tuple_type>::value,
"illegal types in tuple definition: " "illegal types in tuple definition: "
"pointers and references are prohibited"); "pointers and references are prohibited");
typedef detail::tuple_vals<ElementTypes...> tuple_vals_type; typedef detail::tuple_vals<ElementTypes...> data_type;
//typedef detail::tuple_vals<ElementTypes...> vals_t; cow_ptr<detail::abstract_tuple> m_vals;
typedef detail::abstract_tuple vals_t;
cow_ptr<vals_t> m_vals; struct ptr_ctor { };
template<typename CowPtr>
tuple(ptr_ctor const&, CowPtr&& ptr) : m_vals(std::forward<CowPtr>(ptr))
{
}
public: public:
/** /**
* @brief Initializes each element with its default constructor. * @brief Initializes each element with its default constructor.
*/ */
tuple() : m_vals(new tuple_vals_type) tuple() : m_vals(new data_type)
{
}
/**
* @brief Initializes the tuple with @p args.
* @param args Initialization values.
*/
tuple(ElementTypes const&... args) : m_vals(new data_type(args...))
{ {
} }
...@@ -99,8 +103,23 @@ class tuple ...@@ -99,8 +103,23 @@ class tuple
* @brief Initializes the tuple with @p args. * @brief Initializes the tuple with @p args.
* @param args Initialization values. * @param args Initialization values.
*/ */
tuple(ElementTypes const&... args) : m_vals(new tuple_vals_type(args...)) 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;
static tuple from(cow_ptr<detail::abstract_tuple>&& ptr)
{
return tuple(ptr_ctor(), std::move(ptr));
}
static tuple from(cow_ptr<detail::abstract_tuple> const& ptr)
{ {
return tuple(ptr_ctor(), ptr);
} }
/** /**
...@@ -143,7 +162,7 @@ class tuple ...@@ -143,7 +162,7 @@ class tuple
*/ */
cow_ptr<InternalData> vals() const; cow_ptr<InternalData> vals() const;
# else # else
inline cow_ptr<vals_t> const& vals() const inline cow_ptr<detail::abstract_tuple> const& vals() const
{ {
return m_vals; return m_vals;
} }
...@@ -152,10 +171,10 @@ class tuple ...@@ -152,10 +171,10 @@ class tuple
}; };
template<typename TypeList> template<typename TypeList>
struct tuple_type_from_type_list; struct tuple_from_type_list;
template<typename... Types> template<typename... Types>
struct tuple_type_from_type_list<util::type_list<Types...>> struct tuple_from_type_list< util::type_list<Types...> >
{ {
typedef tuple<Types...> type; typedef tuple<Types...> type;
}; };
...@@ -202,7 +221,6 @@ const typename util::at<N, Types...>::type& get(tuple<Types...> const& tup) ...@@ -202,7 +221,6 @@ const typename util::at<N, Types...>::type& get(tuple<Types...> const& tup)
{ {
typedef typename util::at<N, Types...>::type result_type; typedef typename util::at<N, Types...>::type result_type;
return *reinterpret_cast<result_type const*>(tup.at(N)); return *reinterpret_cast<result_type const*>(tup.at(N));
//return get<N>(tup.vals()->data());
} }
template<size_t N, typename... Types> template<size_t N, typename... Types>
...@@ -210,11 +228,10 @@ typename util::at<N, Types...>::type& get_ref(tuple<Types...>& tup) ...@@ -210,11 +228,10 @@ typename util::at<N, Types...>::type& get_ref(tuple<Types...>& tup)
{ {
typedef typename util::at<N, Types...>::type result_type; typedef typename util::at<N, Types...>::type result_type;
return *reinterpret_cast<result_type*>(tup.mutable_at(N)); return *reinterpret_cast<result_type*>(tup.mutable_at(N));
//return get_ref<N>(tup.m_vals->data_ref());
} }
template<typename... Types> template<typename... Types>
typename tuple_type_from_type_list< typename tuple_from_type_list<
typename util::tl_apply<util::type_list<Types...>, typename util::tl_apply<util::type_list<Types...>,
detail::implicit_conversions>::type>::type detail::implicit_conversions>::type>::type
make_tuple(Types const&... args) make_tuple(Types const&... args)
......
...@@ -82,7 +82,7 @@ class tuple_view ...@@ -82,7 +82,7 @@ class tuple_view
} }
tuple_view(vals_t const& vals, mapping_vector& mapping) tuple_view(vals_t const& vals, mapping_vector& mapping)
: m_vals(new detail::decorated_tuple<ElementTypes...>(vals, mapping)) : m_vals(new detail::decorated_tuple<num_elements>(vals, mapping))
{ {
} }
......
#ifndef OPTION_HPP
#define OPTION_HPP
namespace cppa { namespace util {
template<typename What>
class option
{
union
{
What m_value;
};
bool m_valid;
void destroy()
{
if (m_valid) m_value.~What();
}
template<typename V>
void cr(V&& value)
{
m_valid = true;
new (&m_value) What (std::forward<V>(value));
}
public:
option() : m_valid(false) { }
template<typename V>
option(V&& value)
{
cr(std::forward<V>(value));
}
option(option const& other) : m_valid(other.m_valid)
{
if (other.m_valid) cr(other.m_value);
}
option(option&& other) : m_valid(other.m_valid)
{
if (other.m_valid) cr(std::move(other.m_value));
}
~option()
{
destroy();
}
option& operator=(option const& other)
{
if (m_valid)
{
if (other.m_valid)
{
m_value = other.m_value;
}
else
{
destroy();
m_valid = false;
}
}
else
{
if (other.m_valid)
{
cr(other.m_value);
}
}
return *this;
}
option& operator=(option&& other)
{
if (m_valid)
{
if (other.m_valid)
{
m_value = std::move(other.m_value);
}
else
{
destroy();
m_valid = false;
}
}
else
{
if (other.m_valid)
{
cr(std::move(other.m_value));
}
}
return *this;
}
option& operator=(What const& value)
{
if (m_valid) m_value = value;
else cr(value);
return *this;
}
option& operator=(What& value)
{
if (m_valid) m_value = std::move(value);
else cr(std::move(value));
return *this;
}
inline bool valid() const { return m_valid; }
inline What& operator*() { return m_value; }
inline What const& operator*() const { return m_value; }
inline What& get() { return m_value; }
inline What const& get() const { return m_value; }
};
} } // namespace cppa::util
#endif // OPTION_HPP
...@@ -8,12 +8,14 @@ ...@@ -8,12 +8,14 @@
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/util/option.hpp"
#include "cppa/util/enable_if.hpp" #include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp" #include "cppa/util/disable_if.hpp"
#include "cppa/util/conjunction.hpp" #include "cppa/util/conjunction.hpp"
#include "cppa/util/is_primitive.hpp" #include "cppa/util/is_primitive.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
using namespace cppa; using namespace cppa;
...@@ -34,26 +36,63 @@ typedef std::pair<int,int> foobar; ...@@ -34,26 +36,63 @@ typedef std::pair<int,int> foobar;
static detail::types_array<int,anything,float> arr1; static detail::types_array<int,anything,float> arr1;
static detail::types_array<int,anything,foobar> arr2; static detail::types_array<int,anything,foobar> arr2;
//template<template <typename, typename> class Tpl, typename Arg1> template<typename... P>
//struct tbind auto tuple_cast(any_tuple const& tup, pattern<P...> const& p) -> util::option<typename tuple_from_type_list<typename pattern<P...>::filtered_types>::type>
//{ {
// template<typename Arg2> typedef typename pattern<P...>::filtered_types filtered_types;
// struct type typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
// { util::option<tuple_type> result;
// static constexpr bool value = Tpl<Arg1, Arg2>::value; typename pattern<P...>::mapping_vector mv;
// }; if (p(tup, &mv))
//}; {
if (mv.size() == tup.size()) // perfect match
//template<template<typename> class Predicate, class Value> {
//struct foobaz result = tuple_type::from(tup.vals());
//{ }
// static constexpr bool value = Predicate<Value>::value; else
//}; {
result = tuple_type::from(new detail::decorated_tuple<filtered_types::size>(tup.vals(), mv));
}
}
return std::move(result);
}
struct match_helper
{
any_tuple const& what;
match_helper(any_tuple const& w) : what(w) { }
void operator()(invoke_rules&& rules)
{
rules(what);
}
};
match_helper match(any_tuple const& x)
{
return { x };
}
size_t test__pattern() size_t test__pattern()
{ {
//cout << "foobaz: " << foobaz<tbind<std::is_same, void>::type, void>::value << endl; //std::vector<int> ivec = {1, 2, 3};
match(make_tuple(1,2,3))
(
on_arg_match >> [](int a, int b, int c)
{
cout << "MATCH: " << a << ", " << b << ", " << c << endl;
}
);
pattern<int, anything, int> i3;
any_tuple i3_any_tup = make_tuple(1, 2, 3);
auto opt = tuple_cast(i3_any_tup, i3);
if (opt.valid())
{
cout << "x = ( " << get<0>(*opt) << ", " << get<1>(*opt) << " )" << endl;
}
announce<foobar>(&foobar::first, &foobar::second); announce<foobar>(&foobar::first, &foobar::second);
......
...@@ -28,6 +28,8 @@ using std::endl; ...@@ -28,6 +28,8 @@ using std::endl;
using namespace cppa; using namespace cppa;
size_t test__tuple() size_t test__tuple()
{ {
CPPA_TEST(test__tuple); CPPA_TEST(test__tuple);
......
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