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);
|
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>
|
template <typename F>
|
||||||
constexpr auto map(F f) noexcept -> maybe::result<typename std::result_of<F(T)>::type, E>;
|
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>
|
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:
|
private:
|
||||||
constexpr void copy_from(const result<T, E>& other) noexcept;
|
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())));
|
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 T, typename E>
|
||||||
template <typename F>
|
template <typename F>
|
||||||
constexpr auto maybe::result<T, E>::and_then(F f) noexcept -> typename std::result_of<F(T)>::type
|
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
|
main.cpp
|
||||||
result_tests.cpp
|
result_tests.cpp
|
||||||
result_map_tests.cpp
|
result_map_tests.cpp
|
||||||
|
result_map_err_tests.cpp
|
||||||
result_and_then_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