1*ec117158SChuanqi Xu #pragma once 2*ec117158SChuanqi Xu 3*ec117158SChuanqi Xu namespace std { 4*ec117158SChuanqi Xu namespace experimental { 5*ec117158SChuanqi Xu inline namespace coroutines_v1 { 6*ec117158SChuanqi Xu 7*ec117158SChuanqi Xu template <typename R, typename...> struct coroutine_traits { 8*ec117158SChuanqi Xu using promise_type = typename R::promise_type; 9*ec117158SChuanqi Xu }; 10*ec117158SChuanqi Xu 11*ec117158SChuanqi Xu template <typename Promise = void> struct coroutine_handle; 12*ec117158SChuanqi Xu 13*ec117158SChuanqi Xu template <> struct coroutine_handle<void> { 14*ec117158SChuanqi Xu static coroutine_handle from_address(void *addr) noexcept { 15*ec117158SChuanqi Xu coroutine_handle me; 16*ec117158SChuanqi Xu me.ptr = addr; 17*ec117158SChuanqi Xu return me; 18*ec117158SChuanqi Xu } 19*ec117158SChuanqi Xu void operator()() { resume(); } 20*ec117158SChuanqi Xu void *address() const noexcept { return ptr; } 21*ec117158SChuanqi Xu void resume() const { __builtin_coro_resume(ptr); } 22*ec117158SChuanqi Xu void destroy() const { __builtin_coro_destroy(ptr); } 23*ec117158SChuanqi Xu bool done() const { return __builtin_coro_done(ptr); } 24*ec117158SChuanqi Xu coroutine_handle &operator=(decltype(nullptr)) { 25*ec117158SChuanqi Xu ptr = nullptr; 26*ec117158SChuanqi Xu return *this; 27*ec117158SChuanqi Xu } 28*ec117158SChuanqi Xu coroutine_handle(decltype(nullptr)) : ptr(nullptr) {} 29*ec117158SChuanqi Xu coroutine_handle() : ptr(nullptr) {} 30*ec117158SChuanqi Xu // void reset() { ptr = nullptr; } // add to P0057? 31*ec117158SChuanqi Xu explicit operator bool() const { return ptr; } 32*ec117158SChuanqi Xu 33*ec117158SChuanqi Xu protected: 34*ec117158SChuanqi Xu void *ptr; 35*ec117158SChuanqi Xu }; 36*ec117158SChuanqi Xu 37*ec117158SChuanqi Xu template <typename Promise> struct coroutine_handle : coroutine_handle<> { 38*ec117158SChuanqi Xu using coroutine_handle<>::operator=; 39*ec117158SChuanqi Xu 40*ec117158SChuanqi Xu static coroutine_handle from_address(void *addr) noexcept { 41*ec117158SChuanqi Xu coroutine_handle me; 42*ec117158SChuanqi Xu me.ptr = addr; 43*ec117158SChuanqi Xu return me; 44*ec117158SChuanqi Xu } 45*ec117158SChuanqi Xu 46*ec117158SChuanqi Xu Promise &promise() const { 47*ec117158SChuanqi Xu return *reinterpret_cast<Promise *>( 48*ec117158SChuanqi Xu __builtin_coro_promise(ptr, alignof(Promise), false)); 49*ec117158SChuanqi Xu } 50*ec117158SChuanqi Xu static coroutine_handle from_promise(Promise &promise) { 51*ec117158SChuanqi Xu coroutine_handle p; 52*ec117158SChuanqi Xu p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true); 53*ec117158SChuanqi Xu return p; 54*ec117158SChuanqi Xu } 55*ec117158SChuanqi Xu }; 56*ec117158SChuanqi Xu 57*ec117158SChuanqi Xu template <typename _PromiseT> 58*ec117158SChuanqi Xu bool operator==(coroutine_handle<_PromiseT> const &_Left, 59*ec117158SChuanqi Xu coroutine_handle<_PromiseT> const &_Right) noexcept { 60*ec117158SChuanqi Xu return _Left.address() == _Right.address(); 61*ec117158SChuanqi Xu } 62*ec117158SChuanqi Xu 63*ec117158SChuanqi Xu template <typename _PromiseT> 64*ec117158SChuanqi Xu bool operator!=(coroutine_handle<_PromiseT> const &_Left, 65*ec117158SChuanqi Xu coroutine_handle<_PromiseT> const &_Right) noexcept { 66*ec117158SChuanqi Xu return !(_Left == _Right); 67*ec117158SChuanqi Xu } 68*ec117158SChuanqi Xu 69*ec117158SChuanqi Xu struct suspend_always { 70*ec117158SChuanqi Xu bool await_ready() { return false; } 71*ec117158SChuanqi Xu void await_suspend(coroutine_handle<>) {} 72*ec117158SChuanqi Xu void await_resume() {} 73*ec117158SChuanqi Xu }; 74*ec117158SChuanqi Xu struct suspend_never { 75*ec117158SChuanqi Xu bool await_ready() noexcept { return true; } 76*ec117158SChuanqi Xu void await_suspend(coroutine_handle<>) noexcept {} 77*ec117158SChuanqi Xu void await_resume() noexcept {} 78*ec117158SChuanqi Xu }; 79*ec117158SChuanqi Xu 80*ec117158SChuanqi Xu } // namespace coroutines_v1 81*ec117158SChuanqi Xu } // namespace experimental 82*ec117158SChuanqi Xu } // namespace std 83