12#if defined(__cpp_lib_coroutine)
14#elif defined(__clang__)
24void __builtin_coro_destroy(
void *addr);
25void __builtin_coro_resume(
void *addr);
26bool __builtin_coro_done(
void *addr);
27void* __builtin_coro_promise(
void *addr,
int alignment,
bool from_promise);
28void *__builtin_coro_noop();
41template<
class Promise =
void>
42struct coroutine_handle;
45constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y)
noexcept;
53struct noop_coroutine_promise;
56struct coroutine_handle<noop_coroutine_promise>;
57using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
58noop_coroutine_handle noop_coroutine() noexcept;
72namespace experimental {
74template<
class R,
class =
void>
75struct __coroutine_traits_base {};
78struct __coroutine_traits_base<R, void_t<typename R::promise_type>> {
79 using promise_type =
typename R::promise_type;
85template<
class R,
class ... ArgTypes>
86struct coroutine_traits : __coroutine_traits_base<R> {};
90template<
typename Promise>
91struct coroutine_handle :
public std::coroutine_handle<Promise> {};
96template<
typename R,
typename ... ArgTypes>
97using coroutine_traits = std::experimental::coroutine_traits<R, ArgTypes ...>;
103struct coroutine_handle<void> {
105 constexpr coroutine_handle() noexcept {}
106 constexpr coroutine_handle(nullptr_t)
noexcept {}
107 coroutine_handle &operator=(nullptr_t)
noexcept {
113 constexpr void *address() const noexcept {
117 static constexpr coroutine_handle from_address(
void *addr)
noexcept {
118 coroutine_handle handle;
124 constexpr explicit operator bool() const noexcept {
125 return m_ptr !=
nullptr;
128 return __builtin_coro_done(m_ptr);
132 void operator()()
const {
135 void resume()
const {
136 __builtin_coro_resume(m_ptr);
138 void destroy()
const {
139 __builtin_coro_destroy(m_ptr);
143 void *m_ptr =
nullptr;
146template<
class Promise>
147struct coroutine_handle :
public coroutine_handle<> {
149 using coroutine_handle<>::coroutine_handle;
150 static coroutine_handle from_promise(Promise &promise) {
151 coroutine_handle handle;
152 handle.m_ptr = __builtin_coro_promise(&promise,
alignof(Promise),
true);
155 coroutine_handle &operator=(nullptr_t)
noexcept {
156 this->m_ptr =
nullptr;
161 static constexpr coroutine_handle from_address(
void *addr)
noexcept {
162 coroutine_handle handle;
168 Promise &promise()
const {
169 return *
reinterpret_cast<Promise *
>(
170 __builtin_coro_promise(m_ptr,
alignof(Promise),
false));
175constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y)
noexcept {
176 return x.address() == y.address();
182struct noop_coroutine_promise {};
185struct coroutine_handle<noop_coroutine_promise>;
186using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
189struct coroutine_handle<noop_coroutine_promise> :
public coroutine_handle<> {
191 constexpr explicit operator bool() const noexcept {
return true; }
192 constexpr bool done() const noexcept {
return false; }
193 constexpr void operator()() const noexcept {}
194 constexpr void resume() const noexcept {}
195 constexpr void destroy() const noexcept {}
197 noop_coroutine_promise &promise() const noexcept {
198 return *
reinterpret_cast<noop_coroutine_promise *
>(
199 __builtin_coro_promise(__builtin_coro_noop(),
200 alignof(noop_coroutine_promise),
false));
204 coroutine_handle() noexcept
205 : coroutine_handle<>(from_address(__builtin_coro_noop())) {}
207 friend noop_coroutine_handle noop_coroutine() noexcept;
210inline noop_coroutine_handle noop_coroutine() noexcept {
216struct suspend_never {
217 constexpr bool await_ready() const noexcept {
return true; }
218 constexpr void await_resume() const noexcept {}
219 constexpr void await_suspend(coroutine_handle<>)
const noexcept {}
222struct suspend_always {
223 constexpr bool await_ready() const noexcept {
return false; }
224 constexpr void await_suspend(coroutine_handle<>)
const noexcept {}
225 constexpr void await_resume() const noexcept {}
231#pragma error "Current compiler does not support coroutines, or is not supported by QCoro."
236#ifdef QCORO_NO_DEPRECATED_QCOROSTD
240 #define _QCORO_STRINGIFY2(x) #x
241 #define _QCORO_STRINGIFY(x) _QCORO_STRINGIFY2(x)
243 __pragma(message(__FILE__ "(" _QCORO_STRINGIFY(__LINE__) ") QCORO_STD macro is deprecated, use regular 'std' namespace instead, or pass /DQCORO_NO_DEPRECATED_QCOROSTD to suppress this warning.")) \
247 _Pragma("GCC warning \"QCORO_STD macro is deprecated, use regular 'std' namespace instead, or pass -DQCORO_NO_DEPRECATED_QCOROSTD to suppress this warning.\"") \
255#include "concepts_p.h"
264 { t.await_ready() } -> std::same_as<bool>;
265 {t.await_suspend(std::declval<std::coroutine_handle<>>())};
272 { t.operator
co_await() };
278#if defined(_MSC_VER) && !defined(__clang__)
280 { ::operator
co_await(
static_cast<T &&
>(t)) };
282 {
operator co_await(
static_cast<T &&
>(t)) };
A concept describing the Awaitable type.