Initial work on wrapping all continuations into the triple path schema

This commit is contained in:
Denis Blank 2018-12-08 05:53:44 +01:00
parent cb6ce5b43b
commit 4b1f6281fc
5 changed files with 58 additions and 45 deletions

View File

@ -811,14 +811,9 @@ constexpr auto make_continuable(Continuation&& continuation) {
"use make_continuable<void>(...). Continuables with an exact "
"signature may be created through make_continuable<Args...>.");
using hint_t = detail::traits::identity<Args...>;
using continuation_t =
detail::base::proxy_continuable<hint_t,
detail::traits::unrefcv_t<Continuation>>;
return detail::base::attorney::create_from(
continuation_t{std::forward<Continuation>(continuation)},
typename detail::hints::from_explicit<hint_t>::type{},
std::forward<Continuation>(continuation),
typename detail::hints::from_args<Args...>::type{},
detail::util::ownership{});
}
@ -832,19 +827,14 @@ constexpr auto make_continuable(Continuation&& continuation) {
/// function calls.
///
/// \since 3.0.0
inline auto make_ready_continuable() {
return make_continuable<void>(detail::base::ready_continuation<>());
}
/// Returns a continuable_base with one result value which instantly resolves
/// the promise with the given value.
///
/// \copydetails make_ready_continuable()
template <typename... Args>
auto make_ready_continuable(Args&&... args) {
return make_continuable<std::decay_t<Args>...>(
detail::base::ready_continuation<std::decay_t<Args>...>(
std::forward<Args>(args)...));
using detail::base::ready_continuation;
using detail::traits::identity;
using detail::traits::unrefcv_t;
return detail::base::attorney::create_from_raw(
ready_continuation<unrefcv_t<Args>...>{std::forward<Args>(args)...},
identity<unrefcv_t<Args>...>{}, detail::util::ownership{});
}
/// Returns a continuable_base with the parameterized result which instantly

View File

@ -32,6 +32,7 @@
#define CONTINUABLE_TRAIT_HPP_INCLUDED
#include <cstddef>
#include <tuple>
#include <continuable/continuable-base.hpp>
#include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-promise-base.hpp>
@ -70,7 +71,10 @@ public:
/// The continuable type for the given parameters.
using continuable = continuable_base<
ContinuationWrapper<sizeof(detail::base::ready_continuation<Args...>),
void(promise)>,
void(promise), //
bool(is_ready_arg_t) const, //
std::tuple<Args...>(query_arg_t) //
>,
detail::traits::identity<Args...>>;
};
/// \}

View File

@ -114,7 +114,7 @@ auto connect(Strategy strategy, continuable_base<LData, LAnnotation>&& left,
// Return a new continuable containing the tuple and holding
// the current strategy as annotation.
return base::attorney::create_from(std::move(data), strategy, ownership_);
return base::attorney::create_from_raw(std::move(data), strategy, ownership_);
}
/// All strategies should specialize this class in order to provide:

View File

@ -56,13 +56,11 @@ namespace hints {
/// from an argument pack as specified by make_continuable.
///
/// This is the overload taking an arbitrary amount of args
template <typename Hint>
struct from_explicit;
template <typename... HintArgs>
struct from_explicit<traits::identity<HintArgs...>>
struct from_args
: std::common_type<traits::identity<HintArgs...>> {};
template <>
struct from_explicit<traits::identity<void>>
struct from_args<void>
: std::common_type<traits::identity<>> {};
} // namespace hints
} // namespace detail

View File

@ -92,7 +92,7 @@ struct ready_continuation {
return true;
}
std::tuple<Args...> operator()(query_arg_t) && {
std::tuple<Args...> operator()(query_arg_t) {
return std::move(values_);
}
};
@ -114,7 +114,7 @@ struct ready_continuation<> {
return true;
}
std::tuple<> operator()(query_arg_t) && {
std::tuple<> operator()(query_arg_t) {
return std::make_tuple();
}
};
@ -141,21 +141,32 @@ struct proxy_continuable<traits::identity<Args...>, Continuation>
return false;
}
std::tuple<Args...> operator()(query_arg_t) && {
std::tuple<Args...> operator()(query_arg_t) {
util::unreachable();
}
};
struct attorney {
/// Creates a continuable_base from the given continuation, annotation
/// and ownership.
template <
typename T, typename A,
typename Continuable = continuable_base<std::decay_t<T>, std::decay_t<A>>>
static auto create_from(T&& continuation, A annotation,
util::ownership ownership) {
(void)annotation;
return Continuable({std::forward<T>(continuation)}, ownership);
/// Creates a continuable_base from the given continuation,
/// annotation and ownership.
template <typename T, typename Annotation>
static auto create_from_raw(T&& continuation, Annotation,
util::ownership ownership) {
using continuation_t = continuable_base<traits::unrefcv_t<T>, //
traits::unrefcv_t<Annotation>>;
return continuation_t({std::forward<T>(continuation)}, ownership);
}
/// Creates a continuable_base from the given continuation,
/// annotation and ownership.
/// This wraps the continuable to contain the is_ready and query method
/// implemented empty.
template <typename T, typename Hint>
static auto create_from(T&& continuation, Hint, util::ownership ownership) {
using hint_t = traits::unrefcv_t<Hint>;
using proxy_t = proxy_continuable<hint_t, traits::unrefcv_t<T>>;
return continuable_base<proxy_t, hint_t>(
proxy_t{std::forward<T>(continuation)}, ownership);
}
/// Returns the ownership of the given continuable_base
@ -744,17 +755,27 @@ struct chained_continuation<traits::identity<Args...>, HandleResults,
std::move(callback_), std::move(executor_),
std::forward<decltype(next_callback)>(next_callback));
// Invoke the continuation with a proxy callback.
// The proxy callback is responsible for passing
// the result to the callback as well as decorating it.
util::invoke(std::move(continuation_), std::move(proxy));
// TODO Detect statically whether we have a raw ready continuable here
// Check whether the continuation is ready
bool const is_ready = continuation_(is_ready_arg_t{});
if (is_ready) {
// Invoke the proxy callback directly with the result to
// avoid a potential type erasure.
// traits::unpack(std::move(proxy),
// std::move(continuation_)(query_arg_t{}));
} else {
// Invoke the continuation with a proxy callback.
// The proxy callback is responsible for passing
// the result to the callback as well as decorating it.
util::invoke(std::move(continuation_), std::move(proxy));
}
}
bool operator()(is_ready_arg_t) const noexcept {
return false;
}
std::tuple<Args...> operator()(query_arg_t) && {
std::tuple<Args...> operator()(query_arg_t) {
util::unreachable();
}
};
@ -791,10 +812,10 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback,
traits::unrefcv_t<Callback>,
traits::unrefcv_t<Executor>>;
return attorney::create_from(continuation_t(std::move(data),
std::forward<Callback>(callback),
std::forward<Executor>(executor)),
next_hint, ownership);
return attorney::create_from_raw(
continuation_t(std::move(data), std::forward<Callback>(callback),
std::forward<Executor>(executor)),
next_hint, ownership);
}
/// Final invokes the given continuation chain: