220 30482 <615ad4bb-f321-4ace-8dd1-335e97b6c7a0@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: enum_cast proposal
Date: Wed, 11 Jan 2017 09:16:58 -0800 (PST)
Lines: 239
Approved: news@gmane.org
Message-ID: <615ad4bb-f321-4ace-8dd1-335e97b6c7a0@isocpp.org>
References: <efdf2357-00a6-408a-8772-12f99135a880@isocpp.org>
 <57258435-5d82-48e7-8ed7-3c38682418fb@isocpp.org>
 <a35d9f20-9e4f-4789-b7e5-5cb08f99e6bd@isocpp.org>
 <58750288.5080004@gmail.com>
 <e85f0d46-f244-42fe-a276-b4e18b3d627f@isocpp.org>
 <587512E1.1050708@gmail.com>
 <d974c090-2898-4397-8d42-bbc1682158c7@isocpp.org>
 <216fe26f-2155-42b4-9350-cb4c7f4e9f4a@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_2267_635230327.1484155018589"
X-Trace: blaine.gmane.org 1484155031 12847 195.159.176.226 (11 Jan 2017 17:17:11 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Wed, 11 Jan 2017 17:17:11 +0000 (UTC)
Cc: mwoehlke.floss@gmail.com, gmisocpp@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBDGR3HBQKGQELJ6K32Y@isocpp.org Wed Jan 11 18:17:05 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBDGR3HBQKGQELJ6K32Y@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f199.google.com ([209.85.217.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBDGR3HBQKGQELJ6K32Y@isocpp.org>)
	id 1cRMW8-00026E-RU
	for gclcip-std-proposals@m.gmane.org; Wed, 11 Jan 2017 18:16:57 +0100
Original-Received: by mail-ua0-f199.google.com with SMTP id i68sf555191645uad.3
        for <gclcip-std-proposals@m.gmane.org>; Wed, 11 Jan 2017 09:17:01 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=tiMucUFj7iXA5vHMUaxu/BSjk/uM7/+UV0FYp5qlCis=;
        b=b5l9UsVzD5tv7xA39eG6HqyXgoSaHn4RlfnGdLMUgbs2kaH5l843YAfmB1YsLlDaG4
         o/lBlTKueoawdj6NTLM8469iPABMKR8podCjVePKx+iu70vVBzBPhcGXFrRUiqntIRhx
         qzhaF5tzSqGLvf/OeQfW5UpvYiXfiSS0ko8zyVFTBZKli/AxY5OdDjgG5wAT61hXUcoa
         TolkGUzxhmHL7+nKwNr5HirTm78oKRnQNcrOToSkErYEAig6R9yoIt/NJa4gd/UiAAoy
         1VhqCaJtiO45uXBTwcGZSw16wwfoJTVOFdvApA1Hu3KFivrJKFg0PFJGNh6rkmTWZLq3
         WwFA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=tiMucUFj7iXA5vHMUaxu/BSjk/uM7/+UV0FYp5qlCis=;
        b=UkLkQ2HmQb6BkwU81bMwOa/rTqyMD9TQhj/C/QUi4BVjh8ZreHzj4OdJYJqD/G9JE8
         FvAk1rXbSv3o9jidJbWGRTYjlDPDsEMsIphVQp0Ah6d+kbcMwjfui5PE6icwda2C7eTp
         XLe+2WjYEHM5D/s95UzovvXE9xIPyQJaDX8TWLQG9Ot5s8Wx1CpsNbzGMRg7Ft5XdKAW
         KK/BQnDqzHasL8tyNUjd1H7bbrwnIg6aGm/8Fr+cpZk8lSHFKC4GkB5NyjNH8AvJP0nK
         Fjd67H52qej59lDYNhFOuhZP3D3POhiMaAnSW2sJS5FsDdstlMGQCftiyr/BOvSfQHy8
         Ti6g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=tiMucUFj7iXA5vHMUaxu/BSjk/uM7/+UV0FYp5qlCis=;
        b=QAGF8U2/de0rNtGo8cR3jztbu/UFKmSk4HCEDlcyFYuy0vHLFMaY9HAyUSM50mYVzz
         SdorhN6BuTYpVAZrHOKzqm4113IP9mePpi8c7W6KVC6fS7gcbn0DAof9tiVpQvzUdHlr
         AdKcVGaFPfJqc4C8kieIIS93yB4OdsLwC/rSpcDcmi/qb01CR1lWtvRQi4TKsE9036T/
         6A3X56CH00dJFqa/uDd5l0gJ6Pw0Rj/BHSCHyudX9xoBC7p2vPkANj8OEHQ49grlM2Fn
         0gbYtEKLaNbs9t7fJYH/P4ktZDDbpiTR0W56vV9eH0ofiqFVWfl//kch/iTtxy/HE93Z
         cr8A==
X-Gm-Message-State: AIkVDXIja+uRyKBP1ItvmYM3BZjIKgPpLKQkrw7e1D2gCsl2K4llWShLG7PPijYB3CWBug==
X-Received: by 10.159.39.193 with SMTP id b59mr2601456uab.27.1484155021248;
        Wed, 11 Jan 2017 09:17:01 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.73.152 with SMTP id e24ls1462911itd.22.gmail; Wed, 11 Jan
 2017 09:16:59 -0800 (PST)
X-Received: by 10.36.158.136 with SMTP id p130mr726255itd.2.1484155019059;
        Wed, 11 Jan 2017 09:16:59 -0800 (PST)
In-Reply-To: <216fe26f-2155-42b4-9350-cb4c7f4e9f4a@isocpp.org>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:30482
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30482>

------=_Part_2267_635230327.1484155018589
Content-Type: multipart/alternative; 
	boundary="----=_Part_2268_1643635468.1484155018589"

------=_Part_2268_1643635468.1484155018589
Content-Type: text/plain; charset=UTF-8

On Wednesday, January 11, 2017 at 5:40:40 AM UTC-5, gmis...@gmail.com wrote:
>
> On Wednesday, January 11, 2017 at 8:09:42 AM UTC+13, Nicol Bolas wrote:
>>
>> On Tuesday, January 10, 2017 at 11:59:16 AM UTC-5, Matthew Woehlke wrote:
>>>
>>> On 2017-01-10 11:20, Nicol Bolas wrote: 
>>> > On Tuesday, January 10, 2017 at 10:49:34 AM UTC-5, Matthew Woehlke 
>>> wrote: 
>>> >> On 2017-01-10 10:31, m.ce...@gmail.com <javascript:> wrote: 
>>> >>> For sure baseline API must be exception-free. 
>>> >>> Do we really want to additionally support API that throws on error? 
>>> >> 
>>> >> I *really* hope we can use something like std::expected; this is a 
>>> >> textbook use case for that, and makes it trivial to have a 
>>> >> throw-on-error API (just grab the value from the expected without 
>>> >> checking it first; this will turn around and throw if the value is 
>>> not 
>>> >> there). 
>>> > 
>>> > But the fact that it's throwing the wrong exception makes it useless 
>>> from 
>>> > an exception handling perspective. 
>>>
>>> Huh? I'm talking about std::expected, not std::optional. If you didn't 
>>> get a value, you get whatever error/exception (preferably an exception 
>>> in this case, since it doesn't need more storage than the enum and thus 
>>> doesn't cost extra) the API stuffed in instead, which would presumably 
>>> be a std::range_error or std::bad_enum_cast or whatever. IOW, the *SAME* 
>>> exception that an API that throws right away would throw.
>>>
>>
>> Actually, you can't do that. Well, not in P0323 `expected`. It has a 
>> specific requirement that `E` is no-throw move constructible (in order to 
>> ensure never-empty without bloat). But `std::range_error` has no such 
>> guarantee on its move constructor. Also, it throws 
>> `bad_expected_access<E>`, not `E` itself.
>>
>> Even ignoring that, you want the API to return `std::expected<Enum, 
>> std::range_error>`. Well, `std::range_error` derives from 
>> `std::runtime_error`. And that internally stores a string. Not necessarily 
>> `std::string`, but it stores a sequence of characters it dynamically 
>> allocates, along with the means to delete it. And whatever that storage may 
>> be, it's almost certainly bigger than `sizeof(Enum)`.
>>
>> Which now means that your return type is needlessly bloated. If you had 
>> returned `std::optional<Enum>`, there would be no bloat.
>>
>> Generally speaking, you should never use the *actual exception type* 
>> that you would have otherwise thrown as the non-expected value in an 
>> `expected`. `expected` errors are intended to be *lightweight*: error 
>> codes and the like. Not things that own memory and so forth. By contrast, 
>> exceptions can be quite heavy.
>>
>
>
> My suggestion I talked about a  make_bad_enum function which a template 
> function that you passed the type of the enum that you thought was bad and 
> a value (not an enum) that you had that you were asserting was 'bad' - i.e. 
> you had discovered it was not convertible to an enum.
> And I was suggesting that the make_bad_enum function had compiler magic 
> that new how to turn your enum type e.g. enum my::traffic_light 
> {whatever=whatever} into a string/char array "my:;traffic_light".
>
> It would then create a string of the info an give you an exception object 
> back that you could then throw or do whatever with.
> so given namespace my { enum class traffic_light { stop, careful, go }; } }
> make_enum<traffic_light>(3) would produce an exception where what() would 
> return an array with
> '3 is not a valid value for my:;traffic_light'.
>
> I think this is desirable to just having either an 
> std::bad_optional_access with what string exactly in?
>

Sure, but... I'm not arguing against what you suggested. Indeed, I was 
specifically arguing against the idea that generic exceptions (whether 
`bad_optional_access` or ` bad_expected_access<E>`) were a good idea.

Are you sure you intend to be replying to me?

std::range_error was ok with me as that could be constructed with a string 
> and the type more reflected the problem.
>
> What's wrong with this in your opinion?
>

I see no reason to use a generic exception when an exception type specific 
to enumeration casting could be employed instead. It's ultimately more 
descriptive and obvious what's going on.

A bad_enum class would have allowed an internal char buffer of fixed size 
> to be used because we know what length string worst case we are storing 
> here if that was the problem.
>

How? An enumeration can be a member of any number of namespaces and/or 
classes. Thus its name can be quite long. While any particular 
implementation could use its internal compiler limits to give it a maximum 
length, that length would be pretty huge, tens if not hundreds of kilobytes 
long.

Better to dynamically allocate it than to throw such a gargantuan object 
around.

-- 
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/615ad4bb-f321-4ace-8dd1-335e97b6c7a0%40isocpp.org.

------=_Part_2268_1643635468.1484155018589
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, January 11, 2017 at 5:40:40 AM UTC-5, gmis..=
..@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">On Wednesday, January 11, 2017 at 8:09:42 AM UTC+13, Nicol Bolas wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;paddin=
g-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-=
left-style:solid"><div dir=3D"ltr">On Tuesday, January 10, 2017 at 11:59:16=
 AM UTC-5, Matthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,20=
4);border-left-width:1px;border-left-style:solid">On 2017-01-10 11:20, Nico=
l Bolas wrote:
<br>&gt; On Tuesday, January 10, 2017 at 10:49:34 AM UTC-5, Matthew Woehlke=
 wrote:
<br>&gt;&gt; On 2017-01-10 10:31, <a>m.ce...@gmail.com</a> &lt;javascript:&=
gt; wrote:=20
<br>&gt;&gt;&gt; For sure baseline API must be exception-free.=20
<br>&gt;&gt;&gt; Do we really want to additionally support API that throws =
on error?=20
<br>&gt;&gt;
<br>&gt;&gt; I *really* hope we can use something like std::expected; this =
is a=20
<br>&gt;&gt; textbook use case for that, and makes it trivial to have a=20
<br>&gt;&gt; throw-on-error API (just grab the value from the expected with=
out=20
<br>&gt;&gt; checking it first; this will turn around and throw if the valu=
e is not=20
<br>&gt;&gt; there).
<br>&gt;=20
<br>&gt; But the fact that it&#39;s throwing the wrong exception makes it u=
seless from=20
<br>&gt; an exception handling perspective.
<br>
<br>Huh? I&#39;m talking about std::expected, not std::optional. If you did=
n&#39;t
<br>get a value, you get whatever error/exception (preferably an exception
<br>in this case, since it doesn&#39;t need more storage than the enum and =
thus
<br>doesn&#39;t cost extra) the API stuffed in instead, which would presuma=
bly
<br>be a std::range_error or std::bad_enum_cast or whatever. IOW, the *SAME=
*
<br>exception that an API that throws right away would throw.<br></blockquo=
te><div><br>Actually, you can&#39;t do that. Well, not in P0323 `expected`.=
 It has a specific requirement that `E` is no-throw move constructible (in =
order to ensure never-empty without bloat). But `std::range_error` has no s=
uch guarantee on its move constructor. Also, it throws `bad_expected_access=
&lt;E&gt;`, not `E` itself.<br><br>Even ignoring that, you want the API to =
return `std::expected&lt;Enum, std::range_error&gt;`. Well, `std::range_err=
or` derives from `std::runtime_error`. And that internally stores a string.=
 Not necessarily `std::string`, but it stores a sequence of characters it d=
ynamically allocates, along with the means to delete it. And whatever that =
storage may be, it&#39;s almost certainly bigger than `sizeof(Enum)`.<br><b=
r>Which now means that your return type is needlessly bloated. If you had r=
eturned `std::optional&lt;Enum&gt;`, there would be no bloat.<br><br>Genera=
lly speaking, you should never use the <i>actual exception type</i> that yo=
u would have otherwise thrown as the non-expected value in an `expected`. `=
expected` errors are intended to be <i>lightweight</i>: error codes and the=
 like. Not things that own memory and so forth. By contrast, exceptions can=
 be quite heavy.</div></div></blockquote><div><br></div><div><br></div><div=
>My suggestion I talked about a =C2=A0make_bad_enum function which a templa=
te function that you passed the type of the enum that you thought was bad a=
nd a=C2=A0value (not an enum) that you had that you were asserting was &#39=
;bad&#39;=C2=A0- i.e. you had discovered it was not convertible to an enum.=
</div><div>And I was suggesting that the make_bad_enum function had compile=
r magic that new how to turn your enum=C2=A0type e.g. enum my::traffic_ligh=
t {whatever=3Dwhatever}=C2=A0into=C2=A0a=C2=A0<wbr>string/char array=C2=A0&=
quot;my:;traffic_light&quot;.</div><div><br></div><div>It would then create=
 a string of the info an give you an exception object back that you could t=
hen throw or do whatever with.</div><div>so given namespace my { enum class=
 traffic_light { stop, careful, go };=C2=A0} }</div><div>make_enum&lt;traff=
ic_light&gt;(3) would produce an exception where what() would return an arr=
ay with</div><div>&#39;3 is not a valid value for my:;traffic_light&#39;.</=
div><div><br></div><div>I think this is desirable to just having either an =
std::bad_optional_access with what string exactly in?</div></div></blockquo=
te><div><br>Sure, but... I&#39;m not arguing against what you suggested. In=
deed, I was specifically arguing against the idea that generic exceptions (=
whether `bad_optional_access` or ` bad_expected_access&lt;E&gt;`) were a go=
od idea.<br><br>Are you sure you intend to be replying to me?<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><d=
iv>std::range_error was ok with me as that could be constructed with a stri=
ng and the type more reflected the problem.</div><div><br></div><div>What&#=
39;s wrong with this in your opinion?</div></div></blockquote><div><br>I se=
e no reason to use a generic exception when an exception type specific to e=
numeration casting could be employed instead. It&#39;s ultimately more desc=
riptive and obvious what&#39;s going on.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>A bad_enum=C2=A0cl=
ass would have allowed an internal char=C2=A0buffer of=C2=A0fixed size to b=
e used because we know what length string worst case we are storing here if=
 that was the problem.</div></div></blockquote><br>How? An enumeration can =
be a member of any number of namespaces and/or classes. Thus its name can b=
e quite long. While any particular implementation could use its internal co=
mpiler limits to give it a maximum length, that length would be pretty huge=
, tens if not hundreds of kilobytes long.<br><br>Better to dynamically allo=
cate it than to throw such a gargantuan object around.<br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/615ad4bb-f321-4ace-8dd1-335e97b6c7a0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/615ad4bb-f321-4ace-8dd1-335e97b6c7a0=
%40isocpp.org</a>.<br />

------=_Part_2268_1643635468.1484155018589--

------=_Part_2267_635230327.1484155018589--

.
