bool prepare_invoke(message& msg, tuple_type* out) { // detach msg before invoking m_fun if needed if (is_manipulator) { msg.force_detach(); } intermediate_tuple it; detail::meta_elements<pattern> ms; // check if try_match() reports success if (!detail::try_match(msg, ms.arr.data(), ms.arr.size(), it.data)) { return false; } match_case_zipper zip; using indices_type = typename detail::il_indices<intermediate_tuple>::type; //indices_type indices; typename detail::il_take<indices_type, detail::tl_size<projections>::value - num_fun_args>::type lefts; typename detail::il_right<indices_type, num_fun_args>::type rights; has_none hn; // check if guards of discarded arguments are fulfilled auto lhs_tup = tuple_zip(zip, lefts, m_ps, it); if (detail::apply_args(hn, detail::get_indices(lhs_tup), lhs_tup)) { return false; } // zip remaining arguments into output tuple new (out) tuple_type(tuple_zip(zip, rights, m_ps, it)); //tuple_type rhs_tup = tuple_zip(zip, rights, m_ps, it); // check if remaining guards are fulfilled if (detail::apply_args(hn, detail::get_indices(*out), *out)) { out->~tuple_type(); return false; } return true; }
match_case::result invoke(optional<message>& res, message& msg) override { intermediate_tuple it; detail::meta_elements<pattern> ms; // check if try_match() reports success if (!detail::try_match(msg, ms.arr.data(), ms.arr.size(), it.data)) { return match_case::no_match; } // detach msg before invoking m_fun if needed if (is_manipulator) { msg.force_detach(); // update pointers in our intermediate tuple for (size_t i = 0; i < msg.size(); ++i) { // msg is guaranteed to be detached, hence we don't need to // check this condition over and over again via mutable_at it[i] = const_cast<void*>(msg.at(i)); } } lfinvoker<std::is_same<result_type, void>::value, F> fun{m_fun}; detail::optional_message_visitor omv; auto funres = apply_args(fun, detail::get_indices(it), it); res = omv(funres); return match_case::match; }