Resolve ready continuables directly in sequential connections

This commit is contained in:
Denis Blank 2018-12-10 06:22:53 +01:00
parent c7ef5c6f64
commit 30d49141a8
4 changed files with 41 additions and 13 deletions

View File

@ -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 <typename T>
/// bool operator()(async_traverse_visit_tag, T&& element) {

View File

@ -85,7 +85,11 @@ public:
: continuable_(std::move(continuable)) {
}
continuable_base<Data, traits::identity<>>&& fetch() {
auto const& peek() const {
return continuable_;
}
auto&& fetch() {
return std::move(continuable_);
}
@ -97,8 +101,7 @@ public:
}
};
template <typename Data, typename First>
class continuable_box<
continuable_base<Data, traits::identity<First>>> {
class continuable_box<continuable_base<Data, traits::identity<First>>> {
continuable_base<Data, traits::identity<First>> continuable_;
lazy_value_t<First> first_;
@ -109,7 +112,11 @@ public:
: continuable_(std::move(continuable)) {
}
continuable_base<Data, traits::identity<First>>&& fetch() {
auto const& peek() const {
return continuable_;
}
auto&& fetch() {
return std::move(continuable_);
}
@ -125,20 +132,21 @@ template <typename Data, typename First, typename Second, typename... Rest>
class continuable_box<
continuable_base<Data, traits::identity<First, Second, Rest...>>> {
continuable_base<Data, traits::identity<First, Second, Rest...>>
continuable_;
continuable_base<Data, traits::identity<First, Second, Rest...>> continuable_;
lazy_value_t<std::tuple<First, Second, Rest...>> args_;
public:
explicit continuable_box(
continuable_base<Data,
traits::identity<First, Second, Rest...>>&&
continuable_base<Data, traits::identity<First, Second, Rest...>>&&
continuable)
: continuable_(std::move(continuable)) {
}
continuable_base<Data, traits::identity<First, Second, Rest...>>&&
fetch() {
auto const& peek() const {
return continuable_;
}
auto&& fetch() {
return std::move(continuable_);
}

View File

@ -94,9 +94,19 @@ public:
template <typename Box, std::enable_if_t<aggregated::is_continuable_box<
std::decay_t<Box>>::value>* = nullptr>
bool operator()(async_traverse_visit_tag, Box&& /*box*/) {
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<decltype(args)>(args)...);
},
base::attorney::query(box.fetch()));
return true;
} else {
return false;
}
}
template <typename Box, typename N>
void operator()(async_traverse_detach_tag, Box&& box, N&& next) {

View File

@ -178,6 +178,16 @@ struct attorney {
static Data&& consume(continuable_base<Data, Annotation>&& continuation) {
return std::move(continuation).consume();
}
template <typename Continuable>
static bool is_ready(Continuable&& continuation) noexcept {
return util::as_const(continuation.data_)(is_ready_arg_t{});
}
template <typename Data, typename Annotation>
static auto query(continuable_base<Data, Annotation>&& continuation) {
return std::move(continuation).consume()(query_arg_t{});
}
};
/// Returns the signature hint of the given continuable