30 #ifndef PT_COROUTINE_H
31 #define PT_COROUTINE_H
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;
310 class 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;
333 class 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
434 template<
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();
613 #endif // __cplusplus >= 202002L
615 #endif // PT_COROUTINE_H
Core module.
Definition: Allocator.h:33
AwaiterBase()=default
Constructor.
Represents a cancellable C++20 coroutine that produces a single result.
Definition: Coroutine.h:436
void cancel() override
Cancels the running coroutine.
Definition: Coroutine.h:535
T result()
Returns the coroutine result.
Definition: Coroutine.h:561
R await_resume()
Returns the result produced when the awaitable resumes.
Definition: Coroutine.h:212
Task(handle_type h)
Constructs a task that takes ownership of h.
Definition: Coroutine.h:480
Defines the cancellation interface for a pending awaitable.
Definition: Coroutine.h:54
virtual void onBegin()=0
Starts the asynchronous operation.
~Task()
Cancels the task if it still owns a coroutine frame.
Definition: Coroutine.h:509
AwaiterBase(const AwaiterBase &)=delete
No copy constructor.
Task & operator=(Task &&other) noexcept
Moves the coroutine frame from other.
Definition: Coroutine.h:496
virtual ~AwaiterBase()=default
Destructor.
bool await_ready() const noexcept
Returns true if the inner coroutine has already finished.
Definition: Coroutine.h:571
Task(Task &&other) noexcept
Moves the coroutine frame from other.
Definition: Coroutine.h:486
virtual void onReady()=0
Finalizes the operation when the awaitable resumes.
bool done() const
Returns true if the coroutine has finished.
Definition: Coroutine.h:548
void cancel() override
Cancels the in-flight operation.
Definition: Coroutine.h:145
std::coroutine_handle await_suspend(std::coroutine_handle< P > outer)
Suspends the outer coroutine and starts the inner coroutine.
Definition: Coroutine.h:579
bool await_suspend(std::coroutine_handle< P > h)
Starts the operation and suspends the coroutine.
Definition: Coroutine.h:136
virtual void onCancel()=0
Aborts the in-flight operation.
virtual R onReady()=0
Returns the result for the co_await expression.
bool await_ready() const
Returns false so co_await always suspends.
Definition: Coroutine.h:130
AwaiterBase & operator=(const AwaiterBase &)=delete
No copy assignment.
Awaiter()
Constructor.
Definition: Coroutine.h:154
T await_resume()
Returns the result of the inner task.
Definition: Coroutine.h:595
void await_resume()
Resumes the coroutine after the operation completed.
Definition: Coroutine.h:239
void run()
Starts execution of the coroutine.
Definition: Coroutine.h:518
virtual void cancel()=0
Cancels the pending operation.
Provides an awaitable that delivers a result through onReady().
Definition: Coroutine.h:208
void setReady()
Resumes the waiting coroutine.
Definition: Coroutine.h:162
Task() noexcept
Constructs an empty task with no coroutine frame.
Definition: Coroutine.h:474
Provides the base class for I/O-driven co_await-able operations.
Definition: Coroutine.h:126