8 #ifndef DIAG_CLIENT_LIB_LIB_PLATFORM_CORE_RESULT_H_
9 #define DIAG_CLIENT_LIB_LIB_PLATFORM_CORE_RESULT_H_
12 #include <type_traits>
28 template<
typename T,
typename E = ErrorCode>
71 template<
typename... Args>
73 return Result{std::forward<Args>(args)...};
106 template<
typename... Args>
108 return Result{std::forward<Args>(args)...};
161 std::is_nothrow_move_constructible<T>::value &&std::is_nothrow_move_constructible<E>::value) =
default;
171 std::is_nothrow_move_constructible<T>::value &&std::is_nothrow_move_assignable<T>::value
172 &&std::is_nothrow_move_constructible<E>::value &&std::is_nothrow_move_assignable<E>::value) =
default;
186 template<typename... Args>
188 storage_.template emplace<value_type>(std::forward<Args>(args)...);
198 template<
typename... Args>
200 storage_.template emplace<error_type>(std::forward<Args>(args)...);
215 explicit operator bool() const noexcept {
return HasValue(); }
255 T &&
Value() &&noexcept {
return std::move(std::get<value_type>(
storage_)); }
271 E &&
Error() &&noexcept {
return std::move(std::get<error_type>(
storage_)); }
278 std::optional<T>
Ok() const &noexcept {
279 std::optional<T> opt_val{};
289 std::optional<T>
Ok() &&noexcept {
290 std::optional<T> opt_val{};
300 std::optional<E>
Err() const &noexcept {
301 std::optional<E> opt_err{};
311 std::optional<E>
Err() &&noexcept {
312 std::optional<E> opt_err{};
327 template<
typename F,
typename T2 =
typename std::invoke_result_t<F, T>>
342 template<
typename F,
typename E2 = std::invoke_result_t<F, E>>
389 return HasValue() ?
Result{std::move(*
this)} :
static_cast<T
>(defaultValue);
404 return !
HasValue() ?
Result{*
this} :
static_cast<E
>(defaultError);
419 return !
HasValue() ?
Result{std::move(*
this)} :
static_cast<E
>(defaultError);
502 template<
typename... Args>
504 return Result{std::forward<Args>(args)...};
547 Result(
Result &&other) noexcept(std::is_nothrow_move_constructible<E>::value) =
default;
557 std::is_nothrow_move_constructible<E>::value &&std::is_nothrow_move_assignable<E>::value) =
default;
562 ~Result() noexcept { static_assert(std::is_trivially_destructible<E>::value); }
576 template<
typename... Args>
578 storage_.EmplaceError(std::forward<Args>(args)...);
593 explicit operator bool() const noexcept {
return HasValue(); }
616 std::optional<E>
Err() const &noexcept {
617 std::optional<E> opt_err{};
627 std::optional<E>
Err() &&noexcept {
628 std::optional<E> opt_err{};
643 template<
typename F,
typename E2 = std::invoke_result_t<F, E>>
658 template<
typename F,
typename E2 = std::invoke_result_t<F, E>>
676 return Result{std::move(*
this)};
706 return !
HasValue() ?
Result{*
this} :
static_cast<E
>(defaultError);
721 return !
HasValue() ?
Result{std::move(*
this)} :
static_cast<E
>(defaultError);
744 struct empty_value {};
static Result FromError(E &&e) noexcept
Build a new Result from the specified error (given as rvalue)
Result & operator=(const Result &other)=default
Copy-assign another Result to this instance.
constexpr Result() noexcept
Construct a new Result with a "void" value.
Result< void, E2 > CheckError(F &&fn)
Returns the result of the given function on the contained value if it exists; otherwise,...
static Result FromValue() noexcept
Build a new Result with "void" as value.
void EmplaceError(Args &&...args) noexcept
Put a new error into this instance, constructed in-place from the given arguments.
E error_type
Type alias for the type E of errors.
const E & Error() const &noexcept
Access the contained error.
Result AndThen(F &&fn) &&noexcept
Returns the result of the given function on the contained value if it exists; otherwise,...
Result OrElse(F &&fn) &&noexcept
Returns the result itself if it contains a value; otherwise, returns the result of the given function...
void value_type
Type alias for the type T of values, always "void" for this specialization.
E && Error() &&noexcept
Access the contained error.
Result< void, E2 > MapError(F &&fn)
Returns the result of the given function on the contained value if it exists; otherwise,...
bool HasValue() const noexcept
Check whether *this contains a value.
static Result FromError(const E &e) noexcept
Build a new Result from the specified error (given as lvalue)
Result(Result &&other) noexcept(std::is_nothrow_move_constructible< E >::value)=default
Move-construct a new Result from another instance.
Result & operator=(Result &&other) noexcept(std::is_nothrow_move_constructible< E >::value &&std::is_nothrow_move_assignable< E >::value)=default
Move-assign another Result to this instance.
E ErrorOr(G &&defaultError) &&noexcept
Return the contained error or the given default error.
constexpr Result(const E &e) noexcept
Construct a new Result from the specified error (given as lvalue)
E ErrorOr(G &&defaultError) const &noexcept
Return the contained error or the given default error.
static Result FromError(Args &&...args) noexcept
Build a new Result from an error that is constructed in-place from the given arguments.
void Resolve(F &&f) const
Do nothing or call a function.
std::optional< E > Err() &&noexcept
Return the contained error as an Optional.
std::optional< E > Err() const &noexcept
Return the contained error as an Optional.
Result< empty_value, E > storage_
Storage to contain an empty value or error of type E.
void EmplaceValue() noexcept
Put a new value into this instance, constructed in-place from the given arguments.
~Result() noexcept
Destruct an instance of Result.
Result(const Result &other)=default
Copy-construct a new Result from another instance.
constexpr Result(E &&e) noexcept
Construct a new Result from the specified error (given as rvalue)
Class type to contains a value (of type ValueType), or an error (of type ErrorType)
constexpr Result(const T &t) noexcept
Construct a new Result from the specified value (given as lvalue)
const T & operator*() const &noexcept
Access the contained value.
constexpr Result(T &&t) noexcept
Construct a new Result from the specified value (given as rvalue)
Result & operator=(Result &&other) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_constructible< E >::value &&std::is_nothrow_move_assignable< E >::value)=default
Move-assign another Result to this instance.
static Result FromValue(T &&t) noexcept
Build a new Result from the specified value (given as rvalue)
std::optional< E > Err() const &noexcept
Return the contained error as an Optional.
std::optional< T > Ok() const &noexcept
Return the contained value as an Optional.
T ValueOr(U &&defaultValue) const &noexcept
Return the contained value or the given default value.
void EmplaceError(Args &&...args) noexcept
Put a new error into this instance, constructed in-place from the given arguments.
Result< T, E2 > MapError(F &&fn)
Returns the result of the given function on the contained value if it exists; otherwise,...
E ErrorOr(G &&defaultError) &&noexcept
Return the contained error or the given default error.
std::variant< T, E > storage_
Storage to contain value of type T or error of type E.
std::optional< T > Ok() &&noexcept
Return the contained value as an Optional.
Result(const Result &other)=default
Copy-construct a new Result from another instance.
Result(Result &&other) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_move_constructible< E >::value)=default
Move-construct a new Result from another instance.
Result & operator=(const Result &other)=default
Copy-assign another Result to this instance.
const T & Value() const &noexcept
Access the contained value.
static Result FromError(const E &e) noexcept
Build a new Result from the specified error (given as lvalue)
const E & Error() const &noexcept
Access the contained error.
static Result FromError(Args &&...args) noexcept
Build a new Result from an error that is constructed in-place from the given arguments.
E ErrorOr(G &&defaultError) const &noexcept
Return the contained error or the given default error.
E && Error() &&noexcept
Access the contained error.
T Resolve(F &&f) const
Return the contained value or return the result of a function call.
constexpr Result(const E &e) noexcept
Construct a new Result from the specified error (given as lvalue)
bool HasValue() const noexcept
Check whether *this contains a value.
Result< T2, E > AndThen(F &&fn) &&noexcept
Returns the result of the given function on the contained value if it exists; otherwise,...
~Result() noexcept=default
Destruct an instance of Result.
T && Value() &&noexcept
Access the contained value.
T && operator*() &&noexcept
Access the contained value.
Result OrElse(F &&fn) &&noexcept
Returns the result itself if it contains a value; otherwise, returns the result of the given function...
const T * operator->() const noexcept
Access the contained value.
T ValueOr(U &&defaultValue) &&noexcept
Return the contained value or the given default value.
E error_type
Type alias for the type E of errors.
constexpr Result(E &&e) noexcept
Construct a new Result from the specified error (given as rvalue)
T value_type
Type alias for the type T of values.
static Result FromValue(Args &&...args) noexcept
Build a new Result from a value that is constructed in-place from the given arguments.
static Result FromError(E &&e) noexcept
Build a new Result from the specified error (given as rvalue)
void EmplaceValue(Args &&...args) noexcept
Put a new value into this instance, constructed in-place from the given arguments.
static Result FromValue(T &t) noexcept
Build a new Result from the specified value (given as lvalue)
std::optional< E > Err() &&noexcept
Return the contained error as an Optional.