diff --git a/include/beman/execution/detail/continues_on.hpp b/include/beman/execution/detail/continues_on.hpp index c5105e04..9bfeed3f 100644 --- a/include/beman/execution/detail/continues_on.hpp +++ b/include/beman/execution/detail/continues_on.hpp @@ -18,6 +18,7 @@ import std; import beman.execution.detail.as_tuple; import beman.execution.detail.basic_sender; import beman.execution.detail.child_type; +import beman.execution.detail.completion_signature; import beman.execution.detail.completion_signatures; import beman.execution.detail.completion_signatures_for; import beman.execution.detail.completion_signatures_of_t; @@ -29,6 +30,7 @@ import beman.execution.detail.env; import beman.execution.detail.env_of_t; import beman.execution.detail.error_types_of_t; import beman.execution.detail.fwd_env; +import beman.execution.detail.gather_signatures; import beman.execution.detail.get_completion_domain; import beman.execution.detail.get_completion_scheduler; import beman.execution.detail.get_completion_signatures; @@ -37,6 +39,7 @@ import beman.execution.detail.impls_for; import beman.execution.detail.join_env; import beman.execution.detail.make_sender; import beman.execution.detail.meta.combine; +import beman.execution.detail.meta.filter; import beman.execution.detail.meta.prepend; import beman.execution.detail.meta.to; import beman.execution.detail.meta.transform; @@ -48,9 +51,7 @@ import beman.execution.detail.schedule_result_t; import beman.execution.detail.scheduler; import beman.execution.detail.sender; import beman.execution.detail.sender_adaptor_closure; -import beman.execution.detail.sender_for; import beman.execution.detail.sender_in; -import beman.execution.detail.sends_stopped; import beman.execution.detail.set_error; import beman.execution.detail.set_stopped; import beman.execution.detail.set_value; @@ -66,6 +67,7 @@ import beman.execution.detail.start; #include #include #include +#include #include #include #include @@ -73,6 +75,7 @@ import beman.execution.detail.start; #include #include #include +#include #include #include #include @@ -83,9 +86,7 @@ import beman.execution.detail.start; #include #include #include -#include #include -#include #include #include #include @@ -113,6 +114,20 @@ struct continues_on_t { } private: + template + using variant_type = ::beman::execution::detail::meta::unique<::beman::execution::detail::meta::prepend< + ::std::monostate, + ::beman::execution::detail::meta::transform< + ::beman::execution::detail::as_tuple_t, + ::beman::execution::detail::meta::to<::std::variant, + ::beman::execution::completion_signatures_of_t>>>>; + + template + using as_set_error = ::beman::execution::completion_signatures<::beman::execution::set_error_t(E)...>; + + template + using is_not_set_value = ::std::negation<::beman::execution::detail::is_set_value>; + template struct get_signatures; template @@ -121,18 +136,21 @@ struct continues_on_t { struct get_signatures< ::beman::execution::detail::basic_sender<::beman::execution::detail::continues_on_t, Scheduler, Sender>, Env> { - using scheduler_sender = ::beman::execution::schedule_result_t; - using additional_signatures = ::std::conditional_t< - ::beman::execution::sends_stopped, - ::beman::execution::completion_signatures<::beman::execution::set_error_t(::std::exception_ptr), - ::beman::execution::set_stopped_t()>, + using exception_signature = ::std::conditional_t< + ::std::is_nothrow_move_constructible_v>, + ::beman::execution::completion_signatures<>, ::beman::execution::completion_signatures<::beman::execution::set_error_t(::std::exception_ptr)>>; - template - using as_set_error = ::beman::execution::completion_signatures<::beman::execution::set_error_t(E)...>; - using type = ::beman::execution::detail::meta::unique<::beman::execution::detail::meta::combine< - decltype(::beman::execution::get_completion_signatures()), - ::beman::execution::error_types_of_t, - additional_signatures>>; + + static consteval auto get() { + [[maybe_unused]] auto child_sigs = ::beman::execution::get_completion_signatures(); + [[maybe_unused]] auto sched_sigs = + ::beman::execution::get_completion_signatures<::beman::execution::schedule_result_t, Env>(); + using child_sigs_t = decltype(child_sigs); + using extra_sigs_t = ::beman::execution::detail::meta::filter; + using type = ::beman::execution::detail::meta::unique< + ::beman::execution::detail::meta::combine>; + return type{}; + } }; template @@ -170,8 +188,8 @@ struct continues_on_t { public: template - static consteval auto get_completion_signatures() noexcept { - return typename get_signatures<::std::remove_cvref_t, Env...>::type{}; + static consteval auto get_completion_signatures() { + return get_signatures<::std::remove_cvref_t, Env...>::get(); } struct impls_for : ::beman::execution::detail::default_impls { @@ -190,7 +208,7 @@ struct continues_on_t { State* state; auto set_value() && noexcept -> void { - constexpr bool nothrow = std::is_nothrow_move_constructible_vasync_result)>; + constexpr bool nothrow = ::std::is_nothrow_move_constructible_vasync_result)>; try { ::std::visit( [this](Tuple& result) noexcept -> void { @@ -252,14 +270,8 @@ struct continues_on_t { auto sch{sender.template get<1>()}; using sched_t = ::std::remove_cvref_t; - using variant_t = ::beman::execution::detail::meta::unique<::beman::execution::detail::meta::prepend< - ::std::monostate, - ::beman::execution::detail::meta::transform< - ::beman::execution::detail::as_tuple_t, - ::beman::execution::detail::meta::to<::std::variant, - ::beman::execution::completion_signatures_of_t< - ::beman::execution::detail::child_type, - ::beman::execution::env_of_t>>>>>; + using variant_t = variant_type<::beman::execution::detail::child_type, + ::beman::execution::env_of_t>; return state_type(sch, receiver); }; @@ -270,7 +282,7 @@ struct continues_on_t { template auto operator()(auto, auto& state, auto& receiver, Tag, Args&&... args) const noexcept -> void { using result_t = ::beman::execution::detail::decayed_tuple; - constexpr bool nothrow = ::std::is_nothrow_constructible_v; + constexpr bool nothrow = ::std::is_nothrow_move_constructible_v; try { [&]() noexcept(nothrow) { diff --git a/include/beman/execution/detail/let.hpp b/include/beman/execution/detail/let.hpp index 97f8a14b..36831ce2 100644 --- a/include/beman/execution/detail/let.hpp +++ b/include/beman/execution/detail/let.hpp @@ -170,48 +170,50 @@ struct let_t { using let_env_t = decltype(let_env(::std::declval(), ::std::declval())); private: + template + struct apply_decayed; + template + struct apply_decayed { + static_assert(::std::invocable&...>, + "The callback function object of the `let` adapter shall be invocable with `Args&...`"); + using sender_type = ::beman::execution::detail::call_result_t&...>; + static_assert(::beman::execution::sender, "`Fun` shall return a sender"); + using completions = ::std::conditional_t< + noexcept(::std::declval()(::std::declval<::std::decay_t&>()...)), + ::beman::execution::completion_signatures<>, + ::beman::execution::completion_signatures<::beman::execution::set_error_t(::std::exception_ptr)>>; + }; + + template + using other_completion = let_other_completion; + + template + using matching_completion = let_matching_completion; + template struct get_signatures; - template + template requires ::beman::execution::detail::non_dependent_successor::value - struct get_signatures< - ::beman::execution::detail::basic_sender<::beman::execution::detail::let_t, Fun, Child>> - : get_signatures<::beman::execution::detail::basic_sender<::beman::execution::detail::let_t, Fun, Child>, - ::beman::execution::env<>> {}; + struct get_signatures<::beman::execution::detail::basic_sender> + : get_signatures<::beman::execution::detail::basic_sender, ::beman::execution::env<>> {}; - template + template struct get_signatures< - ::beman::execution::detail::basic_sender<::beman::execution::detail::let_t, Fun, Child>, + ::beman::execution::detail::basic_sender<::beman::execution::detail::let_t, Fun, Child>, Env> { - template - using other_completion = let_other_completion; - template - using matching_completion = let_matching_completion; - - template - struct apply_decayed; - template - struct apply_decayed { - using sender_type = ::beman::execution::detail::call_result_t...>; - using completions = ::std::conditional_t< - noexcept(::std::declval()(::std::declval<::std::decay_t>()...)), - ::beman::execution::completion_signatures<>, - ::beman::execution::completion_signatures<::beman::execution::set_error_t(::std::exception_ptr)>>; - }; - using successor_env = ::beman::execution::detail::join_env, ::beman::execution::detail::fwd_env>; template struct get_completions; - template