Commit fd02800e authored by Dominik Charousset's avatar Dominik Charousset

Fix behavior_impl on MSVC

parent 8de9e2ee
......@@ -36,6 +36,11 @@ decltype(auto) apply_args(F& f, detail::int_list<Is...>, Tuple& tup) {
return f(get<Is>(tup)...);
}
template <class F, size_t... Is, class Tuple>
decltype(auto) apply_args(F& f, std::index_sequence<Is...>, Tuple& tup) {
return f(get<Is>(tup)...);
}
template <class F, long... Is, class Tuple>
decltype(auto) apply_args(F& f, Tuple& tup) {
auto token = get_indices(tup);
......
......@@ -98,31 +98,30 @@ struct with_generic_timeout<true, std::tuple<Ts...>> {
std::tuple>::type;
};
template <class Tuple>
class default_behavior_impl;
template <class... Ts>
class default_behavior_impl<std::tuple<Ts...>> : public behavior_impl {
public:
using tuple_type = std::tuple<Ts...>;
struct dummy_timeout_definition {
timespan timeout = infinite;
using back_type = typename tl_back<type_list<Ts...>>::type;
constexpr void handler() {
// nop
}
};
static constexpr bool has_timeout = is_timeout_definition<back_type>::value;
template <class Tuple, class TimeoutDefinition = dummy_timeout_definition>
class default_behavior_impl;
static constexpr size_t num_cases = sizeof...(Ts) - (has_timeout ? 1 : 0);
template <class... Ts, class TimeoutDefinition>
class default_behavior_impl<std::tuple<Ts...>, TimeoutDefinition>
: public behavior_impl {
public:
using super = behavior_impl;
default_behavior_impl(tuple_type&& tup) : cases_(std::move(tup)) {
if constexpr (has_timeout) {
this->timeout_ = std::get<num_cases>(cases_).timeout;
}
}
using tuple_type = std::tuple<Ts...>;
template <class... Us>
default_behavior_impl(Us&&... xs) : cases_(std::forward<Us>(xs)...) {
if constexpr (has_timeout) {
this->timeout_ = std::get<num_cases>(cases_).timeout;
}
default_behavior_impl(tuple_type&& tup, TimeoutDefinition timeout_definition)
: super(timeout_definition.timeout),
cases_(std::move(tup)),
timeout_definition_(std::move(timeout_definition)) {
// nop
}
virtual match_result invoke(detail::invoke_result_visitor& f,
......@@ -136,7 +135,6 @@ public:
auto result = match_result::no_match;
auto dispatch = [&](auto& fun) {
using fun_type = std::decay_t<decltype(fun)>;
if constexpr (!is_timeout_definition<fun_type>::value) {
using trait = get_callable_trait_t<fun_type>;
auto arg_types = to_type_id_list<typename trait::decayed_arg_types>();
if (arg_types == msg.types()) {
......@@ -152,7 +150,6 @@ public:
}
return true;
}
}
return false;
};
static_cast<void>((dispatch(std::get<Is>(cases_)) || ...));
......@@ -160,20 +157,24 @@ public:
}
void handle_timeout() override {
if constexpr (has_timeout) {
std::get<num_cases>(cases_).handler();
}
timeout_definition_.handler();
}
private:
tuple_type cases_;
TimeoutDefinition timeout_definition_;
};
template <class Tuple>
struct behavior_factory {
template <class TimeoutDefinition>
struct behavior_factory_t {
TimeoutDefinition& tdef;
template <class... Ts>
typename behavior_impl::pointer operator()(Ts&&... xs) const {
return make_counted<default_behavior_impl<Tuple>>(std::forward<Ts>(xs)...);
auto operator()(Ts&... xs) {
using impl = default_behavior_impl<std::tuple<Ts...>, TimeoutDefinition>;
return make_counted<impl>(std::make_tuple(std::move(xs)...),
std::move(tdef));
}
};
......@@ -183,10 +184,18 @@ struct make_behavior_t {
}
template <class... Ts>
intrusive_ptr<default_behavior_impl<std::tuple<Ts...>>>
operator()(Ts... xs) const {
auto operator()(Ts... xs) const {
if constexpr ((is_timeout_definition<Ts>::value || ...)) {
auto args = std::tie(xs...);
auto& tdef = std::get<sizeof...(Ts) - 1>(args);
behavior_factory_t<std::decay_t<decltype(tdef)>> f{tdef};
std::make_index_sequence<sizeof...(Ts) - 1> indexes;
return detail::apply_args(f, indexes, args);
} else {
using type = default_behavior_impl<std::tuple<Ts...>>;
return make_counted<type>(std::move(xs)...);
dummy_timeout_definition dummy;
return make_counted<type>(std::make_tuple(std::move(xs)...), dummy);
}
}
};
......
......@@ -32,6 +32,9 @@
#ifdef CAF_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wc99-extensions"
#elif defined(CAF_MSVC)
# pragma warning(push)
# pragma warning(disable : 4200)
#endif
namespace caf::detail {
......@@ -152,4 +155,6 @@ void message_data_init(byte* storage, T&& x, Ts&&... xs) {
#ifdef CAF_CLANG
# pragma clang diagnostic pop
#elif defined(MSVC)
# pragma warning(pop)
#endif
......@@ -230,8 +230,10 @@ public:
private:
typed_behavior() = default;
template <class... Ts>
void set(intrusive_ptr<detail::default_behavior_impl<std::tuple<Ts...>>> bp) {
template <class... Ts, class TimeoutDefinition>
void set(intrusive_ptr<
detail::default_behavior_impl<std::tuple<Ts...>, TimeoutDefinition>>
bp) {
using found_signatures = detail::type_list<deduce_mpi_t<Ts>...>;
using m = interface_mismatch_t<found_signatures, signatures>;
// trigger static assert on mismatch
......
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