From 812420cf06f2069cd82d8fef6741d752089c7c73 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Mon, 26 Nov 2018 04:15:40 +0100 Subject: [PATCH] Unify the exception and result handler * Make the failure handler partial applyable --- include/continuable/detail/core/base.hpp | 72 +++--------------------- 1 file changed, 9 insertions(+), 63 deletions(-) diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 099d40e..755c1a9 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -326,8 +326,8 @@ constexpr auto invoker_of(traits::identity>) { inline auto exception_invoker_of(traits::identity) noexcept { return [](auto&& callback, auto&& next_callback, auto&&... args) { CONTINUABLE_BLOCK_TRY_BEGIN - util::invoke(std::forward(callback), - std::forward(args)...); + util::partial_invoke(std::forward(callback), + std::forward(args)...); // The legacy behaviour is not to proceed the chain // on the first invoked failure handler @@ -336,63 +336,9 @@ inline auto exception_invoker_of(traits::identity) noexcept { }; } -inline auto exception_invoker_of(traits::identity) noexcept { - return [](auto&& callback, auto&& next_callback, auto&&... args) { - CONTINUABLE_BLOCK_TRY_BEGIN - empty_result result = - util::invoke(std::forward(callback), - std::forward(args)...); - - // Don't invoke anything here since returning an empty result - // cancels the asynchronous chain effectively. - (void)result; - CONTINUABLE_BLOCK_TRY_END - }; -} - -inline auto -exception_invoker_of(traits::identity) noexcept { - return [](auto&& callback, auto&& next_callback, auto&&... args) { - CONTINUABLE_BLOCK_TRY_BEGIN - exceptional_result result = - util::invoke(std::forward(callback), - std::forward(args)...); - - // Rethrow the exception to the next handler - invoke_no_except(std::forward(next_callback), - exception_arg_t{}, std::move(result).get_exception()); - CONTINUABLE_BLOCK_TRY_END - }; -} - -template -auto exception_invoker_of(traits::identity>) noexcept { - return [](auto&& callback, auto&& next_callback, auto&&... args) { - CONTINUABLE_BLOCK_TRY_BEGIN - result result = - util::invoke(std::forward(callback), - std::forward(args)...); - - if (result.is_value()) { - // Workaround for MSVC not capturing the reference - // correctly inside the lambda. - - using Next = decltype(next_callback); - - result_trait::visit( - std::move(result), // - [&](auto&&... values) { - invoke_no_except(std::forward(next_callback), - std::forward(values)...); - }); - - } else if (result.is_exception()) { - // Forward the exception to the next available handler - invoke_no_except(std::forward(next_callback), - exception_arg_t{}, std::move(result).get_exception()); - } - CONTINUABLE_BLOCK_TRY_END - }; +template +auto exception_invoker_of(Other other) noexcept { + return invoker_of(other); } #undef CONTINUABLE_BLOCK_TRY_BEGIN @@ -496,8 +442,8 @@ struct error_handler_base { /// The operator which is called when an error occurred void operator()(exception_arg_t, exception_t exception) && { constexpr auto result = traits::identify(this)->callback_), - std::move(exception)))>{}; + util::partial_invoke(std::move(static_cast(this)->callback_), + std::move(exception)))>{}; auto invoker = decoration::exception_invoker_of(result); @@ -514,8 +460,8 @@ struct error_handler_base { /// The operator which is called when an error occurred void operator()(exception_arg_t, exception_t exception) && { constexpr auto result = traits::identify(this)->callback_), - exception_arg_t{}, std::move(exception)))>{}; + util::partial_invoke(std::move(static_cast(this)->callback_), + exception_arg_t{}, std::move(exception)))>{}; auto invoker = decoration::exception_invoker_of(result);