#pragma once namespace std { namespace experimental { inline namespace coroutines_v1 { template struct coroutine_traits { using promise_type = typename R::promise_type; }; template struct coroutine_handle; template <> struct coroutine_handle { static coroutine_handle from_address(void *addr) noexcept { coroutine_handle me; me.ptr = addr; return me; } void operator()() { resume(); } void *address() const { 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 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( __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; } }; template bool operator==(coroutine_handle<_PromiseT> const& _Left, coroutine_handle<_PromiseT> const& _Right) noexcept { return _Left.address() == _Right.address(); } template bool operator!=(coroutine_handle<_PromiseT> const& _Left, coroutine_handle<_PromiseT> const& _Right) noexcept { return !(_Left == _Right); } struct suspend_always { bool await_ready() { return false; } void await_suspend(coroutine_handle<>) {} void await_resume() {} }; struct suspend_never { bool await_ready() { return true; } void await_suspend(coroutine_handle<>) {} void await_resume() {} }; }}}