Class Subspace :: sus :: result :: Result

template <class T, class E>
class Result final
{ ... };

Static Methods

Result(OkVoid)
requires
std::is_void_v<T>
Result(const sus::result::Result::TUnlessVoid& t)
requires
!std::is_void_v<T>
!std::is_reference_v<T>
sus::mem::Copy<T>
Result(sus::result::Result::TUnlessVoid&& t)
requires
!std::is_void_v<T>
!std::is_reference_v<T>
sus::mem::Move<T>
template <class U>
Result(U&& t)
requires
std::convertible_to<U, TUnlessVoid>
!std::is_void_v<T>
std::is_reference_v<T>
sus::construct::SafelyConstructibleFromReference<T, U &&>

Construct an Result that is holding the given success value.

Const References

For Result<const T&, E> it is possible to bind to a temporary which would create a memory safety bug. The [[clang::lifetimebound]] attribute is used to prevent this via Clang. But additionally, the incoming type is required to match with sus::construct::SafelyConstructibleFromReference to prevent conversions that would construct a temporary.

To force accepting a const reference anyway in cases where a type can convert to a reference without constructing a temporary, use an unsafe static_cast<const T&>() at the callsite (and document it =)).

Result(const Result<T, E>&)
requires
sus::mem::CopyOrRefOrVoid<T>
sus::mem::Copy<E>
Result(const Result<T, E>&)
requires
!::sus::mem::CopyOrRefOrVoid<T> || !::sus::mem::Copy<E>
deleted

Copy constructor for Result<T, E> which satisfies sus::mem::Copy<Result<T, E>> if Copy<T> and Copy<E> are satisfied.

If T and E can be trivially copy-constructed, then Result<T, E> can also be trivially copy-constructed.

Result(Result<T, E>&&)
requires
sus::mem::MoveOrRefOrVoid<T>
sus::mem::Move<E>
Result(Result<T, E>&&)
requires
!::sus::mem::MoveOrRefOrVoid<T> || !::sus::mem::Move<E>
deleted

Move constructor for Result<T, E> which satisfies Move, if T and E both satisfy Move.

If T and E can be trivially move-constructed, then Result<T, E> can also be trivially move-constructed. When trivially-moved, the Result is copied on move, and the moved-from Result is unchanged but should still not be used thereafter without reinitializing it.

template <class Iter>
static auto from_product(Iter&& it) -> Result<T, E>
requires
sus::iter::Iterator<Iter, Result<T, E>>
sus::iter::Product<T>

Computes the product of an iterator over Result<T, E> as long as there is no Err found. If an Err is found, the function returns the first Err.

Prefer to call product() on the iterator rather than calling from_product() directly.

Implements sus::iter::Product<Result<T, E>, Result<T, E>>.

The product is computed using the implementation of the inner type T which also satisfies sus::iter::Product<T, T>.

template <class Iter>
static auto from_sum(Iter&& it) -> Result<T, E>
requires
sus::iter::Iterator<Iter, Result<T, E>>
sus::iter::Sum<T>

Computes the sum of an iterator over Result<T, E> as long as there is no Err found. If an Err is found, the function returns the first Err.

Prefer to call sum() on the iterator rather than calling from_sum() directly.

Implements sus::iter::Sum<Result<T, E>, Result<T, E>>.

The sum is computed using the implementation of the inner type T which also satisfies sus::iter::Sum<T, T>.

static auto with_err(const E& e) -> Result<T, E>
requires
sus::mem::Copy<E>
static auto with_err(E&& e) -> Result<T, E>
requires
sus::mem::Move<E>

Construct an Result that is holding the given error value.

Methods

template <class AndFn>
auto and_then(AndFn op) && -> sus::fn::ReturnOnce<AndFn, sus::result::Result::TUnlessVoid&&>
requires
sus::fn::FnOnce<AndFn, ::sus::fn::NonVoid (TUnlessVoid &&)>
sus::result::__private::IsResultWithErrType<sus::fn::ReturnOnce<AndFn, T &&>, E>
template <class AndFn>
auto and_then(AndFn op) && -> sus::fn::ReturnOnce<AndFn>
requires
sus::fn::FnOnce<AndFn, ::sus::fn::NonVoid (void)>
std::is_void_v<T>
sus::result::__private::IsResultWithErrType<sus::fn::ReturnOnce<AndFn>, E>

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.

auto as_err() const& -> const E&
auto as_err() && -> const E&
deleted

Returns a const reference to the contained Err value.

Panics

Panics if the value is an Ok or the Result is moved from.

auto as_value() const& -> const std::remove_reference_t<sus::result::Result::TUnlessVoid>&
requires
!std::is_void_v<T>
auto as_value() && -> const std::remove_reference_t<sus::result::Result::TUnlessVoid>&
deleted

Returns a const reference to the contained Ok value.

Panics

Panics if the value is an Err.

auto as_value_mut() & -> std::remove_reference_t<sus::result::Result::TUnlessVoid>&
requires
!std::is_void_v<T>

Returns a mutable reference to the contained Ok value.

Panics

Panics if the value is an Err.

