Commit 7c55787b authored by Dominik Charousset's avatar Dominik Charousset

Fix matching of atom constants

parent 043aa21d
......@@ -60,8 +60,7 @@ struct meta_element_factory<T, 0> {
template <atom_value V>
struct meta_element_factory<atom_constant<V>, type_nr<atom_value>::value> {
static meta_element create() {
return {V, type_nr<atom_value>::value,
nullptr, match_atom_constant};
return {V, type_nr<atom_value>::value, nullptr, match_atom_constant};
}
};
......
......@@ -267,16 +267,14 @@ public:
/// Queries whether the element at position `p` is of type `T`.
template <class T>
bool match_element(size_t p) const noexcept {
auto rtti = type_nr<T>::value == 0 ? &typeid(T) : nullptr;
return match_element(p, type_nr<T>::value, rtti);
return vals_ ? vals_->match_element<T>(p) : false;
}
/// Queries whether the types of this message are `Ts...`.
template <class... Ts>
bool match_elements() const noexcept {
std::integral_constant<size_t, 0> p0;
detail::type_list<Ts...> tlist;
return size() == sizeof...(Ts) && match_elements_impl(p0, tlist);
detail::type_list<Ts...> token;
return match_elements(token);
}
/// Queries the run-time type information for the element at position `pos`.
......@@ -294,10 +292,13 @@ public:
return vals_->matches(pos, n, p);
}
inline bool match_elements(detail::type_list<>) const noexcept {
return !vals_ || vals_->empty();
}
template <class T, class... Ts>
bool match_elements(detail::type_list<T, Ts...> list) const noexcept {
std::integral_constant<size_t, 0> p0;
return size() == (sizeof...(Ts) + 1) && match_elements_impl(p0, list);
bool match_elements(detail::type_list<T, Ts...>) const noexcept {
return vals_ ? vals_->match_elements<T, Ts...>() : false;
}
/// @cond PRIVATE
......
......@@ -144,19 +144,14 @@ public:
bool match_element(size_t pos) const noexcept {
CAF_ASSERT(pos < size());
auto x = detail::meta_element_factory<T>::create();
return detail::match_element(x, *this, pos);
return x.fun(x, *this, pos);
}
/// Returns `true` if the pattern `Ts...` matches the content of this tuple.
template <class... Ts>
bool match_elements() const noexcept {
if (sizeof...(Ts) != size())
return false;
detail::meta_elements<detail::type_list<Ts...>> xs;
for (size_t i = 0; i < xs.arr.size(); ++i)
if (!detail::match_element(xs.arr[i], *this, i))
return false;
return true;
return detail::try_match(*this, &xs.arr[0], sizeof...(Ts));
}
template <class F>
......
......@@ -22,6 +22,8 @@
#include "caf/error.hpp"
#include "caf/config.hpp"
#include "caf/detail/try_match.hpp"
namespace caf {
type_erased_tuple::~type_erased_tuple() {
......
......@@ -132,4 +132,29 @@ CAF_TEST(atom_constants) {
CAF_CHECK_EQUAL(invoke(expr, atom_value{ho_atom::value}), 1);
}
CAF_TEST(manual_matching) {
using foo_atom = atom_constant<atom("foo")>;
using bar_atom = atom_constant<atom("bar")>;
auto msg1 = make_message(foo_atom::value, 42);
auto msg2 = make_message(bar_atom::value, 42);
CAF_MESSAGE("check individual message elements");
CAF_CHECK((msg1.match_element<int>(1)));
CAF_CHECK((msg2.match_element<int>(1)));
CAF_CHECK((msg1.match_element<foo_atom>(0)));
CAF_CHECK((!msg2.match_element<foo_atom>(0)));
CAF_CHECK((!msg1.match_element<bar_atom>(0)));
CAF_CHECK((msg2.match_element<bar_atom>(0)));
CAF_MESSAGE("check matching whole tuple");
CAF_CHECK((msg1.match_elements<foo_atom, int>()));
CAF_CHECK(!(msg2.match_elements<foo_atom, int>()));
CAF_CHECK(!(msg1.match_elements<bar_atom, int>()));
CAF_CHECK((msg2.match_elements<bar_atom, int>()));
CAF_CHECK((msg1.match_elements<atom_value, int>()));
CAF_CHECK((msg2.match_elements<atom_value, int>()));
CAF_CHECK(!(msg1.match_elements<atom_value, double>()));
CAF_CHECK(!(msg2.match_elements<atom_value, double>()));
CAF_CHECK(!(msg1.match_elements<atom_value, int, int>()));
CAF_CHECK(!(msg2.match_elements<atom_value, int, int>()));
}
CAF_TEST_FIXTURE_SCOPE_END()
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