From 533e69f416f3c64aafbb378c85f246b84b7c0bd0 Mon Sep 17 00:00:00 2001 From: Kristian Duske Date: Mon, 29 Jun 2020 20:18:35 +0200 Subject: [PATCH] 2983: Add map_result function for void result --- lib/kdl/include/kdl/result.h | 56 ++++++++++++++++++++++++++++++++ lib/kdl/test/src/result_test.cpp | 9 +++++ 2 files changed, 65 insertions(+) diff --git a/lib/kdl/include/kdl/result.h b/lib/kdl/include/kdl/result.h index 6c22d71c2b..20abf6915e 100644 --- a/lib/kdl/include/kdl/result.h +++ b/lib/kdl/include/kdl/result.h @@ -462,6 +462,62 @@ namespace kdl { return visitor(); } } + + /** + * Applies the given function to given result and returns a new result with the result type of + * the given function as its value type. + * + * If the given result is a success, the function is applied and the result of applying the + * function is returned wrapped in a result. + * If the given result contains an error, that error is returned as is. + * + * @tparam F the type of the function to apply + * @param f the function to apply + * @param result_ the result to map + */ + template + friend auto map_result(F&& f, const result& result_) { + using R = std::invoke_result_t; + if constexpr (std::is_same_v) { + return visit_result(kdl::overload { + [&]() { f(); return result::success(); }, + [] (const auto& e) { return result::error(e); } + }, result_); + } else { + return visit_result(kdl::overload { + [&]() { return result::success(f()); }, + [] (const auto& e) { return result::error(e); } + }, result_); + } + } + + /** + * Applies the given function to given result and returns a new result with the result type of + * the given function as its value type. + * + * If the given result is a success, the function is applied and the result of applying the + * function is returned wrapped in a result. + * If the given result contains an error, that error is returned as is. + * + * @tparam F the type of the function to apply + * @param f the function to apply + * @param result_ the result to map + */ + template + friend auto map_result(F&& f, result&& result_) { + using R = std::invoke_result_t; + if constexpr (std::is_same_v) { + return visit_result(kdl::overload { + [&]() { f(); return result::success(); }, + [] (const auto& e) { return result::error(e); } + }, std::move(result_)); + } else { + return visit_result(kdl::overload { + [&]() { return result::success(f()); }, + [] (const auto& e) { return result::error(e); } + }, std::move(result_)); + } + } /** * Indicates whether this result is empty. diff --git a/lib/kdl/test/src/result_test.cpp b/lib/kdl/test/src/result_test.cpp index a72d3da472..2eff17c568 100644 --- a/lib/kdl/test/src/result_test.cpp +++ b/lib/kdl/test/src/result_test.cpp @@ -414,6 +414,15 @@ namespace kdl { test_visit_error_rvalue_ref_with_opt_value>(Counter{}); } + TEST_CASE("void_result_test.map", "[void_result_test]") { + CHECK(result::success(true) == map_result( + []() { return true; }, + result::success())); + CHECK(result::error(Error2{}) == map_result( + []() { return true; }, + result::error(Error2{}))); + } + TEST_CASE("opt_result_test.constructor", "[opt_result_test]") { ASSERT_TRUE((result, float, std::string>::success().is_success())); ASSERT_TRUE((result, float, std::string>::success(1).is_success()));