diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index 28bb73f..8f280f3 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -564,7 +564,8 @@ public: #ifdef CONTINUABLE_HAS_DOXYGEN /// Materializes the continuation expression template and finishes - /// the current applied strategy. + /// the current applied strategy such that the resulting continuable + /// will always be a concrete type and Continuable::is_concrete holds. /// /// This can be used in the case where we are chaining continuations lazily /// through a strategy, for instance when applying operators for @@ -589,24 +590,6 @@ public: unspecified finish() &&; #endif // CONTINUABLE_HAS_DOXYGEN -#ifdef CONTINUABLE_HAS_DOXYGEN - /// Returns true if the continuable_base will resolve its promise - /// immediately on request. - /// - /// \since 4.0.0 - bool is_ready() const noexcept; -#endif // CONTINUABLE_HAS_DOXYGEN - -#ifdef CONTINUABLE_HAS_DOXYGEN - /// Returns the result of this continuable immediatly. - /// - /// \attention requires that this continuable resolves immediatly on - /// request which means that is_ready() holds. - /// - /// \since 4.0.0 - unspecified request() &&; -#endif // CONTINUABLE_HAS_DOXYGEN - /// Predicate to check whether the cti::continuable_base is frozen or not. /// /// \returns Returns true when the continuable_base is frozen. @@ -840,6 +823,7 @@ constexpr auto make_continuable(Continuation&& continuation) { "use make_continuable(...). Continuables with an exact " "signature may be created through make_continuable."); + // TODO return detail::base::attorney::create_from( std::forward(continuation), detail::hints::from_explicit(detail::traits::identity{}), @@ -857,7 +841,7 @@ constexpr auto make_continuable(Continuation&& continuation) { /// /// \since 3.0.0 inline auto make_ready_continuable() { - return make_continuable(detail::base::ready_continuable<>()); + return make_continuable(detail::base::ready_continuation<>()); } /// Returns a continuable_base with one result value which instantly resolves @@ -867,7 +851,7 @@ inline auto make_ready_continuable() { template auto make_ready_continuable(Args&&... args) { return make_continuable...>( - detail::base::ready_continuable...>( + detail::base::ready_continuation...>( std::forward(args)...)); } diff --git a/include/continuable/continuable-trait.hpp b/include/continuable/continuable-trait.hpp index cbf40a0..531f87d 100644 --- a/include/continuable/continuable-trait.hpp +++ b/include/continuable/continuable-trait.hpp @@ -69,7 +69,7 @@ public: /// The continuable type for the given parameters. using continuable = continuable_base< - ContinuationWrapper), + ContinuationWrapper), void(promise)>, detail::traits::identity>; }; diff --git a/include/continuable/detail/connection/connection.hpp b/include/continuable/detail/connection/connection.hpp index 44de863..4e0f9aa 100644 --- a/include/continuable/detail/connection/connection.hpp +++ b/include/continuable/detail/connection/connection.hpp @@ -143,8 +143,6 @@ struct connection_annotation_trait { return finalizer::finalize(std::move(connection), std::move(ownership)); } }; - - using is_concrete = std::false_type; }; class prepare_continuables { diff --git a/include/continuable/detail/core/annotation.hpp b/include/continuable/detail/core/annotation.hpp index f7e64d4..03cb20c 100644 --- a/include/continuable/detail/core/annotation.hpp +++ b/include/continuable/detail/core/annotation.hpp @@ -48,11 +48,7 @@ struct annotation_trait> { Continuable&& finish() { return std::move(*static_cast(this)); } - - static constexpr bool is_concrete = true; }; - - using is_concrete = std::true_type; }; namespace hints { diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 5d0af04..915eeca 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -70,15 +70,17 @@ template struct is_continuable> : std::true_type {}; template -struct ready_continuable { +struct ready_continuation { std::tuple values_; - ready_continuable(ready_continuable&&) = default; - ready_continuable(ready_continuable const&) = default; - ready_continuable& operator=(ready_continuable&&) = default; - ready_continuable& operator=(ready_continuable const&) = default; + ready_continuation() = delete; + ~ready_continuation() = default; + ready_continuation(ready_continuation&&) = default; + ready_continuation(ready_continuation const&) = delete; + ready_continuation& operator=(ready_continuation&&) = default; + ready_continuation& operator=(ready_continuation const&) = delete; - explicit ready_continuable(Args... values) : values_(std::move(values)...) { + explicit ready_continuation(Args... values) : values_(std::move(values)...) { } template @@ -86,43 +88,36 @@ struct ready_continuable { traits::unpack(std::forward(callback), std::move(values_)); } - /*bool operator()(is_ready_arg_t) const noexcept { + bool operator()(is_ready_arg_t) const noexcept { return true; } std::tuple operator()(get_arg_t) && { return std::move(values_); - }*/ + } }; template <> -struct ready_continuable<> { +struct ready_continuation<> { + ready_continuation() = default; + ~ready_continuation() = default; + ready_continuation(ready_continuation&&) = default; + ready_continuation(ready_continuation const&) = delete; + ready_continuation& operator=(ready_continuation&&) = default; + ready_continuation& operator=(ready_continuation const&) = delete; + template void operator()(Callback&& callback) { util::invoke(std::forward(callback)); } - /*bool operator()(is_ready_arg_t) const noexcept { - return true; - } - - void operator()(get_arg_t) && { - }*/ -}; - -/*template -struct proxy_continuable : Continuation { - using Continuation::Continuation; - - using Continuation::operator(); - bool operator()(is_ready_arg_t) const noexcept { - return false; + return true; } - std::tuple operator()(get_arg_t) && { - util::unreachable(); + std::tuple<> operator()(get_arg_t) && { + return std::make_tuple(); } -};*/ +}; struct attorney { /// Creates a continuable_base from the given continuation, annotation @@ -681,13 +676,71 @@ auto strip_exception_arg(Callable&& callable) { return proxy{std::forward(callable)}; } -/// Chains a callback together with a continuation and returns a continuation: +template +struct chained_continuation; +template +struct chained_continuation, HandleResults, + HandleErrors, Continuation, Callback, Executor> { + Continuation continuation_; + Callback callback_; + Executor executor_; + + explicit chained_continuation(Continuation continuation, Callback callback, + Executor executor) + : continuation_(std::move(continuation)), callback_(std::move(callback)), + executor_(std::move(executor)) { + } + + chained_continuation() = delete; + ~chained_continuation() = default; + chained_continuation(chained_continuation const&) = delete; + chained_continuation(chained_continuation&&) = default; + chained_continuation& operator=(chained_continuation const&) = delete; + chained_continuation& operator=(chained_continuation&&) = default; + + template + void operator()(NextCallback&& next_callback) { + // Invokes a continuation with a given callback. + // Passes the next callback to the resulting continuable or + // invokes the next callback directly if possible. + // + // For example given: + // - Continuation: continuation<[](auto&& callback) { callback("hi"); }> + // - Callback: [](std::string) { } + // - NextCallback: []() { } + auto proxy = callbacks::make_callback, + HandleResults, HandleErrors>( + 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. + invoke_continuation(std::move(continuation_), std::move(proxy)); + } + + bool operator()(is_ready_arg_t) const noexcept { + return false; + } + + std::tuple operator()(get_arg_t) && { + util::unreachable(); + } +}; + +/// Chains a callback together with a continuation and returns a +/// continuation: /// /// For example given: /// - Continuation: continuation<[](auto&& callback) { callback("hi"); }> /// - Callback: [](std::string) { } /// -/// This function returns a function accepting the next callback in the chain: +/// This function returns a function accepting the next callback in the +/// chain: /// - Result: continuation<[](auto&& callback) { /*...*/ }> /// template (continuation), - callback = std::forward(callback), - executor = std::forward(executor)] // - (auto&& next_callback) mutable { - // Invokes a continuation with a given callback. - // Passes the next callback to the resulting continuable or - // invokes the next callback directly if possible. - // - // For example given: - // - Continuation: continuation<[](auto&& callback) { callback("hi"); }> - // - Callback: [](std::string) { } - // - NextCallback: []() { } - auto proxy = - callbacks::make_callback( - std::move(callback), std::move(executor), - std::forward(next_callback)); + using continuation_t = chained_continuation< + Hint, HandleResults, HandleErrors, traits::unrefcv_t, + traits::unrefcv_t, traits::unrefcv_t>; - // Invoke the continuation with a proxy callback. - // The proxy callback is responsible for passing - // the result to the callback as well as decorating it. - invoke_continuation(std::move(continuation), std::move(proxy)); - }, + return attorney::create_from( + continuation_t(std::forward(continuation), + std::forward(callback), + std::forward(executor)), next_hint, ownership_); }