diff --git a/include/continuable/detail/other/coroutines.hpp b/include/continuable/detail/other/coroutines.hpp index e1304d3..2ec98ba 100644 --- a/include/continuable/detail/other/coroutines.hpp +++ b/include/continuable/detail/other/coroutines.hpp @@ -33,12 +33,12 @@ #define CONTINUABLE_DETAIL_AWAITING_HPP_INCLUDED #include -#include #include #include #include #include #include +#include #include #include #include @@ -77,17 +77,28 @@ class awaitable { public: explicit constexpr awaitable(Continuable&& continuable) : continuable_(std::move(continuable)) { + + // If the continuable is ready resolve the result from the + // continuable immediatly. + if (base::attorney::is_ready(continuable_)) { + traits::unpack( + [&](auto&&... args) { + resolve(std::forward(args)...); + }, + base::attorney::query(std::move(continuable_))); + } } /// Since continuables are evaluated lazily we are not /// capable to say whether the resumption will be instantly. bool await_ready() const noexcept { - return false; + return !result_.is_empty(); } /// Suspend the current context // TODO Convert this to an r-value function once possible void await_suspend(coroutine_handle<> h) { + assert(result_.is_empty()); // Forward every result to the current awaitable std::move(continuable_) .next([h, this](auto&&... args) mutable { @@ -116,11 +127,13 @@ private: /// Resolve the continuation through the result template void resolve(Args&&... args) { + assert(result_.is_empty()); result_.set_value(std::forward(args)...); } /// Resolve the continuation through an error void resolve(exception_arg_t, exception_t exception) { + assert(result_.is_empty()); result_.set_exception(std::move(exception)); } };