25 std::suspend_never initial_suspend() {
return {}; }
26 auto final_suspend()
noexcept {
28 std::coroutine_handle<> release_detached_;
29 bool await_ready()
noexcept {
return false; }
30 std::coroutine_handle<>
31 await_suspend(CoroutineHandle suspended)
noexcept {
32 if (suspended.promise().continuation_) {
33 return suspended.promise().continuation_;
35 if (release_detached_) {
36 release_detached_.destroy();
38 return std::noop_coroutine();
41 void await_resume()
noexcept {}
43 return awaiter{release_detached_};
46 std::coroutine_handle<> continuation_;
47 std::coroutine_handle<> release_detached_;
50template <
class T>
struct task {
52 :
public promise_base<T, std::coroutine_handle<promise_type>> {
54 return std::coroutine_handle<promise_type>::from_promise(*
this);
56 void unhandled_exception() {
57 this->promise_.set_exception(std::current_exception());
60 std::future<T> &get_future() {
return future_; }
61 void set_detached_task(std::coroutine_handle<promise_type> h) {
62 this->release_detached_ = h;
64 std::future<T> future_;
68 std::coroutine_handle<promise_type> h_;
69 task_awaiter(std::coroutine_handle<promise_type> h) : h_(h) {}
70 bool await_ready() {
return h_.done(); }
71 auto await_suspend(std::coroutine_handle<> suspended) {
72 h_.promise().continuation_ = suspended;
74 auto await_resume() {
return h_.promise().future_.get(); }
77 using coroutine_handle_type = std::coroutine_handle<promise_type>;
79 auto operator co_await()
const {
return task_awaiter(h_); }
84 h_.promise().set_detached_task(h_);
92 : h_(std::exchange(other.h_, nullptr)),
93 detached_(std::exchange(other.detached_, true)) {}
94 task(coroutine_handle_type h) : h_(h), detached_(false) {}
95 coroutine_handle_type h_;
97 operator coroutine_handle_type()
const {
return h_; }
98 std::future<T> &get_future()
const {
return h_.promise().get_future(); }
101 h_.promise().set_detached_task(h_);