auto clone() const& -> Result<T, E>
requires
std::is_void_v<T> || ::sus::mem::Clone<T>
sus::mem::Clone<E>
!(::sus::mem::CopyOrRefOrVoid<T> && ::sus::mem::Copy<E>)
auto clone_from(const Result<T, E>& source) & -> void
requires
std::is_void_v<T> || ::sus::mem::Clone<T>
sus::mem::Clone<E>
!(::sus::mem::CopyOrRefOrVoid<T> && ::sus::mem::Copy<E>)
auto err() && -> Option<E>

Converts from Result<T, E> to Option<E>.

Converts self into an Option<E>, consuming self, and discarding the success value, if any.

auto expect(const char* msg) && -> T

Returns the contained Ok value, consuming the self value.

Because this function may panic, its use is generally discouraged. Instead, prefer to use pattern matching and handle the Err case explicitly, or call unwrap_or, unwrap_or_else, or unwrap_or_default.

Panics

Panics if the value is an Err, with a panic message including the passed message, and the content of the Err.

auto into_iter() && -> OptionIter<T>
requires
!std::is_void_v<T>
auto is_err() const& -> bool

Returns true if the result is Err.

auto is_ok() const& -> bool

Returns true if the result is Ok.

auto iter() const& -> OptionIter<const std::remove_reference_t<sus::result::Result::TUnlessVoid>&>
requires
!std::is_void_v<T>
auto iter() && -> OptionIter<const std::remove_reference_t<sus::result::Result::TUnlessVoid>&>
requires
!std::is_void_v<T>
std::is_reference_v<T>
auto iter_mut() & -> OptionIter<sus::result::Result::TUnlessVoid&>
requires
!std::is_void_v<T>
auto iter_mut() && -> OptionIter<sus::result::Result::TUnlessVoid&>
requires
!std::is_void_v<T>
std::is_reference_v<T>
auto ok() && -> Option<T>
requires
!std::is_void_v<T>

Converts from Result<T, E> to Option<T>.

Converts self into an Option<T>, consuming self, and discarding the error, if any.

Option can not hold void, so this method is not present on Result<void, E>.

auto unwrap() && -> T

Returns the contained Ok value, consuming the self value.

Because this function may panic, its use is generally discouraged. Instead, prefer to use pattern matching and handle the Err case explicitly, or call unwrap_or(), unwrap_or_else(), or unwrap_or_default().

Panics

Panics if the value is an Err or the Result is moved from.

auto unwrap_err() && -> E

Returns the contained Err value, consuming the self value.

Panics

Panics if the value is an Ok or the Result is moved from.

Returns the contained Err value, consuming the self value, without checking that the value is not an Ok.

Safety

Calling this method on an Ok or a moved-from Result is Undefined Behavior.

auto unwrap_or_default() && -> T
requires
!std::is_reference_v<T>
std::is_void_v<T> || ::sus::construct::Default<T>

Returns the contained Ok value or a default.

Consumes the Result and, if it held an Ok value, the value is returned. Otherwise the default value of the Ok value's type is returned.

auto unwrap_or_else(FnOnce<T(E&&)> auto op) && -> T

Returns the contained Ok value or computes it from a closure.

Examples

Basic usage:

enum ECode { ItsHappening = -1 };
auto conv = [](ECode e) { return static_cast<i32>(e); };
auto ok = sus::Result<i32, ECode>(2);
sus_check(sus::move(ok).unwrap_or_else(conv) == 2);
auto err = sus::Result<i32, ECode>::with_err(ItsHappening);
sus_check(sus::move(err).unwrap_or_else(conv) == -1);

Returns the contained Ok value, consuming the self value, without checking that the value is not an Err.

Safety

Calling this method on an Err or a moved-from Result is Undefined Behavior.

Conversions

An operator which returns the state of the Result, either #Ok or #Err.

This supports the use of an Result in a switch(), allowing it to act as a tagged union between "success" and "error".

Example

A reimplementation of Result::unwrap_or().

auto x = Result<int, char>(2);
switch (x) {
 case Ok:
  return sus::move(x).unwrap();
 case Err:
  return -1;
}

Operators

auto operator=(const Result<T, E>& o) -> Result<T, E>&
requires
sus::mem::CopyOrRefOrVoid<T>
sus::mem::Copy<E>
auto operator=(const Result<T, E>&) -> Result<T, E>&
requires
!::sus::mem::CopyOrRefOrVoid<T> || !::sus::mem::Copy<E>
deleted

Copy assignment for Result<T, E> which satisfies sus::mem::Copy<Result<T, E>> if Copy<T> and Copy<E> are satisfied.

If T and E can be trivially copy-assigned, then Result<T, E> can also be trivially copy-assigned.

auto operator=(Result<T, E>&&) -> Result<T, E>&
requires
sus::mem::MoveOrRefOrVoid<T>
sus::mem::Move<E>
auto operator=(Result<T, E>&&) -> Result<T, E>&
requires
!::sus::mem::MoveOrRefOrVoid<T> || !::sus::mem::Move<E>
deleted

Move assignment for Result<T, E> which satisfies Move, if T and E both satisfy Move.

If T and E can be trivially move-assigned, then Result<T, E> can also be trivially move-assigned. When trivially-moved, the Result is copied on move, and the moved-from Result is unchanged but should still not be used thereafter without reinitializing it.