basic_result<T, E, NoValuePolicy>
A sum type carrying either a T or an E, with NoValuePolicy specifying what to do if one tries to read state which isn’t there. Either or both of T and E can be void to indicate no value for that state is present. Note that E = void makes basic result into effectively an optional<T>, but with NoValuePolicy configurable behaviour. Detectable using is_basic_result<T>.
Requires: Concept requirements if C++ 20, else static asserted:
- That trait type_can_be_used_in_basic_result<R>is true for bothTandE.
- That either EisvoidorDefaultConstructible.
Namespace: BOOST_OUTCOME_V2_NAMESPACE
Header: <boost/outcome/basic_result.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_TYPEis1,<utility>(defaults to1for C++ 17 or later only)
- If C++ exceptions disabled and BOOST_OUTCOME_DISABLE_EXECINFOundefined 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 result suitable for use in global header files of very large C++ codebases.
Design rationale
The basic result type is the main workhorse type of the Outcome library, providing a simple sum type with optional values representing success or disappointment. Unlike 
 P0323 std::expected<T, E>, Outcome’s result type is designed specifically for convenience when implementing failure handling across very large codebases, and it has a number of API differences to facilitate that.
The first major design difference is that basic result models its constructor design on 
 std::variant<...>, rather than modelling 
 std::optional<T>’s constructor design like std::expected<T, E> does. This means that basic result will implicitly construct either a T or an E if doing so is unambiguous, same as variant does. Where implicit construction is ambiguous, the implicit constructors disable and a T or E can be specified via in_place_type_t<T>, or via success_type<T> or failure_type<T>. We implement a subset of variant’s constructors for improved compile time impact, so the implicit and explicit constructor design is split into fixed subsets to reduce SFINAE execution.
The second major design difference is that union storage is NOT used, as it is assumed that sizeof(E) will be small for failure handling. This very considerably reduces load on the compiler, and substantially improves compile times in very large C++ 14 codebases, because copies and moves do not need to jump through complex ceremony in order to implement the never-empty guarantees which would be required in a union storage based implementation (C++ 17 onwards does far fewer copy and move constructor instantiations, but it all adds up – work avoided is always the fastest).
Public member type aliases
- value_typeis- T.
- error_typeis- E.
- value_type_if_enabledis- Tif construction from- Tis available, else it is a usefully named unusable internal type.
- error_type_if_enabledis- Eif construction from- Eis available, else it is a usefully named unusable internal type.
- rebind<A, B = E, C = NoValuePolicy>is- basic_result<A, B, C>.
Protected member predicate booleans
- predicate::constructors_enabledis constexpr boolean true if decayed- value_typeand decayed- error_typeare not the same type.
- predicate::implicit_constructors_enabledis constexpr boolean true if:- predicate::constructors_enabledis true.
- Trait is_error_type<E>is not true for both decayedvalue_typeand decayederror_typeat the same time.
- value_typeis not implicitly constructible from- error_typeand- error_typeis not implicitly constructible from- value_type.
 OR
 trait- is_error_type<E>is true for decayed- error_typeand- error_typeis not implicitly constructible from- value_typeand- value_typeis an integral type.
 
- predicate::enable_value_converting_constructor<A>is constexpr boolean true if:- predicate::constructors_enabledis true.
- Decayed Ais not thisbasic_resulttype.
- predicate::implicit_constructors_enabledis true.
- Decayed Ais not anin_place_type_t.
- Trait is_error_type_enum<E, Enum>is false forerror_typeand decayedA.
- value_typeis implicitly constructible from- Aand- error_typeis not implicitly constructible from- A.
 OR- value_typeis the exact same type as decayed- Aand- value_typeis implicitly constructible from- A.
 
- predicate::enable_error_converting_constructor<A>is constexpr boolean true if:- predicate::constructors_enabledis true.
- Decayed Ais not thisbasic_resulttype.
- predicate::implicit_constructors_enabledis true.
- Decayed Ais not anin_place_type_t.
- Trait is_error_type_enum<E, Enum>is false forerror_typeand decayedA.
- value_typeis not implicitly constructible from- Aand- error_typeis implicitly constructible from- A.
 OR- error_typeis the exact same type as decayed- Aand- error_typeis implicitly constructible from- A.
 
- predicate::enable_error_condition_converting_constructor<ErrorCondEnum>is constexpr boolean true if:- predicate::constructors_enabledis true.
- Decayed ErrorCondEnumis not thisbasic_resulttype.
- Decayed ErrorCondEnumis not anin_place_type_t.
- Trait is_error_type_enum<E, Enum>is true forerror_typeand decayedErrorCondEnum.
 
- predicate::enable_compatible_conversion<A, B, C>is constexpr boolean true if:- predicate::constructors_enabledis true.
- basic_result<A, B, C>is not this- basic_resulttype.
- Ais- voidOR- value_typeis explicitly constructible from- A.
- Bis- voidOR- error_typeis explicitly constructible from- B.
 
- predicate::enable_inplace_value_constructor<Args...>is constexpr boolean true if:- predicate::constructors_enabledis true.
- value_typeis- voidOR- value_typeis explicitly constructible from- Args....
 
- predicate::enable_inplace_error_constructor<Args...>is constexpr boolean true if:- predicate::constructors_enabledis true.
- error_typeis- voidOR- error_typeis explicitly constructible from- Args....
 
- predicate::enable_inplace_value_error_constructor<Args...>is constexpr boolean true if:- predicate::constructors_enabledis true.
- predicate::implicit_constructors_enabledis true.
- Either, but not both, of value_typeis explicitly constructible fromArgs...orerror_typeis explicitly constructible fromArgs....
 
Summary of standard requirements provided
- DefaultConstructible
- MoveConstructible, if both- value_typeand- error_typeimplement move constructors.
- CopyConstructible, if both- value_typeand- error_typeimplement copy constructors.
- MoveAssignable, if both- value_typeand- error_typeimplement move constructors and move assignment.
- CopyAssignable, if both- value_typeand- error_typeimplement copy constructors and copy assignment.
- Destructible.
- TriviallyCopyable, if both- value_typeand- error_typeare trivially copyable.
- TrivialType, if both- value_typeand- error_typeare trivial types.
- LiteralType, if both- value_typeand- error_typeare literal types.
- StandardLayoutType, if both- value_typeand- error_typeare standard layout types. If so, layout of- basic_resultin C is guaranteed to be:- struct result_layout { value_type value; unsigned int flags; error_type error; };
- EqualityComparable, if both- value_typeand- error_typeimplement equality comparisons with one another.
- LessThanComparable- value_typeand- error_type, this can cause major surprise (i.e. hard to diagnose bugs), so we don’t implement these at all. ~- Swappable
- Hash
Thus basic_result meets the Regular concept if both value_type and error_type are Regular, except for the lack of a default constructor. Often where one needs a default constructor, wrapping basic_result into 
 std::optional<T> will suffice.
Public member functions
Disabling constructors
- 
	basic_result(Args...) = deleteDisabling catchall constructor used to give useful diagnostic error when trying to use non-inplace constructors when predicate::constructors_enabledis false.
- 
	basic_result(X &&) = deleteDisabling implicit constructor used to give useful diagnostic error when trying to use implicit constructors when predicate::implicit_constructors_enabledis false.
Copy and move constructors and assignment, and destructor
- 
    basic_result() = deleteThe default constructor (disabled). 
- 
    basic_result(basic_result &&)Move constructor. Constexpr, triviality and noexcept propagating. 
- 
    basic_result(const basic_result &)Copy constructor. Constexpr, triviality and noexcept propagating. 
- 
    basic_result &operator=(basic_result &&)Move assignment. Constexpr, triviality and noexcept propagating. 
- 
    basic_result &operator=(const basic_result &)Copy assignment. Constexpr, triviality and noexcept propagating. 
- 
    ~basic_result()Destructor. Constexpr, triviality and noexcept propagating. 
Converting constructors
- 
    basic_result(R &&)Implicit value_typeconstructor. Available ifpredicate::enable_value_converting_constructor<R>is true. Constexpr, triviality and noexcept propagating.
- 
    basic_result(S &&)Implicit error_typeconstructor. Available ifpredicate::enable_error_converting_constructor<S>is true. Constexpr, triviality and noexcept propagating.
- 
    basic_result(ErrorCondEnum &&)Implicit error_typefromErrorCondEnumconstructor. Available ifpredicate::enable_error_condition_converting_constructor<ErrorCondEnum>is true. Constexpr, triviality and noexcept propagating.
