Topic: expected and exceptions: learning from variant


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 13 Nov 2015 13:51:14 -0800 (PST)
Raw View
------=_Part_981_126679000.1447451474103
Content-Type: multipart/alternative;
 boundary="----=_Part_982_1609701710.1447451474104"

------=_Part_982_1609701710.1447451474104
Content-Type: text/plain; charset=UTF-8

The N4109 proposal for `expected` <http://wg21.link/N4109> defines a type
that is structurally similar to `variant`. Which means that it has the
exception problem. The problem basically boils down to this: what do you do
if you try to set the data in a live `expected`, a type which is different
from its current type, and the construction of the new type fails?

The current N4109 proposal says that there will be "no effect" in such a
circumstance. As we've learned from our endless `variant` discussions, the
only way to have a never-empty construct that has "no effect" in such a
circumstance without imposing restrictions on the types involved, is to
double-buffer. And a dynamic double buffer is no solution (even if people
would accept such memory allocation, and they absolutely will not), so it
would have to be a static double buffer.

In other words, your `expected` type would have to internally store twice
the size of its data, enough to have two T's or two E's simultaneously
constructed within it.

However, N4109 also has different exception requirements from P0088
<http://wg21.link/P0088>. That `variant` treats exceptions thrown during
copy assignment (ie: the variant has a T and you assign another value of
type T) as being no different from exceptions thrown during copy
construction (ie: the variant has a U and you assign a value of type T).
Both cases will make the variant invalid.

N4109 is designed instead to work like `optional<T>`. If you assign T to an
unengaged optional that throws, then the `optional` remains unengaged. If
you assign T to an engaged `optional<T>` that throws... well, you get
whatever T guarantees on copy assignment failure.

That would make sense for the desired uses for `expected`. But there's just
one problem: it's not really possible. As we learned with variant, the only
way to implement that is with double-buffering.

Unless...

The reason assignment to an unengaged `optional<T>` can get away with it is
because the implementation is always guaranteed to be able to make the
optional unengaged after an assignment failure. Also, the unegaged state is
"monostate" and therefore has no value associated with it.

So all we need to do is leverage something we learned from P0110, aka:
Williams.Variant <http://wg21.link/P0110>. Namely, he discovered a way to
implement a variant that would be able to double-buffer, but only if *two*
types in the variant were nothrow moveable. If only one were nothrow
moveable, then assignment of a different value to the same state would
simply result in whatever exception guarantees that type offers.

Therefore, I suggest that `expected` impose a requirement. The requirements
on T should be as minimal as possible (ie: no more than what optional
requires), we should require that E be nothrow moveable. That way, if you
have an `expected<T, E>` that is in the error state, and you assign/emplace
a T to it, the system can easily move E to temporary stack memory (which is
safe), do the assignment/emplacement, and if it fails, just move E back
(which is still safe). And if your expected has T, and you assign/emplace
an E value to it, the system does the emplacement to the stack. If it
succeeds, then it destroys T and moves the new E into the memory (which is
safe).

This would allow `expected` to fulfill the requirements it states without
having to double buffer.

I do not believe that requiring E to be nothrow moveable would be a
substantial impediment to users. `expected` is not a general-purpose
variant, after all. And even `expected_ptr` is nothrow moveable.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_982_1609701710.1447451474104
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><a href=3D"http://wg21.link/N4109">The N4109 proposal for =
`expected`</a> defines a type that is structurally similar to `variant`. Wh=
ich means that it has the exception problem. The problem basically boils do=
wn to this: what do you do if you try to set the data in a live `expected`,=
 a type which is different from its current type, and the construction of t=
he new type fails?<br><br>The current N4109 proposal says that there will b=
e &quot;no effect&quot; in such a circumstance. As we&#39;ve learned from o=
ur endless `variant` discussions, the only way to have a never-empty constr=
uct that has &quot;no effect&quot; in such a circumstance without imposing =
restrictions on the types involved, is to double-buffer. And a dynamic doub=
le buffer is no solution (even if people would accept such memory allocatio=
n, and they absolutely will not), so it would have to be a static double bu=
ffer.<br><br>In other words, your `expected` type would have to internally =
store twice the size of its data, enough to have two T&#39;s or two E&#39;s=
 simultaneously constructed within it.<br><br>However, N4109 also has diffe=
rent exception requirements from <a href=3D"http://wg21.link/P0088">P0088</=
a>. That `variant` treats exceptions thrown during copy assignment (ie: the=
 variant has a T and you assign another value of type T) as being no differ=
ent from exceptions thrown during copy construction (ie: the variant has a =
U and you assign a value of type T). Both cases will make the variant inval=
id.<br><br>N4109 is designed instead to work like `optional&lt;T&gt;`. If y=
ou assign T to an unengaged optional that throws, then the `optional` remai=
ns unengaged. If you assign T to an engaged `optional&lt;T&gt;` that throws=
.... well, you get whatever T guarantees on copy assignment failure.<br><br>=
That would make sense for the desired uses for `expected`. But there&#39;s =
just one problem: it&#39;s not really possible. As we learned with variant,=
 the only way to implement that is with double-buffering.<br><br>Unless...<=
br><br>The reason assignment to an unengaged `optional&lt;T&gt;` can get aw=
ay with it is because the implementation is always guaranteed to be able to=
 make the optional unengaged after an assignment failure. Also, the unegage=
d state is &quot;monostate&quot; and therefore has no value associated with=
 it.<br><br>So all we need to do is leverage something we learned from <a h=
ref=3D"http://wg21.link/P0110">P0110, aka: Williams.Variant</a>. Namely, he=
 discovered a way to implement a variant that would be able to double-buffe=
r, but only if <i>two</i> types in the variant were nothrow moveable. If on=
ly one were nothrow moveable, then assignment of a different value to the s=
ame state would simply result in whatever exception guarantees that type of=
fers.<br><br>Therefore, I suggest that `expected` impose a requirement. The=
 requirements on T should be as minimal as possible (ie: no more than what =
optional requires), we should require that E be nothrow moveable. That way,=
 if you have an `expected&lt;T, E&gt;` that is in the error state, and you =
assign/emplace a T to it, the system can easily move E to temporary stack m=
emory (which is safe), do the assignment/emplacement, and if it fails, just=
 move E back (which is still safe). And if your expected has T, and you ass=
