1 #include <optional> 2 #include <coroutine> 3 4 template <typename T> 5 struct [[nodiscard]] task { 6 struct promise_type { initial_suspendtask::promise_type7 std::suspend_always initial_suspend() { 8 return {}; 9 } final_suspendtask::promise_type10 auto final_suspend() noexcept { 11 struct awaiter { 12 #if 1 13 std::false_type await_ready() noexcept { 14 return {}; 15 } 16 #else 17 bool await_ready() noexcept { 18 return false; 19 } 20 #endif 21 std::coroutine_handle<> await_suspend(std::coroutine_handle<>) noexcept { 22 return next; 23 } 24 void await_resume() noexcept { 25 } 26 std::coroutine_handle<> next; 27 }; 28 return awaiter{next}; 29 } 30 unhandled_exceptiontask::promise_type31 void unhandled_exception() noexcept { 32 std::terminate(); 33 } get_return_objecttask::promise_type34 auto get_return_object() { 35 return task(this); 36 } corotask::promise_type37 auto coro() { 38 return std::coroutine_handle<promise_type>::from_promise(*this); 39 } return_valuetask::promise_type40 void return_value(T val) { 41 result.emplace(std::move(val)); 42 } 43 44 std::coroutine_handle<> next; 45 std::optional<T> result; 46 }; 47 tasktask48 task(task&& source) : p(std::exchange(source.p, nullptr)) {} tasktask49 explicit task(promise_type* p) : p(p) {} ~tasktask50 ~task() { 51 if (p) 52 p->coro().destroy(); 53 } 54 await_readytask55 bool await_ready() noexcept { 56 return p->coro().done(); 57 } await_suspendtask58 std::coroutine_handle<> await_suspend(std::coroutine_handle<> next) noexcept { 59 p->next = next; 60 return p->coro(); 61 } await_resumetask62 const T& await_resume() const& noexcept { 63 return *p->result; 64 } 65 66 promise_type* p; 67 }; 68 five()69task<int> five() { 70 co_return 5; 71 } 72 six()73task<int> six() { 74 co_return co_await five() + 1; 75 } 76 77 main()78int main() { 79 auto task = six(); 80 task.p->next = std::noop_coroutine(); 81 task.p->coro().resume(); 82 return *task.p->result; 83 } 84