Commit 597a9e09 authored by neverlord's avatar neverlord

fixed pattern matching

parent 627cec59
......@@ -8,6 +8,16 @@ namespace cppa {
*/
struct anything { };
inline bool operator==(const anything&, const anything&)
{
return true;
}
inline bool operator!=(const anything&, const anything&)
{
return false;
}
} // namespace cppa
#endif // ANYTHING_HPP
......@@ -24,6 +24,20 @@ struct boxed<anything>
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
#endif // BOXED_HPP
......@@ -28,44 +28,41 @@ void fill_uti_vec(OutputIterator& ii)
fill_uti_vec<OutputIterator, T1, Tn...>(++ii);
}
template<typename DataTuple, typename T0>
template<typename T0>
struct fill_vecs_util
{
template<typename DataTuple>
inline static void _(size_t pos,
size_t dt_size,
bool* dt_invalids,
const DataTuple& dt,
const cppa::uniform_type_info** utis,
const void** data_ptrs)
{
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);
}
};
template<typename DataTuple>
struct fill_vecs_util<DataTuple, anything>
{
inline static void _(size_t pos,
size_t,
const DataTuple&,
const cppa::uniform_type_info** utis,
const void** data_ptrs)
else
{
utis[pos] = nullptr;
data_ptrs[pos] = nullptr;
}
}
};
template<typename DataTuple, typename T0>
struct fill_vecs_util<DataTuple, util::wrapped<T0>>
template<>
struct fill_vecs_util<anything>
{
template<typename DataTuple>
inline static void _(size_t pos,
size_t,
bool*,
const DataTuple&,
const cppa::uniform_type_info** utis,
const void** data_ptrs)
{
utis[pos] = uniform_typeid<T0>();
utis[pos] = nullptr;
data_ptrs[pos] = nullptr;
}
};
......@@ -73,22 +70,26 @@ struct fill_vecs_util<DataTuple, util::wrapped<T0>>
template<typename DataTuple, typename T0>
void fill_vecs(size_t pos,
size_t dt_size,
bool* dt_invalids,
const DataTuple& dt,
const cppa::uniform_type_info** utis,
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>
void fill_vecs(size_t pos,
size_t dt_size,
bool* dt_invalids,
const DataTuple& dt,
const cppa::uniform_type_info** utis,
const void** data_ptrs)
{
fill_vecs_util<DataTuple, T0>::_(pos, dt_size, dt, utis, data_ptrs);
fill_vecs<DataTuple, T1, Tn...>(pos + 1, dt_size, dt, utis, 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);
}
struct pattern_arg
......
......@@ -4,6 +4,7 @@
#include "cppa/get.hpp"
#include "cppa/util/at.hpp"
#include "cppa/util/wrapped.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/filter_type_list.hpp"
......@@ -61,6 +62,13 @@ struct tdata<Head, Tail...> : tdata<Tail...>
template<typename... Args>
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()
{
// upcast
......
......@@ -51,6 +51,9 @@ class invoke_rule_builder
pattern_ptr_type m_pattern;
typedef typename pattern_type::tuple_view_type tuple_view_type;
/*
typedef cppa::util::type_list<TypeList...> plain_types;
typedef typename cppa::util::filter_type_list<anything, plain_types>::type
......@@ -58,6 +61,7 @@ class invoke_rule_builder
typedef typename cppa::tuple_view_type_from_type_list<filtered_types>::type
tuple_view_type;
*/
public:
......@@ -86,79 +90,33 @@ constexpr typename detail::boxed<T>::type val()
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>
detail::invoke_rule_builder<typename detail::unboxed<Arg0>::type,
typename detail::unboxed<Args>::type...>
on(const Arg0& arg0, const Args&... 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>
detail::invoke_rule_builder<TypeList...> on()
{
return { };
/*
return
{
[](const any_tuple& data, std::vector<size_t>* mv) -> bool
{
return match<TypeList...>(data, mv);
}
};
*/
}
template<atom_value A0, typename... TypeList>
detail::invoke_rule_builder<atom_value, TypeList...> on()
{
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>
detail::invoke_rule_builder<atom_value, atom_value, TypeList...> on()
{
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>
......@@ -166,16 +124,6 @@ detail::invoke_rule_builder<atom_value, atom_value,
atom_value, TypeList...> on()
{
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,
......@@ -185,17 +133,6 @@ detail::invoke_rule_builder<atom_value, atom_value, atom_value,
atom_value, TypeList...> on()
{
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>
......
......@@ -54,7 +54,11 @@ class pattern<T0, Tn...>
template<typename Arg0, typename... 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_utis, m_data_ptr);
}
......
......@@ -14,7 +14,7 @@ size_t test__pattern()
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> p2(atom("FooBar"), 42);
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,
std::string cmd;
{
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();
}
// execute client_part() in a separate process,
......
......@@ -44,6 +44,57 @@ size_t 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
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