basic_outcome<T, EC, EP, NoValuePolicy>
A type carrying one of (i) a successful T
(ii) a disappointment EC
(iii) a failure EP
(iv) both a disappointment EC
and a failure EP
, with NoValuePolicy
specifying what to do if one tries to read state which isn’t there. Any one, two, or all of T
, EC
and EP
can be void
to indicate no value for that state is present. Detectable using is_basic_outcome<T>
.
Requires: Concept requirements if C++ 20, else static asserted:
- That trait
type_can_be_used_in_basic_result<R>
is true forT
,EC
andEP
. - That either
EC
isvoid
orDefaultConstructible
. - That either
EP
isvoid
orDefaultConstructible
.
Namespace: BOOST_OUTCOME_V2_NAMESPACE
Header: <boost/outcome/basic_outcome.hpp>
Inclusions: The very lightest weight of C and C++ header files:
<cstdint>
<initializer_list>
<iosfwd>
<new>
<type_traits>
- If
BOOST_OUTCOME_USE_STD_IN_PLACE_TYPE
is1
,<utility>
(defaults to1
for C++ 17 or later only) - If C++ exceptions disabled and
BOOST_OUTCOME_DISABLE_EXECINFO
undefined only (used to print stack backtraces on “exception throw”):<sal.h>
(Windows only)<stddef.h>
(Windows only)<string.h>
(Windows only)<execinfo.h>
(POSIX only)
<cstdio>
<cstdlib>
<cassert>
This very light weight set of inclusion dependencies makes basic outcome suitable for use in global header files of very large C++ codebases.
Design rationale
basic_outcome
extends basic_result<T, E, NoValuePolicy>
with a third state to transport,
conventionally (but not necessarily) some sort of “abort” or “exceptional” state which a function can
return to indicate that not only did the operation fail, but it did so catastrophically i.e. please
abort any attempt to retry the operation.
A perfect alternative is to throw a C++ exception for the abort code path, and indeed most programs
ought to do exactly that instead of using basic_outcome
. However there are a number of use cases
where choosing basic_outcome
shines:
- Where C++ exceptions or RTTI is not available, but the ability to fail catastrophically without terminating the program is important.
- Where deterministic behaviour is required even in the catastrophic failure situation.
- In unit test suites of code using Outcome it is extremely convenient to accumulate test failures
into a
basic_outcome
for later reporting. A similar convenience applies to RPC situations, where C++ exception throws need to be accumulated for reporting back to the initiating endpoint. - Where a function is “dual use deterministic” i.e. it can be used deterministically, in which case
one switches control flow based on
.error()
, or it can be used non-deterministically by throwing an exception perhaps carrying a custom payload.
Public member type aliases
value_type
isT
.error_type
isEC
.exception_type
isEP
.no_value_policy_type
isNoValuePolicy
.value_type_if_enabled
isT
if construction fromT
is available, else it is a usefully named unusable internal type.error_type_if_enabled
isEC
if construction fromEC
is available, else it is a usefully named unusable internal type.exception_type_if_enabled
isEP
if construction fromEP
is available, else it is a usefully named unusable internal type.rebind<A, B = EC, C = EP, D = NoValuePolicy>
isbasic_outcome<A, B, C, D>
.
Protected member predicate booleans
predicate::constructors_enabled
is constexpr boolean true if:- Decayed
value_type
and decayederror_type
are not the same type, or both arevoid
. - Decayed
value_type
and decayedexception_type
are not the same type, or both arevoid
. - Decayed
error_type
and decayedexception_type
are not the same type, or both arevoid
.
- Decayed
predicate::implicit_constructors_enabled
is constexpr boolean true if:predicate::constructors_enabled
is true.- Trait
is_error_type<E>
is not true for both decayedvalue_type
and decayederror_type
at the same time. value_type
is not implicitly constructible fromerror_type
anderror_type
is not implicitly constructible fromvalue_type
.
OR
traitis_error_type<E>
is true for decayederror_type
anderror_type
is not implicitly constructible fromvalue_type
andvalue_type
is an integral type.value_type
is not implicitly constructible fromexception_type
.error_type
is not implicitly constructible fromexception_type
.exception_type
is not implicitly constructible fromvalue_type
.exception_type
is not implicitly constructible fromerror_type
.
predicate::enable_value_converting_constructor<A>
is constexpr boolean true if:predicate::constructors_enabled
is true.- Decayed
A
is not thisbasic_outcome
type. predicate::implicit_constructors_enabled
is true.- Decayed
A
is not anin_place_type_t
. - Trait
is_error_type_enum<E, Enum>
is false forerror_type
and decayedA
. value_type
is implicitly constructible fromA
anderror_type
is not implicitly constructible fromA
.
ORvalue_type
is the exact same type as decayedA
andvalue_type
is implicitly constructible fromA
.exception_type
is not implicitly constructible fromA
.
predicate::enable_error_converting_constructor<A>
is constexpr boolean true if:predicate::constructors_enabled
is true.- Decayed
A
is not thisbasic_outcome
type. predicate::implicit_constructors_enabled
is true.- Decayed
A
is not anin_place_type_t
. - Trait
is_error_type_enum<E, Enum>
is false forerror_type
and decayedA
. value_type
is not implicitly constructible fromA
anderror_type
is implicitly constructible fromA
.
ORerror_type
is the exact same type as decayedA
anderror_type
is implicitly constructible fromA
.exception_type
is not implicitly constructible fromA
.
predicate::enable_error_condition_converting_constructor<ErrorCondEnum>
is constexpr boolean true if:predicate::constructors_enabled
is true.- Decayed
ErrorCondEnum
is not thisbasic_outcome
type. - Decayed
ErrorCondEnum
is not anin_place_type_t
. - Trait
is_error_type_enum<E, Enum>
is true forerror_type
and decayedErrorCondEnum
. exception_type
is not implicitly constructible fromErrorCondEnum
.
predicate::enable_exception_converting_constructor<A>
is constexpr boolean true if:predicate::constructors_enabled
is true.- Decayed
A
is not thisbasic_outcome
type. predicate::implicit_constructors_enabled
is true.- Decayed
A
is not anin_place_type_t
. value_type
is not implicitly constructible fromA
.error_type
is not implicitly constructible fromA
.exception_type
is implicitly constructible fromA
.
predicate::enable_error_exception_converting_constructor<A, B>
is constexpr boolean true if:predicate::constructors_enabled
is true.- Decayed
A
is not thisbasic_outcome
type. predicate::implicit_constructors_enabled
is true.- Decayed
A
is not anin_place_type_t
. value_type
is not implicitly constructible fromA
.error_type
is implicitly constructible fromA
.value_type
is not implicitly constructible fromB
.exception_type
is implicitly constructible fromB
.
predicate::enable_compatible_conversion<A, B, C, D>
is constexpr boolean true if:predicate::constructors_enabled
is true.basic_outcome<A, B, C, D>
is not thisbasic_outcome
type.A
isvoid
ORvalue_type
is explicitly constructible fromA
.B
isvoid
ORerror_type
is explicitly constructible fromB
.C
isvoid
ORexception_type
is explicitly constructible fromC
.
predicate::enable_make_error_code_compatible_conversion<A, B, C, D>
is constexpr boolean true if:predicate::constructors_enabled
is true.basic_outcome<A, B, C, D>
is not thisbasic_outcome
type.- Trait
is_error_code_available<T>
is true for decayederror_type
. predicate::enable_compatible_conversion<A, B, C, D>
is not true.A
isvoid
ORvalue_type
is explicitly constructible fromA
.error_type
is explicitly constructible frommake_error_code(B)
.C
isvoid
ORexception_type
is explicitly constructible fromC
.
predicate::enable_inplace_value_constructor<Args...>
is constexpr boolean true if:predicate::constructors_enabled
is true.value_type
isvoid
ORvalue_type
is explicitly constructible fromArgs...
.
predicate::enable_inplace_error_constructor<Args...>
is constexpr boolean true if:predicate::constructors_enabled
is true.error_type
isvoid
ORerror_type
is explicitly constructible fromArgs...
.
predicate::enable_inplace_exception_constructor<Args...>
is constexpr boolean true if:predicate::constructors_enabled
is true.exception_type
isvoid
ORexception_type
is explicitly constructible fromArgs...
.
predicate::enable_inplace_value_error_exception_constructor<Args...>
is constexpr boolean true if:predicate::constructors_enabled
is true.predicate::implicit_constructors_enabled
is true.- Exactly one of
value_type
is explicitly constructible fromArgs...
, orerror_type
is explicitly constructible fromArgs...
, orexception_type
is explicitly constructible fromArgs...
.
Summary of standard requirements provided
, always deleted to force user to choose valued or errored or excepted for every outcome instanced.DefaultConstructible
MoveConstructible
, if all ofvalue_type
,error_type
andexception_type
implement move constructors.CopyConstructible
, if all ofvalue_type
,error_type
andexception_type
implement copy constructors.MoveAssignable
, if all ofvalue_type
,error_type
andexception_type
implement move constructors and move assignment.CopyAssignable
, if all ofvalue_type
,error_type
andexception_type
implement copy constructors and copy assignment.Destructible
.TriviallyCopyable
, if all ofvalue_type
,error_type
andexception_type
are trivially copyable.TrivialType
, if all ofvalue_type
,error_type
andexception_type
are trivial types.LiteralType
, if all ofvalue_type
,error_type
andexception_type
are literal types.. It is implementation defined ifStandardLayoutType
basic_outcome
can be used by C. However all of the three major compilers MSVC, GCC and clang implement C layout ofbasic_outcome
as follows:struct outcome_layout { struct result_layout { value_type value; unsigned int flags; error_type error; }; exception_type exception; };
If you choose standard layout
value_type
,error_type
andexception_type
,basic_outcome
works fine from C on MSVC, GCC and clang.EqualityComparable
, if all ofvalue_type
,error_type
andexception_type
implement equality comparisons with one another., not implemented due to availability of implicit conversions fromLessThanComparable
value_type
,error_type
andexception_type
, this can cause major surprise (i.e. hard to diagnose bugs), so we don’t implement these at all. ~Swappable
, not implemented as a generic implementation of a unique hash for non-valued items which are unequal would require a dependency on RTTI being enabled.Hash
Thus basic_outcome
meets the Regular
concept if all of value_type
, error_type
and exception_type
are Regular
, except for the lack of a default constructor. Often where one needs a default constructor, wrapping basic_outcome
into
std::optional<T>
will suffice.
Public member functions
Disabling constructors
-
basic_outcome(Args...) = delete
Disabling catchall constructor used to give useful diagnostic error when trying to use non-inplace constructors when
predicate::constructors_enabled
is false. -
basic_outcome(X &&) = delete
Disabling implicit constructor used to give useful diagnostic error when trying to use implicit constructors when
predicate::implicit_constructors_enabled
is false.
Copy and move constructors and assignment, and destructor
-
basic_outcome() = delete
The default constructor (disabled).
-
basic_outcome(basic_outcome &&)
Move constructor. Constexpr, triviality and noexcept propagating.
-
basic_outcome(const basic_outcome &)
Copy constructor. Constexpr, triviality and noexcept propagating.
-
basic_outcome &operator=(basic_outcome &&)
Move assignment. Constexpr, triviality and noexcept propagating.
-
basic_outcome &operator=(const basic_outcome &)
Copy assignment. Constexpr, triviality and noexcept propagating.
-
~basic_outcome()
Destructor. Constexpr, triviality and noexcept propagating.
Converting constructors
-
basic_outcome(R &&)
Implicit
value_type
constructor. Available ifpredicate::enable_value_converting_constructor<R>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(S &&)
Implicit
error_type
constructor. Available ifpredicate::enable_error_converting_constructor<S>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(ErrorCondEnum &&)
Implicit
error_type
fromErrorCondEnum
constructor. Available ifpredicate::enable_error_condition_converting_constructor<ErrorCondEnum>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(P &&)
Implicit
exception_type
constructor. Available ifpredicate::enable_exception_converting_constructor<P>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(S &&, P &&)
Implicit
error_type
+exception_type
constructor. Available ifpredicate::enable_error_exception_converting_constructor<S, P>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(ValueOrError<T, E> &&)
Explicit converting constructor from
ValueOrError<T, E>
concept matching types. Available ifconvert::value_or_error<>
permits it. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(const basic_outcome<A, B, C, D> &)
Explicit converting copy constructor from compatible
basic_outcome
. Available ifpredicate::enable_compatible_conversion<A, B, C, D>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(basic_outcome<A, B, C, D> &&)
Explicit converting move constructor from compatible
basic_outcome
. Available ifpredicate::enable_compatible_conversion<A, B, C, D>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(const basic_result<A, B, C> &)
Explicit converting copy constructor from compatible
basic_result
. Available ifpredicate::enable_compatible_conversion<A, B, void, C>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(basic_result<A, B, C> &&)
Explicit converting move constructor from compatible
basic_result
. Available ifpredicate::enable_compatible_conversion<A, B, void, C>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(const basic_result<A, B, C> &)
Explicit converting copy constructor from compatible
basic_result
. Available ifpredicate::enable_make_error_code_compatible_conversion<A, B, void, C>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(basic_result<A, B, C> &&)
Explicit converting move constructor from compatible
basic_result
. Available ifpredicate::enable_make_error_code_compatible_conversion<A, B, void, C>
is true. Constexpr, triviality and noexcept propagating.
Inplace constructors
-
explicit basic_outcome(in_place_type_t<value_type_if_enabled>, Args ...)
Explicit inplace value constructor. Available if
predicate::enable_inplace_value_constructor<Args ...>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(in_place_type_t<value_type_if_enabled>, std::initializer_list<U>, Args ...)
Explicit inplace value constructor. Available if
predicate::enable_inplace_value_constructor<std::initializer_list<U>, Args ...>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(in_place_type_t<error_type_if_enabled>, Args ...)
Explicit inplace error constructor. Available if
predicate::enable_inplace_error_constructor<Args ...>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(in_place_type_t<error_type_if_enabled>, std::initializer_list<U>, Args ...)
Explicit inplace error constructor. Available if
predicate::enable_inplace_error_constructor<std::initializer_list<U>, Args ...>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(in_place_type_t<exception_type_if_enabled>, Args ...)
Explicit inplace exception constructor. Available if
predicate::enable_inplace_exception_constructor<Args ...>
is true. Constexpr, triviality and noexcept propagating. -
explicit basic_outcome(in_place_type_t<exception_type_if_enabled>, std::initializer_list<U>, Args ...)
Explicit inplace exception constructor. Available if
predicate::enable_inplace_exception_constructor<std::initializer_list<U>, Args ...>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(A1 &&, A2 &&, Args ...)
Implicit inplace value or error or exception constructor. Available if
predicate::enable_inplace_value_error_exception_constructor<A1, A2, Args ...>
is true. Constexpr, triviality and noexcept propagating.
Tagged constructors
-
basic_outcome(const success_type<T> &)
Implicit value-from-success-type-sugar copy constructor. Available if
predicate::enable_compatible_conversion<T, void, void>
is true, orT
isvoid
. Constexpr, triviality and noexcept propagating. -
basic_outcome(success_type<T> &&)
Implicit value-from-success-type-sugar move constructor. Available if
predicate::enable_compatible_conversion<T, void, void>
is true, orT
isvoid
. Constexpr, triviality and noexcept propagating. -
basic_outcome(const failure_type<EC> &)
Implicit error-from-failure-type-sugar copy constructor. Available if
predicate::enable_compatible_conversion<void, EC, void, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(failure_type<EC> &&)
Implicit error-from-failure-type-sugar move constructor. Available if
predicate::enable_compatible_conversion<void, EC, void, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(const failure_type<EC> &)
Implicit error-from-failure-type-sugar copy constructor. Available if
predicate::enable_make_error_code_compatible_conversion<void, EC, void, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(failure_type<EC> &&)
Implicit error-from-failure-type-sugar move constructor. Available if
predicate::enable_make_error_code_compatible_conversion<void, EC, void, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(const failure_type<EP> &)
Implicit exception-from-failure-type-sugar copy constructor. Available if
predicate::enable_compatible_conversion<void, void, EP, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(failure_type<EP> &&)
Implicit exception-from-failure-type-sugar move constructor. Available if
predicate::enable_compatible_conversion<void, void, EP, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(const failure_type<EC, EP> &)
Implicit error-and-exception-from-failure-type-sugar copy constructor. Available if
predicate::enable_compatible_conversion<void, EC, EP, void>
is true. Constexpr, triviality and noexcept propagating. -
basic_outcome(failure_type<EC, EP> &&)
Implicit error-and-exception-from-failure-type-sugar move constructor. Available if
predicate::enable_compatible_conversion<void, EC, EP, void>
is true. Constexpr, triviality and noexcept propagating.
Observers
-
explicit operator bool() const noexcept
Returns true if a value is present. Constexpr, never throws.
-
bool has_value() const noexcept
Returns true if a value is present. Constexpr, never throws.
-
bool has_error() const noexcept
Returns true if an error is present. Constexpr, never throws.
-
bool has_exception() const noexcept
Returns true if an exception is present. Constexpr, never throws.
-
bool has_failure() const noexcept
Returns true if there is either an error or an exception. Constexpr, never throws.
-
value_type &assume_value() & noexcept
Narrow contract lvalue reference observer of any value present. Constexpr propagating, never throws.
-
const value_type &assume_value() const & noexcept
Narrow contract const lvalue reference observer of any value present. Constexpr propagating, never throws.
-
value_type &&assume_value() && noexcept
Narrow contract rvalue reference observer of any value present. Constexpr propagating, never throws.
-
const value_type &&assume_value() const && noexcept
Narrow contract const rvalue reference observer of any value present. Constexpr propagating, never throws.
-
value_type &value() &
Wide contract lvalue reference observer of any value present. Constexpr propagating.
-
const value_type &value() const &
Wide contract const lvalue reference observer of any value present. Constexpr propagating.
-
value_type &&value() &&
Wide contract rvalue reference observer of any value present. Constexpr propagating.
-
const value_type &&value() const &&
Wide contract const rvalue reference observer of any value present. Constexpr propagating.
-
error_type &assume_error() & noexcept
Narrow contract lvalue reference observer of the stored error. Constexpr propagating, never throws.
-
const error_type &assume_error() const & noexcept
Narrow contract const lvalue reference observer of the stored error. Constexpr propagating, never throws.
-
error_type &&assume_error() && noexcept
Narrow contract rvalue reference observer of the stored error. Constexpr propagating, never throws.
-
const error_type &&assume_error() const && noexcept
Narrow contract const rvalue reference observer of the stored error. Constexpr propagating, never throws.
-
error_type &error() &
Wide contract lvalue reference observer of the stored error. Constexpr propagating.
-
const error_type &error() const &
Wide contract const lvalue reference observer of the stored error. Constexpr propagating.
-
error_type &&error() &&
Wide contract rvalue reference observer of the stored error. Constexpr propagating.
-
const error_type &&error() const &&
Wide contract const rvalue reference observer of the stored error. Constexpr propagating.
-
exception_type &assume_exception() & noexcept
Narrow contract lvalue reference observer of the stored exception. Constexpr propagating, never throws.
-
const exception_type &assume_exception() const & noexcept
Narrow contract const lvalue reference observer of the stored exception. Constexpr propagating, never throws.
-
const exception_type &&assume_exception() const && noexcept
Narrow contract const rvalue reference observer of the stored exception. Constexpr propagating, never throws.
-
exception_type &&assume_exception() && noexcept
Narrow contract rvalue reference observer of the stored exception. Constexpr propagating, never throws.
-
exception_type &exception() &
Wide contract lvalue reference observer of the stored exception. Constexpr propagating.
-
const exception_type &exception() const &
Wide contract const lvalue reference observer of the stored exception. Constexpr propagating.
-
exception_type &&exception() &&
Wide contract rvalue reference observer of the stored exception. Constexpr propagating.
-
const exception_type &&exception() const &&
Wide contract const rvalue reference observer of the stored exception. Constexpr propagating.
-
exception_type failure() const noexcept
Synthesising observer of the stored exception or error. Available if the traits
is_error_code_available<T>
andis_exception_ptr_available<T>
are both true. Never throws. -
failure_type<error_type, exception_type> as_failure() const &
Return the output from free function
failure()
containing a copy of any errored and/or excepted state.
Modifiers
-
void swap(basic_outcome &)
Swap one basic_outcome with another, with the strong guarantee. Noexcept propagating.
-
failure_type<error_type, exception_type> as_failure() &&
Return the output from free function
failure()
containing a move of any errored and/or excepted state.
Comparisons
See above for why LessThanComparable
is not implemented.
-
bool operator==(const basic_result<A, B, C> &) const
Returns true if this outcome compares equal to the other result. Constexpr and noexcept propagating.
-
bool operator==(const basic_outcome<A, B, C, D> &) const
Returns true if this outcome compares equal to the other outcome. Constexpr and noexcept propagating.
-
bool operator==(const success_type<A> &) const
Returns true if this result compares equal to the success type sugar. Constexpr and noexcept propagating.
-
bool operator==(const failure_type<A, B> &) const
Returns true if this outcome compares equal to the failure type sugar. Constexpr and noexcept propagating.
-
bool operator!=(const basic_result<A, B, C> &) const
Returns true if this outcome does not compare equal to the other result. Constexpr and noexcept propagating.
-
bool operator!=(const basic_outcome<A, B, C, D> &) const
Returns true if this outcome does not compare equal to the other outcome. Constexpr and noexcept propagating.
-
bool operator!=(const success_type<A> &) const
Returns true if this outcome does not compare equal to the success type sugar. Constexpr and noexcept propagating.
-
bool operator!=(const failure_type<A, B> &) const
Returns true if this outcome does not compare equal to the failure type sugar. Constexpr and noexcept propagating.