| // { dg-additional-options "-w" } |
| |
| #include "coro.h" |
| |
| #include <vector> |
| |
| template <typename T> struct promise { |
| T _value; |
| coro::coroutine_handle<> _continuation = nullptr; |
| |
| struct final_awaitable { |
| bool _has_continuation; |
| final_awaitable(bool has_continuation) |
| : _has_continuation(has_continuation) {} |
| |
| bool await_ready() const noexcept { return !_has_continuation; } |
| |
| template <typename Promise> |
| coro::coroutine_handle<> |
| await_suspend(coro::coroutine_handle<Promise> coro) noexcept { |
| return coro.promise()._continuation; |
| } |
| |
| void await_resume() noexcept {} |
| }; |
| |
| auto get_return_object() noexcept { |
| return coro::coroutine_handle<promise>::from_promise(*this); |
| } |
| |
| auto initial_suspend() noexcept { return coro::suspend_always(); } |
| |
| auto final_suspend() noexcept { |
| return final_awaitable(_continuation != nullptr); |
| } |
| |
| void return_value(T value) { _value = value; } |
| |
| void unhandled_exception() { /*std::terminate();*/ } |
| |
| }; |
| |
| template <typename T> struct task { |
| using promise_type = promise<T>; |
| coro::coroutine_handle<promise<T>> _handle; |
| |
| task(coro::coroutine_handle<promise<T>> handle) : _handle(handle) {} |
| |
| bool await_ready() noexcept { return _handle.done(); } |
| |
| coro::coroutine_handle<> |
| await_suspend(coro::coroutine_handle<> handle) noexcept { |
| _handle.promise()._continuation = handle; |
| return _handle; |
| } |
| |
| T await_resume() noexcept { return _handle.promise()._value; } |
| }; |
| |
| task<std::vector<int>> foo() |
| { |
| co_return std::vector<int>(); |
| } |
| |
| task<int> bar() |
| { |
| while ((co_await foo()).empty()) { |
| } |
| co_return 0; |
| } |