From a48dc1424bf7978c7bef3672730c18b2a8cc34f9 Mon Sep 17 00:00:00 2001 From: Klemens Morgenstern Date: Wed, 18 Oct 2023 11:27:19 +0800 Subject: [PATCH] clang-win workarounds. --- include/boost/cobalt/detail/detached.hpp | 25 +---- include/boost/cobalt/detail/fork.hpp | 122 +++++++++++----------- include/boost/cobalt/detail/generator.hpp | 63 +++++------ include/boost/cobalt/detail/join.hpp | 1 - include/boost/cobalt/detail/promise.hpp | 65 ++++++------ include/boost/cobalt/detail/task.hpp | 78 +++++++------- include/boost/cobalt/detail/thread.hpp | 21 ++-- include/boost/cobalt/detail/with.hpp | 74 ++++++------- include/boost/cobalt/this_coro.hpp | 1 - 9 files changed, 219 insertions(+), 231 deletions(-) diff --git a/include/boost/cobalt/detail/detached.hpp b/include/boost/cobalt/detail/detached.hpp index 627e44db..97c8b98c 100644 --- a/include/boost/cobalt/detail/detached.hpp +++ b/include/boost/cobalt/detail/detached.hpp @@ -49,30 +49,11 @@ struct detached_promise [[nodiscard]] detached get_return_object(); - auto await_transform( + std::suspend_never await_transform( cobalt::this_coro::reset_cancellation_source_t reset) noexcept { - struct result - { - detached_promise * promise; - asio::cancellation_slot slot; - - constexpr bool await_ready() const noexcept - { - return true; - } - - void await_suspend(std::coroutine_handle) noexcept - { - } - - auto await_resume() - { - promise->reset_cancellation_source(std::move(slot)); - } - }; - - return result{this, std::move(reset.source)}; + this->reset_cancellation_source(reset.source); + return {}; } using executor_type = executor; diff --git a/include/boost/cobalt/detail/fork.hpp b/include/boost/cobalt/detail/fork.hpp index d15360a5..d630e9d4 100644 --- a/include/boost/cobalt/detail/fork.hpp +++ b/include/boost/cobalt/detail/fork.hpp @@ -136,90 +136,92 @@ struct fork cancellation_slot_type get_cancellation_slot() const { return cancel; } constexpr static std::suspend_never initial_suspend() noexcept {return {};} - auto final_suspend() noexcept + + struct final_awaitable { - if (cancel.is_connected()) - cancel.clear(); - struct awaitable + promise_type * self; + bool await_ready() noexcept { - promise_type * self; - bool await_ready() noexcept - { - return self->state->use_count != 1u; - } + return self->state->use_count != 1u; + } - std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept - { - auto pp = h.promise().state.detach(); + std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept + { + auto pp = h.promise().state.detach(); #if defined(BOOST_COBALT_NO_SELF_DELETE) - h.promise().~promise_type(); + h.promise().~promise_type(); #else - // mem is in a monotonic_resource, this is fine on msvc- gcc doesn't like it though - h.destroy(); + // mem is in a monotonic_resource, this is fine on msvc- gcc doesn't like it though + h.destroy(); #endif - pp->use_count--; - BOOST_ASSERT(pp->use_count == 0u); - if (pp->coro) - return pp->coro.release(); - else - return std::noop_coroutine(); - } - - constexpr static void await_resume() noexcept {} - }; - return awaitable{this}; + pp->use_count--; + BOOST_ASSERT(pp->use_count == 0u); + if (pp->coro) + return pp->coro.release(); + else + return std::noop_coroutine(); + } + + constexpr static void await_resume() noexcept {} + }; + final_awaitable final_suspend() noexcept + { + if (cancel.is_connected()) + cancel.clear(); + return final_awaitable{this}; } void return_void() { } template Aw> - auto await_transform(Aw & aw) + struct wrapped_awaitable { - struct wrapped_awaitable + Aw & aw; + constexpr static bool await_ready() noexcept + { + return false; + } + + auto await_suspend(std::coroutine_handle h) { - Aw & aw; - constexpr static bool await_ready() noexcept - { - return false; - } - - auto await_suspend(std::coroutine_handle h) - { - BOOST_ASSERT(h.promise().state->wired_up()); + BOOST_ASSERT(h.promise().state->wired_up()); #if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING) - if constexpr (requires {aw.await_suspend(h, boost::source_location ());}) + if constexpr (requires {aw.await_suspend(h, boost::source_location ());}) return aw.await_suspend(h, h.promise().state->loc); #endif - return aw.await_suspend(h); - } + return aw.await_suspend(h); + } - auto await_resume() - { - return aw.await_resume(); - } - }; + auto await_resume() + { + return aw.await_resume(); + } + }; - return wrapped_awaitable{aw}; + template Aw> + auto await_transform(Aw & aw) + { + return wrapped_awaitable{aw}; } - auto await_transform(wired_up_t) + struct wired_up_awaitable { - struct awaitable + promise_type * promise; + bool await_ready() const noexcept { - promise_type * promise; - bool await_ready() const noexcept - { - return promise->state->wired_up(); - } - void await_suspend(std::coroutine_handle) - { - } - constexpr static void await_resume() noexcept {} - }; - - return awaitable{this}; + return promise->state->wired_up(); + } + void await_suspend(std::coroutine_handle) + { + } + constexpr static void await_resume() noexcept {} + }; + + auto await_transform(wired_up_t) + { + return wired_up_awaitable{this}; } diff --git a/include/boost/cobalt/detail/generator.hpp b/include/boost/cobalt/detail/generator.hpp index 4645a58b..003a6e47 100644 --- a/include/boost/cobalt/detail/generator.hpp +++ b/include/boost/cobalt/detail/generator.hpp @@ -306,45 +306,46 @@ struct generator_promise } std::suspend_never initial_suspend() {return {};} - auto final_suspend() noexcept + + struct final_awaitable { - struct final_awaitable + generator_promise * generator; + bool await_ready() const noexcept { - generator_promise * generator; - bool await_ready() const noexcept - { - return generator->receiver && generator->receiver->awaited_from.get() == nullptr; - } - - auto await_suspend(std::coroutine_handle h) noexcept - { - std::coroutine_handle res = std::noop_coroutine(); - if (generator->receiver && generator->receiver->awaited_from.get() != nullptr) - res = generator->receiver->awaited_from.release(); - if (generator->receiver) - generator->receiver->done = true; - + return generator->receiver && generator->receiver->awaited_from.get() == nullptr; + } - if (auto & rec = h.promise().receiver; rec != nullptr) - { - if (!rec->done && !rec->exception) - rec->exception = detail::completed_unexpected(); - rec->done = true; - rec->awaited_from.reset(nullptr); - rec = nullptr; - } + auto await_suspend(std::coroutine_handle h) noexcept + { + std::coroutine_handle res = std::noop_coroutine(); + if (generator->receiver && generator->receiver->awaited_from.get() != nullptr) + res = generator->receiver->awaited_from.release(); + if (generator->receiver) + generator->receiver->done = true; - detail::self_destroy(h); - return res; - } - void await_resume() noexcept + if (auto & rec = h.promise().receiver; rec != nullptr) { - if (generator->receiver) - generator->receiver->done = true; + if (!rec->done && !rec->exception) + rec->exception = detail::completed_unexpected(); + rec->done = true; + rec->awaited_from.reset(nullptr); + rec = nullptr; } - }; + detail::self_destroy(h); + return res; + } + + void await_resume() noexcept + { + if (generator->receiver) + generator->receiver->done = true; + } + }; + + auto final_suspend() noexcept + { return final_awaitable{this}; } diff --git a/include/boost/cobalt/detail/join.hpp b/include/boost/cobalt/detail/join.hpp index 448d4838..d9a60fc6 100644 --- a/include/boost/cobalt/detail/join.hpp +++ b/include/boost/cobalt/detail/join.hpp @@ -292,7 +292,6 @@ struct join_ranged_impl struct awaitable : fork::shared_state { - struct dummy { template diff --git a/include/boost/cobalt/detail/promise.hpp b/include/boost/cobalt/detail/promise.hpp index 491a3a33..c46e217e 100644 --- a/include/boost/cobalt/detail/promise.hpp +++ b/include/boost/cobalt/detail/promise.hpp @@ -320,38 +320,6 @@ struct cobalt_promise std::suspend_never initial_suspend() {return {};} auto final_suspend() noexcept { - struct final_awaitable - { - cobalt_promise * promise; - bool await_ready() const noexcept - { - return promise->receiver && promise->receiver->awaited_from.get() == nullptr; - } - - std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept - { - std::coroutine_handle res = std::noop_coroutine(); - if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) - res = promise->receiver->awaited_from.release(); - - - if (auto &rec = h.promise().receiver; rec != nullptr) - { - if (!rec->done && !rec->exception) - rec->exception = completed_unexpected(); - rec->set_done(); - rec->awaited_from.reset(nullptr); - rec = nullptr; - } - detail::self_destroy(h); - return res; - } - - void await_resume() noexcept - { - } - }; - return final_awaitable{this}; } @@ -374,6 +342,39 @@ struct cobalt_promise } } + private: + struct final_awaitable + { + cobalt_promise * promise; + bool await_ready() const noexcept + { + return promise->receiver && promise->receiver->awaited_from.get() == nullptr; + } + + std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept + { + std::coroutine_handle res = std::noop_coroutine(); + if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) + res = promise->receiver->awaited_from.release(); + + + if (auto &rec = h.promise().receiver; rec != nullptr) + { + if (!rec->done && !rec->exception) + rec->exception = completed_unexpected(); + rec->set_done(); + rec->awaited_from.reset(nullptr); + rec = nullptr; + } + detail::self_destroy(h); + return res; + } + + void await_resume() noexcept + { + } + }; + }; diff --git a/include/boost/cobalt/detail/task.hpp b/include/boost/cobalt/detail/task.hpp index a040196b..f73e6ec1 100644 --- a/include/boost/cobalt/detail/task.hpp +++ b/include/boost/cobalt/detail/task.hpp @@ -309,58 +309,60 @@ struct task_promise this->reset_cancellation_source(signal.slot()); } - auto initial_suspend() + struct initial_awaitable { - struct initial_awaitable + task_promise * promise; + + bool await_ready() const noexcept {return false;} + void await_suspend(std::coroutine_handle<>) {} + + void await_resume() { - task_promise * promise; + promise->started = true; + } + }; - bool await_ready() const noexcept {return false;} - void await_suspend(std::coroutine_handle<>) {} + auto initial_suspend() + { - void await_resume() - { - promise->started = true; - } - }; return initial_awaitable{this}; } - auto final_suspend() noexcept + struct final_awaitable { - struct final_awaitable + task_promise * promise; + bool await_ready() const noexcept { - task_promise * promise; - bool await_ready() const noexcept - { - return promise->receiver && promise->receiver->awaited_from.get() == nullptr; - } + return promise->receiver && promise->receiver->awaited_from.get() == nullptr; + } + + BOOST_NOINLINE + auto await_suspend(std::coroutine_handle h) noexcept + { + std::coroutine_handle res = std::noop_coroutine(); + if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) + res = promise->receiver->awaited_from.release(); - BOOST_NOINLINE - auto await_suspend(std::coroutine_handle h) noexcept - { - std::coroutine_handle res = std::noop_coroutine(); - if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) - res = promise->receiver->awaited_from.release(); - - - if (auto & rec = h.promise().receiver; rec != nullptr) - { - if (!rec->done && !rec->exception) - rec->exception = completed_unexpected(); - rec->set_done(); - rec->awaited_from.reset(nullptr); - rec = nullptr; - } - detail::self_destroy(h); - return res; - } - void await_resume() noexcept + if (auto & rec = h.promise().receiver; rec != nullptr) { + if (!rec->done && !rec->exception) + rec->exception = completed_unexpected(); + rec->set_done(); + rec->awaited_from.reset(nullptr); + rec = nullptr; } - }; + detail::self_destroy(h); + return res; + } + void await_resume() noexcept + { + } + }; + + auto final_suspend() noexcept + { return final_awaitable{this}; } diff --git a/include/boost/cobalt/detail/thread.hpp b/include/boost/cobalt/detail/thread.hpp index 2fc766fb..1631e873 100644 --- a/include/boost/cobalt/detail/thread.hpp +++ b/include/boost/cobalt/detail/thread.hpp @@ -59,19 +59,20 @@ struct thread_promise : signal_helper_2, { BOOST_COBALT_DECL thread_promise(); - auto initial_suspend() noexcept + struct initial_awaitable { - struct aw + bool await_ready() const {return false;} + void await_suspend(std::coroutine_handle h) { - bool await_ready() const {return false;} - void await_suspend(std::coroutine_handle h) - { - h.promise().mtx.unlock(); - } + h.promise().mtx.unlock(); + } - void await_resume() {} - }; - return aw{}; + void await_resume() {} + }; + + auto initial_suspend() noexcept + { + return initial_awaitable{}; } std::suspend_never final_suspend() noexcept { diff --git a/include/boost/cobalt/detail/with.hpp b/include/boost/cobalt/detail/with.hpp index 5994e09b..303f5317 100644 --- a/include/boost/cobalt/detail/with.hpp +++ b/include/boost/cobalt/detail/with.hpp @@ -59,53 +59,55 @@ struct with_impl::promise_type enable_awaitables, enable_await_allocator { - using enable_awaitables::await_transform; - using enable_await_allocator::await_transform; + using enable_awaitables::await_transform; + using enable_await_allocator::await_transform; - using executor_type = executor; - const executor_type & get_executor() const {return *exec;} - std::optional exec; + using executor_type = executor; + const executor_type & get_executor() const {return *exec;} + std::optional exec; - with_impl get_return_object() + with_impl get_return_object() + { + return with_impl{*this}; + } + + std::exception_ptr e; + void unhandled_exception() + { + e = std::current_exception(); + } + + std::suspend_always initial_suspend() {return {};} + + struct final_awaitable + { + promise_type *promise; + + bool await_ready() const noexcept { - return with_impl{*this}; + return false; } - - std::exception_ptr e; - void unhandled_exception() + BOOST_NOINLINE + auto await_suspend(std::coroutine_handle h) noexcept -> std::coroutine_handle { - e = std::current_exception(); + return std::coroutine_handle::from_address(h.promise().awaited_from.address()); } - std::suspend_always initial_suspend() {return {};} - auto final_suspend() noexcept + void await_resume() noexcept { - struct final_awaitable - { - promise_type *promise; - - bool await_ready() const noexcept - { - return false; - } - BOOST_NOINLINE - auto await_suspend(std::coroutine_handle h) noexcept -> std::coroutine_handle - { - return std::coroutine_handle::from_address(h.promise().awaited_from.address()); - } - - void await_resume() noexcept - { - } - }; - return final_awaitable{this}; } - using cancellation_slot_type = asio::cancellation_slot; - cancellation_slot_type get_cancellation_slot() const {return slot_;} - asio::cancellation_slot slot_; + }; + + auto final_suspend() noexcept + { + return final_awaitable{this}; + } + using cancellation_slot_type = asio::cancellation_slot; + cancellation_slot_type get_cancellation_slot() const {return slot_;} + asio::cancellation_slot slot_; - std::coroutine_handle awaited_from{nullptr}; + std::coroutine_handle awaited_from{nullptr}; }; diff --git a/include/boost/cobalt/this_coro.hpp b/include/boost/cobalt/this_coro.hpp index 32f2b4ef..78f505c8 100644 --- a/include/boost/cobalt/this_coro.hpp +++ b/include/boost/cobalt/this_coro.hpp @@ -98,7 +98,6 @@ struct promise_cancellation_base : source_(slot), state_{source_, filter} {} - // This await transformation resets the associated cancellation state. auto await_transform(cobalt::this_coro::cancelled_t) noexcept {