outcome v2.0-boost Release Notes
Release Date: 2018-01-18 // over 6 years ago-
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.
🚚 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.
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.
- You can now customise types directly, same as Expected, so