From 9e27dce52c3113d58d7351790d1c05887c7a2c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Thu, 7 Aug 2025 20:59:27 +0100 Subject: [PATCH 1/3] restructuring the awaiter to cope with environments --- include/beman/task/detail/awaiter.hpp | 16 +++++---- include/beman/task/detail/handle.hpp | 3 ++ include/beman/task/detail/state.hpp | 34 ++---------------- include/beman/task/detail/state_rep.hpp | 48 +++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 include/beman/task/detail/state_rep.hpp diff --git a/include/beman/task/detail/awaiter.hpp b/include/beman/task/detail/awaiter.hpp index 8320ec4..eb9b861 100644 --- a/include/beman/task/detail/awaiter.hpp +++ b/include/beman/task/detail/awaiter.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -45,18 +46,21 @@ struct awaiter_op_t { }; template -class awaiter : public ::beman::task::detail::state_base { +class awaiter : public ::beman::task::detail::state_base, ::beman::task::detail::state_rep> { public: using stop_token_type = typename ::beman::task::detail::state_base::stop_token_type; using scheduler_type = typename ::beman::task::detail::state_base::scheduler_type; - explicit awaiter(::beman::task::detail::handle h) : handle(::std::move(h)) {} + explicit awaiter(::beman::task::detail::handle h) : + ::beman::task::detail::state_rep>(std::move(h)) + { + } constexpr auto await_ready() const noexcept -> bool { return false; } auto await_suspend(::std::coroutine_handle parent) noexcept { this->scheduler.emplace( this->template from_env(::beman::execution::get_env(parent.promise()))); this->parent = ::std::move(parent); - return this->handle.start(this); + return this->receiver.start(this); } auto await_resume() { return this->result_resume(); } @@ -79,18 +83,16 @@ class awaiter : public ::beman::task::detail::state_base { return this->actual_complete(); } auto actual_complete() -> std::coroutine_handle<> { - return this->no_completion_set() ? this->parent.promise().unhandled_stopped() : ::std::move(this->parent); + return this->::beman::task::detail::state_base::no_completion_set() ? this->parent.promise().unhandled_stopped() : ::std::move(this->parent); } auto do_get_scheduler() -> scheduler_type override { return *this->scheduler; } auto do_set_scheduler(scheduler_type other) -> scheduler_type override { return ::std::exchange(*this->scheduler, other); } auto do_get_stop_token() -> stop_token_type override { return {}; } - auto do_get_environment() -> Env& override { return this->env; } + auto do_get_environment() -> Env& override { return this->context; } - Env env; ::std::optional scheduler; - ::beman::task::detail::handle handle; ::std::coroutine_handle parent{}; ::std::optional> reschedule{}; }; diff --git a/include/beman/task/detail/handle.hpp b/include/beman/task/detail/handle.hpp index 2a848d3..b2e40ab 100644 --- a/include/beman/task/detail/handle.hpp +++ b/include/beman/task/detail/handle.hpp @@ -32,6 +32,9 @@ class handle { auto release() -> ::std::coroutine_handle

{ return ::std::coroutine_handle

::from_promise(*this->h.release()); } + auto get_env() const noexcept { + return ::beman::execution::get_env(*this->h); + } }; } // namespace beman::task::detail diff --git a/include/beman/task/detail/state.hpp b/include/beman/task/detail/state.hpp index df2b315..714a077 100644 --- a/include/beman/task/detail/state.hpp +++ b/include/beman/task/detail/state.hpp @@ -4,8 +4,9 @@ #ifndef INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_STATE #define INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_STATE -#include #include +#include +#include #include #include #include @@ -13,37 +14,6 @@ // ---------------------------------------------------------------------------- namespace beman::task::detail { -template -struct state_rep { - std::remove_cvref_t receiver; - C context; - template - state_rep(R&& r) : receiver(std::forward(r)), context() {} -}; -template - requires requires { C(::beman::execution::get_env(std::declval&>())); } && - (not requires(const Receiver& receiver) { - typename C::template env_type; - }) -struct state_rep { - std::remove_cvref_t receiver; - C context; - template - state_rep(R&& r) : receiver(std::forward(r)), context(::beman::execution::get_env(this->receiver)) {} -}; -template - requires requires(const Receiver& receiver) { - typename C::template env_type; - } -struct state_rep { - using upstream_env = decltype(::beman::execution::get_env(std::declval&>())); - std::remove_cvref_t receiver; - typename C::template env_type own_env; - C context; - template - state_rep(R&& r) - : receiver(std::forward(r)), own_env(::beman::execution::get_env(this->receiver)), context(this->own_env) {} -}; template struct state : ::beman::task::detail::state_base, ::beman::task::detail::state_rep { diff --git a/include/beman/task/detail/state_rep.hpp b/include/beman/task/detail/state_rep.hpp new file mode 100644 index 0000000..250b8e8 --- /dev/null +++ b/include/beman/task/detail/state_rep.hpp @@ -0,0 +1,48 @@ +// include/beman/task/detail/state_rep.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_STATE_REP +#define INCLUDED_INCLUDE_BEMAN_TASK_DETAIL_STATE_REP + +#include +#include + +// ---------------------------------------------------------------------------- + +namespace beman::task::detail { +template +struct state_rep { + std::remove_cvref_t receiver; + C context; + template + state_rep(R&& r) : receiver(std::forward(r)), context() {} +}; +template + requires requires { C(::beman::execution::get_env(std::declval&>())); } && + (not requires(const Receiver& receiver) { + typename C::template env_type; + }) +struct state_rep { + std::remove_cvref_t receiver; + C context; + template + state_rep(R&& r) : receiver(std::forward(r)), context(::beman::execution::get_env(this->receiver)) {} +}; +template + requires requires(const Receiver& receiver) { + typename C::template env_type; + } +struct state_rep { + using upstream_env = decltype(::beman::execution::get_env(std::declval&>())); + std::remove_cvref_t receiver; + typename C::template env_type own_env; + C context; + template + state_rep(R&& r) + : receiver(std::forward(r)), own_env(::beman::execution::get_env(this->receiver)), context(this->own_env) {} +}; +} + +// ---------------------------------------------------------------------------- + +#endif From e86ea3e4af491c0ff9a770d83666fe670a08cc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Thu, 7 Aug 2025 21:09:36 +0100 Subject: [PATCH 2/3] added a missing function to the result_type --- include/beman/task/detail/result_type.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/beman/task/detail/result_type.hpp b/include/beman/task/detail/result_type.hpp index c74ab62..7a8bffe 100644 --- a/include/beman/task/detail/result_type.hpp +++ b/include/beman/task/detail/result_type.hpp @@ -162,6 +162,7 @@ class result_type> { auto set_value(T&& value) -> void { this->result.template emplace<1u>(::std::forward(value)); } + auto no_completion_set() const noexcept -> bool { return this->result.index() == 0u; } /** * \brief Call the completion function according to the current result. From b460f9a3f003992e58b85a4f495f707878be7b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Thu, 7 Aug 2025 21:11:39 +0100 Subject: [PATCH 3/3] clang-format --- include/beman/task/detail/awaiter.hpp | 13 +++++++------ include/beman/task/detail/handle.hpp | 4 +--- include/beman/task/detail/state_rep.hpp | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/beman/task/detail/awaiter.hpp b/include/beman/task/detail/awaiter.hpp index eb9b861..ab751b5 100644 --- a/include/beman/task/detail/awaiter.hpp +++ b/include/beman/task/detail/awaiter.hpp @@ -46,15 +46,14 @@ struct awaiter_op_t { }; template -class awaiter : public ::beman::task::detail::state_base, ::beman::task::detail::state_rep> { +class awaiter : public ::beman::task::detail::state_base, + ::beman::task::detail::state_rep> { public: using stop_token_type = typename ::beman::task::detail::state_base::stop_token_type; using scheduler_type = typename ::beman::task::detail::state_base::scheduler_type; - explicit awaiter(::beman::task::detail::handle h) : - ::beman::task::detail::state_rep>(std::move(h)) - { - } + explicit awaiter(::beman::task::detail::handle h) + : ::beman::task::detail::state_rep>(std::move(h)) {} constexpr auto await_ready() const noexcept -> bool { return false; } auto await_suspend(::std::coroutine_handle parent) noexcept { this->scheduler.emplace( @@ -83,7 +82,9 @@ class awaiter : public ::beman::task::detail::state_base, ::beman::t return this->actual_complete(); } auto actual_complete() -> std::coroutine_handle<> { - return this->::beman::task::detail::state_base::no_completion_set() ? this->parent.promise().unhandled_stopped() : ::std::move(this->parent); + return this->::beman::task::detail::state_base::no_completion_set() + ? this->parent.promise().unhandled_stopped() + : ::std::move(this->parent); } auto do_get_scheduler() -> scheduler_type override { return *this->scheduler; } auto do_set_scheduler(scheduler_type other) -> scheduler_type override { diff --git a/include/beman/task/detail/handle.hpp b/include/beman/task/detail/handle.hpp index b2e40ab..28d9c3d 100644 --- a/include/beman/task/detail/handle.hpp +++ b/include/beman/task/detail/handle.hpp @@ -32,9 +32,7 @@ class handle { auto release() -> ::std::coroutine_handle

{ return ::std::coroutine_handle

::from_promise(*this->h.release()); } - auto get_env() const noexcept { - return ::beman::execution::get_env(*this->h); - } + auto get_env() const noexcept { return ::beman::execution::get_env(*this->h); } }; } // namespace beman::task::detail diff --git a/include/beman/task/detail/state_rep.hpp b/include/beman/task/detail/state_rep.hpp index 250b8e8..abb2baa 100644 --- a/include/beman/task/detail/state_rep.hpp +++ b/include/beman/task/detail/state_rep.hpp @@ -41,7 +41,7 @@ struct state_rep { state_rep(R&& r) : receiver(std::forward(r)), own_env(::beman::execution::get_env(this->receiver)), context(this->own_env) {} }; -} +} // namespace beman::task::detail // ----------------------------------------------------------------------------