| // 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 |
| #ifndef STD_COROUTINE_H |
| #define STD_COROUTINE_H |
| |
| namespace std { |
| namespace experimental { |
| template <typename R, typename...> struct coroutine_traits { |
| using promise_type = typename R::promise_type; |
| }; |
| |
| template <typename Promise = void> struct coroutine_handle; |
| |
| template <> struct coroutine_handle<void> { |
| static coroutine_handle from_address(void *addr) noexcept { |
| coroutine_handle me; |
| me.ptr = addr; |
| return me; |
| } |
| void operator()() { resume(); } |
| void *address() const noexcept { return ptr; } |
| void resume() const { __builtin_coro_resume(ptr); } |
| void destroy() const { __builtin_coro_destroy(ptr); } |
| bool done() const { return __builtin_coro_done(ptr); } |
| coroutine_handle &operator=(decltype(nullptr)) { |
| ptr = nullptr; |
| return *this; |
| } |
| coroutine_handle(decltype(nullptr)) : ptr(nullptr) {} |
| coroutine_handle() : ptr(nullptr) {} |
| // void reset() { ptr = nullptr; } // add to P0057? |
| explicit operator bool() const { return ptr; } |
| |
| protected: |
| void *ptr; |
| }; |
| |
| template <typename Promise> struct coroutine_handle : coroutine_handle<> { |
| using coroutine_handle<>::operator=; |
| |
| static coroutine_handle from_address(void *addr) noexcept { |
| coroutine_handle me; |
| me.ptr = addr; |
| return me; |
| } |
| |
| Promise &promise() const { |
| return *reinterpret_cast<Promise *>( |
| __builtin_coro_promise(ptr, alignof(Promise), false)); |
| } |
| static coroutine_handle from_promise(Promise &promise) { |
| coroutine_handle p; |
| p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true); |
| return p; |
| } |
| }; |
| |
| struct suspend_always { |
| bool await_ready() { return false; } |
| void await_suspend(coroutine_handle<>) {} |
| void await_resume() {} |
| }; |
| |
| struct suspend_never { |
| bool await_ready() noexcept { return true; } |
| void await_suspend(coroutine_handle<>) noexcept {} |
| void await_resume() noexcept {} |
| }; |
| } // namespace experimental |
| } // namespace std |
| |
| #endif // STD_COROUTINE_H |