13 #define LIBCORO_MSC_FAILED_SYMMETRIC_TRANSFER
54 template<
typename T, coro_allocator Alloc = std_allocator>
79 return reinterpret_cast<future<T> *
>(std::uintptr_t(-1));
83 this->fut = invalid_value();
84 trace::set_class(std::coroutine_handle<promise_type>::from_promise(*
this),
typeid(
async).name());
87 struct initial_awaiter {
89 bool await_ready()
const noexcept {
return me->fut != invalid_value();}
90 void await_suspend([[maybe_unused]] std::coroutine_handle<> h) noexcept {
93 trace::on_suspend(h, {});
95 static constexpr
void await_resume() noexcept {};
98 struct final_awaiter {
100 bool await_ready()
const noexcept {
return detached;}
101 #ifdef LIBCORO_MSC_FAILED_SYMMETRIC_TRANSFER
102 void await_suspend(std::coroutine_handle<promise_type> h)
const noexcept {
103 promise_type &
self = h.promise();
104 std::coroutine_handle<> retval =
trace::on_switch(h,
self.set_resolved().symmetric_transfer(),{});
109 std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h)
const noexcept {
110 promise_type &
self = h.promise();
111 std::coroutine_handle<> retval =
trace::on_switch(h,
self.set_resolved().symmetric_transfer(),{});
117 void await_resume()
const noexcept {}
120 initial_awaiter initial_suspend() noexcept {
return {
this};}
121 final_awaiter final_suspend()
const noexcept {
return {this->fut ==
nullptr};}
122 async get_return_object() {
return {
this};}
126 auto h = std::coroutine_handle<promise_type>::from_promise(*
this);
127 trace::awaiting_ref(h, fut);
128 if (std::exchange(this->fut, fut) ==
nullptr) {
134 if (std::exchange(this->fut,
nullptr) ==
nullptr) {
135 return std::coroutine_handle<promise_type>::from_promise(*
this);
155 _promise_ptr.release()->detach();
164 return _promise_ptr.release()->detach().symmetric_transfer();
170 me._promise_ptr.release()->attach(
promise);
176 _promise_ptr.release()->attach(prom);
181 return [me = std::move(*
this)](
auto promise)
mutable {
182 return me._promise_ptr.release()->attach(
promise);
188 return [me = std::move(*
this)](
auto promise)
mutable {
189 me._promise_ptr.release()->attach(
promise);
201 me._promise_ptr.release()->attach(
promise);
217 template<std::constructible_from<T> U>
219 return U(
start().get());
224 return start().get();
227 operator ident_t()
const {
return std::coroutine_handle<promise_type>::from_promise(*_promise_ptr);}
232 void operator()(promise_type *p) {
233 auto h = std::coroutine_handle<promise_type>::from_promise(*p);
238 async(promise_type *p): _promise_ptr(p) {}
240 std::unique_ptr<promise_type, Deleter> _promise_ptr;
243 static promise_type *cast_promise(X *other) {
244 return static_cast<promise_type *
>(
static_cast<_details::coro_promise<T> *
>(other));
254 template<
typename T,
typename ... Args>
255 struct std::coroutine_traits<
coro::future<T>, Args...> {
260 template<
typename T,
typename ... Args>
261 struct std::coroutine_traits<
coro::deferred_future<T>, Args...> {
266 template<
typename T,
typename ... Args>
267 struct std::coroutine_traits<
coro::shared_future<T>, Args...> {
void start(promise< T > prom)
Start coroutine and pass return value to promise.
async(async< T, A > &&other)
convert from different allocator (because the allocator is only used during creation)
auto run()
run synchronously
void detach()
Run coroutine detached.
std::coroutine_handle detach_on_await_suspend()
detach coroutine using symmetric transfer
deferred_future< T > defer_start()
Defer start of coroutine.
async()=default
construct uninitialized object
shared_future< T > shared_start()
Start coroutine and return shared future.
future< T > start()
Start coroutine and return future.
COROUTINE: Coroutine for asynchronous operation.
inherit this class to include coro_allocator into your promise_type
Contains future value of T, where evaluation is deferred until the value is needed.
Contains future value of T, can be co_awaited in coroutine.
contains prepared coroutine (prepared to run)
FutureType * release()
Release the future pointer from the promise object.
Carries reference to future<T>, callable, sets value of an associated future<T>
Future which can be shared (by copying - like shared_ptr)
std::coroutine_handle on_switch(std::coroutine_handle<>, std::coroutine_handle<> to, const void *)
Record switch (symmetric transfer) from one coroutine to other.