mirror of
https://github.com/trafi/maybe-result-cpp
synced 2024-11-26 04:26:06 +01:00
Add map_err and some docs.
This commit is contained in:
parent
52c783731e
commit
dc721316df
@ -195,11 +195,40 @@ namespace maybe {
|
||||
return std::addressof(err_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a result<T, E> to result<U, E> (where U is return value of F(T)) by applying a function F to a
|
||||
* contained ok value, leaving an err value untouched.
|
||||
*
|
||||
* This function can be used to compose the results of two functions.
|
||||
*
|
||||
* @param f F(T) -> U
|
||||
* @return maybe::result<U, E>
|
||||
*/
|
||||
template <typename F>
|
||||
constexpr auto map(F f) noexcept -> maybe::result<typename std::result_of<F(T)>::type, E>;
|
||||
|
||||
/**
|
||||
* Maps a result<T, E> to result<T, U> (where U is return value of F(E)) by applying a function to a
|
||||
* contained err value, leaving an ok value untouched.
|
||||
*
|
||||
* This function can be used to pass through a successful result while changing an error.
|
||||
*
|
||||
* @param f F(E) -> U
|
||||
* @return maybe::result<T, U>
|
||||
*/
|
||||
template <typename F>
|
||||
constexpr auto and_then(F f) noexcept -> typename std::result_of<F(T)>::type;
|
||||
constexpr auto map_err(F f) noexcept -> maybe::result<T, typename std::result_of<F(E)>::type>;
|
||||
|
||||
/**
|
||||
* Calls op if the result is ok, otherwise returns the err value of self.
|
||||
*
|
||||
* This function can be used for control flow based on result values.
|
||||
*
|
||||
* @param f F(T) -> maybe::result<U, E>
|
||||
* @return maybe::result<U, E>
|
||||
*/
|
||||
template <typename F>
|
||||
constexpr auto and_then(F op) noexcept -> typename std::result_of<F(T)>::type;
|
||||
|
||||
private:
|
||||
constexpr void copy_from(const result<T, E>& other) noexcept;
|
||||
|
@ -109,6 +109,19 @@ constexpr auto maybe::result<T, E>::map(F f) noexcept
|
||||
return return_result_t::ok(f(std::forward<T>(ok_value())));
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
template <typename F>
|
||||
constexpr auto maybe::result<T, E>::map_err(F f) noexcept
|
||||
-> maybe::result<T, typename std::result_of<F(E)>::type>
|
||||
{
|
||||
typedef maybe::result<T, typename std::result_of<F(E)>::type> return_result_t;
|
||||
|
||||
if (is_ok()) {
|
||||
return return_result_t::ok(std::forward<T>(ok_value()));
|
||||
}
|
||||
return return_result_t::err(f(std::forward<E>(err_value())));
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
template <typename F>
|
||||
constexpr auto maybe::result<T, E>::and_then(F f) noexcept -> typename std::result_of<F(T)>::type
|
||||
|
@ -6,6 +6,7 @@ add_executable(${TARGET}
|
||||
main.cpp
|
||||
result_tests.cpp
|
||||
result_map_tests.cpp
|
||||
result_map_err_tests.cpp
|
||||
result_and_then_tests.cpp
|
||||
)
|
||||
|
||||
|
32
tests/result_map_err_tests.cpp
Normal file
32
tests/result_map_err_tests.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <maybe/result.hpp>
|
||||
|
||||
class A final {
|
||||
public:
|
||||
A(std::string value) : value(value)
|
||||
{
|
||||
}
|
||||
std::string value;
|
||||
};
|
||||
|
||||
using maybe::result;
|
||||
|
||||
TEST_CASE("result_map_err")
|
||||
{
|
||||
SECTION("converts err bool to err int")
|
||||
{
|
||||
auto a = result<A, bool>::err(true);
|
||||
auto b = a.map_err([](bool v) { return v ? 42 : 43; });
|
||||
REQUIRE(!b);
|
||||
REQUIRE(b.err_value() == 42);
|
||||
}
|
||||
|
||||
SECTION("does not convert anything and returns ok if not err")
|
||||
{
|
||||
auto a = result<A, bool>::ok(A("hi"));
|
||||
auto b = a.map_err([](bool v) { return v ? 42 : 43; });
|
||||
REQUIRE(b);
|
||||
REQUIRE(b.ok_value().value == "hi");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user