7#if __has_include(<coroutine>) && __cpp_impl_coroutine
11 using std::coroutine_handle;
12 using std::noop_coroutine;
13 using std::suspend_always;
14 using std::suspend_never;
16#elif __has_include(<experimental/coroutine>)
18#include <experimental/coroutine>
20 using std::experimental::coroutine_handle;
21 using std::experimental::noop_coroutine;
22 using std::experimental::suspend_always;
23 using std::experimental::suspend_never;
34namespace std::experimental {
35 inline namespace coroutines_v1 {
42 template<
class _Tp,
class =
void>
43 struct __coroutine_traits_sfinae {};
46 struct __coroutine_traits_sfinae<_Tp, typename __void_t<typename _Tp::promise_type>::type> {
47 using promise_type =
typename _Tp::promise_type;
50 template<
typename _Ret,
typename... _Args>
51 struct coroutine_traits :
public __coroutine_traits_sfinae<_Ret> {};
53 template<
typename _Promise =
void>
54 class __attribute__((__visibility__(
"default"))) coroutine_handle;
57 class __attribute__((__visibility__(
"default"))) coroutine_handle<void> {
59 __attribute__((__visibility__(
"hidden")))
60 __attribute__((__always_inline__)) constexpr coroutine_handle() noexcept
61 : __handle_(
nullptr) {}
63 __attribute__((__visibility__(
"hidden")))
64 __attribute__((__always_inline__)) constexpr coroutine_handle(nullptr_t) noexcept
65 : __handle_(
nullptr) {}
67 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) coroutine_handle&
68 operator=(nullptr_t) noexcept {
73 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) constexpr
void*
74 address() const noexcept {
78 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) constexpr explicit
79 operator
bool() const noexcept {
83 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void operator()()
const {
87 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void resume()
const {
88 assert(__is_suspended());
90 __builtin_coro_resume(__handle_);
93 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void destroy()
const {
94 assert(__is_suspended());
95 __builtin_coro_destroy(__handle_);
98 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool done() const noexcept {
99 assert(__is_suspended());
100 return __builtin_coro_done(__handle_);
104 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) static coroutine_handle
105 from_address(
void* __addr) noexcept {
106 coroutine_handle __tmp;
107 __tmp.__handle_ = __addr;
112 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) static coroutine_handle
113 from_address(nullptr_t) noexcept {
114 return coroutine_handle(
nullptr);
117 template<
class _Tp,
bool _CallIsVal
id = false>
118 static coroutine_handle from_address(_Tp*) {
119 static_assert(_CallIsValid,
"coroutine_handle<void>::from_address cannot be called with "
120 "non-void pointers");
124 bool __is_suspended() const noexcept {
129 template<
class _PromiseT>
130 friend class coroutine_handle;
135 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
136 operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
137 return __x.address() == __y.address();
139 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
140 operator!=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
141 return !(__x == __y);
143 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
144 operator<(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
145 return less<void*>()(__x.address(), __y.address());
147 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
148 operator>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
151 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
152 operator<=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
155 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
156 operator>=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
160 template<
typename _Promise>
161 class __attribute__((__visibility__(
"default"))) coroutine_handle :
public coroutine_handle<> {
162 using _Base = coroutine_handle<>;
166 using coroutine_handle<>::coroutine_handle;
167 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) coroutine_handle&
168 operator=(nullptr_t) noexcept {
169 _Base::operator=(
nullptr);
173 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) _Promise& promise()
const {
174 return *
static_cast<_Promise*
>(__builtin_coro_promise(this->__handle_,
alignof(_Promise),
false));
178 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) static coroutine_handle
179 from_address(
void* __addr) noexcept {
180 coroutine_handle __tmp;
181 __tmp.__handle_ = __addr;
189 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) static coroutine_handle
190 from_address(nullptr_t) noexcept {
191 return coroutine_handle(
nullptr);
194 template<
class _Tp,
bool _CallIsVal
id = false>
195 static coroutine_handle from_address(_Tp*) {
196 static_assert(_CallIsValid,
"coroutine_handle<promise_type>::from_address cannot be called with "
197 "non-void pointers");
200 template<
bool _CallIsVal
id = false>
201 static coroutine_handle from_address(_Promise*) {
202 static_assert(_CallIsValid,
"coroutine_handle<promise_type>::from_address cannot be used with "
203 "pointers to the coroutine's promise type; use 'from_promise' instead");
206 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) static coroutine_handle
207 from_promise(_Promise& __promise) noexcept {
208 typedef typename remove_cv<_Promise>::type _RawPromise;
209 coroutine_handle __tmp;
210 __tmp.__handle_ = __builtin_coro_promise(std::addressof(
const_cast<_RawPromise&
>(__promise)),
211 alignof(_Promise),
true);
216#if __has_builtin(__builtin_coro_noop)
217 struct noop_coroutine_promise {};
220 class __attribute__((__visibility__(
"default")))
221 coroutine_handle<noop_coroutine_promise> :
public coroutine_handle<> {
222 using _Base = coroutine_handle<>;
223 using _Promise = noop_coroutine_promise;
226 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) _Promise& promise()
const {
227 return *
static_cast<_Promise*
>(__builtin_coro_promise(this->__handle_,
alignof(_Promise),
false));
230 constexpr explicit operator bool() const noexcept {
return true; }
231 constexpr bool done() const noexcept {
return false; }
233 constexpr void operator()() const noexcept {}
234 constexpr void resume() const noexcept {}
235 constexpr void destroy() const noexcept {}
238 __attribute__((__visibility__(
"hidden")))
239 __attribute__((__always_inline__)) friend coroutine_handle<noop_coroutine_promise>
240 noop_coroutine() noexcept;
242 __attribute__((__visibility__("hidden"))) __attribute__((__always_inline__)) coroutine_handle() noexcept {
243 this->__handle_ = __builtin_coro_noop();
247 using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
249 inline __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__)) noop_coroutine_handle
250 noop_coroutine() noexcept {
251 return noop_coroutine_handle();
255 struct suspend_never {
256 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
257 await_ready() const noexcept {
260 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void
261 await_suspend(coroutine_handle<>) const noexcept {}
262 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void
263 await_resume() const noexcept {}
266 struct suspend_always {
267 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
bool
268 await_ready() const noexcept {
271 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void
272 await_suspend(coroutine_handle<>) const noexcept {}
273 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
void
274 await_resume() const noexcept {}
282 struct hash<std::experimental::coroutine_handle<_Tp>> {
283 using __arg_type = std::experimental::coroutine_handle<_Tp>;
284 __attribute__((__visibility__(
"hidden"))) __attribute__((__always_inline__))
size_t
285 operator()(__arg_type const& __v) const noexcept {
286 return hash<void*>()(__v.address());
292 using std::experimental::coroutine_handle;
293 using std::experimental::noop_coroutine;
294 using std::experimental::suspend_always;
295 using std::experimental::suspend_never;