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