Created
November 30, 2021 09:41
-
-
Save HappyCerberus/5b48d7bd4849be4879368add643ce522 to your computer and use it in GitHub Desktop.
[Article] C++20 Practical Coroutines - chainable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct awaitable_final_continuation { | |
constexpr bool await_ready() const noexcept { return false; } | |
std::coroutine_handle<> | |
await_suspend(HandleWithContinuation auto caller) const noexcept { | |
return caller.promise().continuation; | |
} | |
constexpr void await_resume() const noexcept {} | |
}; | |
struct chainable_task { | |
struct chainable_promise { | |
using handle_t = std::coroutine_handle<chainable_promise>; | |
chainable_task get_return_object() { | |
return chainable_task{handle_t::from_promise(*this)}; | |
} | |
std::suspend_always initial_suspend() noexcept { return {}; } | |
awaitable_final_continuation final_suspend() noexcept { return {}; } | |
void unhandled_exception() { std::terminate(); } | |
void return_value(utils::AwaitResult result) { result_ = result; } | |
private: | |
std::coroutine_handle<> continuation = std::noop_coroutine(); | |
utils::AwaitResult result_; | |
friend struct chainable_task; | |
friend struct awaitable_final_continuation; | |
}; | |
using promise_type = chainable_promise; | |
explicit chainable_task(promise_type::handle_t handle) : handle_(handle) {} | |
chainable_task(const chainable_task &) = delete; | |
chainable_task(chainable_task &&task) | |
: handle_(std::exchange(task.handle_, nullptr)) {} | |
chainable_task &operator=(const chainable_task &) = delete; | |
chainable_task &operator=(chainable_task &&task) { | |
handle_ = std::exchange(task.handle_, nullptr); | |
return *this; | |
} | |
~chainable_task() { | |
if (handle_) | |
handle_.destroy(); | |
} | |
bool await_ready() noexcept { return false; } | |
std::coroutine_handle<> await_suspend(std::coroutine_handle<> caller) { | |
handle_.promise().continuation = caller; | |
return handle_; | |
} | |
utils::AwaitResult await_resume() { return handle_.promise().result_; } | |
private: | |
promise_type::handle_t handle_; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment