Commit 18c47cbd authored by Dominik Charousset's avatar Dominik Charousset

Add convenience `match_element(s)` overloads

parent 7d541296
...@@ -134,15 +134,6 @@ class message { ...@@ -134,15 +134,6 @@ class message {
*/ */
const void* at(size_t p) const; const void* at(size_t p) const;
/**
* Tries to match element at position `pos` to given RTTI.
* @param pos Index of element in question.
* @param typenr Number of queried type or `0` for custom types.
* @param rtti Queried type or `nullptr` for builtin types.
*/
bool match_element(size_t pos, uint16_t typenr,
const std::type_info* rtti) const;
const char* uniform_name_at(size_t pos) const; const char* uniform_name_at(size_t pos) const;
/** /**
...@@ -288,6 +279,30 @@ class message { ...@@ -288,6 +279,30 @@ class message {
*/ */
cli_res filter_cli(std::vector<cli_arg> args) const; cli_res filter_cli(std::vector<cli_arg> args) const;
/**
* Queries whether the element at `pos` is of type `T`.
* @param pos Index of element in question.
*/
template <class T>
bool match_element(size_t pos) const {
const std::type_info* rtti = nullptr;
if (detail::type_nr<T>::value == 0) {
rtti = &typeid(T);
}
return match_element(pos, detail::type_nr<T>::value, rtti);
}
/**
* Queries whether the types of this message are `Ts...`.
*/
template <class... Ts>
bool match_elements() const {
std::integral_constant<size_t, 0> p0;
detail::type_list<Ts...> tlist;
return size() == sizeof...(Ts) && match_elements_impl(p0, tlist);
}
/** @cond PRIVATE */ /** @cond PRIVATE */
inline uint32_t type_token() const { inline uint32_t type_token() const {
...@@ -321,9 +336,37 @@ class message { ...@@ -321,9 +336,37 @@ class message {
return detail::apply_args(f, detail::get_indices(tup), tup); return detail::apply_args(f, detail::get_indices(tup), tup);
} }
/**
* Tries to match element at position `pos` to given RTTI.
* @param pos Index of element in question.
* @param typenr Number of queried type or `0` for custom types.
* @param rtti Queried type or `nullptr` for builtin types.
*/
bool match_element(size_t pos, uint16_t typenr,
const std::type_info* rtti) const;
template <class T, class... Ts>
bool match_elements(detail::type_list<T, Ts...> list) const {
std::integral_constant<size_t, 0> p0;
return size() == (sizeof...(Ts) + 1) && match_elements_impl(p0, list);
}
/** @endcond */ /** @endcond */
private: private:
template <size_t P>
bool match_elements_impl(std::integral_constant<size_t, P>,
detail::type_list<>) const {
return true; // end of recursion
}
template <size_t P, class T, class... Ts>
bool match_elements_impl(std::integral_constant<size_t, P>,
detail::type_list<T, Ts...>) const {
std::integral_constant<size_t, P + 1> next_p;
detail::type_list<Ts...> next_list;
return match_element<T>(P)
&& match_elements_impl(next_p, next_list);
}
message filter_impl(size_t start, message_handler handler) const; message filter_impl(size_t start, message_handler handler) const;
data_ptr m_vals; data_ptr m_vals;
}; };
......
...@@ -289,7 +289,7 @@ class invoke_policy { ...@@ -289,7 +289,7 @@ class invoke_policy {
const message& msg = node->msg; const message& msg = node->msg;
auto mid = node->mid; auto mid = node->mid;
if (msg.size() == 1) { if (msg.size() == 1) {
if (msg.match_element(0, detail::type_nr<exit_msg>::value, nullptr)) { if (msg.match_element<exit_msg>(0)) {
auto& em = msg.get_as<exit_msg>(0); auto& em = msg.get_as<exit_msg>(0);
CAF_REQUIRE(!mid.valid()); CAF_REQUIRE(!mid.valid());
// make sure to get rid of attachables if they're no longer needed // make sure to get rid of attachables if they're no longer needed
...@@ -301,7 +301,7 @@ class invoke_policy { ...@@ -301,7 +301,7 @@ class invoke_policy {
} }
return msg_type::normal_exit; return msg_type::normal_exit;
} }
} else if (msg.match_element(0, detail::type_nr<timeout_msg>::value, nullptr)) { } else if (msg.match_element<timeout_msg>(0)) {
auto& tm = msg.get_as<timeout_msg>(0); auto& tm = msg.get_as<timeout_msg>(0);
auto tid = tm.timeout_id; auto tid = tm.timeout_id;
CAF_REQUIRE(!mid.valid()); CAF_REQUIRE(!mid.valid());
...@@ -310,8 +310,7 @@ class invoke_policy { ...@@ -310,8 +310,7 @@ class invoke_policy {
} }
return self->waits_for_timeout(tid) ? msg_type::inactive_timeout return self->waits_for_timeout(tid) ? msg_type::inactive_timeout
: msg_type::expired_timeout; : msg_type::expired_timeout;
} else if (mid.is_response() } else if (mid.is_response() && msg.match_element<sync_timeout_msg>(0)) {
&& msg.match_element(0, detail::type_nr<sync_timeout_msg>::value, nullptr)) {
return msg_type::timeout_response; return msg_type::timeout_response;
} }
} }
......
...@@ -273,8 +273,7 @@ void basp_broker::local_dispatch(const basp::header& hdr, message&& msg) { ...@@ -273,8 +273,7 @@ void basp_broker::local_dispatch(const basp::header& hdr, message&& msg) {
CAF_REQUIRE(!dest || dest->node() == node()); CAF_REQUIRE(!dest || dest->node() == node());
// intercept message used for link signaling // intercept message used for link signaling
if (dest && src == dest) { if (dest && src == dest) {
if (msg.size() == 2 if (msg.match_elements<atom_value, actor_addr>()) {
&& msg.match_element(1, detail::type_nr<actor_addr>::value, nullptr)) {
actor_addr other; actor_addr other;
bool is_unlink = true; bool is_unlink = true;
// extract arguments // extract arguments
......
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