1 // { dg-additional-options "-std=c++20 -fpreprocessed -w" } 2 namespace std { 3 inline namespace { 4 template <typename _Result, typename> struct coroutine_traits { 5 using promise_type = _Result::promise_type; 6 }; 7 template <typename = void> struct coroutine_handle; 8 template <> struct coroutine_handle<> { public: }; 9 template <typename> struct coroutine_handle : coroutine_handle<> {}; 10 struct suspend_always { 11 bool await_ready(); 12 void await_suspend(coroutine_handle<>); 13 void await_resume(); 14 }; 15 } // namespace 16 } // namespace std 17 namespace coro = std; 18 namespace cppcoro { 19 class task { 20 private: 21 struct awaitable_base { 22 coro::coroutine_handle<> m_coroutine; 23 bool await_ready() const noexcept; 24 void await_suspend(coro::coroutine_handle<> awaitingCoroutine) noexcept; 25 }; 26 27 public: 28 auto operator co_await() const &noexcept { 29 struct awaitable : awaitable_base { 30 decltype(auto) await_resume() {} 31 }; 32 return awaitable{m_coroutine}; 33 } 34 35 private: 36 coro::coroutine_handle<> m_coroutine; 37 }; 38 class shared_task; 39 class shared_task_promise_base { 40 struct final_awaiter { 41 bool await_ready() const noexcept; 42 template <typename PROMISE> 43 void await_suspend(coro::coroutine_handle<PROMISE> h) noexcept; 44 void await_resume() noexcept; 45 }; 46 47 public: 48 coro::suspend_always initial_suspend() noexcept; 49 final_awaiter final_suspend() noexcept; 50 void unhandled_exception() noexcept; 51 }; 52 class shared_task_promise : public shared_task_promise_base { 53 public: 54 shared_task get_return_object() noexcept; 55 void return_void() noexcept; 56 }; 57 class shared_task { 58 public: 59 using promise_type = shared_task_promise; 60 }; 61 auto make_shared_task(cppcoro::task awaitable) -> shared_task { 62 co_return co_await static_cast<cppcoro::task &&>(awaitable); 63 } 64 } // namespace cppcoro 65