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