1 // { dg-additional-options "-w" } 2 3 #include "coro.h" 4 5 #include <vector> 6 7 template <typename T> 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 43 template <typename T> struct task { 44 using promise_type = promise<T>; 45 coro::coroutine_handle<promise<T>> _handle; 46 tasktask47 task(coro::coroutine_handle<promise<T>> handle) : _handle(handle) {} 48 await_readytask49 bool await_ready() noexcept { return _handle.done(); } 50 51 coro::coroutine_handle<> await_suspendtask52 await_suspend(coro::coroutine_handle<> handle) noexcept { 53 _handle.promise()._continuation = handle; 54 return _handle; 55 } 56 await_resumetask57 T await_resume() noexcept { return _handle.promise()._value; } 58 }; 59 foo()60task<std::vector<int>> foo() 61 { 62 co_return std::vector<int>(); 63 } 64 bar()65task<int> bar() 66 { 67 while ((co_await foo()).empty()) { 68 } 69 co_return 0; 70 } 71