diff --git a/include/beman/task/detail/awaiter.hpp b/include/beman/task/detail/awaiter.hpp index 8320ec4..ab751b5 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,20 @@ 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 +82,18 @@ 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..28d9c3d 100644 --- a/include/beman/task/detail/handle.hpp +++ b/include/beman/task/detail/handle.hpp @@ -32,6 +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); } }; } // namespace beman::task::detail 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. 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..abb2baa --- /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) {} +}; +} // namespace beman::task::detail + +// ---------------------------------------------------------------------------- + +#endif