34#include <Pt/Connectable.h>
36#if __cplusplus >= 202002L
166 std::coroutine_handle<> h = _handle;
188 std::coroutine_handle<> _handle;
263 AwaiterBase* pending = _pending;
271 AwaiterBase* _pending =
nullptr;
272 std::coroutine_handle<> _continuation =
nullptr;
273 PromiseBase* _outer =
nullptr;
276 PromiseBase() =
default;
277 ~PromiseBase() =
default;
279 PromiseBase(
const PromiseBase&) =
delete;
280 PromiseBase& operator=(
const PromiseBase&) =
delete;
290 void return_value(T v)
291 { _result = std::move(v); }
294 {
return std::move(_result); }
299 PromiseResult() =
default;
300 ~PromiseResult() =
default;
302 PromiseResult(
const PromiseResult&) =
delete;
303 PromiseResult& operator=(
const PromiseResult&) =
delete;
310class PromiseResult<T&>
313 void return_value(T& v)
319 T* _result =
nullptr;
322 PromiseResult() =
default;
323 ~PromiseResult() =
default;
325 PromiseResult(
const PromiseResult&) =
delete;
326 PromiseResult& operator=(
const PromiseResult&) =
delete;
333class PromiseResult<void>
343 PromiseResult() =
default;
344 ~PromiseResult() =
default;
346 PromiseResult(
const PromiseResult&) =
delete;
347 PromiseResult& operator=(
const PromiseResult&) =
delete;
358 PromiseBase* _promise;
361 {
return _awaitable.await_ready(); }
364 auto await_suspend(std::coroutine_handle<P> h) ->
decltype(_awaitable.await_suspend(h))
365 {
return _awaitable.await_suspend(h); }
367 auto await_resume() ->
decltype(_awaitable.await_resume())
369 _promise->setFinished();
370 return _awaitable.await_resume();
380 bool await_ready() const noexcept
384 std::coroutine_handle<> await_suspend(std::coroutine_handle<P> h)
noexcept
386 PromiseBase* outer = h.promise()._outer;
388 if( outer && outer != &h.promise() )
389 outer->setFinished();
391 h.promise()._outer =
nullptr;
393 if( h.promise()._continuation )
394 return h.promise()._continuation;
396 return std::noop_coroutine();
399 void await_resume() noexcept
434template<
typename T =
void>
440 class Promise :
public PromiseResult<T>
444 std::exception_ptr _exception;
447 AwaiterProxy<A> await_transform(A&& a)
450 return AwaiterProxy<A>{ std::forward<A>(a),
this };
453 Task get_return_object()
455 return Task(std::coroutine_handle<promise_type>::from_promise(*
this));
458 std::suspend_always initial_suspend()
noexcept
461 FinalAwaiter final_suspend()
noexcept
464 void unhandled_exception()
465 { _exception = std::current_exception(); }
468 using promise_type = Promise;
469 using handle_type = std::coroutine_handle<promise_type>;
487 : _handle(other._handle)
489 other._handle =
nullptr;
501 _handle = other._handle;
502 other._handle =
nullptr;
520 if( _handle && ! _handle.done() )
522 if (_handle.promise()._outer)
523 throw std::logic_error(
"task pending");
525 _handle.promise()._outer = &_handle.promise();
539 _handle.promise().cancel();
540 handle_type handle = _handle;
549 {
return _handle && _handle.done(); }
553 explicit operator bool()
const
554 {
return _handle !=
nullptr; }
563 if( _handle.promise()._exception )
564 std::rethrow_exception(_handle.promise()._exception);
566 return _handle.promise().getResult();
581 if(_handle.promise()._outer)
583 throw std::logic_error(
"task pending");
586 _handle.promise()._continuation = outer;
587 _handle.promise()._outer = &outer.promise();
597 if( _handle.promise()._exception )
598 std::rethrow_exception(_handle.promise()._exception);
600 return _handle.promise().getResult();
AwaiterBase & operator=(const AwaiterBase &)=delete
No copy assignment.
AwaiterBase(const AwaiterBase &)=delete
No copy constructor.
virtual void cancel()=0
Cancels the pending operation.
virtual ~AwaiterBase()=default
Destructor.
AwaiterBase()=default
Constructor.
virtual void onCancel()=0
Aborts the in-flight operation.
void cancel() override
Cancels the in-flight operation.
Definition Coroutine.h:145
virtual void onBegin()=0
Starts the asynchronous operation.
bool await_suspend(std::coroutine_handle< P > h)
Starts the operation and suspends the coroutine.
Definition Coroutine.h:136
bool await_ready() const
Returns false so co_await always suspends.
Definition Coroutine.h:130
void setReady()
Resumes the waiting coroutine.
Definition Coroutine.h:162
Awaiter()
Constructor.
Definition Coroutine.h:154
void await_resume()
Resumes the coroutine after the operation completed.
Definition Coroutine.h:239
virtual void onReady()=0
Finalizes the operation when the awaitable resumes.
Provides an awaitable that delivers a result through onReady().
Definition Coroutine.h:208
R await_resume()
Returns the result produced when the awaitable resumes.
Definition Coroutine.h:212
virtual R onReady()=0
Returns the result for the co_await expression.
Represents a cancellable C++20 coroutine that produces a single result.
Definition Coroutine.h:436
std::coroutine_handle await_suspend(std::coroutine_handle< P > outer)
Suspends the outer coroutine and starts the inner coroutine.
Definition Coroutine.h:579
void run()
Starts execution of the coroutine.
Definition Coroutine.h:518
~Task()
Cancels the task if it still owns a coroutine frame.
Definition Coroutine.h:509
bool await_ready() const noexcept
Returns true if the inner coroutine has already finished.
Definition Coroutine.h:571
T await_resume()
Returns the result of the inner task.
Definition Coroutine.h:595
bool done() const
Returns true if the coroutine has finished.
Definition Coroutine.h:548
void cancel() override
Cancels the running coroutine.
Definition Coroutine.h:535
Task & operator=(Task &&other) noexcept
Moves the coroutine frame from other.
Definition Coroutine.h:496
Task() noexcept
Constructs an empty task with no coroutine frame.
Definition Coroutine.h:474
T result()
Returns the coroutine result.
Definition Coroutine.h:561
Task(Task &&other) noexcept
Moves the coroutine frame from other.
Definition Coroutine.h:486
Task(handle_type h)
Constructs a task that takes ownership of h.
Definition Coroutine.h:480
Core module.
Definition Allocator.h:33