67 concept directly_awaitable = requires(T v, std::coroutine_handle<> h) {
68 {v.await_ready()}->std::convertible_to<
bool>;
69 {v.await_suspend(h)}->await_suspend_valid_return_value;
74 concept indirectly_awaitable = requires(T v) {
75 {v.operator co_await()} -> directly_awaitable;
80 concept
awaitable = directly_awaitable<T> || indirectly_awaitable<T>;
82 template<
typename T,
typename RetVal>
83 concept directly_awaitable_r = requires(T v, std::coroutine_handle<> h) {
84 {v.await_ready()}->std::convertible_to<
bool>;
85 {v.await_suspend(h)}->await_suspend_valid_return_value;
86 {v.await_resume()}->std::convertible_to<RetVal>;
89 template<
typename T,
typename RetVal>
90 concept indirectly_awaitable_r = requires(T v) {
91 {v.operator co_await()} -> directly_awaitable_r<RetVal>;
94 template<
typename T,
typename RetVal>
95 concept awaitable_r = directly_awaitable_r<T,RetVal> || indirectly_awaitable_r<T,RetVal>;
98 struct awaitable_result_impl;
100 template<directly_awaitable T>
101 struct awaitable_result_impl<T> {
102 using type = decltype(std::declval<T>().await_resume());
105 template<indirectly_awaitable T>
106 struct awaitable_result_impl<T> {
107 using type =
typename awaitable_result_impl<decltype(std::declval<T>().operator co_await())>::type;
110 template<awaitable T>
111 using awaitable_result =
typename awaitable_result_impl<T>::type;
115 #define CORO_OPT_BARRIER [[clang::optnone]]
125 #define CORO_OPT_BARRIER
132 ident_t(std::coroutine_handle<X> h):_addr(h.address()) {}
133 bool operator==(
const ident_t &other)
const =
default;
134 bool operator<=>(
const ident_t &other)
const =
default;
136 friend std::size_t hash(
const ident_t &other) {
137 return std::bit_cast<std::size_t>(other._addr);
140 const void *address()
const {
return _addr;}
143 const void *_addr = 0;
concept awaitable
Tests, whether T is coroutine awaitable.
concept await_suspend_valid_return_value
Tests, whether T is valid await_suspend return value.