Releases: ned14/outcome
All tests passed 6417eac8f0f831066782311cd6b6ee1641454ec8
Don't include .git in the release tarball.
Use the 'all-sources' tarball below, NOT the github generated one which is missing dependencies:
v2.1.4 Boost 1.74 release
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 aresult<T>
from a non-errored
result<void>
, it default constructedT
. This was found to cause unhelpful
surprise, so it has been disabled. -
New macro
OUTCOME_ENABLE_LEGACY_SUPPORT_FOR
: 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, unlessOUTCOME_ENABLE_LEGACY_SUPPORT_FOR
is set to210
or lower. -
Concepts now live in
OUTCOME_V2_NAMESPACE::concepts
namespace
: Previously concepts lived in theconvert
namespace, now they live in their
own namespace. -
New concepts
basic_result<T>
andbasic_outcome<T>
added
: End users were finding an unhelpful gap in betweenis_basic_result<T>
andvalue_or_error<T>
where they wanted a concept that matched
types which werebasic_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:
#224
: 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.
Sorry.
v2.1.3 Boost 1.73 release
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
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 theoutcome::hl
cmake target to precompile Outcome, if
and only ifPROJECT_IS_DEPENDENCY
is false.PROJECT_IS_DEPENDENCY
is set
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:
#214
: 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.
#215
: For standalone Outcome, CMAKE_TOOLCHAIN_FILE
is now passed through during
dependency superbuild. This should solve build issues for some embedded toolchain
users.
#220
: A false positive undefined behaviour sanitiser failure in some use cases of
Experimental Outcome was worked around to avoid the failure message.
#221
: 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.
#223
: Fix a segfault in Debug builds only when cloning a status_code_ptr
in
Experimental.Outcome only.
v2.1.2 Boost 1.72 release
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.
Non-permissive parsing is now default in Visual Studio
: 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:
- Add Outcome as subdirectory to cmake build.
- Use cmake superbuild (i.e.
ExternalProject_Add()
) to build and install Outcome into
a local installation. - 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)
.
#199
: 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.
#210
: 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:
#184
: The detection of [[nodiscard]]
support in the compiler was very mildly broken.
v2.1.1 Boost 1.71 release
v2.1.1 19th August 2019 (Boost 1.71) [release]
Enhancements:
#184
: 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.
#185
: Add FAQ item explaining issue #185, and why we will do nothing to
fix it right now.
#189
: 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.
#183
: Added a separate motivation/plug_error_code
specifically for Boost.
Bug fixes:
: OUTCOME_VERSION_MINOR
hadn't been updated to 1.
#181
: Fix issue #181 where Outcome didn't actually implement the strong swap guarantee,
despite being documented as doing so.
#190
: Fix issue #190 in Boost edition where unit test suite was not runnable from
the Boost release distro.
#182
: 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()
.
#194
: 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 Boost 1.70 release
-
success()
andfailure()
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.
-
- GCC 5 no longer can compile Outcome at all due to https://stackoverflow.com/questions/45607450/gcc5-nested-variable-template-is-not-a-function-template.
Added explicit version trap for GCC 5 to say it can not work. Note this is not a
breaking change, GCC 5 was never supported officially in any v2 Outcome.
- GCC 5 no longer can compile Outcome at all due to https://stackoverflow.com/questions/45607450/gcc5-nested-variable-template-is-not-a-function-template.
-
- BREAKING CHANGE
result<T, E>
,boost_result<T, E>
andstd_result<T, E>
no longer implement hard UB on fetching a value from a valueless instance ifE
is
a UDT, they now fail to compile with a useful error message. If you wish hard UB,
useunchecked<T, E>
,boost_unchecked<T, E>
orstd_unchecked<T, E>
instead.
- BREAKING CHANGE
-
- 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.
- Fixed a nasty corner case bug where value type's without a copy constructor
-
Added experimental
status_result
andstatus_outcome
based on experimental
status_code
. -
Boost edition is now 100% Boost, so defaults for
result
andoutcome
are
boost::system::error_code::errc_t
andboost::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 withstd
types. -
Renamed ADL discovered customisation point
throw_as_system_error_with_payload()
tooutcome_throw_as_system_error_with_payload()
. -
- Added much clearer compile failure when user tries
result<T, T>
oroutcome
where two or more types are identical. Thanks to Andrzej Krzemieński
for suggesting a technique which combines SFINAE correctness with
the remaining ability forresult<T, T>
etc to be a valid type, but
not constructible.
- Added much clearer compile failure when user tries
-
- Fixed one of the oldest long open bugs in Outcome, that the noexcept
unit tests failed on OS X for an unknown reason.
- Fixed one of the oldest long open bugs in Outcome, that the noexcept
-
- Outcome did not construct correctly from
failure_type
.
- Outcome did not construct correctly from
-
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! -
operator==
andoperator!=
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 correctnoexcept
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 selectsvoid
orauto
edition
according to input parameter count.
-
- Fix generation of double underscored temporary variables in
OUTCOME_UNIQUE_NAME
, which is UB.
- Fix generation of double underscored temporary variables in
-
- Separated
result
from its hard coded dependency on the<system_error>
header. - Renamed
result
andoutcome
tobasic_result
andbasic_outcome
. - Renamed
result.hpp
intobasic_result.hpp
. - Moved
<system_error>
and<exception>
dependent code into new
std_result.hpp
andstd_outcome.hpp
header files. - Added
boost_result.hpp
andboost_outcome.hpp
which use Boost.System
and Boost.Exception (these areresult.hpp
andoutcome.hpp
in the Boost edition).
- Separated
v2.0 (Boost peer review edition)
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>
andoutcome<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
andE
types are interpreted viatrait::has_error_code_v<EC>
andtrait::has_exception_ptr_v<E>
. This allows custom payloads to
be easily attached toerror_code
andexception_ptr
.- C interoperability is now available, and some C macros for
working withstruct result_TYPE
are available in result.h. - Concepts TS is used when available, otherwise a partial
SFINAE-based emulation is used. - Types
EC
andE
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 withstd::variant
, in place
construction is achieved viain_place_type<T>
tagging. Explicit
conversion construction also works, we replicatestd::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 ofresult
oroutcome
we are constructing. - We implement construction from
ValueOrError
Concept matching
types which includestd::expected<T, E>
, as per theValueOrError
paper https://wg21.link/P0786. .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()
throwsbad_result_access|bad_outcome_access
orstd::system_error(EC)
orstd::rethrow_exception(EC)
or UB
if no value or returns a reference to the value..error()
throwsbad_result_access|bad_outcome_access
or UB if no
error or returns a reference to the error..exception()
throwsbad_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 nullexception_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.
- You can now customise types directly, same as Expected, so
-
Stuff removed:
- Anything even faintly smelling of monads.
- All the
make_XXX()
functions. Thestd::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
https://ned14.github.io/outcome/tutorial/hooks/keeping_state- 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 newchecked<T, E>
is a close substitute to Expected. See the FAQ entry on how to adapt
aresult<T, E>
into anexpected<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.
- Type traits now work direct on all member functions. Member
-
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
enabled. - 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.
- Outcome v2 needs a much newer compiler than before: clang 4 or
v1.0 Boost peer review (updated)
Outcome with all the changes from when the peer review was announced up until the peer review actually begins. See changelog below.
NOTE: Use the .rar tarball, NOT the github generated ones, theirs are missing all the submodule dependencies
20170519 boost_peer_review4:
-
Issue #13 The opcode counting CI tests in test/constexprs was severely broken on POSIX.
Thanks to Tom Westerhout for finding the problem and supplying its fix. -
unittests.cpp had become clang-tidy unclean, fixed.
-
Issue #15 Move
outcome::expected<T, E>
intooutcome::experimental::expected<T, E>
. Thanks to
Vicente J. Botet Escriba for persuading me to do this. -
Issue #14 Removed all the static asserts in the Expected implementation apart from the nothrow
move constructor check, which is now correct unlike the incorrect assert from before. Thanks to
Vicente J. Botet Escriba for explaining Expected's semantics. -
Issue #21 Correct misspelling of
extended_error_code
witherror_code_extended
in the docs.
Thanks to Deniz Bahadir for reporting this. -
Issue #17 Give credit to Paul Bristow for the name "Outcome". Thanks to Peter Dimov
for finding the correct person. -
Issue #18
result<T>
had a.set_exception()
which it should not have had. Thanks to Peter Dimov
for reporting this. -
Issue #19 Remove observers
.is_ready()
,.get_error_or()
,.get_exception_or()
. Thanks to Peter
Dimov and Andrzej Krzemienski for suggesting this. -
Issue #20 Rename:
monad_error
tobad_outcome
monad_errc
tobad_outcome_errc
monad_category
tobad_outcome_category
BOOST_OUTCOME_THROW_MONAD_ERROR
toBOOST_OUTCOME_THROW_BAD_OUTCOME
Thanks to Peter Dimov, Andrzej Krzemienski and Paul Bristow for suggesting this.
20170511 boost_peer_review3:
- First release for Boost peer review. If you want changelog before this, please consult the git log.
v1.0 Boost peer review (original)
Edition of Outcome submitted to Boost for peer review
NOTE: Use the tar.xz tarball, NOT the github generated ones, theirs are missing all the submodule dependencies