diff --git a/include/continuable/continuable-traverse-async.hpp b/include/continuable/continuable-traverse-async.hpp index b23d226..3614079 100644 --- a/include/continuable/continuable-traverse-async.hpp +++ b/include/continuable/continuable-traverse-async.hpp @@ -74,7 +74,7 @@ using async_traverse_in_place_tag = /// ```cpp /// struct my_async_visitor { /// /// The synchronous overload is called for each object, -/// /// it may return false to suspend the current control. +/// /// it may return false to suspend the current control flow. /// /// In that case the overload below is called. /// template /// bool operator()(async_traverse_visit_tag, T&& element) { diff --git a/include/continuable/detail/connection/connection-aggregated.hpp b/include/continuable/detail/connection/connection-aggregated.hpp index ad06059..61fb73e 100644 --- a/include/continuable/detail/connection/connection-aggregated.hpp +++ b/include/continuable/detail/connection/connection-aggregated.hpp @@ -85,7 +85,11 @@ public: : continuable_(std::move(continuable)) { } - continuable_base>&& fetch() { + auto const& peek() const { + return continuable_; + } + + auto&& fetch() { return std::move(continuable_); } @@ -97,8 +101,7 @@ public: } }; template -class continuable_box< - continuable_base>> { +class continuable_box>> { continuable_base> continuable_; lazy_value_t first_; @@ -109,7 +112,11 @@ public: : continuable_(std::move(continuable)) { } - continuable_base>&& fetch() { + auto const& peek() const { + return continuable_; + } + + auto&& fetch() { return std::move(continuable_); } @@ -125,20 +132,21 @@ template class continuable_box< continuable_base>> { - continuable_base> - continuable_; + continuable_base> continuable_; lazy_value_t> args_; public: explicit continuable_box( - continuable_base>&& + continuable_base>&& continuable) : continuable_(std::move(continuable)) { } - continuable_base>&& - fetch() { + auto const& peek() const { + return continuable_; + } + + auto&& fetch() { return std::move(continuable_); } diff --git a/include/continuable/detail/connection/connection-seq.hpp b/include/continuable/detail/connection/connection-seq.hpp index f9b07fe..f48e2e9 100644 --- a/include/continuable/detail/connection/connection-seq.hpp +++ b/include/continuable/detail/connection/connection-seq.hpp @@ -94,8 +94,18 @@ public: template >::value>* = nullptr> - bool operator()(async_traverse_visit_tag, Box&& /*box*/) { - return false; + bool operator()(async_traverse_visit_tag, Box&& box) { + if (base::attorney::is_ready(box.peek())) { + // The result can be resolved directly + traits::unpack( + [&](auto&&... args) mutable { + box.assign(std::forward(args)...); + }, + base::attorney::query(box.fetch())); + return true; + } else { + return false; + } } template diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 74b2e3e..186b2ca 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -178,6 +178,16 @@ struct attorney { static Data&& consume(continuable_base&& continuation) { return std::move(continuation).consume(); } + + template + static bool is_ready(Continuable&& continuation) noexcept { + return util::as_const(continuation.data_)(is_ready_arg_t{}); + } + + template + static auto query(continuable_base&& continuation) { + return std::move(continuation).consume()(query_arg_t{}); + } }; /// Returns the signature hint of the given continuable