- 
    explicit basic_result(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_result(const basic_result<R, S, P> &)Explicit converting copy constructor from compatible basic_result. Available ifpredicate::enable_compatible_conversion<R, S, P>is true. Constexpr, triviality and noexcept propagating.
- 
    explicit basic_result(basic_result<R, S, P> &&)Explicit converting move constructor from compatible basic_result. Available ifpredicate::enable_compatible_conversion<R, S, P>is true. Constexpr, triviality and noexcept propagating.
Inplace constructors
- 
    explicit basic_result(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_result(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_result(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_result(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.
- 
    basic_result(A1 &&, A2 &&, Args ...)Implicit inplace value or error constructor. Available if predicate::enable_inplace_value_error_constructor<A1, A2, Args ...>is true. Constexpr, triviality and noexcept propagating.
Tagged constructors
- 
    basic_result(const success_type<T> &)Implicit value-from-success-type-sugar copy constructor. Available if predicate::enable_compatible_conversion<T, void, void>is true, orTisvoid. Constexpr, triviality and noexcept propagating.
- 
    basic_result(success_type<T> &&)Implicit value-from-success-type-sugar move constructor. Available if predicate::enable_compatible_conversion<T, void, void>is true, orTisvoid. Constexpr, triviality and noexcept propagating.
- 
    basic_result(const failure_type<T> &)Implicit error-from-failure-type-sugar copy constructor. Available if predicate::enable_compatible_conversion<void, T, void>is true, orTisvoid. Constexpr, triviality and noexcept propagating.
- 
    basic_result(failure_type<T> &&)Implicit error-from-failure-type-sugar move constructor. Available if predicate::enable_compatible_conversion<void, T, void>is true, orTisvoid. Constexpr, triviality and noexcept propagating.
Observers
- 
    explicit operator bool() const noexceptReturns true if a value is present. Constexpr, never throws. 
- 
    bool has_value() const noexceptReturns true if a value is present. Constexpr, never throws. 
- 
    bool has_error() const noexceptReturns true if an error is present. Constexpr, never throws. 
- 
    bool has_exception() const noexceptAlways returns false for basic_result. Constexpr, never throws.
- 
    bool has_failure() const noexceptReturns true if there is either an error or an exception. Constexpr, never throws. 
- 
    value_type &assume_value() & noexceptNarrow contract lvalue reference observer of any value present. Constexpr propagating, never throws. 
- 
    const value_type &assume_value() const & noexceptNarrow contract const lvalue reference observer of any value present. Constexpr propagating, never throws. 
- 
    value_type &&assume_value() && noexceptNarrow contract rvalue reference observer of any value present. Constexpr propagating, never throws. 
- 
    const value_type &&assume_value() const && noexceptNarrow 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() & noexceptNarrow contract lvalue reference observer of the stored error. Constexpr propagating, never throws. 
- 
    const error_type &assume_error() const & noexceptNarrow contract const lvalue reference observer of the stored error. Constexpr propagating, never throws. 
- 
    error_type &&assume_error() && noexceptNarrow contract rvalue reference observer of the stored error. Constexpr propagating, never throws. 
- 
    const error_type &&assume_error() const && noexceptNarrow 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. 
- 
    auto as_failure() const &Return the output from free function failure()containing a copy of any errored state.
Modifiers
- 
    void swap(basic_result &)Swap one basic_result with another. Noexcept propagating. 
- 
    auto as_failure() &&Return the output from free function failure()containing a move of any errored state.
Comparisons
See above for why LessThanComparable is not implemented.
- 
    bool operator==(const basic_result<A, B, C> &) constReturns true if this result compares equal to the other result. Constexpr and noexcept propagating. 
- 
    bool operator==(const success_type<A> &) constReturns true if this result compares equal to the success type sugar. Constexpr and noexcept propagating. 
- 
    bool operator==(const failure_type<A, void> &) constReturns true if this result compares equal to the failure type sugar. Constexpr and noexcept propagating. 
- 
    bool operator!=(const basic_result<A, B, C> &) constReturns true if this result does not compare equal to the other result. Constexpr and noexcept propagating. 
- 
    bool operator!=(const success_type<A> &) constReturns true if this result does not compare equal to the success type sugar. Constexpr and noexcept propagating. 
- 
    bool operator!=(const failure_type<A, void> &) constReturns true if this result does not compare equal to the failure type sugar. Constexpr and noexcept propagating. 



