From 4b1f6281fce725723cf68251eb1e389382dfef72 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sat, 8 Dec 2018 05:53:44 +0100 Subject: [PATCH] Initial work on wrapping all continuations into the triple path schema --- include/continuable/continuable-base.hpp | 26 +++----- include/continuable/continuable-trait.hpp | 6 +- .../detail/connection/connection.hpp | 2 +- .../continuable/detail/core/annotation.hpp | 6 +- include/continuable/detail/core/base.hpp | 63 ++++++++++++------- 5 files changed, 58 insertions(+), 45 deletions(-) diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index b1f469b..e923baa 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -811,14 +811,9 @@ constexpr auto make_continuable(Continuation&& continuation) { "use make_continuable(...). Continuables with an exact " "signature may be created through make_continuable."); - using hint_t = detail::traits::identity; - using continuation_t = - detail::base::proxy_continuable>; - return detail::base::attorney::create_from( - continuation_t{std::forward(continuation)}, - typename detail::hints::from_explicit::type{}, + std::forward(continuation), + typename detail::hints::from_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(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 auto make_ready_continuable(Args&&... args) { - return make_continuable...>( - detail::base::ready_continuation...>( - std::forward(args)...)); + using detail::base::ready_continuation; + using detail::traits::identity; + using detail::traits::unrefcv_t; + return detail::base::attorney::create_from_raw( + ready_continuation...>{std::forward(args)...}, + identity...>{}, detail::util::ownership{}); } /// Returns a continuable_base with the parameterized result which instantly diff --git a/include/continuable/continuable-trait.hpp b/include/continuable/continuable-trait.hpp index 531f87d..4e69507 100644 --- a/include/continuable/continuable-trait.hpp +++ b/include/continuable/continuable-trait.hpp @@ -32,6 +32,7 @@ #define CONTINUABLE_TRAIT_HPP_INCLUDED #include +#include #include #include #include @@ -70,7 +71,10 @@ public: /// The continuable type for the given parameters. using continuable = continuable_base< ContinuationWrapper), - void(promise)>, + void(promise), // + bool(is_ready_arg_t) const, // + std::tuple(query_arg_t) // + >, detail::traits::identity>; }; /// \} diff --git a/include/continuable/detail/connection/connection.hpp b/include/continuable/detail/connection/connection.hpp index 4e0f9aa..025c23d 100644 --- a/include/continuable/detail/connection/connection.hpp +++ b/include/continuable/detail/connection/connection.hpp @@ -114,7 +114,7 @@ auto connect(Strategy strategy, continuable_base&& 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: diff --git a/include/continuable/detail/core/annotation.hpp b/include/continuable/detail/core/annotation.hpp index 88e1924..29a8d1b 100644 --- a/include/continuable/detail/core/annotation.hpp +++ b/include/continuable/detail/core/annotation.hpp @@ -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 -struct from_explicit; template -struct from_explicit> +struct from_args : std::common_type> {}; template <> -struct from_explicit> +struct from_args : std::common_type> {}; } // namespace hints } // namespace detail diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 507bd88..1ffbb82 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -92,7 +92,7 @@ struct ready_continuation { return true; } - std::tuple operator()(query_arg_t) && { + std::tuple 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, Continuation> return false; } - std::tuple operator()(query_arg_t) && { + std::tuple 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>> - static auto create_from(T&& continuation, A annotation, - util::ownership ownership) { - (void)annotation; - return Continuable({std::forward(continuation)}, ownership); + /// Creates a continuable_base from the given continuation, + /// annotation and ownership. + template + static auto create_from_raw(T&& continuation, Annotation, + util::ownership ownership) { + using continuation_t = continuable_base, // + traits::unrefcv_t>; + return continuation_t({std::forward(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 + static auto create_from(T&& continuation, Hint, util::ownership ownership) { + using hint_t = traits::unrefcv_t; + using proxy_t = proxy_continuable>; + return continuable_base( + proxy_t{std::forward(continuation)}, ownership); } /// Returns the ownership of the given continuable_base @@ -744,17 +755,27 @@ struct chained_continuation, HandleResults, std::move(callback_), std::move(executor_), std::forward(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 operator()(query_arg_t) && { + std::tuple operator()(query_arg_t) { util::unreachable(); } }; @@ -791,10 +812,10 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback, traits::unrefcv_t, traits::unrefcv_t>; - return attorney::create_from(continuation_t(std::move(data), - std::forward(callback), - std::forward(executor)), - next_hint, ownership); + return attorney::create_from_raw( + continuation_t(std::move(data), std::forward(callback), + std::forward(executor)), + next_hint, ownership); } /// Final invokes the given continuation chain: