From 9955f9e469c52958cf2469e89934f9418c17633e Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Mon, 26 Nov 2018 02:19:16 +0100 Subject: [PATCH] Add the invoker for result<...> --- include/continuable/continuable-result.hpp | 1 + include/continuable/detail/core/base.hpp | 27 +++++++++---------- .../detail/utility/flat-variant.hpp | 3 +++ .../detail/utility/result-trait.hpp | 17 ++++++++++++ 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/include/continuable/continuable-result.hpp b/include/continuable/continuable-result.hpp index 0324b88..7c62dc0 100644 --- a/include/continuable/continuable-result.hpp +++ b/include/continuable/continuable-result.hpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace cti { /// \defgroup Result Result diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 8faba9f..b427716 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -260,23 +261,23 @@ auto invoker_of(traits::identity>) { result result = util::partial_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); - traits::unpack( - [&](auto&&... types) { - /// TODO Add inplace resolution here - - invoke_no_except(std::forward(next_callback), - std::forward(types)...); - }, - std::move(result)); + 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()); } // Otherwise the result is empty and we are cancelling our @@ -300,11 +301,9 @@ inline auto sequenced_unpack_invoker() { using Next = decltype(next_callback); traits::unpack( - [&](auto&&... types) { - /// TODO Add inplace resolution here - + [&](auto&&... values) { invoke_no_except(std::forward(next_callback), - std::forward(types)...); + std::forward(values)...); }, std::move(result)); CONTINUABLE_BLOCK_TRY_END diff --git a/include/continuable/detail/utility/flat-variant.hpp b/include/continuable/detail/utility/flat-variant.hpp index 25f42d6..38a1ec4 100644 --- a/include/continuable/detail/utility/flat-variant.hpp +++ b/include/continuable/detail/utility/flat-variant.hpp @@ -359,6 +359,9 @@ private: #endif } detail::slot_t get_slot() const noexcept { + // Check for invalid values especially for memory corruption, + // the empty element is included. + assert(this->slot_ <= sizeof...(T)); return this->slot_; } bool is_slot(detail::slot_t const slot) const noexcept { diff --git a/include/continuable/detail/utility/result-trait.hpp b/include/continuable/detail/utility/result-trait.hpp index cd18296..9d7012b 100644 --- a/include/continuable/detail/utility/result-trait.hpp +++ b/include/continuable/detail/utility/result-trait.hpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace cti { namespace detail { @@ -52,6 +53,10 @@ struct result_trait<> { static constexpr void unwrap(surrogate_t) { } + + template + static void visit(Result&& /*result*/, Mapper&& /*mapper*/) { + } }; template struct result_trait { @@ -66,6 +71,12 @@ struct result_trait { static decltype(auto) unwrap(R&& unwrap) { return std::forward(unwrap); } + + template + static auto visit(Result&& result, Mapper&& mapper) { + return util::invoke(std::forward(mapper), + std::forward(result).get_value()); + } }; template struct result_trait { @@ -81,6 +92,12 @@ struct result_trait { static decltype(auto) unwrap(R&& unwrap) { return std::forward(unwrap); } + + template + static auto visit(Result&& result, Mapper&& mapper) { + return traits::unpack(std::forward(mapper), + std::forward(result).get_value()); + } }; } // namespace detail } // namespace cti