API reference¶
is_ok¶
basic_result<_, T, E> → bool
Returns true if the result is success
.
declarations
template <mutability _mu, class T, class E>
class basic_result {
constexpr bool is_ok() const noexcept ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<unsigned, std::string> x = success(3);
assert(x.is_ok() == true);
result<unsigned, std::string> y = failure("Some error message"s);
assert(y.is_ok() == false);
}
// end example
is_err¶
basic_result<_, T, E> → bool
Returns true if the result is failure.
declarations
template <mutability _mu, class T, class E>
class basic_result {
constexpr bool is_err() const noexcept ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<unsigned, std::string> x = success(3);
assert(x.is_err() == false);
result<unsigned, std::string> y = failure("Some error message"s);
assert(y.is_err() == true);
}
// end example
ok¶
basic_result<_, T, E> → maybe<T>
Converts from basic_result
to maybe
.
Converts self into a maybe
, and discarding the failure value, if any.
Note that these functions propagate mutability to element type of maybe
.
Remarks
If self is rvalue and T
is a reference type,
this function returns maybe<dangling<std::reference_wrapper<std::remove_reference_t<T>>>>
.
declarations
template <class T, class E>
class basic_result<mutability::immut, T, E> {
constexpr auto result<T, E>::ok() &
-> maybe<const T> ;
constexpr auto result<T, E>::ok() const &
-> maybe<const T> ;
constexpr auto result<T, E>::ok() &&
-> maybe<const T> ;
};
template <class T, class E>
class basic_result<mutability::mut, T, E> {
constexpr auto mut_result<T, E>::ok() &
-> maybe<T> ;
constexpr auto mut_result<T, E>::ok() const &
-> maybe<const T> ;
constexpr auto mut_result<T, E>::ok() &&
-> maybe<T> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<unsigned, std::string> x = success(2);
assert(x.ok() == just(2));
result<unsigned, std::string> y = failure("Nothing here"s);
assert(y.ok() == nothing);
}
// end example
err¶
basic_result<_, T, E> → maybe<E>
Converts from basic_result
to maybe
.
Converts self into a maybe
, and discarding the success value, if any.
Note that these functions propagate mutability to element type of maybe
.
remarks
If self is rvalue and E
is a reference type,
this function returns maybe<dangling<std::reference_wrapper<std::remove_reference_t<E>>>>
.
declarations
template <class T, class E>
class basic_result<mutability::immut, T, E> {
constexpr auto result<T, E>::err() &
-> maybe<const E> ;
constexpr auto result<T, E>::err() const &
-> maybe<const E> ;
constexpr auto result<T, E>::err() &&
-> maybe<const E> ;
};
template <class T, class E>
class basic_result<mutability::mut, T, E> {
constexpr auto mut_result<T, E>::err() &
-> maybe<E> ;
constexpr auto mut_result<T, E>::err() const &
-> maybe<const E> ;
constexpr auto mut_result<T, E>::err() &&
-> maybe<E> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<unsigned, std::string> x = success(2);
assert(x.err() == nothing);
result<unsigned, std::string> y = failure("Nothing here"s);
assert(y.err() == just("Nothing here"s));
}
// end example
map¶
basic_result<, T, E> → O → basic_result<, U, E>
Maps a result<T, E>
to result<U, E>
by applying a function to a contained success
value, leaving an failure
value untouched.
This function can be used to compose the results of two functions.
constraints
requires std::invocable<O, T>
declarations
template <mutability _mu, class T, class E>
class basic_result {
constexpr auto map(O && op)const &
-> std::enable_if_t<std::is_invocable_v<O, T>, result<std::invoke_result_t<O, T>, E>> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<int, int> ok = success(2);
assert(ok.map([](int x) { return x * 2; }) == success(4));
result<int, int> err = failure(2);
assert(err.map([](int x) { return x * 2; }) == failure(2));
}
// end example
map_or_else¶
basic_result<_, T, E> → Fallback → Map → U,
where Fallback: E → U, Map: T → U
Maps a result<T, E>
to U
by applying a function to a contained success
value, or a fallback function to a contained failure
value.
This function can be used to unpack a successful result while handling an error.
constraints
requires {
typename std::common_type<std::invoke_result_t<Map, T>,
std::invoke_result_t<Fallback, E> >::type;
}
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class Map, class Fallback>
constexpr auto map_or_else(Fallback&& _fallback, Map&& _map) const&
-> std::common_type_t<std::invoke_result_t<Map, T>, std::invoke_result_t<Fallback, E>> ;
};
Examples¶
Basic usages:
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
auto k = 21;
{
result<std::string, std::string> x = success("foo"s);
assert(x.map_or_else([k](auto){ return k * 2; }, [](auto v) { return v.length(); }) == 3);
}
{
result<std::string, std::string> x = failure("bar"s);
assert(x.map_or_else([k](auto){ return k * 2; }, [](auto v) { return v.length(); }) == 42);
}
}
// end example
map_anything_else [since v7.8.0]¶
basic_result<_, T, E> → Map → U,
where
Map: T → U,
Map: E → U
Maps a result<T, E>
to U
by applying a function _map
to a contained either success
or failure
value.
This function is syntax sugar for res.map_or_else(_map, _map)
.
constraints
requires (Map map, T ok, E err) {
{ map(ok) };
{ map(err) };
typename std::common_type<std::invoke_result_t<Map, T>,
std::invoke_result_t<Map, E> >::type;
}
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class Map>
constexpr auto map_or_else(Map&& _map) const&
-> std::common_type_t<std::invoke_result_t<Map, T>, std::invoke_result_t<Fallback, E>> ;
};
Examples¶
Basic usage:
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
{
result<std::string, std::string> x = success("foo"s);
assert(x.map_anything_else([](auto v) { return v.length(); }) == 3);
}
{
result<std::string, std::string> x = failure("bar"s);
assert(x.map_anything_else([](auto v) { return v.length(); }) == 3);
}
}
// end example
map_err¶
basic_result<, T, E> → O → basic_result<, T, F>
where O: E -> F
Maps a result<T, E>
to result<T, F>
by applying a function to a contained failure value, leaving an success value untouched.
This function can be used to pass through a successful result while handling an error.
constraints
requires (O&& op, E err) {
typename std::invoke_result<O&&, E>::type;
}
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class O>
constexpr auto map_err(O && op) const &
-> std::enable_if_t<std::is_invocable_v<O, E>, result<T, std::invoke_result_t<O, E>>> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
auto stringify = [](unsigned x) -> std::string{
return "error code: "s + std::to_string(x);
};
result<unsigned, unsigned> x = success(2);
assert(x.map_err(stringify) == success(2u));
result<unsigned, unsigned> y = failure(13);
assert(y.map_err(stringify) == failure("error code: 13"s));
}
// end example
conj¶
basic_result<, T, E> → basic_result<, U, E> → basic_result<_, U, E>
self.conj(res)
returns res
if the result is success
, otherwise returns the failure
value of self.
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <mutability _, class U>
constexpr auto basic_result<_, T, E>::conj(basic_result<_, U, E> const&) const &
-> basic_result<U, E> ;
template <mutability _, class U>
constexpr auto basic_result<_, T, E>::operator&&(basic_result<_, U, E> const &) const &
-> basic_result<U, E> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
{
result<unsigned, std::string> x = success(2);
result<std::string, std::string> y = failure("late error"s);
assert((x && y) == failure("late error"s));
}
{
result<unsigned, std::string> x = failure("early error"s);
result<std::string, std::string> y = success("foo"s);
assert((x && y) == failure("early error"s));
}
{
result<unsigned, std::string> x = failure("not a 2"s);
result<std::string, std::string> y = failure("late error"s);
assert((x && y) == failure("not a 2"s));
}
{
result<unsigned, std::string> x = success(2);
result<std::string, std::string> y = success("different result type"s);
assert((x && y) == success("different result type"s));
}
}
// end example
and_then¶
basic_result<, T, E> → O → basic_result<, U, E>,
where O: T → basic_result<_, U, E>
self.and_then(op)
calls op
if the result is success, otherwise returns the failure value of self.
This function can be used for control flow based on result values.
constraints
requires (is_result_v<std::invoke_result_t<O, T>>
and std::convertible_to<typename std::invoke_result_t<O, T>::err_type, E>)
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class O,
std::enable_of>
constexpr auto and_then(O&& op) &
-> std::enable_if_t<is_convertible_result_with_v<std::invoke_result_t<O&&, T&>, failure<E>>,
std::invoke_result_t<O, T>> ;
template <class O>
constexpr auto and_then(O&& op) const&
-> std::enable_if_t<is_convertible_result_with_v<std::invoke_result_t<O&&, T const&>, failure<E>>,
std::invoke_result_t<O, T>> ;
template <class O>
constexpr auto and_then(O&& op) &&
-> std::enable_if_t<is_convertible_result_with_v<std::invoke_result_t<O&&, T&&>, failure<E>>,
std::invoke_result_t<O, T>> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
auto sq = [](unsigned x) -> result<unsigned, unsigned> { return success(x * x); };
auto err = [](unsigned x) -> result<unsigned, unsigned> { return failure(x); };
result<int, int> x = success(2u);
result<int, int> y = failure(3u);
assert(x.and_then(sq).and_then(sq) == success(16u));
assert(x.and_then(sq).and_then(err) == failure(4u));
assert(x.and_then(err).and_then(sq) == failure(2u));
assert(y.and_then(sq).and_then(sq) == failure(3u));
}
// end example
disj¶
basic_result<, T, E> → basic_result<, T, F> → basic_result<_, T, F>
self.disj(res)
returns res
if the result is failure
, otherwise returns the success
value of self.
Arguments passed to or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use or_else
, which is lazily evaluated.
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class F>
constexpr auto basic_result<_, T, E>::disj(basic_result<_, T, F> const& res) const &
-> basic_result<_, T, F> ;
template <class F>
constexpr auto basic_result<_, T, E>::operator||(basic_result<_, T, F> const& res) const &
-> basic_result<_, T, F> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
{
result<unsigned, std::string> x = success(2);
result<unsigned, std::string> y = failure("late error"s);
assert(x.disj(y) == success(2u));
assert((x || y) == success(2u));
}
{
result<unsigned, std::string> x = failure("early error"s);
result<unsigned, std::string> y = success(2);
assert(x.disj(y) == success(2u));
assert((x || y) == success(2u));
}
{
result<unsigned, std::string> x = failure("not a 2"s);
result<unsigned, std::string> y = failure("late error"s);
assert(x.disj(y) == failure("late error"s));
assert((x || y) == failure("late error"s));
}
{
result<unsigned, std::string> x = success(2);
result<unsigned, std::string> y = success(100);
assert(x.disj(y) == success(2u));
assert((x || y) == success(2u));
}
}
// end example
or_else¶
basic_result<, T, E> → O → basic_result<, T, F>,
where O: E -> basic_result<_, T, F>
self.or_else(op)
calls op
if the result is failure
, otherwise returns the success
value of self.
This function can be used for control flow based on result values.
constraints
requires (is_result_v<std::invoke_result_t<O, T>>
and std::convertible_to<typename std::invoke_result_t<O, T>::ok_type, T>)
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class O>
constexpr auto basic_result<_, T, E>::or_else(O && op) const &
-> std::invoke_result<O&&, E> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
auto sq = [](unsigned x) -> result<unsigned, unsigned> { return success(x * x); };
auto err = [](unsigned x) -> result<unsigned, unsigned> { return failure(x); };
result<int, int> x = success(2u);
result<int, int> y = failure(3u);
assert(x.or_else(sq).or_else(sq) == success(2u));
assert(x.or_else(err).or_else(sq) == success(2u));
assert(y.or_else(sq).or_else(err) == success(9u));
assert(y.or_else(err).or_else(err) == failure(3u));
}
// end example
unwrap_or¶
basic_result<_, T, E> → T const& → T
self.unwrap_or(optb)
unwraps a result, yielding the content of an success
. Else, it returns optb
.
Arguments passed to unwrap_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use unwrap_or_else
, which is lazily evaluated.
declarations
template <mutability _mu, class T, class E>
class basic_result {
auto basic_result<_, T, E>::unwrap_or(T const& optb) const noexcept
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<unsigned, unsigned> ok = success(2);
result<unsigned, unsigned> err = failure(2);
assert(ok.unwrap_or(1u) == 2u);
assert(err.unwrap_or(1u) == 1u);
}
// end example
unwrap_or_else¶
basic_result<_, T, E> → O → T,
where O: E → T
self.unwrap_or_else(op)
unwraps a result, yielding the content of an success
. If the value is an failure
then it invokes op
with its value.
constraints
requires (O&& op, E err) {
{ std::invoke(op, err) } -> std::convertible_to<T>;
}
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class O>
auto basic_result<_, T, E>::unwrap_or_else(O && op) const noexcept
-> std::enable_if_t<std::is_invocable_r_v<T, O, E>, T> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<int, std::string> ok = success(2);
result<int, std::string> err = failure("foo"s);
assert(ok.unwrap_or_else(&std::string::size) == 2);
assert(err.unwrap_or_else(&std::string::size) == 3);
}
// end example
unwrap¶
basic_result<_, T, E> → E
Unwraps a result, yielding the content of an success
.
exceptions
Raise mitama::runtime_panic
if a result is containing failure
value.
remarks
If self is rvalue and T
is a reference type,
this function returns maybe<dangling<std::reference_wrapper<std::remove_reference_t<T>>>>
.
declarations
template <class T, class E>
class basic_result<mutability::immut, T, E> {
auto unwrap() & -> const T ;
auto unwrap() const& -> const T ;
auto unwrap() && -> const T ;
};
template <class T, class E>
class basic_result<mutability::mut, T, E> {
auto unwrap() & -> T ;
auto unwrap() const& -> const T ;
auto unwrap() && -> T ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
{
result<unsigned, std::string> x = success(2);
assert(x.unwrap() == 2);
}
try {
result<unsigned, std::string> x = failure("emergency failure"s);
x.unwrap(); // panics with `emergency failure`
}
catch ( mitama::runtime_panic const& panic ) {
std::cerr << panic.what() << std::endl;
}
}
// end example
unwrap_err¶
basic_result<_, T, E> → E
Unwraps a result, yielding the content of an failure
.
exceptions
Raise mitama::runtime_panic
if a result is containing success
value.
remarks
If self is rvalue and E
is a reference type,
this function returns maybe<dangling<std::reference_wrapper<std::remove_reference_t<E>>>>
.
declarations
template <class T, class E>
class basic_result<mutability::immut, T, E> {
auto unwrap_err() & -> const E ;
auto unwrap_err() const& -> const E ;
auto unwrap_err() && -> const E ;
};
template <class T, class E>
class basic_result<mutability::mut, T, E> {
auto mut_unwrap_err() & -> E ;
auto mut_unwrap_err() const& -> const E ;
auto mut_unwrap_err() && -> E ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
try {
result<unsigned, std::string> x = success(2);
x.unwrap_err(); // panics with `2`
}
catch (runtime_panic const &panic)
{
std::cerr << panic.what() << std::endl;
}
{
result<unsigned, std::string> x = failure("emergency failure"s);
assert(x.unwrap_err() == "emergency failure"s);
}
}
// end example
unwrap_or_default¶
basic_result<_, T, E> → T
Returns the contained value or a default.
If success
, returns the contained value, otherwise if failure
, returns the default value for that type.
constraints
requires std::default_initializable<T>
remarks
This operator shall be defined as deleted unless is_default_constructible_v<T>
is true.
declarations
template <mutability _mu, class T, class E>
class basic_result {
auto basic_result<_, T, E>::unwrap_or_default() const & -> T ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
using namespace std::string_literals;
int main() {
result<int, void> good = success(1909);
result<int, void> bad = failure<>();
auto good_year = good.unwrap_or_default();
auto bad_year = bad.unwrap_or_default();
assert(1909 == good_year);
assert(0 == bad_year);
}
// end example
transpose¶
basic_result<, maybe<T>, E> → maybe<basic_result<, T, E>>
Transposes a result
of a maybe
into a maybe
of a result
.
success(nothing)
will be mapped to nothing
.
success(just(v))
and failure(v)
will be mapped to just(success(v))
and just(failure(v))
.
declarations
template <mutability _mu, class T, class E>
class basic_result {
auto basic_result<_, maybe<T>, E>::transpose()
-> maybe<basic_result<_, T, E>> ;
auto basic_result<_, maybe<T>, E>::transpose()
-> maybe<basic_result<_, T, E>> ;
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
#include <string>
using namespace mitama;
int main() {
result<maybe<int>, std::string> x = success(just(5));
maybe<result<int, std::string>> y = just(success(5));
assert(x.transpose() == y);
}
// end example
and_finally¶
basic_result<T, E> → F → void
Invokes the provided function with the contained success value (if success), or doing nothing (if failure). The return value of F will be discarded whether void or not.
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class F>
constexpr
std::enable_if_t<std::is_invocable_v<F&&, ok_type ${CVREF}>>
and_finally(F&& f) ${CVREF}
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
using namespace mitama;
int main() {
result<int, std::string> x = success(42);
int hook = 0;
x.and_finally([&](int const& v){ hook = v; });
assert(hook == 42);
}
// end example
or_finally¶
basic_result<T, E> → F → void
Invokes the provided function with contained failure value (if failure), or doing nothing (if success). The return value of F will be discarded whether void or not.
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class F>
constexpr
std::enable_if_t<std::is_invocable_v<F&&, err_type ${CVREF}>>
and_finally(F&& f) ${CVREF}
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <string>
#include <cassert>
using namespace mitama;
int main() {
using namespace std::literals;
std::string hook = "default";
result<int, std::string> x = success(42);
x.or_finally([&hook](std::string v){
hook = v;
});
assert(hook == "default"s);
result<int, std::string> y = failure("error"s);
y.or_finally([&hook](std::string v){
hook = v;
});
assert(hook == "error"s);
}
// end example
and_peek¶
basic_result<T, E> → F → basic_result<T, E>
Peeks the contained success value and then returns self.
Invokes the provided function with the contained value and then return self (if success), or return self without doing anything (if failure).
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class F>
constexpr
std::enable_if_t<
std::disjunction_v<
std::is_invocable<F, ok_type ${CVREF}>,
std::is_invocable<F>>,
basic_result&>
and_peek(F&& f) ${CVREF}
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
using namespace mitama;
int main() {
result<int, std::string> x = success(42);
int hook = 0;
assert(x.and_peek([&](int const& v){ hook = v; }) == success(42));
assert(hook == 42);
}
// end example
or_peek¶
basic_result<T, E> → F → basic_result<T, E>
Peeks the contained failure value and then returns self.
Invokes the provided function and then return self (if failure), or return self without doing anything (if success).
declarations
template <mutability _mu, class T, class E>
class basic_result {
template <class F>
constexpr
std::enable_if_t<
std::disjunction_v<
std::is_invocable<F, err_type ${CVREF}>,
std::is_invocable<F>>,
basic_result&>
or_peek(F&& f) ${CVREF}
};
Examples¶
// begin example
#include <mitama/result/result.hpp>
#include <cassert>
using namespace mitama;
int main() {
maybe x = nothing;
int hook = 0;
assert(x.or_peek([&]{ hook = 42; }) == nothing);
assert(hook == 42);
}
// end example