ign/emplace an E value to it, the system does the emplacement to the stack.=
 If it succeeds, then it destroys T and moves the new E into the memory (wh=
ich is safe).<br><br>This would allow `expected` to fulfill the requirement=
s it states without having to double buffer.<br><br>I do not believe that r=
equiring E to be nothrow moveable would be a substantial impediment to user=
s. `expected` is not a general-purpose variant, after all. And even `expect=
ed_ptr` is nothrow moveable.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_982_1609701710.1447451474104--
------=_Part_981_126679000.1447451474103--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Fri, 13 Nov 2015 14:13:24 -0800
Raw View
--001a113cf57c430a4c0524735e63
Content-Type: text/plain; charset=UTF-8

On Fri, Nov 13, 2015 at 1:51 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>
> I do not believe that requiring E to be nothrow moveable would be a
> substantial impediment to users. `expected` is not a general-purpose
> variant, after all. And even `expected_ptr` is nothrow moveable.
>

While I agree that constraining E or constraining operations on an
expected<> that contain a type with a move-constructor that can throw
*shouldn't* be a problem, I doubt that people would be willing to accept
this, and I'd personally be dismayed if we got these constraints for
expected<> yet not for variant<>. The arguments that people were giving as
to why they didn't want constraints for variant fields/operations on those
fields still would apply here. If they have an E that contains something
like a standard library type whose move may or may not be noexcept, then
they cannot be guaranteed to use it (or at least use assignment) with
expected<>. I'm under the assumption that whatever variant<> does
(consensus is the corrupted_by_exception state), then expected<> should do
the same and for the same reasons. As much as I personally dislike the
notion of a "corrupted" state both for variant<> *and* for expected<>, I'd
rather that expected<> at least be consistent with variant<>. It's not
clear why it would be "okay" to constrain "E" for expected<> but not
constrain a variant<> field or one of the associated operations. Both are
general-purpose facilities even if you happen to label E as "unexpected."

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a113cf57c430a4c0524735e63
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Nov 13, 2015 at 1:51 PM, Nicol Bolas=C2=A0<span dir=3D"ltr">&lt;<a href=
=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&g=
t;</span>=C2=A0wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bord=
er-left-style:solid;padding-left:1ex"><div dir=3D"ltr">I do not believe tha=
t requiring E to be nothrow moveable would be a substantial impediment to u=
sers. `expected` is not a general-purpose variant, after all. And even `exp=
ected_ptr` is nothrow moveable.</div></blockquote><div><br></div><div>While=
 I agree that constraining E or constraining operations on an expected&lt;&=
gt; that contain a type with a move-constructor that can throw <i>shouldn&#=
39;t</i> be a problem, I doubt that people would be willing to accept this,=
 and I&#39;d personally be dismayed if we got these constraints for expecte=
d&lt;&gt; yet not for variant&lt;&gt;. The arguments that people were givin=
g as to why they didn&#39;t want constraints for variant fields/operations =
on those fields still would apply here. If they have an E that contains som=
ething like a standard library type whose move may or may not be noexcept, =
then they cannot be guaranteed to use it (or at least use assignment) with =
expected&lt;&gt;. I&#39;m under the assumption that whatever variant&lt;&gt=
; does (consensus is the corrupted_by_exception state), then expected&lt;&g=
t; should do the same and for the same reasons. As much as I personally dis=
like the notion of a &quot;corrupted&quot; state both for variant&lt;&gt; <=
i>and</i> for expected&lt;&gt;, I&#39;d rather that expected&lt;&gt; at lea=
st be consistent with variant&lt;&gt;. It&#39;s not clear why it would be &=
quot;okay&quot; to constrain &quot;E&quot; for expected&lt;&gt; but not con=
strain a variant&lt;&gt; field or one of the associated operations. Both ar=
e general-purpose facilities even if you happen to label E as &quot;unexpec=
ted.&quot;</div></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cf57c430a4c0524735e63--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 13 Nov 2015 16:12:10 -0800 (PST)
Raw View
------=_Part_1083_1537248349.1447459930541
Content-Type: multipart/alternative;
 boundary="----=_Part_1084_1836893081.1447459930542"

------=_Part_1084_1836893081.1447459930542
Content-Type: text/plain; charset=UTF-8



On Friday, November 13, 2015 at 5:13:26 PM UTC-5, Matt Calabrese wrote:
>
> On Fri, Nov 13, 2015 at 1:51 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>>
>> I do not believe that requiring E to be nothrow moveable would be a
>> substantial impediment to users. `expected` is not a general-purpose
>> variant, after all. And even `expected_ptr` is nothrow moveable.
>>
>
> While I agree that constraining E or constraining operations on an
> expected<> that contain a type with a move-constructor that can throw
> *shouldn't* be a problem, I doubt that people would be willing to accept
> this, and I'd personally be dismayed if we got these constraints for
> expected<> yet not for variant<>. The arguments that people were giving as
> to why they didn't want constraints for variant fields/operations on those
> fields still would apply here. If they have an E that contains something
> like a standard library type whose move may or may not be noexcept, then
> they cannot be guaranteed to use it (or at least use assignment) with
> expected<>. I'm under the assumption that whatever variant<> does
> (consensus is the corrupted_by_exception state), then expected<> should do
> the same and for the same reasons. As much as I personally dislike the
> notion of a "corrupted" state both for variant<> *and* for expected<>,
> I'd rather that expected<> at least be consistent with variant<>. It's not
> clear why it would be "okay" to constrain "E" for expected<> but not
> constrain a variant<> field or one of the associated operations. Both are
> general-purpose facilities even if you happen to label E as "unexpected."
>

`expected` is not a "general-purpose facility"; it is a means of error
handling. That's why it doesn't use `variant`'s get-style interface, nor
does it allow `variant`-style visitation. That's why it's explicitly
limited to 2 items. There's a "good" state and a "bad" state. `variant`
makes no judgement about any particular state.

`expected` is functionality similar to `variant`, but in terms of users, it
will be treated much more like `optional`. Therefore, it should have
`optional`'s behavior, not `variant`'s.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1084_1836893081.1447459930542
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Friday, November 13, 2015 at 5:13:26 PM UTC-5, Matt Calabrese wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div=
 class=3D"gmail_quote">On Fri, Nov 13, 2015 at 1:51 PM, Nicol Bolas=C2=A0<s=
pan dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"RYI8mn3nFwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;=
;return true;">jmck...@gmail.com</a>&gt;</span>=C2=A0<wbr>wrote:<blockquote=
 class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:=
1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left=
:1ex"><div dir=3D"ltr">I do not believe that requiring E to be nothrow move=
able would be a substantial impediment to users. `expected` is not a genera=
l-purpose variant, after all. And even `expected_ptr` is nothrow moveable.<=
/div></blockquote><div><br></div><div>While I agree that constraining E or =
constraining operations on an expected&lt;&gt; that contain a type with a m=
ove-constructor that can throw <i>shouldn&#39;t</i> be a problem, I doubt t=
hat people would be willing to accept this, and I&#39;d personally be disma=
yed if we got these constraints for expected&lt;&gt; yet not for variant&lt=
;&gt;. The arguments that people were giving as to why they didn&#39;t want=
 constraints for variant fields/operations on those fields still would appl=
