4 namespace experimental
{
5 inline namespace coroutines_v1
{
7 template <typename R
, typename
...> struct coroutine_traits
{
8 using promise_type
= typename
R::promise_type
;
11 template <typename Promise
= void> struct coroutine_handle
;
13 template <> struct coroutine_handle
<void> {
14 static coroutine_handle
from_address(void *addr
) noexcept
{
19 void operator()() { resume(); }
20 void *address() const noexcept
{ return ptr
; }
21 void resume() const { __builtin_coro_resume(ptr
); }
22 void destroy() const { __builtin_coro_destroy(ptr
); }
23 bool done() const { return __builtin_coro_done(ptr
); }
24 coroutine_handle
&operator=(decltype(nullptr)) {
28 coroutine_handle(decltype(nullptr)) : ptr(nullptr) {}
29 coroutine_handle() : ptr(nullptr) {}
30 // void reset() { ptr = nullptr; } // add to P0057?
31 explicit operator bool() const { return ptr
; }
37 template <typename Promise
> struct coroutine_handle
: coroutine_handle
<> {
38 using coroutine_handle
<>::operator=;
40 static coroutine_handle
from_address(void *addr
) noexcept
{
46 Promise
&promise() const {
47 return *reinterpret_cast<Promise
*>(
48 __builtin_coro_promise(ptr
, alignof(Promise
), false));
50 static coroutine_handle
from_promise(Promise
&promise
) {
52 p
.ptr
= __builtin_coro_promise(&promise
, alignof(Promise
), true);
57 template <typename _PromiseT
>
58 bool operator==(coroutine_handle
<_PromiseT
> const &_Left
,
59 coroutine_handle
<_PromiseT
> const &_Right
) noexcept
{
60 return _Left
.address() == _Right
.address();
63 template <typename _PromiseT
>
64 bool operator!=(coroutine_handle
<_PromiseT
> const &_Left
,
65 coroutine_handle
<_PromiseT
> const &_Right
) noexcept
{
66 return !(_Left
== _Right
);
69 struct suspend_always
{
70 bool await_ready() { return false; }
71 void await_suspend(coroutine_handle
<>) {}
72 void await_resume() {}
74 struct suspend_never
{
75 bool await_ready() noexcept
{ return true; }
76 void await_suspend(coroutine_handle
<>) noexcept
{}
77 void await_resume() noexcept
{}
80 } // namespace coroutines_v1
81 } // namespace experimental