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()60 task<std::vector<int>> foo()
61 {
62   co_return std::vector<int>();
63 }
64 
bar()65 task<int> bar()
66 {
67   while ((co_await foo()).empty()) {
68   }
69   co_return 0;
70 }
71