1 #include "coro.h" 2 3 #include <exception> 4 #include <vector> 5 6 template <typename T> 7 struct promise { 8 T _value; 9 coro::coroutine_handle<> _continuation = nullptr; 10 11 struct final_awaitable { 12 bool _has_continuation; final_awaitablepromise::final_awaitable13 final_awaitable(bool has_continuation) 14 : _has_continuation(has_continuation) {} 15 await_readypromise::final_awaitable16 bool await_ready() const noexcept { return !_has_continuation; } 17 18 template <typename Promise> 19 coro::coroutine_handle<> await_suspendpromise::final_awaitable20 await_suspend(coro::coroutine_handle<Promise> coro) noexcept { 21 return coro.promise()._continuation; 22 } 23 await_resumepromise::final_awaitable24 void await_resume() noexcept {} 25 }; 26 get_return_objectpromise27 auto get_return_object() noexcept { 28 return coro::coroutine_handle<promise>::from_promise(*this); 29 } 30 initial_suspendpromise31 auto initial_suspend() noexcept { return coro::suspend_always(); } 32 final_suspendpromise33 auto final_suspend() noexcept { 34 return final_awaitable(_continuation != nullptr); 35 } 36 return_valuepromise37 void return_value(T value) { _value = value; } 38 unhandled_exceptionpromise39 void unhandled_exception() { std::terminate(); } 40 }; 41 42 template <typename T> 43 struct task { 44 using promise_type = promise<T>; 45 std::coroutine_handle<promise<T>> _handle; 46 tasktask47 task (coro::coroutine_handle<promise<T>> handle) : _handle(handle) {} 48 #if DELETE_COPY_CTOR 49 task (const task &) = delete; // no copying 50 #endif 51 #if DELETE_MOVE_CTOR tasktask52 task(task&& t) noexcept 53 : _handle(t._handle) { t._handle = nullptr; } 54 #endif await_readytask55 bool await_ready() noexcept { return _handle.done(); } 56 57 std::coroutine_handle<> await_suspendtask58 await_suspend(std::coroutine_handle<> handle) noexcept { 59 _handle.promise()._continuation = handle; 60 return _handle; 61 } 62 await_resumetask63 T await_resume() noexcept { return _handle.promise()._value; } 64 }; 65