Commit 597a9e09 authored by neverlord's avatar neverlord

fixed pattern matching

parent 627cec59
...@@ -8,6 +8,16 @@ namespace cppa { ...@@ -8,6 +8,16 @@ namespace cppa {
*/ */
struct anything { }; struct anything { };
inline bool operator==(const anything&, const anything&)
{
return true;
}
inline bool operator!=(const anything&, const anything&)
{
return false;
}
} // namespace cppa } // namespace cppa
#endif // ANYTHING_HPP #endif // ANYTHING_HPP
...@@ -24,6 +24,20 @@ struct boxed<anything> ...@@ -24,6 +24,20 @@ struct boxed<anything>
typedef anything type; typedef anything type;
}; };
template<typename T>
struct is_boxed
{
static const bool value = false;
};
template<typename T>
struct is_boxed< util::wrapped<T> >
{
static const bool value = true;
};
} } // namespace cppa::detail } } // namespace cppa::detail
#endif // BOXED_HPP #endif // BOXED_HPP
...@@ -28,25 +28,36 @@ void fill_uti_vec(OutputIterator& ii) ...@@ -28,25 +28,36 @@ void fill_uti_vec(OutputIterator& ii)
fill_uti_vec<OutputIterator, T1, Tn...>(++ii); fill_uti_vec<OutputIterator, T1, Tn...>(++ii);
} }
template<typename DataTuple, typename T0> template<typename T0>
struct fill_vecs_util struct fill_vecs_util
{ {
template<typename DataTuple>
inline static void _(size_t pos, inline static void _(size_t pos,
size_t dt_size, size_t dt_size,
bool* dt_invalids,
const DataTuple& dt, const DataTuple& dt,
const cppa::uniform_type_info** utis, const cppa::uniform_type_info** utis,
const void** data_ptrs) const void** data_ptrs)
{ {
utis[pos] = uniform_typeid<T0>(); utis[pos] = uniform_typeid<T0>();
data_ptrs[pos] = (pos < dt_size) ? dt.at(pos) : nullptr; if (pos < dt_size && dt_invalids[pos] == false)
{
data_ptrs[pos] = dt.at(pos);
}
else
{
data_ptrs[pos] = nullptr;
}
} }
}; };
template<typename DataTuple> template<>
struct fill_vecs_util<DataTuple, anything> struct fill_vecs_util<anything>
{ {
template<typename DataTuple>
inline static void _(size_t pos, inline static void _(size_t pos,
size_t, size_t,
bool*,
const DataTuple&, const DataTuple&,
const cppa::uniform_type_info** utis, const cppa::uniform_type_info** utis,
const void** data_ptrs) const void** data_ptrs)
...@@ -56,39 +67,29 @@ struct fill_vecs_util<DataTuple, anything> ...@@ -56,39 +67,29 @@ struct fill_vecs_util<DataTuple, anything>
} }
}; };
template<typename DataTuple, typename T0>
struct fill_vecs_util<DataTuple, util::wrapped<T0>>
{
inline static void _(size_t pos,
size_t,
const DataTuple&,
const cppa::uniform_type_info** utis,
const void** data_ptrs)
{
utis[pos] = uniform_typeid<T0>();
data_ptrs[pos] = nullptr;
}
};
template<typename DataTuple, typename T0> template<typename DataTuple, typename T0>
void fill_vecs(size_t pos, void fill_vecs(size_t pos,
size_t dt_size, size_t dt_size,
bool* dt_invalids,
const DataTuple& dt, const DataTuple& dt,
const cppa::uniform_type_info** utis, const cppa::uniform_type_info** utis,
const void** data_ptrs) const void** data_ptrs)
{ {
fill_vecs_util<DataTuple, T0>::_(pos, dt_size, dt, utis, data_ptrs); fill_vecs_util<T0>::_(pos, dt_size, dt_invalids, dt, utis, data_ptrs);
} }
template<typename DataTuple, typename T0, typename T1, typename... Tn> template<typename DataTuple, typename T0, typename T1, typename... Tn>
void fill_vecs(size_t pos, void fill_vecs(size_t pos,
size_t dt_size, size_t dt_size,
bool* dt_invalids,
const DataTuple& dt, const DataTuple& dt,
const cppa::uniform_type_info** utis, const cppa::uniform_type_info** utis,
const void** data_ptrs) const void** data_ptrs)
{ {
fill_vecs_util<DataTuple, T0>::_(pos, dt_size, dt, utis, data_ptrs); fill_vecs_util<T0>::_(pos, dt_size, dt_invalids,
fill_vecs<DataTuple, T1, Tn...>(pos + 1, dt_size, dt, utis, data_ptrs); dt, utis, data_ptrs);
fill_vecs<DataTuple, T1, Tn...>(pos + 1, dt_size, dt_invalids,
dt, utis, data_ptrs);
} }
struct pattern_arg struct pattern_arg
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "cppa/get.hpp" #include "cppa/get.hpp"
#include "cppa/util/at.hpp" #include "cppa/util/at.hpp"
#include "cppa/util/wrapped.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/filter_type_list.hpp" #include "cppa/util/filter_type_list.hpp"
...@@ -61,6 +62,13 @@ struct tdata<Head, Tail...> : tdata<Tail...> ...@@ -61,6 +62,13 @@ struct tdata<Head, Tail...> : tdata<Tail...>
template<typename... Args> template<typename... Args>
tdata(const Head& v0, const Args&... vals) : super(vals...), head(v0) { } tdata(const Head& v0, const Args&... vals) : super(vals...), head(v0) { }
// allow initialization with wrapped<Head> (uses the default constructor)
template<typename... Args>
tdata(const util::wrapped<Head>&, const Args&... vals)
: super(vals...), head()
{
}
inline tdata<Tail...>& tail() inline tdata<Tail...>& tail()
{ {
// upcast // upcast
......
...@@ -51,6 +51,9 @@ class invoke_rule_builder ...@@ -51,6 +51,9 @@ class invoke_rule_builder
pattern_ptr_type m_pattern; pattern_ptr_type m_pattern;
typedef typename pattern_type::tuple_view_type tuple_view_type;
/*
typedef cppa::util::type_list<TypeList...> plain_types; typedef cppa::util::type_list<TypeList...> plain_types;
typedef typename cppa::util::filter_type_list<anything, plain_types>::type typedef typename cppa::util::filter_type_list<anything, plain_types>::type
...@@ -58,6 +61,7 @@ class invoke_rule_builder ...@@ -58,6 +61,7 @@ class invoke_rule_builder
typedef typename cppa::tuple_view_type_from_type_list<filtered_types>::type typedef typename cppa::tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type; tuple_view_type;
*/
public: public:
...@@ -86,79 +90,33 @@ constexpr typename detail::boxed<T>::type val() ...@@ -86,79 +90,33 @@ constexpr typename detail::boxed<T>::type val()
return typename detail::boxed<T>::type(); return typename detail::boxed<T>::type();
} }
//constexpr detail::boxed<anything> any_vals = detail::boxed<anything>();
constexpr anything any_vals = anything();
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
detail::invoke_rule_builder<typename detail::unboxed<Arg0>::type, detail::invoke_rule_builder<typename detail::unboxed<Arg0>::type,
typename detail::unboxed<Args>::type...> typename detail::unboxed<Args>::type...>
on(const Arg0& arg0, const Args&... args) on(const Arg0& arg0, const Args&... args)
{ {
return { arg0, args... }; return { arg0, args... };
/*
typedef util::type_list<typename detail::unboxed<Arg0>::type,
typename detail::unboxed<Args>::type...> mt;
typedef util::type_list<Arg0, Args...> vt;
typedef detail::tdata<any_tuple, std::vector<size_t>*, Arg0 , Args...>
arg_tuple_type;
arg_tuple_type arg_tuple(any_tuple(), nullptr, arg0, args...);
return
{
[arg_tuple](const any_tuple& data, std::vector<size_t>* mapping) -> bool
{
arg_tuple_type& tref = const_cast<arg_tuple_type&>(arg_tuple);
cppa::get_ref<0>(tref) = data;
cppa::get_ref<1>(tref) = mapping;
return invoke(&detail::match_util<mt,vt>::_, tref);
}
};
*/
} }
template<typename... TypeList> template<typename... TypeList>
detail::invoke_rule_builder<TypeList...> on() detail::invoke_rule_builder<TypeList...> on()
{ {
return { }; return { };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<TypeList...>(data, mv);
}
};
*/
} }
template<atom_value A0, typename... TypeList> template<atom_value A0, typename... TypeList>
detail::invoke_rule_builder<atom_value, TypeList...> on() detail::invoke_rule_builder<atom_value, TypeList...> on()
{ {
return { A0 }; return { A0 };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<atom_value, TypeList...>(data, mv, A0);
}
};
*/
} }
template<atom_value A0, atom_value A1, typename... TypeList> template<atom_value A0, atom_value A1, typename... TypeList>
detail::invoke_rule_builder<atom_value, atom_value, TypeList...> on() detail::invoke_rule_builder<atom_value, atom_value, TypeList...> on()
{ {
return { A0, A1 }; return { A0, A1 };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<atom_value, atom_value, TypeList...>(data, mv, A0, A1);
}
};
*/
} }
template<atom_value A0, atom_value A1, atom_value A2, typename... TypeList> template<atom_value A0, atom_value A1, atom_value A2, typename... TypeList>
...@@ -166,16 +124,6 @@ detail::invoke_rule_builder<atom_value, atom_value, ...@@ -166,16 +124,6 @@ detail::invoke_rule_builder<atom_value, atom_value,
atom_value, TypeList...> on() atom_value, TypeList...> on()
{ {
return { A0, A1, A2 }; return { A0, A1, A2 };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<atom_value, atom_value,
atom_value, TypeList...>(data, mv, A0, A1, A2);
}
};
*/
} }
template<atom_value A0, atom_value A1, template<atom_value A0, atom_value A1,
...@@ -185,17 +133,6 @@ detail::invoke_rule_builder<atom_value, atom_value, atom_value, ...@@ -185,17 +133,6 @@ detail::invoke_rule_builder<atom_value, atom_value, atom_value,
atom_value, TypeList...> on() atom_value, TypeList...> on()
{ {
return { A0, A1, A2, A3 }; return { A0, A1, A2, A3 };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<atom_value, atom_value, atom_value,
atom_value, TypeList...>(data, mv, A0, A1, A2, A3);
}
};
*/
} }
template<class Rep, class Period> template<class Rep, class Period>
......
...@@ -54,7 +54,11 @@ class pattern<T0, Tn...> ...@@ -54,7 +54,11 @@ class pattern<T0, Tn...>
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
pattern(const Arg0& arg0, const Args&... args) : m_data(arg0, args...) pattern(const Arg0& arg0, const Args&... args) : m_data(arg0, args...)
{ {
detail::fill_vecs<decltype(m_data), T0, Tn...>(0, sizeof...(Args) + 1, bool invalid_args[] = { detail::is_boxed<Arg0>::value,
detail::is_boxed<Args>::value... };
detail::fill_vecs<decltype(m_data), T0, Tn...>(0,
sizeof...(Args) + 1,
invalid_args,
m_data, m_data,
m_utis, m_data_ptr); m_utis, m_data_ptr);
} }
......
...@@ -14,7 +14,7 @@ size_t test__pattern() ...@@ -14,7 +14,7 @@ size_t test__pattern()
auto x = make_tuple(atom("FooBar"), 42, "hello world"); auto x = make_tuple(atom("FooBar"), 42, "hello world");
pattern<atom_value, int, std::string> p0; 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> p1(atom("FooBar"));
pattern<atom_value, int, std::string> p2(atom("FooBar"), 42); 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, int, std::string> p3(atom("FooBar"), 42, "hello world");
......
...@@ -69,7 +69,7 @@ size_t test__remote_actor(const char* app_path, bool is_client, ...@@ -69,7 +69,7 @@ size_t test__remote_actor(const char* app_path, bool is_client,
std::string cmd; std::string cmd;
{ {
std::ostringstream oss; std::ostringstream oss;
oss << app_path << " run=remote_actor port=" << port << " &>remote.txt" ;//" &>/dev/null"; oss << app_path << " run=remote_actor port=" << port << " &>/dev/null";
cmd = oss.str(); cmd = oss.str();
} }
// execute client_part() in a separate process, // execute client_part() in a separate process,
......
...@@ -44,6 +44,57 @@ size_t test__tuple() ...@@ -44,6 +44,57 @@ size_t test__tuple()
{ {
CPPA_TEST(test__tuple); CPPA_TEST(test__tuple);
bool p1_invoked = false;
bool p2_invoked = false;
bool p3_invoked = false;
bool p4_invoked = false;
auto reset_invoke_states = [&]() {
p1_invoked = p2_invoked = p3_invoked = p4_invoked = false;
};
auto patterns =
(
on<int, anything, int>() >> [&](int v1, int v2)
{
CPPA_CHECK_EQUAL(v1, 1);
CPPA_CHECK_EQUAL(v2, 3);
p1_invoked = true;
},
on<std::string>() >> [&](const std::string& str)
{
CPPA_CHECK_EQUAL(str, "hello foo");
p2_invoked = true;
},
on(std::string("1"), val<int>(), any_vals) >> [&]()
{
p3_invoked = true;
},
//on<int, std::string, anything>() >> [&](const std::string& str)
on(1, val<std::string>(), any_vals) >> [&](const std::string& str)
{
CPPA_CHECK_EQUAL(str, "2");
p4_invoked = true;
}
);
patterns(make_tuple(1, "2", 3));
CPPA_CHECK(p1_invoked);
reset_invoke_states();
patterns(make_tuple("hello foo"));
CPPA_CHECK(p2_invoked);
reset_invoke_states();
patterns(make_tuple("1", 2, 3));
CPPA_CHECK(p3_invoked);
reset_invoke_states();
patterns(make_tuple(1, "2", "3"));
CPPA_CHECK(p4_invoked);
reset_invoke_states();
/* /*
// test of filter_type_list // test of filter_type_list
typedef filter_type_list<any_type, typedef filter_type_list<any_type,
......
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