From 07c8ed0cf9472186dc178955083e3e7d0109d659 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sun, 25 Nov 2018 02:54:35 +0100 Subject: [PATCH] Add invoker for the result class and specialized ones --- include/continuable/continuable-result.hpp | 9 +++ include/continuable/detail/core/base.hpp | 74 ++++++++++++++++++---- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/include/continuable/continuable-result.hpp b/include/continuable/continuable-result.hpp index 4441a3d..bd48cbe 100644 --- a/include/continuable/continuable-result.hpp +++ b/include/continuable/continuable-result.hpp @@ -182,6 +182,15 @@ public: } }; +template +struct is_result : std::false_type {}; +template +struct is_result> : std::true_type {}; +template <> +struct is_result : std::true_type {}; +template <> +struct is_result : std::true_type {}; + template constexpr auto make_result(T&&... values) { return result...>(std::forward(values)...); diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 2f93595..faf83a0 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -159,9 +159,9 @@ constexpr auto make_invoker(T&& invoke, hints::signature_hint_tag) { } /// - continuable -> result(next_callback); -template +template constexpr auto -invoker_of(traits::identity>) { +invoker_of(Hint, traits::identity>) { /// Get the hint of the unwrapped returned continuable using Type = decltype(std::declval>().finish()); @@ -184,8 +184,8 @@ invoker_of(traits::identity>) { } /// - ? -> next_callback(?) -template -constexpr auto invoker_of(traits::identity) { +template +constexpr auto invoker_of(Hint, traits::identity) { return make_invoker( [](auto&& callback, auto&& next_callback, auto&&... args) { CONTINUABLE_BLOCK_TRY_BEGIN @@ -201,7 +201,8 @@ constexpr auto invoker_of(traits::identity) { } /// - void -> next_callback() -inline auto invoker_of(traits::identity) { +template +auto invoker_of(Hint, traits::identity) { return make_invoker( [](auto&& callback, auto&& next_callback, auto&&... args) { CONTINUABLE_BLOCK_TRY_BEGIN @@ -214,6 +215,51 @@ inline auto invoker_of(traits::identity) { traits::identity<>{}); } +/// - empty_result -> +template +auto invoker_of(Hint, traits::identity) { + return make_invoker( + [](auto&& callback, auto&& next_callback, auto&&... args) { + /*CONTINUABLE_BLOCK_TRY_BEGIN + util::partial_invoke(std::forward(callback), + std::forward(args)...); + invoke_no_except( + std::forward(next_callback)); + CONTINUABLE_BLOCK_TRY_END*/ + }, + Hint{}); +} + +/// - exceptional_result -> Hint +template +auto invoker_of(Hint, traits::identity) { + return make_invoker( + [](auto&& callback, auto&& next_callback, auto&&... args) { + /*CONTINUABLE_BLOCK_TRY_BEGIN + util::partial_invoke(std::forward(callback), + std::forward(args)...); + invoke_no_except( + std::forward(next_callback)); + CONTINUABLE_BLOCK_TRY_END*/ + }, + Hint{}); +} + +/// - result -> Args... +template +auto invoker_of(Hint, traits::identity>) { + return make_invoker( + [](auto&& callback, auto&& next_callback, auto&&... args) { + /*CONTINUABLE_BLOCK_TRY_BEGIN + util::partial_invoke(std::forward(callback), + std::forward(args)...); + invoke_no_except( + std::forward(next_callback)); + CONTINUABLE_BLOCK_TRY_END*/ + }, + traits::identity{}); +} + /// Returns a sequenced invoker which is able to invoke /// objects where std::get is applicable. inline auto sequenced_unpack_invoker() { @@ -240,15 +286,15 @@ inline auto sequenced_unpack_invoker() { } // namespace decoration // - std::pair -> next_callback(?, ?) -template -constexpr auto invoker_of(traits::identity>) { +template +constexpr auto invoker_of(Hint, traits::identity>) { return make_invoker(sequenced_unpack_invoker(), traits::identity{}); } // - std::tuple -> next_callback(?...) -template -constexpr auto invoker_of(traits::identity>) { +template +constexpr auto invoker_of(Hint, traits::identity>) { return make_invoker(sequenced_unpack_invoker(), traits::identity{}); } @@ -327,7 +373,9 @@ struct result_handler_base(this)->callback_), std::move(args)...))>{}; // Pick the correct invoker that handles decorating of the result - auto invoker = decoration::invoker_of(result); + auto invoker = + decoration::invoker_of(hints::signature_hint_tag{}, // + result); // Invoke the callback packed_dispatch(std::move(static_cast(this)->executor_), @@ -493,13 +541,15 @@ template constexpr auto next_hint_of(std::integral_constant, traits::identity /*callback*/, - hints::signature_hint_tag /*current*/) { + hints::signature_hint_tag current) { // Partial Invoke the given callback using Result = decltype( util::partial_invoke(std::declval(), std::declval()...)); // Return the hint of thr given invoker - return decltype(decoration::invoker_of(traits::identify{}).hint()){}; + return decltype(decoration::invoker_of(current, // + traits::identify{}) + .hint()){}; } /// Don't progress the hint when we don't continue template