1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value 2 #ifndef STD_COROUTINE_H 3 #define STD_COROUTINE_H 4 5 namespace std { 6 7 template <typename R, typename...> struct coroutine_traits { 8 using promise_type = typename R::promise_type; 9 }; 10 11 template <typename Promise = void> struct coroutine_handle; 12 13 template <> struct coroutine_handle<void> { 14 static coroutine_handle from_address(void *addr) noexcept { 15 coroutine_handle me; 16 me.ptr = addr; 17 return me; 18 } 19 void operator()() { resume(); } 20 void *address() const noexcept { return ptr; } 21 void resume() const { __builtin_coro_resume(ptr); } 22 void destroy() const { __builtin_coro_destroy(ptr); } 23 bool done() const { return __builtin_coro_done(ptr); } 24 coroutine_handle &operator=(decltype(nullptr)) { 25 ptr = nullptr; 26 return *this; 27 } 28 coroutine_handle(decltype(nullptr)) : ptr(nullptr) {} 29 coroutine_handle() : ptr(nullptr) {} 30 // void reset() { ptr = nullptr; } // add to P0057? 31 explicit operator bool() const { return ptr; } 32 33 protected: 34 void *ptr; 35 }; 36 37 template <typename Promise> struct coroutine_handle : coroutine_handle<> { 38 using coroutine_handle<>::operator=; 39 40 static coroutine_handle from_address(void *addr) noexcept { 41 coroutine_handle me; 42 me.ptr = addr; 43 return me; 44 } 45 46 Promise &promise() const { 47 return *reinterpret_cast<Promise *>( 48 __builtin_coro_promise(ptr, alignof(Promise), false)); 49 } 50 static coroutine_handle from_promise(Promise &promise) { 51 coroutine_handle p; 52 p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true); 53 return p; 54 } 55 }; 56 57 struct suspend_always { 58 bool await_ready() noexcept { return false; } 59 void await_suspend(coroutine_handle<>) noexcept {} 60 void await_resume() noexcept {} 61 }; 62 63 struct suspend_never { 64 bool await_ready() noexcept { return true; } 65 void await_suspend(coroutine_handle<>) noexcept {} 66 void await_resume() noexcept {} 67 }; 68 69 } // namespace std 70 71 #endif // STD_COROUTINE_H 72