y here. If they have an E that contains something like a standard library t=
ype whose move may or may not be noexcept, then they cannot be guaranteed t=
o use it (or at least use assignment) with expected&lt;&gt;. I&#39;m under =
the assumption that whatever variant&lt;&gt; does (consensus is the corrupt=
ed_by_exception state), then expected&lt;&gt; should do the same and for th=
e same reasons. As much as I personally dislike the notion of a &quot;corru=
pted&quot; state both for variant&lt;&gt; <i>and</i> for expected&lt;&gt;, =
I&#39;d rather that expected&lt;&gt; at least be consistent with variant&lt=
;&gt;. It&#39;s not clear why it would be &quot;okay&quot; to constrain &qu=
ot;E&quot; for expected&lt;&gt; but not constrain a variant&lt;&gt; field o=
r one of the associated operations. Both are general-purpose facilities eve=
n if you happen to label E as &quot;unexpected.&quot;</div></div></div></di=
v></blockquote><div><br>`expected` is not a &quot;general-purpose facility&=
quot;; it is a means of error handling. That&#39;s why it doesn&#39;t use `=
variant`&#39;s get-style interface, nor does it allow `variant`-style visit=
ation. That&#39;s why it&#39;s explicitly limited to 2 items. There&#39;s a=
 &quot;good&quot; state and a &quot;bad&quot; state. `variant` makes no jud=
gement about any particular state.<br><br>`expected` is functionality simil=
ar to `variant`, but in terms of users, it will be treated much more like `=
optional`. Therefore, it should have `optional`&#39;s behavior, not `varian=
t`&#39;s.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1084_1836893081.1447459930542--
------=_Part_1083_1537248349.1447459930541--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 13 Nov 2015 20:52:41 -0500
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
 255, 255); line-height: initial;">                                        =
                                              <div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">I think it is totally reasonable to place constraints on E.&nbs=
p;</div><div style=3D"width: 100%; font-size: initial; font-family: Calibri=
, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align:=
 initial; background-color: rgb(255, 255, 255);"><br></div>                =
                                                                           =
                                          <div style=3D"width: 100%; font-s=
ize: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; co=
lor: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255,=
 255);"><br style=3D"display:initial"></div>                               =
                                                                           =
                                                                           =
              <div style=3D"font-size: initial; font-family: Calibri, 'Slat=
e Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initia=
l; background-color: rgb(255, 255, 255);">Sent&nbsp;from&nbsp;my&nbsp;Black=
Berry&nbsp;10&nbsp;smartphone&nbsp;on&nbsp;the&nbsp;Rogers&nbsp;network.</d=
iv>                                                                        =
                                                                           =
                               <table width=3D"100%" style=3D"background-co=
lor:white;border-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"font-=
size: initial; text-align: initial; background-color: rgb(255, 255, 255);">=
                           <div style=3D"border-style: solid none none; bor=
der-top-color: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in =
0in; font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;"> =
 <div><b>From: </b>Nicol Bolas</div><div><b>Sent: </b>Friday, November 13, =
2015 7:12 PM</div><div><b>To: </b>ISO C++ Standard - Future Proposals</div>=
<div><b>Reply To: </b>std-proposals@isocpp.org</div><div><b>Subject: </b>Re=
: [std-proposals] expected and exceptions: learning from variant</div></div=
></td></tr></tbody></table><div style=3D"border-style: solid none none; bor=
der-top-color: rgb(186, 188, 209); border-top-width: 1pt; font-size: initia=
l; text-align: initial; background-color: rgb(255, 255, 255);"></div><br><d=
iv id=3D"_originalContent" style=3D""><br><br>On Friday, November 13, 2015 =
at 5:13:26 PM UTC-5, Matt Calabrese wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote">On Fri, Nov 13=
, 2015 at 1:51 PM, Nicol Bolas&nbsp;<span dir=3D"ltr">&lt;<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"RYI8mn3nFwAJ" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"thi=
s.href=3D'javascript:';return true;">jmck...@gmail.com</a>&gt;</span>&nbsp;=
<wbr>wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-st=
yle:solid;padding-left:1ex"><div dir=3D"ltr">I do not believe that requirin=
g E to be nothrow moveable would be a substantial impediment to users. `exp=
ected` is not a general-purpose variant, after all. And even `expected_ptr`=
 is nothrow moveable.</div></blockquote><div><br></div><div>While I agree t=
hat constraining E or constraining operations on an expected&lt;&gt; that c=
ontain a type with a move-constructor that can throw <i>shouldn't</i> be a =
problem, I doubt that people would be willing to accept this, and I'd perso=
nally be dismayed if we got these constraints for expected&lt;&gt; yet not =
for variant&lt;&gt;. The arguments that people were giving as to why they d=
idn't want constraints for variant fields/operations on those fields still =
would apply here. If they have an E that contains something like a standard=
 library type whose move may or may not be noexcept, then they cannot be gu=
aranteed to use it (or at least use assignment) with expected&lt;&gt;. I'm =
under the assumption that whatever variant&lt;&gt; does (consensus is the c=
orrupted_by_exception state), then expected&lt;&gt; should do the same and =
for the same reasons. As much as I personally dislike the notion of a "corr=
upted" state both for variant&lt;&gt; <i>and</i> for expected&lt;&gt;, I'd =
rather that expected&lt;&gt; at least be consistent with variant&lt;&gt;. I=
t's not clear why it would be "okay" to constrain "E" for expected&lt;&gt; =
but not constrain a variant&lt;&gt; field or one of the associated operatio=
ns. Both are general-purpose facilities even if you happen to label E as "u=
nexpected."</div></div></div></div></blockquote><div><br>`expected` is not =
a "general-purpose facility"; it is a means of error handling. That's why i=
t doesn't use `variant`'s get-style interface, nor does it allow `variant`-=
style visitation. That's why it's explicitly limited to 2 items. There's a =
"good" state and a "bad" state. `variant` makes no judgement about any part=
icular state.<br><br>`expected` is functionality similar to `variant`, but =
in terms of users, it will be treated much more like `optional`. Therefore,=
 it should have `optional`'s behavior, not `variant`'s.<br></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br>
<br><!--end of _originalContent --></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 14 Nov 2015 09:10:15 +0100
Raw View
This is a multi-part message in MIME format.
--------------010700000506060206040407
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 13/11/2015 22:51, Nicol Bolas a =C3=A9crit :
> The N4109 proposal for `expected` <http://wg21.link/N4109> defines a type
> that is structurally similar to `variant`. Which means that it has the
> exception problem. The problem basically boils down to this: what do you =
do
> if you try to set the data in a live `expected`, a type which is differen=
t
> from its current type, and the construction of the new type fails?
Thanks for starting this thread.
>
> The current N4109 proposal says that there will be "no effect" in such a
> circumstance. As we've learned from our endless `variant` discussions, th=
e
> only way to have a never-empty construct that has "no effect" in such a
> circumstance without imposing restrictions on the types involved, is to
> double-buffer. And a dynamic double buffer is no solution (even if people
> would accept such memory allocation, and they absolutely will not), so it
> would have to be a static double buffer.
>
> In other words, your `expected` type would have to internally store twice
> the size of its data, enough to have two T's or two E's simultaneously
> constructed within it.
>
> However, N4109 also has different exception requirements from P0088
> <http://wg21.link/P0088>. That `variant` treats exceptions thrown during
> copy assignment (ie: the variant has a T and you assign another value of
> type T) as being no different from exceptions thrown during copy
> construction (ie: the variant has a U and you assign a value of type T).
> Both cases will make the variant invalid.
>
> N4109 is designed instead to work like `optional<T>`. If you assign T to =
an
> unengaged optional that throws, then the `optional` remains unengaged. If
> you assign T to an engaged `optional<T>` that throws... well, you get
> whatever T guarantees on copy assignment failure.
>
> That would make sense for the desired uses for `expected`. But there's ju=
st
> one problem: it's not really possible. As we learned with variant, the on=
ly
> way to implement that is with double-buffering.
>
> Unless...
>
> The reason assignment to an unengaged `optional<T>` can get away with it =
is
> because the implementation is always guaranteed to be able to make the
> optional unengaged after an assignment failure. Also, the unegaged state =
is
> "monostate" and therefore has no value associated with it.
>
> So all we need to do is leverage something we learned from P0110, aka:
> Williams.Variant <http://wg21.link/P0110>. Namely, he discovered a way to
> implement a variant that would be able to double-buffer, but only if *two=
*
> types in the variant were nothrow moveable. If only one were nothrow
> moveable, then assignment of a different value to the same state would
> simply result in whatever exception guarantees that type offers.
>
> Therefore, I suggest that `expected` impose a requirement. The requiremen=
ts
> on T should be as minimal as possible (ie: no more than what optional
> requires), we should require that E be nothrow moveable. That way, if you
> have an `expected<T, E>` that is in the error state, and you assign/empla=
ce
> a T to it, the system can easily move E to temporary stack memory (which =
is
> safe), do the assignment/emplacement, and if it fails, just move E back
> (which is still safe). And if your expected has T, and you assign/emplace
> an E value to it, the system does the emplacement to the stack. If it
> succeeds, then it destroys T and moves the new E into the memory (which i=
s
> safe).
>
> This would allow `expected` to fulfill the requirements it states without
> having to double buffer.
>
> I do not believe that requiring E to be nothrow moveable would be a
> substantial impediment to users. `expected` is not a general-purpose
> variant, after all. And even `expected_ptr` is nothrow moveable.
>

expected<T,E> is special respect to E. If E means Error, we can not=20
throw another error while copying it. This is similar to why an=20
exception object must be no-throw copyable.

In addition if value throw the error in any way, we must be able to copy=20
it without exception or terminate could be called.
 From [except.throw] p7

 2.

    If the exception handling mechanism, after completing the
    initialization of the exception object but before the activation of
    a handler for the exception, calls a function that exits via an
    exception, std::terminate is called

C++ International Standar
I don't remember if this constraint is not clear in the proposal but=20
this must be stated clearly.

I would even require that the constructor don't throw neither. What=20
could be the purpose to return an error that throws?

Vicente

P.S. From http://www.boost.org/community/error_handling.html

*/Don't/ embed a std::string object* or any other data member or base=20
class whose copy constructor could throw an exception. That could lead=20
directly to std::terminate() at the throw point.


--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--------------010700000506060206040407
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">Le 13/11/2015 22:51, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:18b5b3a2-40c3-44e8-ba9a-5e64dd3c3904@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">The N4109 proposal for `expected` <a class=3D"moz-txt-=
link-rfc2396E" href=3D"http://wg21.link/N4109">&lt;http://wg21.link/N4109&g=
t;</a> defines a type=20
that is structurally similar to `variant`. Which means that it has the=20
exception problem. The problem basically boils down to this: what do you do=
=20
if you try to set the data in a live `expected`, a type which is different=
=20
from its current type, and the construction of the new type fails?</pre>
    </blockquote>
    Thanks for starting this thread.<br>
    <blockquote
      cite=3D"mid:18b5b3a2-40c3-44e8-ba9a-5e64dd3c3904@isocpp.org"
      type=3D"cite">
      <pre wrap=3D"">

The current N4109 proposal says that there will be "no effect" in such a=20
circumstance. As we've learned from our endless `variant` discussions, the=
=20
only way to have a never-empty construct that has "no effect" in such a=20
circumstance without imposing restrictions on the types involved, is to=20
double-buffer. And a dynamic double buffer is no solution (even if people=
=20
would accept such memory allocation, and they absolutely will not), so it=
=20
would have to be a static double buffer.

In other words, your `expected` type would have to internally store twice=
=20
the size of its data, enough to have two T's or two E's simultaneously=20
constructed within it.

However, N4109 also has different exception requirements from P0088=20
<a class=3D"moz-txt-link-rfc2396E" href=3D"http://wg21.link/P0088">&lt;http=
://wg21.link/P0088&gt;</a>. That `variant` treats exceptions thrown during=
=20
copy assignment (ie: the variant has a T and you assign another value of=20
type T) as being no different from exceptions thrown during copy=20
construction (ie: the variant has a U and you assign a value of type T).=20
Both cases will make the variant invalid.

N4109 is designed instead to work like `optional&lt;T&gt;`. If you assign T=
 to an=20
unengaged optional that throws, then the `optional` remains unengaged. If=
=20
you assign T to an engaged `optional&lt;T&gt;` that throws... well, you get=
=20
whatever T guarantees on copy assignment failure.

That would make sense for the desired uses for `expected`. But there's just=
=20
one problem: it's not really possible. As we learned with variant, the only=
=20
way to implement that is with double-buffering.

Unless...

The reason assignment to an unengaged `optional&lt;T&gt;` can get away with=
 it is=20
because the implementation is always guaranteed to be able to make the=20
optional unengaged after an assignment failure. Also, the unegaged state is=
=20
"monostate" and therefore has no value associated with it.

So all we need to do is leverage something we learned from P0110, aka:=20
Williams.Variant <a class=3D"moz-txt-link-rfc2396E" href=3D"http://wg21.lin=
k/P0110">&lt;http://wg21.link/P0110&gt;</a>. Namely, he discovered a way to=
=20
implement a variant that would be able to double-buffer, but only if *two*=
=20
types in the variant were nothrow moveable. If only one were nothrow=20
moveable, then assignment of a different value to the same state would=20
simply result in whatever exception guarantees that type offers.

Therefore, I suggest that `expected` impose a requirement. The requirements=
=20
on T should be as minimal as possible (ie: no more than what optional=20
requires), we should require that E be nothrow moveable. That way, if you=
=20
have an `expected&lt;T, E&gt;` that is in the error state, and you assign/e=
mplace=20
a T to it, the system can easily move E to temporary stack memory (which is=
=20
safe), do the assignment/emplacement, and if it fails, just move E back=20
(which is still safe). And if your expected has T, and you assign/emplace=
=20
an E value to it, the system does the emplacement to the stack. If it=20
succeeds, then it destroys T and moves the new E into the memory (which is=
=20
safe).

This would allow `expected` to fulfill the requirements it states without=
=20
having to double buffer.

I do not believe that requiring E to be nothrow moveable would be a=20
substantial impediment to users. `expected` is not a general-purpose=20
variant, after all. And even `expected_ptr` is nothrow moveable.

</pre>
    </blockquote>
    <br>
    expected&lt;T,E&gt; is special respect to E. If E means Error, we
    can not throw another error while copying it. This is similar to why
    an exception object must be no-throw copyable.<br>
    <br>
    In addition if value throw the error in any way, we must be able to
    copy it without exception or terminate could be called.=C2=A0 <span
      style=3D"font-size: 11.000000pt; font-family: 'LMRoman10';
      font-weight: 700"><br>
      From [except.throw]</span> p7 <br>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
    <div class=3D"page" title=3D"Page 430">
      <div class=3D"layoutArea">
        <div class=3D"column">
          <ol start=3D"2" style=3D"list-style-type: none">
            <li>
              <p><span style=3D"font-size: 10.000000pt; font-family:
                  'LMRoman10'">If the exception handling mechanism,
                  after completing the initialization of the exception
                  object but before
                  the activation of a handler for the exception, calls a
                  function that exits via an exception, </span><span
                  style=3D"font-size: 10.000000pt; font-family:
                  'LMMono10'">std::terminate
                </span><span style=3D"font-size: 10.000000pt; font-family:
                  'LMRoman10'">is called
                </span></p>
            </li>
          </ol>
        </div>
      </div>
    </div>
    <title>C++ International Standar</title>
    <br>
    I don't remember if this constraint is not clear in the proposal but
    this must be stated clearly.<br>
    <br>
    I would even require that the constructor don't throw neither. What
    could be the purpose to return an error that throws?<br>
    <br>
    Vicente<br>
    <br>
    P.S. From <a class=3D"moz-txt-link-freetext" href=3D"http://www.boost.o=
rg/community/error_handling.html">http://www.boost.org/community/error_hand=
ling.html</a><br>
    <br>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    <strong><i>Don't</i> embed a std::string object</strong> or any
    other data member or base class whose copy constructor could throw
    an exception. That could lead directly to std::terminate() at the
    throw point. <br>
    <br>
    <br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------010700000506060206040407--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 14 Nov 2015 09:19:35 +0100
Raw View
Le 13/11/2015 23:13, 'Matt Calabrese' via ISO C++ Standard - Future=20
Proposals a =C3=A9crit :
> On Fri, Nov 13, 2015 at 1:51 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>> I do not believe that requiring E to be nothrow moveable would be a
>> substantial impediment to users. `expected` is not a general-purpose
>> variant, after all. And even `expected_ptr` is nothrow moveable.
>>
> While I agree that constraining E or constraining operations on an
> expected<> that contain a type with a move-constructor that can throw
> *shouldn't* be a problem, I doubt that people would be willing to accept
> this, and I'd personally be dismayed if we got these constraints for
> expected<> yet not for variant<>. The arguments that people were giving a=
s
> to why they didn't want constraints for variant fields/operations on thos=
e
> fields still would apply here. If they have an E that contains something
> like a standard library type whose move may or may not be noexcept, then
> they cannot be guaranteed to use it (or at least use assignment) with
> expected<>.
I don't expect that expected<T,E> assignment will be used often. The=20
parameter E has a special meaning. It is used to report error=20
conditions. If we allow to throw while reporting the error we lost the=20
added value of expected. Construction or assignment of Error classes=20
must not throw.

> I'm under the assumption that whatever variant<> does
> (consensus is the corrupted_by_exception state), then expected<> should d=
o
> the same and for the same reasons. As much as I personally dislike the
> notion of a "corrupted" state both for variant<> *and* for expected<>, I'=
d
> rather that expected<> at least be consistent with variant<>. It's not
> clear why it would be "okay" to constrain "E" for expected<> but not
> constrain a variant<> field or one of the associated operations.
Hopping the rationale above will be enough.
> Both are
> general-purpose facilities even if you happen to label E as "unexpected."
>
This makes the difference.

Vicente

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 14 Nov 2015 08:10:37 -0800 (PST)
Raw View
------=_Part_385_2021192303.1447517437500
Content-Type: multipart/alternative;
 boundary="----=_Part_386_956251894.1447517437501"

------=_Part_386_956251894.1447517437501
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Saturday, November 14, 2015 at 3:10:18 AM UTC-5, Vicente J. Botet=20
Escriba wrote:
>
> Le 13/11/2015 22:51, Nicol Bolas a =C3=A9crit :
>
> The N4109 proposal for `expected` <http://wg21.link/N4109> <http://wg21.l=
ink/N4109> defines a type=20
> that is structurally similar to `variant`. Which means that it has the=20
> exception problem. The problem basically boils down to this: what do you =
do=20
> if you try to set the data in a live `expected`, a type which is differen=
t=20
> from its current type, and the construction of the new type fails?
>
> Thanks for starting this thread.
>
> The current N4109 proposal says that there will be "no effect" in such a=
=20
> circumstance. As we've learned from our endless `variant` discussions, th=
e=20
> only way to have a never-empty construct that has "no effect" in such a=
=20
> circumstance without imposing restrictions on the types involved, is to=
=20
> double-buffer. And a dynamic double buffer is no solution (even if people=
=20
> would accept such memory allocation, and they absolutely will not), so it=
=20
> would have to be a static double buffer.
>
> In other words, your `expected` type would have to internally store twice=
=20
> the size of its data, enough to have two T's or two E's simultaneously=20
> constructed within it.
>
> However, N4109 also has different exception requirements from P0088 <http=
://wg21.link/P0088> <http://wg21.link/P0088>. That `variant` treats excepti=
ons thrown during=20
> copy assignment (ie: the variant has a T and you assign another value of=
=20
> type T) as being no different from exceptions thrown during copy=20
> construction (ie: the variant has a U and you assign a value of type T).=
=20
> Both cases will make the variant invalid.
>
> N4109 is designed instead to work like `optional<T>`. If you assign T to =
an=20
> unengaged optional that throws, then the `optional` remains unengaged. If=
=20
> you assign T to an engaged `optional<T>` that throws... well, you get=20
> whatever T guarantees on copy assignment failure.
>
> That would make sense for the desired uses for `expected`. But there's ju=
st=20
> one problem: it's not really possible. As we learned with variant, the on=
ly=20
> way to implement that is with double-buffering.
>
> Unless...
>
> The reason assignment to an unengaged `optional<T>` can get away with it =
is=20
> because the implementation is always guaranteed to be able to make the=20
> optional unengaged after an assignment failure. Also, the unegaged state =
is=20
> "monostate" and therefore has no value associated with it.
>
> So all we need to do is leverage something we learned from P0110, aka:=20
> Williams.Variant <http://wg21.link/P0110> <http://wg21.link/P0110>. Namel=
y, he discovered a way to=20
> implement a variant that would be able to double-buffer, but only if *two=
*=20
> types in the variant were nothrow moveable. If only one were nothrow=20
> moveable, then assignment of a different value to the same state would=20
> simply result in whatever exception guarantees that type offers.
>
> Therefore, I suggest that `expected` impose a requirement. The requiremen=
ts=20
> on T should be as minimal as possible (ie: no more than what optional=20
> requires), we should require that E be nothrow moveable. That way, if you=
=20
> have an `expected<T, E>` that is in the error state, and you assign/empla=
ce=20
> a T to it, the system can easily move E to temporary stack memory (which =
is=20
> safe), do the assignment/emplacement, and if it fails, just move E back=
=20
> (which is still safe). And if your expected has T, and you assign/emplace=
=20
> an E value to it, the system does the emplacement to the stack. If it=20
> succeeds, then it destroys T and moves the new E into the memory (which i=
s=20
> safe).
>
> This would allow `expected` to fulfill the requirements it states without=
=20
> having to double buffer.
>
> I do not believe that requiring E to be nothrow moveable would be a=20
> substantial impediment to users. `expected` is not a general-purpose=20
> variant, after all. And even `expected_ptr` is nothrow moveable.
>
>
>
> expected<T,E> is special respect to E. If E means Error, we can not throw=
=20
> another error while copying it. This is similar to why an exception objec=
t=20
> must be no-throw copyable.
>
> In addition if value throw the error in any way, we must be able to copy=
=20
> it without exception or terminate could be called. =20
> From [except.throw] p7=20
>
>    1.=20
>   =20
>    If the exception handling mechanism, after completing the=20
>    initialization of the exception object but before the activation of a=
=20
>    handler for the exception, calls a function that exits via an exceptio=
n, std::terminate=20
>    is called=20
>   =20
>
> I don't remember if this constraint is not clear in the proposal but this=
=20
> must be stated clearly.
>
> I would even require that the constructor don't throw neither. What could=
=20
> be the purpose to return an error that throws?
>
> Vicente
>
> P.S. From http://www.boost.org/community/error_handling.html
>
> *Don't embed a std::string object* or any other data member or base class=
=20
> whose copy constructor could throw an exception. That could lead directly=
=20
> to std::terminate() at the throw point.
>

Boost doesn't follow their own advice then. std::runtime_error uses an=20
internal std::string (or otherwise allocates memory, thus potentially=20
throwing on copy). And Boost has at least possibly hundreds of uses of=20
std::runtime_error. filesystem_error also stores objects that can throw on=
=20
copy. Indeed, I think the Boost.Exception library's ability to add data to=
=20
exceptions doesn't even follow this guideline.

Personally, I would prefer that we put the fewest limitations on the error=
=20
type that we possibly can. If we limit the error type to having=20
non-throwing move, then we can provide perfect exception forwarding ala=20
`optional<T>`. However, if we add non-throwing copy to that list, or=20
non-throwing construction of all kinds, we don't gain anything from it. We=
=20
don't really change the implementation of `expected` much, and what few=20
changes there would be would be purely performance ones, not behavioral.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_386_956251894.1447517437501
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 14, 2015 at 3:10:18 AM UTC-5, Vicente J. Bote=
t Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 13/11/2015 22:51, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <pre>The N4109 proposal for `expected` <a href=3D"http://wg21.link/N4=
109" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;htt=
p://www.google.com/url?q\75http%3A%2F%2Fwg21.link%2FN4109\46sa\75D\46sntz\0=
751\46usg\75AFQjCNGdSz13fqKI7yHWEa6WGWd9iDmAbA&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwg21.link%2=
FN4109\46sa\75D\46sntz\0751\46usg\75AFQjCNGdSz13fqKI7yHWEa6WGWd9iDmAbA&#39;=
;return true;">&lt;http://wg21.link/N4109&gt;</a> defines a type=20
that is structurally similar to `variant`. Which means that it has the=20
exception problem. The problem basically boils down to this: what do you do=
=20
if you try to set the data in a live `expected`, a type which is different=
=20
from its current type, and the construction of the new type fails?</pre>
    </blockquote>
    Thanks for starting this thread.<br>
    <blockquote type=3D"cite">
      <pre>The current N4109 proposal says that there will be &quot;no effe=
ct&quot; in such a=20
circumstance. As we&#39;ve learned from our endless `variant` discussions, =
the=20
only way to have a never-empty construct that has &quot;no effect&quot; in =
such a=20
circumstance without imposing restrictions on the types involved, is to=20
double-buffer. And a dynamic double buffer is no solution (even if people=
=20
would accept such memory allocation, and they absolutely will not), so it=
=20
would have to be a static double buffer.

In other words, your `expected` type would have to internally store twice=
=20
the size of its data, enough to have two T&#39;s or two E&#39;s simultaneou=
sly=20
constructed within it.

However, N4109 also has different exception requirements from P0088=20
<a href=3D"http://wg21.link/P0088" target=3D"_blank" rel=3D"nofollow" onmou=
sedown=3D"this.href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwg21.=
link%2FP0088\46sa\75D\46sntz\0751\46usg\75AFQjCNF0gvWDhhVhLhkF75trUa3hT7LAL=
A&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?=
q\75http%3A%2F%2Fwg21.link%2FP0088\46sa\75D\46sntz\0751\46usg\75AFQjCNF0gvW=
DhhVhLhkF75trUa3hT7LALA&#39;;return true;">&lt;http://wg21.link/P0088&gt;</=
a>. That `variant` treats exceptions thrown during=20
copy assignment (ie: the variant has a T and you assign another value of=20
type T) as being no different from exceptions thrown during copy=20
construction (ie: the variant has a U and you assign a value of type T).=20
Both cases will make the variant invalid.

N4109 is designed instead to work like `optional&lt;T&gt;`. If you assign T=
 to an=20
unengaged optional that throws, then the `optional` remains unengaged. If=
=20
you assign T to an engaged `optional&lt;T&gt;` that throws... well, you get=
=20
whatever T guarantees on copy assignment failure.

That would make sense for the desired uses for `expected`. But there&#39;s =
just=20
one problem: it&#39;s not really possible. As we learned with variant, the =
only=20
way to implement that is with double-buffering.

Unless...

The reason assignment to an unengaged `optional&lt;T&gt;` can get away with=
 it is=20
because the implementation is always guaranteed to be able to make the=20
optional unengaged after an assignment failure. Also, the unegaged state is=
=20
&quot;monostate&quot; and therefore has no value associated with it.

So all we need to do is leverage something we learned from P0110, aka:=20
Williams.Variant <a href=3D"http://wg21.link/P0110" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\7=
5http%3A%2F%2Fwg21.link%2FP0110\46sa\75D\46sntz\0751\46usg\75AFQjCNEgK7Pe-8=
uCt_TOjoTd2AMgxaEV2g&#39;;return true;" onclick=3D"this.href=3D&#39;http://=
www.google.com/url?q\75http%3A%2F%2Fwg21.link%2FP0110\46sa\75D\46sntz\0751\=
46usg\75AFQjCNEgK7Pe-8uCt_TOjoTd2AMgxaEV2g&#39;;return true;">&lt;http://wg=
21.link/P0110&gt;</a>. Namely, he discovered a way to=20
implement a variant that would be able to double-buffer, but only if *two*=
=20
types in the variant were nothrow moveable. If only one were nothrow=20
moveable, then assignment of a different value to the same state would=20
simply result in whatever exception guarantees that type offers.

Therefore, I suggest that `expected` impose a requirement. The requirements=
=20
on T should be as minimal as possible (ie: no more than what optional=20
requires), we should require that E be nothrow moveable. That way, if you=
=20
have an `expected&lt;T, E&gt;` that is in the error state, and you assign/e=
mplace=20
a T to it, the system can easily move E to temporary stack memory (which is=
=20
safe), do the assignment/emplacement, and if it fails, just move E back=20
(which is still safe). And if your expected has T, and you assign/emplace=
=20
an E value to it, the system does the emplacement to the stack. If it=20
succeeds, then it destroys T and moves the new E into the memory (which is=
=20
safe).

This would allow `expected` to fulfill the requirements it states without=
=20
having to double buffer.

I do not believe that requiring E to be nothrow moveable would be a=20
substantial impediment to users. `expected` is not a general-purpose=20
variant, after all. And even `expected_ptr` is nothrow moveable.

</pre>
    </blockquote>
    <br>
    expected&lt;T,E&gt; is special respect to E. If E means Error, we
    can not throw another error while copying it. This is similar to why
    an exception object must be no-throw copyable.<br>
    <br>
    In addition if value throw the error in any way, we must be able to
    copy it without exception or terminate could be called.=C2=A0 <span sty=
le=3D"font-size:11.000000pt;font-family:&#39;LMRoman10&#39;;font-weight:700=
"><br>
      From [except.throw]</span> p7 <br>
   =20
    <div title=3D"Page 430">
      <div>
        <div>
          <ol start=3D"2" style=3D"list-style-type:none">
            <li>
              <p><span style=3D"font-size:10.000000pt;font-family:&#39;LMRo=
man10&#39;">If the exception handling mechanism,
                  after completing the initialization of the exception
                  object but before
                  the activation of a handler for the exception, calls a
                  function that exits via an exception, </span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMMono10&#39;">std::terminate
                </span><span style=3D"font-size:10.000000pt;font-family:&#3=
9;LMRoman10&#39;">is called
                </span></p>
            </li>
          </ol>
        </div>
      </div>
    </div>
   =20
    <br>
    I don&#39;t remember if this constraint is not clear in the proposal bu=
t
    this must be stated clearly.<br>
    <br>
    I would even require that the constructor don&#39;t throw neither. What
    could be the purpose to return an error that throws?<br>
    <br>
    Vicente<br>
    <br>
    P.S. From <a href=3D"http://www.boost.org/community/error_handling.html=
" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http:/=
/www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fcommunity%2Ferror_hand=
ling.html\46sa\75D\46sntz\0751\46usg\75AFQjCNFY5WAw3-8Qw0sOHirV1neBMhfkzA&#=
39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\7=
5http%3A%2F%2Fwww.boost.org%2Fcommunity%2Ferror_handling.html\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNFY5WAw3-8Qw0sOHirV1neBMhfkzA&#39;;return true;">http:=
//www.boost.org/<wbr>community/error_handling.html</a><br>
    <br>
   =20
    <b><i>Don&#39;t</i> embed a std::string object</b> or any
    other data member or base class whose copy constructor could throw
    an exception. That could lead directly to std::terminate() at the
    throw point.<br></div></blockquote><div><br>Boost doesn&#39;t follow th=
eir own advice then. std::runtime_error uses an internal std::string (or ot=
herwise allocates memory, thus potentially throwing on copy). And Boost has=
 at least possibly hundreds of uses of std::runtime_error. filesystem_error=
 also stores objects that can throw on copy. Indeed, I think the Boost.Exce=
ption library&#39;s ability to add data to exceptions doesn&#39;t even foll=
ow this guideline.<br><br>Personally, I would prefer that we put the fewest=
 limitations on the error type that we possibly can. If we limit the error =
type to having non-throwing move, then we can provide perfect exception for=
warding ala `optional&lt;T&gt;`. However, if we add non-throwing copy to th=
at list, or non-throwing construction of all kinds, we don&#39;t gain anyth=
ing from it. We don&#39;t really change the implementation of `expected` mu=
ch, and what few changes there would be would be purely performance ones, n=
ot behavioral.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_386_956251894.1447517437501--
------=_Part_385_2021192303.1447517437500--

.


Author: =?UTF-8?Q?Agust=c3=adn_K-ballo_Berg=c3=a9?= <kaballo86@hotmail.com>
Date: Sat, 14 Nov 2015 13:23:00 -0300
Raw View
On 11/14/2015 1:10 PM, Nicol Bolas wrote:
> On Saturday, November 14, 2015 at 3:10:18 AM UTC-5, Vicente J. Botet
> Escriba wrote:
>
>     P.S. From http://www.boost.org/community/error_handling.html
>     <http://www.boost.org/community/error_handling.html>
>
>     */Don't/ embed a std::string object* or any other data member or
>     base class whose copy constructor could throw an exception. That
>     could lead directly to std::terminate() at the throw point.
>
>
> Boost doesn't follow their own advice then. std::runtime_error uses an
> internal std::string (or otherwise allocates memory, thus potentially
> throwing on copy). And Boost has at least possibly hundreds of uses of
> std::runtime_error.

Implementations of `std::runtime_error` are required to not throw=20
exceptions on copy, which generally means resorting to ref-counted strings.

 > 18.8.1 [exception]/2
 > Each standard library class `T` that derives from class `exception`=20
shall have a publicly accessible copy constructor and a publicly=20
accessible copy assignment operator that do not exit with an exception.

User-defined types that derive from `exception` ought to play nice and=20
do the same. Allocating memory on construction does not equate to=20
potentially throwing on copy.

Regards,
--=20
Agust=C3=ADn K-ballo Berg=C3=A9.-
http://talesofcpp.fusionfenix.com

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 14 Nov 2015 09:44:55 -0800 (PST)
Raw View
------=_Part_456_95915610.1447523095484
Content-Type: multipart/alternative;
 boundary="----=_Part_457_1336228563.1447523095484"

------=_Part_457_1336228563.1447523095484
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Saturday, November 14, 2015 at 11:23:00 AM UTC-5, Agust=C3=ADn K-ballo B=
erg=C3=A9=20
wrote:
>
> On 11/14/2015 1:10 PM, Nicol Bolas wrote:=20
> > On Saturday, November 14, 2015 at 3:10:18 AM UTC-5, Vicente J. Botet=20
> > Escriba wrote:=20
> >=20
> >     P.S. From http://www.boost.org/community/error_handling.html=20
> >     <http://www.boost.org/community/error_handling.html>=20
> >=20
> >     */Don't/ embed a std::string object* or any other data member or=20
> >     base class whose copy constructor could throw an exception. That=20
> >     could lead directly to std::terminate() at the throw point.=20
> >=20
> >=20
> > Boost doesn't follow their own advice then. std::runtime_error uses an=
=20
> > internal std::string (or otherwise allocates memory, thus potentially=
=20
> > throwing on copy). And Boost has at least possibly hundreds of uses of=
=20
> > std::runtime_error.=20
>
> Implementations of `std::runtime_error` are required to not throw=20
> exceptions on copy, which generally means resorting to ref-counted=20
> strings.=20
>
>  > 18.8.1 [exception]/2=20
>  > Each standard library class `T` that derives from class `exception`=20
> shall have a publicly accessible copy constructor and a publicly=20
> accessible copy assignment operator that do not exit with an exception.
>

Grr... The standard makes it *really* hard to find requirements like this.=
=20
You'd think that this would be part of the definition of std::runtime_error=
=20
or something.

And it turns out that filesystem_error also abides by this rule. So=20
nevermind.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_457_1336228563.1447523095484
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 14, 2015 at 11:23:00 AM UTC-5, Agust=C3=ADn K=
-ballo Berg=C3=A9 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 11/=
14/2015 1:10 PM, Nicol Bolas wrote:
<br>&gt; On Saturday, November 14, 2015 at 3:10:18 AM UTC-5, Vicente J. Bot=
et
<br>&gt; Escriba wrote:
<br>&gt;
<br>&gt; =C2=A0 =C2=A0 P.S. From <a href=3D"http://www.boost.org/community/=
error_handling.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this=
..href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fcom=
munity%2Ferror_handling.html\46sa\75D\46sntz\0751\46usg\75AFQjCNFY5WAw3-8Qw=
0sOHirV1neBMhfkzA&#39;;return true;" onclick=3D"this.href=3D&#39;http://www=
..google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fcommunity%2Ferror_handling=
..html\46sa\75D\46sntz\0751\46usg\75AFQjCNFY5WAw3-8Qw0sOHirV1neBMhfkzA&#39;;=
return true;">http://www.boost.org/<wbr>community/error_handling.html</a>
<br>&gt; =C2=A0 =C2=A0 &lt;<a href=3D"http://www.boost.org/community/error_=
handling.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fcommunit=
y%2Ferror_handling.html\46sa\75D\46sntz\0751\46usg\75AFQjCNFY5WAw3-8Qw0sOHi=
rV1neBMhfkzA&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.goog=
le.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fcommunity%2Ferror_handling.html=
\46sa\75D\46sntz\0751\46usg\75AFQjCNFY5WAw3-8Qw0sOHirV1neBMhfkzA&#39;;retur=
n true;">http://www.boost.org/<wbr>community/error_handling.html</a>&gt;
<br>&gt;
<br>&gt; =C2=A0 =C2=A0 */Don&#39;t/ embed a std::string object* or any othe=
r data member or
<br>&gt; =C2=A0 =C2=A0 base class whose copy constructor could throw an exc=
eption. That
<br>&gt; =C2=A0 =C2=A0 could lead directly to std::terminate() at the throw=
 point.
<br>&gt;
<br>&gt;
<br>&gt; Boost doesn&#39;t follow their own advice then. std::runtime_error=
 uses an
<br>&gt; internal std::string (or otherwise allocates memory, thus potentia=
lly
<br>&gt; throwing on copy). And Boost has at least possibly hundreds of use=
s of
<br>&gt; std::runtime_error.
<br>
<br>Implementations of `std::runtime_error` are required to not throw=20
<br>exceptions on copy, which generally means resorting to ref-counted stri=
ngs.
<br>
<br>=C2=A0&gt; 18.8.1 [exception]/2
<br>=C2=A0&gt; Each standard library class `T` that derives from class `exc=
eption`=20
<br>shall have a publicly accessible copy constructor and a publicly=20
<br>accessible copy assignment operator that do not exit with an exception.=
<br></blockquote><div><br>Grr... The standard makes it <i>really</i> hard t=
o find requirements like this. You&#39;d think that this would be part of t=
he definition of std::runtime_error or something.<br><br>And it turns out t=
hat filesystem_error also abides by this rule. So nevermind.<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_457_1336228563.1447523095484--
------=_Part_456_95915610.1447523095484--

.