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()69 task<int> five() {
70     co_return 5;
71 }
72 
six()73 task<int> six() {
74     co_return co_await five() + 1;
75 }
76 
77 
main()78 int main() {
79     auto task = six();
80     task.p->next = std::noop_coroutine();
81     task.p->coro().resume();
82     return *task.p->result;
83 }
84