65#include "promises.hpp"
70template<
typename T>
struct TFinalAwaiter;
72template<
typename T>
struct TFuture;
84 std::suspend_never initial_suspend() {
return {}; }
87 std::coroutine_handle<>
Caller = std::noop_coroutine();
102 void return_value(
const T& t) {
106 void return_value(T&& t) {
110 void unhandled_exception() {
111 ErrorOr = std::unexpected(std::current_exception());
115 std::optional<std::expected<T, std::exception_ptr>>
ErrorOr;
130 : Coro(Coro.from_promise(promise))
134 *
this = std::move(other);
139 if (
this != &other) {
143 Coro = std::exchange(other.Coro,
nullptr);
150 bool await_ready()
const {
151 return Coro.promise().ErrorOr.has_value();
158 std::coroutine_handle<> raw() {
162 void await_suspend(std::coroutine_handle<> caller) {
163 Coro.promise().Caller = caller;
169 std::coroutine_handle<TPromise<T>> Coro =
nullptr;
172template<>
struct TFuture<void>;
187 auto& errorOr = *this->Coro.promise().ErrorOr;
188 if (errorOr.has_value()) {
189 return std::move(errorOr.value());
191 std::rethrow_exception(errorOr.error());
206 template<
typename Func>
208 auto prev = std::move(*
this);
209 auto ret =
co_await prev;
234 void unhandled_exception() {
235 ErrorOr = std::current_exception();
238 std::optional<std::exception_ptr>
ErrorOr;
250 void await_resume() {
251 auto& errorOr = *this->Coro.promise().ErrorOr;
253 std::rethrow_exception(errorOr);
264 template<
typename Func>
266 auto prev = std::move(*
this);
274 auto prev = std::move(*
this);
291 bool await_ready()
noexcept {
return false; }
292 std::coroutine_handle<> await_suspend(std::coroutine_handle<
TPromise<T>> h)
noexcept {
293 return h.promise().Caller;
295 void await_resume()
noexcept { }
300TFuture<T> TPromise<T>::get_return_object() {
return { TFuture<T>{*
this} }; }
304TFinalAwaiter<T> TPromiseBase<T>::final_suspend() noexcept {
return {}; }
318 auto waiting = std::move(futures);
319 std::vector<T> ret; ret.reserve(waiting.size());
320 for (
auto& f : waiting) {
321 ret.emplace_back(std::move(
co_await f));
333 auto waiting = std::move(futures);
334 for (
auto& f : waiting) {
354 std::vector<TFuture<T>> all = std::move(futures);
356 auto it = std::find_if(all.begin(), all.end(), [](
auto& f) { return f.done(); });
357 if (it != all.end()) {
358 co_return it->await_resume();
361 auto self =
co_await Self();
362 for (
auto& f : all) {
363 f.await_suspend(self);
365 co_await std::suspend_always();
366 co_return std::find_if(all.begin(), all.end(), [](
auto& f) { return f.done(); })->await_resume();
376 std::vector<TFuture<void>> all = std::move(futures);
378 if (std::find_if(all.begin(), all.end(), [](
auto& f) { return f.done(); }) != all.end()) {
382 auto self =
co_await Self();
383 for (
auto& f : all) {
384 f.await_suspend(self);
386 co_await std::suspend_always();
TFuture< T > Any(std::vector< TFuture< T > > &&futures)
Returns the result of whichever future completes first.
Definition corochain.hpp:353
TFuture< std::vector< T > > All(std::vector< TFuture< T > > &&futures)
Awaits every future in order and collects their results.
Definition corochain.hpp:317
Final awaiter for a coroutine.
Definition corochain.hpp:290
Base future type for coroutines.
Definition corochain.hpp:127
auto Accept(Func func) -> TFuture< void >
Registers a continuation to be executed after the coroutine completes.
Definition corochain.hpp:265
Owned coroutine handle that carries a result of type T.
Definition corochain.hpp:185
auto Apply(Func func) -> TFuture< decltype(func(std::declval< T >()))>
Applies a function to the result of the coroutine.
Definition corochain.hpp:207
TFuture< void > Ignore()
Awaits the coroutine and ignores its result.
Definition corochain.hpp:273
Base promise type for coroutines.
Definition corochain.hpp:83
std::coroutine_handle Caller
Handle to the caller coroutine (initialized to a no-operation coroutine).
Definition corochain.hpp:87
Promise for coroutines that return a value of type T.
Definition corochain.hpp:99
std::optional< std::expected< T, std::exception_ptr > > ErrorOr
Optional container that holds either the result or an exception.
Definition corochain.hpp:115