Outcome (proposed std result)

Outcome (the library described by this documentation) originated in a negative reaction to then originally proposed std::expected<T, E>, though what got eventually standardised as std::expected<T, E> looks much more like Outcome’s result<T, E> than the original Expected. You can read here how those experiences led me to develop Outcome v1. Outcome comes in both standalone and Boost editions, and its current design was completed in 2018.

Outcome’s core is two workhorse types and a macro:

These three core items are then mixed into a veritable cornucopia of convenience typedefs and variations to support a wide range of use cases, including in C++ coroutines, plus there is extensive plumbing and customisation points for deciding how incompatible types ought to interact, or being notified of lifecycle events (e.g. capture a stack backtrace if a result<T, E> is constructed with an error).

Outcome perfectly propagates constexpr, triviality and noexcept-ness of each individual operation of the types you configure it with. It never touches dynamic memory allocation, and it has been carefully written so the compiler will optimise it out of codegen entirely wherever that is possible. It is capable of ‘true moves’ for types which declare themselves ‘move bitcopying compatible’ i.e. destructor calls on moved-from values are elided. ‘True moves’ can have a game changing performance gain on types with virtual destructors.

Outcome takes a lot of care to have the least possible impact on build times, and it guarantees that a binary built with it will have stable ABI so it is safe to use in really large C++ codebases (standalone edition only). For interoperation with other languages, it guarantees that C code can work with Outcome data types, and it provides a C macro API header file to help with that.

Outcome recognises Expected-like types and will construct from them, which aids interoperability. A simplified Result type is proposed for standardisation as std::result<T> where the E type is hard coded to a proposed std::error. This proposed standardisation has been deployed on billions of devices at the time of writing, and you can use it today via Experimental.Outcome, the reference implementation.