All Versions
Latest Version
Avg Release Cycle
176 days
Latest Release
1283 days ago

Changelog History

  • v2.1.5

    December 11, 2020
  • v2.1.4 Changes

    August 18, 2020

    πŸš€ v2.1.4 14th August 2020 (Boost 1.74) [release]

    ✨ Enhancements:

    πŸ’₯ BREAKING CHANGE void results and outcomes no longer default construct types during explicit construction
    : Previously if you explicitly constructed a result<T> from a non-errored
    0️⃣ result<void>, it default constructed T. This was found to cause unhelpful
    surprise, so it has been disabled.

    : The macro OUTCOME_ENABLE_LEGACY_SUPPORT_FOR` can be used to
    enable aliasing of older naming and features to newer naming and features when
    using a newer version of Outcome.

    πŸ’… Concepts now have snake case style naming instead of camel case style
    : When Outcome was first implemented, it was thought that C++ 20 concepts were
    πŸš€ going to have camel case style. This was changed before the C++ 20 release, and
    Outcome's concepts have been renamed similarly. This won't break any code in
    Outcome v2.1, as compatibility aliases are provided. However code compiled
    against Outcome v2.2 will need to be upgraded, unless OUTCOME_ENABLE_LEGACY_SUPPORT_FOR
    is set to 210 or lower.

    Concepts now live in OUTCOME_V2_NAMESPACE::concepts namespace
    : Previously concepts lived in the convert namespace, now they live in their
    own namespace.

    New concepts basic_result<T> and basic_outcome<T> added
    : End users were finding an unhelpful gap in between is_basic_result<T>
    and value_or_error<T> where they wanted a concept that matched
    types which were basic_result, but not exactly one of those. Concepts filling
    that gap were added.

    Operation TRY works differently from Outcome v2.2 onwards
    : This is a severely code breaking change which change the syntax of how one uses
    ⬆️ OUTCOME_TRY(). A regular expression suitable for upgrading code can be found in
    the list of changes between Outcome v2.1 and v2.2.

    πŸ› Bug fixes:

    βœ… : The clang Apple ships in Xcode 11.4 (currently the latest) has not been patched
    πŸ›  with the fixes to LLVM clang that fix noexcept(std::is_constructible<T, void>)
    failing to compile which I originally submitted years ago. So give up waiting on
    β†ͺ Apple to fix their clang, add a workaround to Outcome.

    Spare storage could not be used from within no-value policy classes
    : Due to an obvious brain fart when writing the code at the time, the spare storage
    APIs had the wrong prototype which prevented them working from within policy classes.

  • v2.1.3 Changes

    April 28, 2020

    πŸš€ v2.1.3 29th April 2020 (Boost 1.73) [release]

    The v2.1 branch is expected to be retired end of 2020, with the v2.2 branch
    0️⃣ becoming the default. You can use the future v2.2 branch now using
    πŸ‘ better_optimisation.
    πŸ‘€ This branch has a number of major changes to Outcome v2.1, see the front page
    for details.

    ✨ Enhancements:

    🐎 Performance of Outcome-based code compiled by clang has been greatly improved
    : The previous implementation of Outcome's status bitfield confused clang's
    optimiser, which caused low quality codegen. Unlike most codegen issues, this was
    πŸ”” noticeably in empirical benchmarks of real world code, as was shown by
    P1886 Error speed benchmarking.

    πŸ‘ The safe part of the better_optimisation
    πŸ”€ Outcome v2.2.0 future branch was merged to Outcome v2.1.3 which includes a new
    status bitfield implementation. This appears to not confuse clang's optimiser,
    and clang 9 produces code which routinely beats GCC 9's code for various canned
    πŸ‘‰ use cases.

    Precompiled headers are automatically enabled on new enough cmake's for standalone Outcome
    πŸ— : If on cmake 3.16 or later, its new precompiled headers build support is used
    to tell consumers of the outcome::hl cmake target to precompile Outcome, if
    and only if
    by Outcome's CMakeLists.txt if it detects that it was included using
    add_subdirectory(), so for the vast majority of Outcome end users, the use
    of precompiled headers will NOT be enabled.

    Exported targets do NOT request precompilation of headers, as it is
    πŸ”§ assumed that importers of the Outcome cmake targets will configure their own
    precompiled headers which incorporate Outcome.

    πŸ‘· Installability is now CI tested per commit
    : Due to installability of standalone Outcome (e.g. make install) breaking
    πŸ‘· itself rather more frequently than is ideal, installability is now tested on CI
    per commit.

    πŸ‘ Coroutines support has been documented
    πŸ‘ : The coroutines support added in v2.1.2 has now been properly documented.

    πŸ› Bug fixes:

    : Newer Concepts implementing compilers were unhappy with the early check for
    🚚 destructibility of T and E, so removed template constraints, falling back
    to static assert which runs later in the type instantiation sequence.

    : For standalone Outcome, CMAKE_TOOLCHAIN_FILE is now passed through during
    πŸ— dependency superbuild. This should solve build issues for some embedded toolchain
    πŸ‘‰ users.

    : A false positive undefined behaviour sanitiser failure in some use cases of
    Experimental Outcome was worked around to avoid the failure message.

    🏁 : Restored compatibility with x86 on Windows, which was failing with link errors.
    It was quite surprising that this bug was not reported sooner, but obviously
    🏁 almost nobody is using Outcome with x86 on Windows.

    : Fix a segfault in Debug builds only when cloning a status_code_ptr in
    Experimental.Outcome only.

  • v2.1.2 Changes

    December 18, 2019

    πŸš€ v2.1.2 11th December 2019 (Boost 1.72) [release]

    ✨ Enhancements:

    πŸ‘Œ Improved compatibility with cmake tooling
    πŸ“¦ : Standalone outcome is now make install-able, and cmake find_package() can find it.
    πŸ“¦ Note that you must separately install and find_package() Outcome's dependency, quickcpplib,
    πŸ“¦ else find_package() of Outcome will fail.

    0️⃣ Non-permissive parsing is now default in Visual Studio
    0️⃣ : The default targets in standalone Outcome's cmake now enable non-permissive parsing.
    This was required partially because VS2019 16.3's quite buggy Concepts implementation is
    πŸ“œ unusuable in permissive parsing mode. Even then, lazy ADL two phase lookup is broken
    βœ… in VS2019 16.3 with /std:latest, you may wish to use an earlier language standard.

    πŸ’₯ Breaking change!
    : The git submodule mechanism used by standalone Outcome of specifying dependent libraries
    has been replaced with a cmake superbuild of dependencies mechanism instead. Upon cmake
    πŸ”§ configure, an internal copy of quickcpplib will be git cloned, built and installed into the
    πŸ— build directory from where an internal find_package() uses it. This breaks the use of
    the unconfigured Outcome repo as an implementation of Outcome, one must now do one of:

    πŸ— 1. Add Outcome as subdirectory to cmake build. πŸ— 2. Use cmake superbuild (i.e. ExternalProject_Add()) to build and install Outcome into
    a local installation.

    1. Use one of the single header editions.

    πŸ’₯ Breaking change!
    : For standalone Outcome, the current compiler is now checked for whether it will compile
    code containing C++ Concepts, and if it does, all cmake consumers of Outcome will enable
    C++ Concepts. Set the cmake variable CXX_CONCEPTS_FLAGS to an empty string to prevent
    πŸ‘ auto detection and enabling of C++ Concepts support occurring.

    OUTCOME_TRY operation now hints to the compiler that operation will be successful
    : P1886 Error speed benchmarking showed that there is
    considerable gain in very small functions by hinting to the compiler whether the expression
    is expected to be successful or not. OUTCOME_TRY previously did not hint to the compiler
    at all, but now it does. A new suite of macros OUTCOME_TRY_FAILURE_LIKELY hint to the
    compiler that failure is expected. If you wish to return to the previously unhinted
    behaviour, define OUTCOME_TRY_LIKELY(expr) to (!!expr).

    πŸ‘ : Support for C++ Coroutines has been added. This comes in two parts, firstly there is
    now an OUTCOME_CO_TRY() operation suitable for performing the TRY operation from
    πŸ‘ within a C++ Coroutine. Secondly, in the header outcome/coroutine_support.hpp there are
    implementations of eager<OutcomeType> and lazy<OutcomeType> which let you more
    naturally and efficiently use basic_result or basic_outcome from within C++
    πŸ‘» Coroutines -- specifically, if the result or outcome will construct from an exception
    pointer, exceptions thrown in the coroutine return an errored or excepted result with
    πŸ‘» the thrown exception instead of throwing the exception through the coroutine machinery
    (which in current compilers, has a high likelihood of blowing up the program). Both
    βœ… eager<T> and lazy<T> can accept any T as well. Both have been tested and found
    working on VS2019 and clang 9.

    : make_error_code() and make_exception_ptr() are now additionally considered for
    🚚 compatible copy and move conversions for basic_result<>. This lets you construct
    a basic_result<T, E> into a basic_result<T, error_code>, where E is a
    πŸ†“ custom type which has implemented the ADL discovered free function
    error_code make_error_code(E), but is otherwise unrelated to error_code.
    The same availability applies for exception_ptr with make_exception_ptr() being
    πŸ‘ the ADL discovered free function. basic_outcome<> has less support for this than
    basic_result<> in order to keep constructor count down, but it will accept via
    this mechanism conversions from basic_result<> and failure_type<>.

    πŸ› Bug fixes:

    πŸ‘ : The detection of [[nodiscard]] support in the compiler was very mildly broken.

  • v2.1.1 Changes

    September 24, 2019

    πŸš€ v2.1.1 19th August 2019 (Boost 1.71) [release]

    ✨ Enhancements:

    πŸš€ : As per request from Boost release managers, relocated version.hpp and
    revision.hpp into detail, and added the Boost licence boilerplate to the top
    of every source file which was missing one (I think). Also took the opportunity
    to run the licence restamping script over all Outcome, so copyright dates are now
    up to date.

    πŸ™‹ : Add FAQ item explaining issue #185, and why we will do nothing to
    πŸ›  fix it right now.

    πŸ”¨ : Refactored the OUTCOME_TRY implementation to use more clarified
    🚚 customisation points capable of accepting very foreign inputs. Removed the
    std::experimental::expected<T, E> specialisations, as those are no longer
    πŸ“š necessary. Fixed the documentation for the customisation points which
    previously claimed that they are ADL discovered, which they are not. Added
    πŸ‘ a recipe describing how to add in support for foreign input types.

    : Added a separate motivation/plug_error_code specifically for Boost.

    πŸ› Bug fixes:

    πŸ”– : OUTCOME_VERSION_MINOR hadn't been updated to 1.

    : Fix issue #181 where Outcome didn't actually implement the strong swap guarantee,
    despite being documented as doing so.

    βœ… : Fix issue #190 in Boost edition where unit test suite was not runnable from
    πŸš€ the Boost release distro.

    πŸ‘» : Fix issue #182 where trait::is_exception_ptr_available<T> was always true,
    πŸ–¨ thus causing much weirdness, like not printing diagnostics and trying to feed
    πŸ‘» everything to make_exception_ptr().

    : Fix issue #192 where the std::basic_outcome_failure_exception_from_error()
    🌐 was being defined twice for translation units which combine standalone and
    Boost Outcome's.

  • v2.1 Changes

    June 17, 2019


    - success() and failure() now produce types marked [[nodiscard]].

    include/outcome/outcome.natvis is now namespace permuted like the rest of
    Outcome, so debugging Outcome based code in Visual Studio should look much
    prettier than before.


    - .has_failure() was returning false at times when it should have returned true.



    • BREAKING CHANGE result<T, E>, boost_result<T, E> and std_result<T, E>
      no longer implement hard UB on fetching a value from a valueless instance if E is
      a UDT, they now fail to compile with a useful error message. If you wish hard UB,
      use unchecked<T, E>, boost_unchecked<T, E> or std_unchecked<T, E> instead.


    • Fixed a nasty corner case bug where value type's without a copy constructor
      🚚 but with a move constructor would indicate via traits that copy construction
      was available. Thanks to Microsoft's compiler team for reporting this issue.

    Added experimental status_result and status_outcome based on experimental

    0️⃣ Boost edition is now 100% Boost, so defaults for result and outcome are
    boost::system::error_code::errc_t and boost::exception_ptr. Moreover,
    βœ… the test suite in the Boost edition now exclusively tests the Boost edition.
    One can, of course, freely use the standalone edition with Boost, and the Boost
    edition with std types.

    Renamed ADL discovered customisation point throw_as_system_error_with_payload()
    to outcome_throw_as_system_error_with_payload().


    • Added much clearer compile failure when user tries result<T, T> or outcome
      where two or more types are identical. Thanks to Andrzej KrzemieΔΉβ€žski
      for suggesting a technique which combines SFINAE correctness with
      the remaining ability for result<T, T> etc to be a valid type, but
      not constructible.


    • Fixed one of the oldest long open bugs in Outcome, that the noexcept
      βœ… unit tests failed on OS X for an unknown reason.


    - Outcome did not construct correctly from failure_type.

    🚚 Inexplicably outcome's error + exception constructor had been removed.
    πŸ‘€ Nobody noticed during the Boost peer review, which is worrying seeing as that
    constructor is needed for one of the main advertised features to Boost!

    #107 and #116

    • operator== and operator!= now become disabled if the value, error and
      πŸ‘» exception types do not implement the same operator.

    - Relatedly, both comparison operators simply didn't work right. Fixed.


    • swap() now has correct noexcept calculation and now correctly orders
      the swaps to be whichever is the throwing swap first.

    βž• Added reference dump of v2.1 ABI so we can check if ABI breakage detection
    πŸ‘· works in the next set of changes, plus Travis job to check ABI and API compatibility
    per commit.


    • OUTCOME_TRY is now overloaded and selects void or auto edition
      according to input parameter count.


    • Fix generation of double underscored temporary variables in
      OUTCOME_UNIQUE_NAME, which is UB.


    • Separated result from its hard coded dependency on the <system_error> header.
    • Renamed result and outcome to basic_result and basic_outcome.
    • Renamed result.hpp into basic_result.hpp.
    • Moved <system_error> and <exception> dependent code into new
      std_result.hpp and std_outcome.hpp header files.
    • Added boost_result.hpp and boost_outcome.hpp which use Boost.System
      πŸ‘» and Boost.Exception (these are result.hpp and outcome.hpp in the Boost edition).
  • v2.0-boost Changes

    January 18, 2018

    NOTE: Use the .tar.xz tarball attached, NOT the github generated ones, theirs are missing all the submodule dependencies

    πŸ”„ Changes since v1.0:

    As per the Boost peer review feedback, v2 Outcome has been pared down to
    no more than the barest of bare essentials. The plan is to participate
    πŸ“„ in a generalised C++ Monadic interface (P0650R0)
    🚚 so all the monadic stuff is removed.

    Major changes:

    • You can now customise types directly, same as Expected, so result<T, EC = std::error_code> and outcome<T, EC = std::error_code, E = std::exception_ptr>.
    • Default construction no longer permitted, as per review feedback.
    • Empty state no longer possible, as per review feedback. Write
      optional<result<T, E>> if you want that.
    • As per review feedback, Variant storage gone, it's now a struct-based
      type for simplicity.
    • EC and E types are interpreted via trait::has_error_code_v<EC>
      πŸ‘» and trait::has_exception_ptr_v<E>. This allows custom payloads to
      πŸ‘» be easily attached to error_code and exception_ptr.
    • C interoperability is now available, and some C macros for
      working with struct result_TYPE are available in result.h.
    • Concepts TS is used when available, otherwise a partial
      SFINAE-based emulation is used.
    • Types EC and E must be default constructible. T need not
      be so.
    • Constructors now follow those of std::variant, so it will
      implicitly convert from any input constructible to any of its types so
      long as it is not ambiguous. As with std::variant, in place
      construction is achieved via in_place_type<T> tagging. Explicit
      conversion construction also works, we replicate std::variant's
      value semantics very closely despite not having variant storage.
    • New type sugar types success<T>, failure<EC, E> for being
      explicit about which kind of result or outcome we are constructing.
    • We implement construction from ValueOrError Concept matching
      types which include std::expected<T, E>, as per the ValueOrError
    • .has_value(), .has_error() and .has_exception() now only
      return true if that specific member is present. A new
      .has_failure() is true if errored or excepted.
    • .value() throws bad_result_access|bad_outcome_access
      or std::system_error(EC) or std::rethrow_exception(EC) or UB
      if no value or returns a reference to the value.
    • .error() throws bad_result_access|bad_outcome_access or UB if no
      error or returns a reference to the error.
    • .exception() throws bad_result_access|bad_outcome_access or UB if no
      πŸ‘» exception or returns a reference to the exception.
    • .failure() returns the exception if present, else a synthesised
      πŸ‘» exception_ptr from the error, else a null exception_ptr.
    • .assume_value(), .assume_error(), .assume_payload() and
      .assume_exception() all provide runtime unchecked UB access to the
      underlying storage.
    • The doxygen docs which were widely criticised have been replaced
      with an experimental Standardese + Hugo based solution instead.

    🚚 Stuff removed:

    • Anything even faintly smelling of monads.
    • All the make_XXX() functions. The std::variant based constructor
      interface make them no longer necessary.
    • All preprocessor assembly of code fragments. You now have an
      equally complex rabbit warren of policy and trait driven composited
      fragments of template into implementation. I did warn reviewers during
      πŸ‘ the v1 review that a pure C++ v2 would be no better in this regard than
      the preprocessor assembled v1.
    • All macro based customisation points. We now use an ADL function
      based, or injection of type specialisation, customisation points. 100% C++.
    • error_code_extended is gone for now. It is believed that via the
      customisation points you can easily implement your own. There is
      a worked example at
    • Any operators apart from boolean test, strict equality and
      inequality comparison.
    • Any ability to change state after construction.
    • LEWG expected<T, E> is gone. The new checked<T, E>
      πŸ‘€ is a close substitute to Expected. See the FAQ entry on how to adapt
      a result<T, E> into an expected<T, E> with a simple shim class.

    Stuff retained:

    • OUTCOME_TRY, OUTCOME_TRYV, OUTCOME_TRYX all work as before.
    • noexcept propagation from types chosen works correctly.
    • Triviality of copy, move and destruction from types
      chosen is propagated correctly.
    • v1 unit test has been almost entirely ported over to v2 without
      much change other than what was needed. Porting v1 based code to v2
      should be 95% possible using find regex in files and replace.

    Stuff gained:

    • Type traits now work direct on all member functions. Member
      🚚 variable traits are no longer necessary, and so have been removed.
    • Outcome v2 now conforms in every way to a typical STL vocabulary
      type. No unusual design tradeoffs or changes.

    Stuff lost:

    • Outcome v2 needs a much newer compiler than before: clang 4 or
      πŸ‘ better, GCC 6 or better, VS2017 or better. Ideally with Concepts
    • Compile time load may now be higher than with v1. In my own
      code, there is an approx 15% compile time regression in v2 over v1.