$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Outcome/expected/etc/etc/etc
From: Peter Dimov (lists_at_[hidden])
Date: 2017-06-05 11:57:20
Gottlob Frege wrote:
> Some days I'm like "man just accept empty, it would be a simple API", but 
> then I think "it is stupid for variant<int, double> to be empty". Other 
> days I think "just double buffer when necessary" (I assume that's your 
> direction Peter?), but then I think "I don't want double-buffering 
> variant<list, vector> to go on/off based on whether I use MS std vs libc++ 
> etc" and also "I don't want double buffering for cases that only happen in 
> theory, not in practice".
That is my direction, yes. My variant uses double storage when (1) not all 
types have noexcept move constructors and (2) there isn't a noexcept default 
constructible type in the list.
I think that in practice few variants will hit the double case, as it's rare 
to have variant<list, vector> without a scalar alternative, although who 
knows.
For variant<list, vector> specifically, when going from libstdc++ to MS STL 
the difference is that sizeof(variant) changes, but it changes for 
std::variant, too. Obviously, double storage can never be as good as single 
storage, but I view this as an acceptable compromise. You can guarantee 
single storage by putting a nothrow default constructible type in the list 
of alternatives.
> - I think std::expected should always throw something deriving from 
> std::exception.  So if E derives from std::exception, we can throw it. If 
> E is exception_ptr we can (re)throw it. If E is 
> error_code/system_error/etc we can figure out what to throw.  If E is 
> user-type, then we wrap it in bad_expected or whatever.
My suggested expected<> just calls `throw_on_unexpected(e)` unqualified 
(it's a customization point.) There are overloads for std::error_code and 
std::exception_ptr and the fallback default is to throw 
bad_expected_access<E>.