Skip to content

Commit

Permalink
2983: Add map_result function for void result
Browse files Browse the repository at this point in the history
  • Loading branch information
kduske committed Jul 14, 2020
1 parent 030b4e5 commit 533e69f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
56 changes: 56 additions & 0 deletions lib/kdl/include/kdl/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename F>
friend auto map_result(F&& f, const result& result_) {
using R = std::invoke_result_t<F>;
if constexpr (std::is_same_v<R, void>) {
return visit_result(kdl::overload {
[&]() { f(); return result<R, Errors...>::success(); },
[] (const auto& e) { return result<R, Errors...>::error(e); }
}, result_);
} else {
return visit_result(kdl::overload {
[&]() { return result<R, Errors...>::success(f()); },
[] (const auto& e) { return result<R, Errors...>::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 <typename F>
friend auto map_result(F&& f, result&& result_) {
using R = std::invoke_result_t<F>;
if constexpr (std::is_same_v<R, void>) {
return visit_result(kdl::overload {
[&]() { f(); return result<R, Errors...>::success(); },
[] (const auto& e) { return result<R, Errors...>::error(e); }
}, std::move(result_));
} else {
return visit_result(kdl::overload {
[&]() { return result<R, Errors...>::success(f()); },
[] (const auto& e) { return result<R, Errors...>::error(e); }
}, std::move(result_));
}
}

/**
* Indicates whether this result is empty.
Expand Down
9 changes: 9 additions & 0 deletions lib/kdl/test/src/result_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,15 @@ namespace kdl {
test_visit_error_rvalue_ref_with_opt_value<result<void, Counter, Error2>>(Counter{});
}

TEST_CASE("void_result_test.map", "[void_result_test]") {
CHECK(result<bool, Error1, Error2>::success(true) == map_result(
[]() { return true; },
result<void, Error1, Error2>::success()));
CHECK(result<bool, Error1, Error2>::error(Error2{}) == map_result(
[]() { return true; },
result<void, Error1, Error2>::error(Error2{})));
}

TEST_CASE("opt_result_test.constructor", "[opt_result_test]") {
ASSERT_TRUE((result<opt<int>, float, std::string>::success().is_success()));
ASSERT_TRUE((result<opt<int>, float, std::string>::success(1).is_success()));
Expand Down

0 comments on commit 533e69f

Please sign in to comment.