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