diff --git a/include/beman/execution/detail/when_all.hpp b/include/beman/execution/detail/when_all.hpp index 47ce6fde..ec6ab4be 100644 --- a/include/beman/execution/detail/when_all.hpp +++ b/include/beman/execution/detail/when_all.hpp @@ -46,7 +46,9 @@ import beman.execution.detail.meta.size; import beman.execution.detail.meta.to; import beman.execution.detail.meta.transform; import beman.execution.detail.meta.unique; +import beman.execution.detail.never_stop_token; import beman.execution.detail.on_stop_request; +import beman.execution.detail.prop; import beman.execution.detail.sender; import beman.execution.detail.sender_in; import beman.execution.detail.sends_stopped; @@ -85,6 +87,7 @@ import beman.execution.detail.value_types_of_t; #include #include #include +#include #include #include #include @@ -117,13 +120,20 @@ concept valid_when_all_sender = ::beman::execution::dependent_sender || inline constexpr auto make_when_all_env = [](const ::beman::execution::inplace_stop_source& stop_src, const auto& env) noexcept { return ::beman::execution::detail::join_env( - ::beman::execution::detail::make_env(::beman::execution::get_stop_token, stop_src.get_token()), env); + ::beman::execution::env{::beman::execution::prop{::beman::execution::get_stop_token, stop_src.get_token()}}, + env); }; template using when_all_env = decltype(make_when_all_env(::std::declval<::beman::execution::inplace_stop_source>(), ::std::declval())); +static_assert(std::same_as<::beman::execution::never_stop_token, + decltype(::beman::execution::get_stop_token(::std::declval<::beman::execution::env<>>()))>); +static_assert(std::same_as<::beman::execution::inplace_stop_token, + decltype(::beman::execution::get_stop_token( + ::std::declval>>()))>); + struct when_all_t { template <::beman::execution::sender... Sender> requires(0u != sizeof...(Sender)) && (... && beman::execution::detail::valid_when_all_sender) && @@ -155,13 +165,14 @@ struct when_all_t { using value_types = typename ::beman::execution::detail::when_all_value_types<::beman::execution::detail::meta::combine< - ::beman::execution:: - value_types_of_t...>>:: - type; + ::beman::execution::value_types_of_t, + ::beman::execution::detail::type_list, + ::std::type_identity_t>...>>::type; using error_types = ::beman::execution::detail::meta::unique<::beman::execution::detail::meta::combine< - ::beman::execution::error_types_of_t...>>; + ::beman::execution::error_types_of_t, error_comps>...>>; using stopped_types = - ::std::conditional_t<(false || ... || ::beman::execution::sends_stopped), + ::std::conditional_t<(false || ... || ::beman::execution::sends_stopped>), ::beman::execution::completion_signatures<::beman::execution::set_stopped_t()>, ::beman::execution::completion_signatures<>>; using type = ::beman::execution::detail::meta::combine; @@ -202,7 +213,7 @@ struct when_all_t { template struct state_type { struct nonesuch {}; - using env_t = ::beman::execution::env_of_t; + using env_t = when_all_env<::beman::execution::env_of_t>; using copy_fail = ::std::conditional_t< (... && ::beman::execution::value_types_of_t struct make_state { - template <::beman::execution::sender_in<::beman::execution::env_of_t>... Sender> + template <::beman::execution::sender_in>>... Sender> auto operator()(auto, auto, Sender&&...) const { return state_type{}; } diff --git a/tests/beman/execution/exec-read-env.test.cpp b/tests/beman/execution/exec-read-env.test.cpp index 13968254..aa1a4a80 100644 --- a/tests/beman/execution/exec-read-env.test.cpp +++ b/tests/beman/execution/exec-read-env.test.cpp @@ -5,16 +5,20 @@ #include #ifdef BEMAN_HAS_MODULES import beman.execution; +import beman.execution.detail.join_env; #else #include #include #include +#include #include #include #include #include #include #include +#include +#include #endif // ---------------------------------------------------------------------------- @@ -74,7 +78,25 @@ auto test_read_env_completions() -> void { auto r{test_std::read_env(test_std::get_stop_token)}; test::check_type>( test_std::get_completion_signatures>()); + test::check_type>( + test_std::get_completion_signatures()); + test::check_type>( + test_std::get_completion_signatures()}})>()); + test::check_type>( + test_std::get_completion_signatures< + decltype(r), + decltype(test_detail::join_env( + test_std::env{test_std::prop{test_std::get_stop_token, std::declval()}}, + test_std::env{ + test_std::prop{test_std::get_stop_token, std::declval()}}))>()); test::use(r); + + test_std::sync_wait(test_std::read_env(test_std::get_stop_token)); + test_std::sync_wait(test_std::when_all(test_std::read_env(test_std::get_stop_token))); + test_std::sync_wait(test_std::when_all(test_std::read_env(test_std::get_scheduler))); } } // namespace diff --git a/tests/beman/execution/exec-when-all.test.cpp b/tests/beman/execution/exec-when-all.test.cpp index cb6a1dea..6bf697fe 100644 --- a/tests/beman/execution/exec-when-all.test.cpp +++ b/tests/beman/execution/exec-when-all.test.cpp @@ -234,6 +234,10 @@ auto test_when_all() -> void { await_cancel(), add_value{test_std::just_stopped()}, test_std::just(true, 3.5)); + + test_std::sync_wait(test_std::read_env(test_std::get_stop_token)); + test_std::sync_wait( + test_std::when_all(test_std::read_env(test_std::get_stop_token) | test_std::then([](auto&&) {}))); } auto test_when_all_with_variant() -> void { @@ -265,7 +269,6 @@ TEST(exec_when_all) { static_assert(std::same_as); try { - test_when_all(); test_when_all_with_variant(); } catch (...) {