1 // This is a mock file for <coroutine>. 2 #pragma once 3 4 namespace std { 5 6 template <typename R, typename...> struct coroutine_traits { 7 using promise_type = typename R::promise_type; 8 }; 9 10 template <typename Promise = void> struct coroutine_handle; 11 12 template <> struct coroutine_handle<void> { 13 static coroutine_handle from_address(void *addr) noexcept { 14 coroutine_handle me; 15 me.ptr = addr; 16 return me; 17 } 18 void operator()() { resume(); } 19 void *address() const noexcept { return ptr; } 20 void resume() const { __builtin_coro_resume(ptr); } 21 void destroy() const { __builtin_coro_destroy(ptr); } 22 bool done() const { return __builtin_coro_done(ptr); } 23 coroutine_handle &operator=(decltype(nullptr)) { 24 ptr = nullptr; 25 return *this; 26 } 27 coroutine_handle(decltype(nullptr)) : ptr(nullptr) {} 28 coroutine_handle() : ptr(nullptr) {} 29 // void reset() { ptr = nullptr; } // add to P0057? 30 explicit operator bool() const { return ptr; } 31 32 protected: 33 void *ptr; 34 }; 35 36 template <typename Promise> struct coroutine_handle : coroutine_handle<> { 37 using coroutine_handle<>::operator=; 38 39 static coroutine_handle from_address(void *addr) noexcept { 40 coroutine_handle me; 41 me.ptr = addr; 42 return me; 43 } 44 45 Promise &promise() const { 46 return *reinterpret_cast<Promise *>( 47 __builtin_coro_promise(ptr, alignof(Promise), false)); 48 } 49 static coroutine_handle from_promise(Promise &promise) { 50 coroutine_handle p; 51 p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true); 52 return p; 53 } 54 }; 55 56 template <typename _PromiseT> 57 bool operator==(coroutine_handle<_PromiseT> const &_Left, 58 coroutine_handle<_PromiseT> const &_Right) noexcept { 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 return !(_Left == _Right); 66 } 67 68 struct noop_coroutine_promise {}; 69 70 template <> 71 struct coroutine_handle<noop_coroutine_promise> { 72 operator coroutine_handle<>() const noexcept { 73 return coroutine_handle<>::from_address(address()); 74 } 75 76 constexpr explicit operator bool() const noexcept { return true; } 77 constexpr bool done() const noexcept { return false; } 78 79 constexpr void operator()() const noexcept {} 80 constexpr void resume() const noexcept {} 81 constexpr void destroy() const noexcept {} 82 83 noop_coroutine_promise &promise() const noexcept { 84 return *static_cast<noop_coroutine_promise *>( 85 __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); 86 } 87 88 constexpr void *address() const noexcept { return __handle_; } 89 90 private: 91 friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept; 92 93 coroutine_handle() noexcept { 94 this->__handle_ = __builtin_coro_noop(); 95 } 96 97 void *__handle_ = nullptr; 98 }; 99 100 using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; 101 102 inline noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } 103 104 struct suspend_always { 105 bool await_ready() noexcept { return false; } 106 void await_suspend(coroutine_handle<>) noexcept {} 107 void await_resume() noexcept {} 108 }; 109 struct suspend_never { 110 bool await_ready() noexcept { return true; } 111 void await_suspend(coroutine_handle<>) noexcept {} 112 void await_resume() noexcept {} 113 }; 114 115 } // namespace std 116