expected#
Fully qualified name: omni::expected
Defined in omni/Expected.h
-
template<typename TValue, typename TError>
class expected : public omni::detail::ExpectedImpl<TValue, TError># A monad which holds either an expected value (the success case) or an unexpected value (the error case).
Simple use of
expectedinstances involve checking if an instancehas_value()before accessing either thevalue()orerror()member.expected<int, string> foo(); int main() { auto ex = foo(); if (ex) std::cout << "Successfully got " << ex.value() << std::endl; else std::cout << "Error: " << ex.error() << std::endl; }
Advanced usage of
expectedinvolves using the monadic operations, which act on the stored value. This example is equivalent to the above:expected<int, string> foo(); int main() { foo() .transform([](int value) { std::cout << "Successfully got " << value << std::endl; }) .transform_error([](string const& err) { std::cout << "Error: " << err << std::endl; }); }
- Template Parameters:
TValue – The type of expected value, returned in the success case.
TError – The type of unexpected value, returned in the error case.
Public Types
-
using error_type = TError#
The type used in error cases. Unlike the C++23 definition of
std::expected, this is allowed to bevoidto match parity with other languages with result monads.
-
using unexpected_type = unexpected<error_type>#
The
unexpectedtype which contains this monad’s error_type.
-
template<typename UValue>
using rebind = expected<UValue, error_type># Get an
expectedtype withUValueas the value_type and the same error_type as this.
Public Functions
-
expected() = default#
Create a valued instance through default construction.
This constructor is only enabled if value_type is default-constructable or
void.This function is
noexceptif value_type has anoexceptdefault constructor or if it isvoid.
-
expected(expected const &src) = default#
Copy an expected instance from another. After this call,
this->has_value() == src.has_value()and either thevalueorerrorwill have been constructed from the src instance.This operation is only enabled if both value_type and error_type are copy-constructible or
void. This operation is trivial if both value_type and error_type have trivial copy constructors or arevoid.This function is
noexceptif both value_type and error_type havenoexceptcopy constructors or arevoid.- Parameters:
src – The source to copy from. It will remain unchanged by this operation.
-
expected(expected &&src) = default#
Move an expected instance from another. After this call,
this->has_value() == src.has_value()and either thevalueorerrorwill have been constructed fromstd::move(src).value()orstd::move(src).error(). Note that thehas_valuestate is unchanged, but the src instance will be moved-from.This operation is only enabled if both value_type and error_type are move-constructible or
void. This operation is trivial if both value_type and error_type have trivial move constructors or arevoid.This function is
noexceptif both value_type and error_type havenoexceptmove constructors or arevoid.- Parameters:
src – The source to move from. While the has_value state will remain unchanged, the active src instance will have been moved-from.
-
expected &operator=(expected const &src) = default#
Copy-assign this instance from another. After this call,
this->has_value() == src.has_value().Assignment can happen in one of two ways. In the simple case,
this->has_value() == src.has_value()before the call, so the copy assignment operator of the underlying type is used. Ifthis->has_value() != src.has_value()before the call, then the active instance ofthisgets the destructor called, then the other type is copy constructed (generally — see the “exceptions” section for more info). Note that this destruct-then-construct process happens even when value_type and error_type are the same.This operation is only enabled if both value_type and error_type are copy-assignable or
void. This operation is trivial if both value_type and error_type have trivial copy assignment operators and trivial destructors or arevoid.This function is
noexceptif both value_type and error_type havenoexceptcopy constructors, copy assignment operators, andnoexceptdestructors or arevoid.Note
On type-changing assignment with exceptions enabled, care is taken to ensure the contents of the monad are valid for use when exceptions are thrown. The “simple” destruct-then-construct process is only followed when copy construction of the type of the created instance is non-throwing. The exact algorithm used depends on the available
noexceptoperations (if any), but they involve a stack-based temporary and rollback. Note that a new instance might be constructed before the destruction of the old, so the ordering of these operations should not be relied on.- Parameters:
src – The source to copy from. It will remain unchanged by this operation.
-
expected &operator=(expected &&src) = default#
Move-assign this instance from another. After this call,
this->has_value() == src.has_value().Assignment can happen in one of two ways. In the simple case,
this->has_value() == src.has_value()before the call, so the move assignment operator of the underlying type is used. Ifthis->has_value() != src.has_value()before the call, then the active instance ofthisgets the destructor called, then the other type is move constructed (generally — see the “exceptions” section for more info). Note that this destruct-then-construct process happens even when value_type and error_type are the same.This operation is only enabled if both value_type and error_type are move-assignable or
void. This operation is trivial if both value_type and error_type have trivial move assignment operators and trivial destructors or arevoid.This function is
noexceptif both value_type and error_type havenoexceptmove constructors, move assignment operators, andnoexceptdestructors or arevoid.Note
On type-changing assignment with exceptions enabled, care is taken to ensure the contents of the monad are valid for use when exceptions are thrown. The “simple” destruct-then-construct process is only followed when move construction of the type of the created instance is non-throwing. The exact algorithm used depends on the available
noexceptoperations (if any), but they involve a stack-based temporary and rollback. Note that a new instance might be constructed before the destruction of the old, so the ordering of these operations should not be relied on.- Parameters:
src – The source to move from. While the has_value will remain unchanged, the active src instance will have been moved-from.
-
~expected() = default#
Destroy this instance by calling the destructor of the active value.
This operation is trivial if both value_type and error_type are trivially destructible. This function is
noexceptif both value_type and error_type havenoexceptdestructors.
-
template<typename UValue = TValue, std::enable_if_t<omni::detail::IsExpectedDirectConstructibleFrom<UValue, expected>::is_explicit, bool> = true>
inline explicit constexpr expected( - UValue &&src,
Construct an instance by forwarding src to construct the value_type by direct initialization. After this call,
this->has_value()will be true.This constructor is only enabled when all of the following criteria is met:
value_type is constructible from
UValuevalue_type is not
voidremove_cvref_t<UValue>is notin_place_tremove_cvref_t<UValue>is notexpected<TValue, TError>(the copy or move constructor is used instead)remove_cvref_t<UValue>is not a specialization ofunexpectedif value_type is
bool, thenUValuecan not be a specialization ofexpected
This constructor is
explicitif conversion fromUValueto value_type isexplicit.
-
template<typename UValue, typename UError, std::enable_if_t<omni::detail::IsExpectedCopyConstructibleFrom<expected<UValue, UError>, expected>::is_explicit, bool> = true>
inline explicit constexpr expected(
)# Convert from src by direct initialization from the active element. If
src.has_value(), then this instance will have a value constructed fromsrc.value(); otherwise, this instance will have an error constructed fromsrc.error(). After this call,this->has_value() == src.has_value().This converting constructor is not
explicitif conversion fromUValuetoTValueandUErrortoTErrorare notexplicit. Conversion fromvoidtovoidis also considered a nonexplicitconversion. Stated differently, aUExpectedis implicitly convertible to aTExpectedif both of its components are implicitly convertible.Note
The rules for this are almost identical to
std::expected, but they are expanded to supportvoidas the error_type. Any case where the C++ Standard makes an exception when value_type isvoid, that same exception has been extended to error_type ofvoid.
-
template<typename UValue, typename UError, std::enable_if_t<omni::detail::IsExpectedMoveConstructibleFrom<expected<UValue, UError>, expected>::is_explicit, bool> = true>
inline explicit constexpr expected(
)# Convert from src by direct initialization from the active element. If
src.has_value(), then this instance will have a value constructed frommove(src).value(); otherwise, this instance will have an error constructed frommove(src).error(). After this call,this->has_value() == src.has_value(). Note that the contents of src are moved-from, but not destructed, so the instances is still accessable.This converting constructor is not
explicitif conversion fromUValuetoTValueandUErrortoTErrorare notexplicit. Conversion fromvoidtovoidis also considered a nonexplicitconversion. Stated differently, aUExpectedis implicitly convertible to aTExpectedif both of its components are implicitly convertible.Note
The rules for this are almost identical to
std::expected, but they are expanded to supportvoidas the error_type. Any case where the C++ Standard makes an exception when value_type isvoid, that same exception has been extended to error_type ofvoid.
-
template<typename UError, std::enable_if_t<std::conjunction<std::is_constructible<TError, UError const&>, std::negation<std::is_convertible<UError const&, TError>>>::value, bool> = true>
inline explicit constexpr expected( - unexpected<UError> const &src,
Construct an instance using src as the error value. The constructed instance
!this->has_value()and thethis->error()will have been constructed bysrc.error().This constructor is not
explicitif the conversion from the sourceUErrortoTErroris not explicit. Stated differently, anunexpected<UError>is implicitly convertible to aexpected<TValue, TError>(of arbitraryTValue) ifUErroris implicitly convertible to aTError.If
TErrorisvoid, thenUErrormust also bevoidto construct an instance.
-
template<typename UError, std::enable_if_t<std::conjunction<std::is_constructible<TError, UError&&>, std::negation<std::is_convertible<UError&&, TError>>>::value, bool> = true>
inline explicit constexpr expected( - unexpected<UError> &&src,
Construct an instance using src as the error value. The constructed instance
!this->has_value()and thethis->error()will have been constructed bystd::move(src).error().This constructor is not
explicitif the conversion from the sourceUErrortoTErroris not explicit. Stated differently, anunexpected<UError>is implicitly convertible to aexpected<TValue, TError>(of arbitraryTValue) ifUErroris implicitly convertible to aTError.If
TErrorisvoid, thenUErrormust also bevoidto construct an instance.
-
inline constexpr bool has_value() const noexcept#
Test if this instance has a
value. If this returnstrue, then a call tovalue()will succeed, while a call toerror()would not. If this returnsfalse, a call toerror()will succeed, while a call tovalue()would not.
-
inline explicit constexpr operator bool() const noexcept#
Test if this instance has a
value. If this returnstrue, then a call tovalue()will succeed, while a call toerror()would not. If this returnsfalse, a call toerror()will succeed, while a call tovalue()would not.See also
-
constexpr value_type &value() &#
If this instance
has_value(), the value is returned by&.If this instance does not have a value, this call will not succeed. If exceptions are enabled, then a
bad_expected_accessexception is thrown containing the copied contents oferror(). If exceptions are disabled, then the program will terminate.Note
If value_type is
void, the return type is exactlyvoidinstead ofvoid&(which is illegal).
-
constexpr value_type const &value() const &#
If this instance
has_value(), the value is returned byconst&.If this instance does not have a value, this call will not succeed. If exceptions are enabled, then a
bad_expected_accessexception is thrown containing the copied contents oferror(). If exceptions are disabled, then the program will terminate.Note
If value_type is
void, the return type is exactlyvoidinstead ofvoid const&(which is illegal).
-
constexpr value_type &&value() &&#
If this instance
has_value(), the value is returned by&&.If this instance does not have a value, this call will not succeed. If exceptions are enabled, then a
bad_expected_accessexception is thrown containing the moved contents oferror(). If exceptions are disabled, then the program will terminate.Note
If value_type is
void, the return type is exactlyvoidinstead ofvoid&&(which is illegal).
-
constexpr value_type const &&value() const &&#
If this instance
has_value(), the value is returned byconst&&.If this instance does not have a value, this call will not succeed. If exceptions are enabled, then a
bad_expected_accessexception is thrown containing the copied contents oferror(). If exceptions are disabled, then the program will terminate.Note
If value_type is
void, the return type is exactlyvoidinstead ofvoid const&&(which is illegal).
-
template<typename UValue>
constexpr value_type value_or( - UValue &&default_value,
If this instance
has_value(), the value is copied and returned; otherwise, a value_type instance is constructed from default_value.Note
If value_type is
void, this member function does not exist. If value_type is not copy constructible, this will fail to compile in the immediate context (not SFINAE-safe).- Template Parameters:
UValue – Must be convertible to value_type.
-
template<typename UValue>
constexpr value_type value_or( - UValue &&default_value,
If this instance
has_value(), the value is moved and returned; otherwise, a value_type instance is constructed from default_value.Note
If value_type is
void, this member function does not exist. If value_type is not move constructible, this will fail to compile in the immediate context (not SFINAE-safe).- Template Parameters:
UValue – Must be convertible to value_type.
-
constexpr error_type &error() & noexcept#
If this instance
!has_value(), the error is returned by&.Note
If error_type is
void, the return type is exactlyvoidinstead ofvoid&(which is illegal).- Pre:
!this->has_value(): if this instance is not in the unexpected state, the program will terminate.
-
constexpr error_type const &error() const & noexcept#
If this instance
!has_value(), the error is returned byconst&.Note
If error_type is
void, the return type is exactlyvoidinstead ofvoid const&(which is illegal).- Pre:
!this->has_value(): if this instance is not in the unexpected state, the program will terminate.
-
constexpr error_type &&error() && noexcept#
If this instance
!has_value(), the error is returned by&&.Note
If error_type is
void, the return type is exactlyvoidinstead ofvoid&&(which is illegal).- Pre:
!this->has_value(): if this instance is not in the unexpected state, the program will terminate.
-
constexpr error_type const &&error() const && noexcept#
If this instance
!has_value(), the error is returned byconst&&.Note
If error_type is
void, the return type is exactlyvoidinstead ofvoid const&&(which is illegal).- Pre:
!this->has_value(): if this instance is not in the unexpected state, the program will terminate.
-
constexpr value_type *operator->() noexcept#
Access the underlying value instance. If
has_value()isfalse, the program will terminate.This function is only available if value_type is not
void.
-
constexpr value_type const *operator->() const noexcept#
Access the underlying value instance. If
has_value()isfalse, the program will terminate.This function is only available if value_type is not
void.
-
constexpr value_type &operator*() & noexcept#
If this instance
has_value(), the value is returned by&.If this instance does not have a value, the program will terminate.
Note
If value_type is
void, this overload is not enabled (only theconst&is accessible).
-
constexpr value_type const &operator*() const & noexcept#
If this instance
has_value(), the value is returned byconst&.If this instance does not have a value, the program will terminate.
Note
If value_type is
void, the return type is exactlyvoidinstead ofvoid const&(which is illegal).
-
constexpr value_type &&operator*() && noexcept#
If this instance
has_value(), the value is returned by&&.If this instance does not have a value, the program will terminate.
Note
If value_type is
void, this overload is not enabled (only theconst&is accessible).
-
constexpr value_type const &&operator*() const && noexcept#
If this instance
has_value(), the value is returned byconst&&.If this instance does not have a value, the program will terminate.
Note
If value_type is
void, this overload is not enabled (only theconst&is accessible).
-
template<typename ...TArgs>
value_type &emplace( - TArgs&&... args,
Destroy the current contents of this instance and construct the value_type of this instance through direct-initialization.
If value_type is not
void, this function accepts two overloads:template <typename... TArgs> value_type& emplace(TArgs&&... args) noexcept(only enabled ifstd::is_nothrow_constructible<value_type, TArgs...>::valueistrue)template <typename U, typename... TArgs> value_type& emplace(std::initializer_list<U>& il, TArgs&&... args) noexcept(only enabled ifstd::is_nothrow_constructible<value_type, std::initializer_list<U>&, TArgs...>::valueistrue)
After calling this function,
has_value()will returntrue.
-
void emplace() noexcept#
If value_type is
void, thenemplaceis a no argument function that returnsvoid.After calling this function,
has_value()will returntrue.
-
template<typename F>
inline constexpr auto transform(F &&f) const &# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureUValue (value_type const&); if value_type isvoid,Fhas the signatureUValue ().- Returns:
An
expected<UValue, error_type>, where the returned value has been transformed by f. The value_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform(F &&f) &# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureUValue (value_type&); if value_type isvoid,Fhas the signatureUValue ().- Returns:
An
expected<UValue, error_type>, where the returned value has been transformed by f. The value_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform(F &&f) &&# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureUValue (value_type&&); if value_type isvoid,Fhas the signatureUValue ().- Returns:
An
expected<UValue, error_type>, where the returned value has been transformed by f. The value_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform(F &&f) const &&# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureUValue (value_type const&&); if value_type isvoid,Fhas the signatureUValue ().- Returns:
An
expected<UValue, error_type>, where the returned value has been transformed by f. The value_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto and_then(F &&f) const &# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureexpected<UValue, UError> (value_type const&); if value_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UErrormust be constructible from error_type orvoid.
-
template<typename F>
inline constexpr auto and_then(F &&f) &# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureexpected<UValue, UError> (value_type&); if value_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UErrormust be constructible from error_type orvoid.
-
template<typename F>
inline constexpr auto and_then(F &&f) &&# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureexpected<UValue, UError> (value_type&&); if value_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UErrormust be constructible from error_type orvoid.
-
template<typename F>
inline constexpr auto and_then(F &&f) const &&# Transform the value by f if this
has_value()or return the error if it does not.- Template Parameters:
F – If value_type is not
void,Fhas the signatureexpected<UValue, UError> (value_type const&&); if value_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UErrormust be constructible from error_type orvoid.
-
template<typename F>
inline constexpr auto transform_error( - F &&f,
Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureUError (error_type const&); if error_type isvoid,Fhas the signatureUError ().- Returns:
An
expected<value_type, UError>, where the returned error has been transformed by f. The error_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform_error(F &&f) &# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureUError (error_type&); if error_type isvoid,Fhas the signatureUError ().- Returns:
An
expected<value_type, UError>, where the returned error has been transformed by f. The error_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform_error(F &&f) &&# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureUError (error_type&&); if error_type isvoid,Fhas the signatureUError ().- Returns:
An
expected<value_type, UError>, where the returned error has been transformed by f. The error_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto transform_error( - F &&f,
Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureUError (error_type const&&); if error_type isvoid,Fhas the signatureUError ().- Returns:
An
expected<value_type, UError>, where the returned error has been transformed by f. The error_type of the returned instance is the result type ofF.
-
template<typename F>
inline constexpr auto or_else(F &&f) const &# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureexpected<UValue, UError> (error_type const&); if error_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UValuemust be constructible from value_type orvoid.
-
template<typename F>
inline constexpr auto or_else(F &&f) &# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureexpected<UValue, UError> (error_type&); if error_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UValuemust be constructible from value_type orvoid.
-
template<typename F>
inline constexpr auto or_else(F &&f) &&# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureexpected<UValue, UError> (error_type&&); if error_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UValuemust be constructible from value_type orvoid.
-
template<typename F>
inline constexpr auto or_else(F &&f) const &&# Transform the error by f if this
has_value()isfalseor return the value if it does not.- Template Parameters:
F – If error_type is not
void,Fhas the signatureexpected<UValue, UError> (error_type const&&); if error_type isvoid,Fhas the signatureexpected<UValue, UError> (). In both cases,UValuemust be constructible from value_type orvoid.