From 12d64d8e11bec38c8d985ae920d9993756337072 Mon Sep 17 00:00:00 2001 From: Cra3z Date: Fri, 31 Jul 2026 14:06:47 +0800 Subject: [PATCH 1/2] Add the missing `task::error_types` --- include/beman/execution/detail/task.hpp | 25 ++++++++++++------------ tests/beman/execution/exec-task.test.cpp | 9 ++++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/include/beman/execution/detail/task.hpp b/include/beman/execution/detail/task.hpp index 49976b11..341b8118 100644 --- a/include/beman/execution/detail/task.hpp +++ b/include/beman/execution/detail/task.hpp @@ -750,16 +750,13 @@ class task { friend ::beman::execution::detail::task::promise_type; public: - using sender_concept = ::beman::execution::sender_tag; - using promise_type = ::beman::execution::detail::task::promise_type; - using allocator_type = ::beman::execution::detail::task::allocator_of_t; - using start_scheduler_type = ::beman::execution::detail::task::start_scheduler_of_t; - using stop_source_type = ::beman::execution::detail::task::stop_source_of_t; - using stop_token_type = decltype(::std::declval().get_token()); - using completion_signatures = ::beman::execution::detail::meta::combine< - ::beman::execution::completion_signatures<::beman::execution::detail::task::value_signature_t, - ::beman::execution::set_stopped_t()>, - ::beman::execution::detail::task::error_types_of_t>; + using sender_concept = ::beman::execution::sender_tag; + using promise_type = ::beman::execution::detail::task::promise_type; + using allocator_type = ::beman::execution::detail::task::allocator_of_t; + using start_scheduler_type = ::beman::execution::detail::task::start_scheduler_of_t; + using stop_source_type = ::beman::execution::detail::task::stop_source_of_t; + using stop_token_type = decltype(::std::declval().get_token()); + using error_types = ::beman::execution::detail::task::error_types_of_t; private: template @@ -780,8 +777,12 @@ class task { ~task() = default; template <::beman::execution::detail::decayed_same_as, typename...> - static consteval auto get_completion_signatures() noexcept -> completion_signatures { - return {}; + static consteval auto get_completion_signatures() noexcept { + using completion_signatures = ::beman::execution::detail::meta::combine< + ::beman::execution::completion_signatures<::beman::execution::detail::task::value_signature_t, + ::beman::execution::set_stopped_t()>, + error_types>; + return completion_signatures{}; } template <::beman::execution::receiver Receiver> diff --git a/tests/beman/execution/exec-task.test.cpp b/tests/beman/execution/exec-task.test.cpp index c24149e5..0c9fc50c 100644 --- a/tests/beman/execution/exec-task.test.cpp +++ b/tests/beman/execution/exec-task.test.cpp @@ -131,11 +131,11 @@ auto test_task_interface() -> void { static_assert(!std::default_initializable); static_assert(!std::copy_constructible); static_assert(std::movable); - static_assert(std::same_as, test_std::completion_signatures>); - static_assert(std::same_as, test_std::completion_signatures>); @@ -185,7 +185,10 @@ auto test_task_errors() -> void { caught = false; try { - test::use(test_std::sync_wait(integer_error_task())); + auto t = integer_error_task(); + static_assert( + std::same_as>); + test::use(test_std::sync_wait(std::move(t))); } catch (int value) { ASSERT(value == 17); caught = true; From b3ad87b9b6620fc36bc6335d5abca5ecb9c62d43 Mon Sep 17 00:00:00 2001 From: Cra3z Date: Fri, 31 Jul 2026 15:37:19 +0800 Subject: [PATCH 2/2] Optimization for `inline_scheduler` --- include/beman/execution/detail/task.hpp | 64 ++++++++++++++----------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/include/beman/execution/detail/task.hpp b/include/beman/execution/detail/task.hpp index 341b8118..0f24b82c 100644 --- a/include/beman/execution/detail/task.hpp +++ b/include/beman/execution/detail/task.hpp @@ -33,6 +33,7 @@ import beman.execution.detail.get_env; import beman.execution.detail.get_scheduler; import beman.execution.detail.get_start_scheduler; import beman.execution.detail.get_stop_token; +import beman.execution.detail.inline_scheduler; import beman.execution.detail.inplace_stop_source; import beman.execution.detail.meta.combine; import beman.execution.detail.meta.contains; @@ -68,6 +69,7 @@ import beman.execution.detail.unreachable; #include #include #include +#include #include #include #include @@ -451,6 +453,26 @@ class propagator { StopToken stop_token_; }; +template +auto make_sched(const Env& env, const Alloc& alloc) noexcept -> Sched { + if constexpr (requires { + ::std::make_obj_using_allocator(alloc, ::beman::execution::get_start_scheduler(env)); + }) { + return ::std::make_obj_using_allocator(alloc, ::beman::execution::get_start_scheduler(env)); + } else if constexpr (requires { + ::std::make_obj_using_allocator(alloc, ::beman::execution::get_scheduler(env)); + }) { + return ::std::make_obj_using_allocator(alloc, ::beman::execution::get_scheduler(env)); + } else if constexpr (std::default_initializable) { + return Sched(); + } else { + static_assert(false, + "`Env` should provide `get_start_scheduler` or `get_scheduler`; otherwise, `Sched` should be " + "default-initializable."); + ::beman::execution::detail::unreachable(); + } +} + template // ReSharper disable once CppPolymorphicClassWithNonVirtualPublicDestructor class state_base : public result_type> { @@ -478,25 +500,6 @@ class state_base : public result_type> { auto get_environment() noexcept -> Environment& { return this->do_get_environment(); } auto get_start_scheduler() noexcept -> scheduler_type { return this->do_get_start_scheduler(); } - protected: - template - static auto make_sched(const Env& env, const Alloc& alloc) noexcept -> scheduler_type { - if constexpr (requires { - ::std::make_obj_using_allocator( - alloc, ::beman::execution::get_start_scheduler(env)); - }) { - return ::std::make_obj_using_allocator(alloc, - ::beman::execution::get_start_scheduler(env)); - } else if constexpr (requires { - ::std::make_obj_using_allocator( - alloc, ::beman::execution::get_scheduler(env)); - }) { - return ::std::make_obj_using_allocator(alloc, ::beman::execution::get_scheduler(env)); - } else { - return scheduler_type(); - } - } - private: virtual auto do_complete() noexcept -> ::std::coroutine_handle<> = 0; virtual auto do_get_allocator() noexcept -> allocator_type = 0; @@ -520,7 +523,7 @@ struct state : state_base { : rcvr(::std::move(r)), handle(std::move(h)), holder(env), - scheduler(this->make_sched(env, do_get_allocator())), + scheduler(::beman::execution::detail::task::make_sched(env, do_get_allocator())), propagator(::beman::execution::get_stop_token(env)) {} auto start() & noexcept -> void { this->handle.start(this).resume(); } @@ -569,7 +572,7 @@ class awaiter : public state_base { : parent(parent), handle(std::move(h)), holder(env), - scheduler(this->make_sched(env, do_get_allocator())), + scheduler(::beman::execution::detail::task::make_sched(env, do_get_allocator())), propagator(::beman::execution::get_stop_token(env)) {} static constexpr auto await_ready() noexcept -> bool { return false; } @@ -714,7 +717,11 @@ class promise_type : public ::beman::execution::detail::task::promise_base<::std template <::beman::execution::sender Expr> auto await_transform(Expr&& expr) -> decltype(auto) { - return ::beman::execution::as_awaitable(::beman::execution::affine(::std::forward(expr)), *this); + if constexpr (::std::same_as) { + return ::beman::execution::as_awaitable(::std::forward(expr), *this); + } else { + return ::beman::execution::as_awaitable(::beman::execution::affine(::std::forward(expr)), *this); + } } template @@ -765,6 +772,11 @@ class task { template using awaiter = ::beman::execution::detail::task::awaiter; + using signatures = ::beman::execution::detail::meta::combine< + ::beman::execution::completion_signatures<::beman::execution::detail::task::value_signature_t, + ::beman::execution::set_stopped_t()>, + error_types>; + public: task(const task&) = delete; @@ -777,12 +789,8 @@ class task { ~task() = default; template <::beman::execution::detail::decayed_same_as, typename...> - static consteval auto get_completion_signatures() noexcept { - using completion_signatures = ::beman::execution::detail::meta::combine< - ::beman::execution::completion_signatures<::beman::execution::detail::task::value_signature_t, - ::beman::execution::set_stopped_t()>, - error_types>; - return completion_signatures{}; + static consteval auto get_completion_signatures() noexcept -> signatures { + return {}; } template <::beman::execution::receiver Receiver>