220 30210 <0aa20bca-079b-4ca8-b744-08bdaeeb8d44@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: Tue, 3 Jan 2017 19:52:18 -0800 (PST)
Lines: 313
Approved: news@gmane.org
Message-ID: <0aa20bca-079b-4ca8-b744-08bdaeeb8d44@isocpp.org>
References: <efdf2357-00a6-408a-8772-12f99135a880@isocpp.org>
 <a19ed9c6-45c0-e3d7-e92a-06468bff63b7@wanadoo.fr>
 <119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6@isocpp.org>
 <53189e5e-b1cf-0411-c87e-542822dbd4c0@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_2482_1134974176.1483501938664"
X-Trace: blaine.gmane.org 1483501954 24300 195.159.176.226 (4 Jan 2017 03:52:34 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Wed, 4 Jan 2017 03:52:34 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBB5HCWHBQKGQEOGXPJWQ@isocpp.org Wed Jan 04 04:52:25 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBB5HCWHBQKGQEOGXPJWQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-it0-f69.google.com ([209.85.214.69])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBB5HCWHBQKGQEOGXPJWQ@isocpp.org>)
	id 1cOcca-0004Lq-Mo
	for gclcip-std-proposals@m.gmane.org; Wed, 04 Jan 2017 04:52:17 +0100
Original-Received: by mail-it0-f69.google.com with SMTP id g187sf451337468itc.2
        for <gclcip-std-proposals@m.gmane.org>; Tue, 03 Jan 2017 19:52:21 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to: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=e/dBrS6ppPIZnwBIIzxB3OnFXiMp7SgQLfWE961ulWI=;
        b=ImpI3GrfSYlkRNka/d71H8LZe2jNGXs3bjCbMWOnLJwxfJBU9uzxIMPDZxcpP5bsqp
         vk+dOmKFcgvNEkaaV++JeTMDre+9tUsUvgwXKNOTrPgxdfM7hmnFiS+ZcMhyg+7Vpfkw
         nlKrqiCkMmbD5MNtntguRxbZ1ZnoLnTA/9HJkEQEUOhswAD1KMsrB8DEfeTCQMm+Dl+1
         GCsVimv0Btf/WTizPVtTqLQnXk22+APLKOPSJuIFSJYW+W9xrHdHMkc+ESr6kHtKN+zL
         4U7X6k59VPYTe2y0x3oZNO7HMtpaGHSvxG+bzDYSNHMLrN6OD37c2Qc2QqTznPY7mABV
         Elqw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to: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=e/dBrS6ppPIZnwBIIzxB3OnFXiMp7SgQLfWE961ulWI=;
        b=M9Ty5kEPPxFFWEAj42oEgil2bpBQOzczAam1PYzc/mYwGD0R460QmQ5JK8wtjMwMej
         OfsRgww+NpgzHiEC3B1xkPC9Oh92sn6DzmBAYOJL3UlOpYEoNQEMfmqSxF01nQWHJxQw
         koJJrR5vxKU4FA+U64LHujAbususdiC4FH1s7nNgQTqoP4PmNDOno/Gx66aMqbWYKbcF
         Y7ylD2AYtePUJrWk0c+Dtw6zvjsavrqpbnbSkLc3JBEMONTbBLvWUd43sxuu6JxGHQck
         f1s/t70My+i7c7Yi7SNGmmAuJiYgR5cmgy/pTQfKQrK/btnECNWKYXhkt6zpK+Q5YCBL
         Rwmw==
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: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=e/dBrS6ppPIZnwBIIzxB3OnFXiMp7SgQLfWE961ulWI=;
        b=A/WtcUwzXQFkkVTN+2bMZtVQ4dtGG2dEI49ZbupCYvw7eWfbLxL5TZn68gjo1RMWtK
         TawZZeLVzcQuCeKo/dnESWljF54bTnfrvWHv9GEIqaXAH0vDlRX9zlcZ5cHjTOM2fpPK
         vRFptc+DOgi8HeC0NXOlxzRpg373K6eQug6ltJU5Mbn09MMIEdgQHM3UT309goM6+ZDD
         OvOmdXGgQBR+R1ZfqCjlcl+QNok2RMEfMc8rkY21SylZ4RC/9GWk68oBMn7y3mVlfdL4
         ThoJHQXeBrfaZt04Wla7T4CMm69+osUs4HerSPKgEBE8kjfgQXqjtWXoky8V+a2ysXZD
         YhWQ==
X-Gm-Message-State: AIkVDXIayGZPHAZgSOBqvYSnI+icxx/3j+zrZzrVsw8rTDQdZuNHDsJrd3+J+QTDl1MGeg==
X-Received: by 10.36.95.209 with SMTP id r200mr14266694itb.16.1483501940507;
        Tue, 03 Jan 2017 19:52:20 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.17.154 with SMTP id v26ls160007otf.0.gmail; Tue, 03 Jan
 2017 19:52:19 -0800 (PST)
X-Received: by 10.157.42.16 with SMTP id t16mr2030261ota.18.1483501939421;
        Tue, 03 Jan 2017 19:52:19 -0800 (PST)
In-Reply-To: <53189e5e-b1cf-0411-c87e-542822dbd4c0@wanadoo.fr>
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:30210
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30210>

------=_Part_2482_1134974176.1483501938664
Content-Type: multipart/alternative; 
	boundary="----=_Part_2483_1262497948.1483501938664"

------=_Part_2483_1262497948.1483501938664
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, January 3, 2017 at 5:04:22 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 03/01/2017 =C3=A0 19:43, Nicol Bolas a =C3=A9crit :
>
>
>
> On Tuesday, January 3, 2017 at 1:25:20 PM UTC-5, Vicente J. Botet Escriba=
=20
> wrote:=20
>>
>> Le 03/01/2017 =C3=A0 10:56, m.ce...@gmail.com a =C3=A9crit :
>>
>> Hi,=20
>>
>> I propose to add a enum_cast function that safely casts int value to a=
=20
>> target enum type if int value represents a valid enumerator.
>>
>> template <typename Enum, typename Int>
>> optional<Enum> enum_cast(Int value);
>>
>> requires: is_enum<Enum>, is_integral<Int>
>>
>>
>> Why do we want this:
>>  - validation of input data (e.g. coming from user or deserialization).
>>  - other?
>>
>> I know this could be purely library extension if based on reflection, bu=
t=20
>> since we don't know when we will get reflection,
>> and implementation based on reflection may not be optimal,
>> I think it should be implemented with compiler support (i.e. via=20
>> __builtin_* intrinsic).
>>
>> Hi, I believe this could be useful. Library implementers could be free t=
o=20
>> use builtins or reflection once it is there.
>>
>> Now, I believe that we need two kind of functions. One that is a cast an=
d=20
>> that says just that we are casting. It would be the same as a static_cas=
t.=20
>> Something like gsl::narrow_cast so that we express better the intent. In=
=20
>> addition we need the function you are proposing similar to gsl::narrow.
>> The question is how the function reports errors. If we use exceptions, I=
=20
>> agree with Nicol that a specific exception would be better.
>>
>> I will then propose=20
>> * enum_cast ~static_cast
>>
>
> What's the point of `enum_cast`, save the fact that it would SFINAE on th=
e=20
> given type being an actual enumeration? `static_cast` is the standard way=
=20
> of saying "make this integer an enum without checking". I don't think we=
=20
> need another way to spell that.
>
> What is the point of narrow_cast?
>

.... I don't know. But I'm pretty sure it's not part of the C++ standard, so=
=20
why are you asking?
=20

> I believe it is useful to know the kind of cast we are using. This helps=
=20
> to inspect the code we (others) have written in a more efficient way.
>

It's a static_cast. That's the kind of cast you're using.

I have a strong dislike of proliferating non-standard cast functions.=20
Pointer-based casts that are equivalent to standard library casts, those=20
are fine. But inventing a new cast with its own special behavior? Why?=20

> =20
>
>> * to_enum : throw exception if error
>> * try_to_enum : returns optional<Enum> or an interface based on=20
>> error_code (like from_chars). status_value and expected can be considere=
d=20
>> also once adopted.
>> Do we expect several error conditions?
>>
>
> Well, there's only one failure state: the given value is not in the=20
> enumeration. As such, I see no need for using complicated objects that=20
> store errors; `optional` should be sufficient.
>
> If there is only one error case, yes optional is a good candidate.
> However it would be weird to have a different exception depending on=20
> whether the user uses to_enum or try_to_enum (or whatever names are more=
=20
> appropriated)
>

The function returning an `optional` doesn't throw an exception. The=20
exception is thrown by the improper use of `optional`.

Remember: the user who asked for an `optional` *wants the behavior* of an=
=20
`optional`. Which almost certainly means that they're not going to call=20
`value` without actually checking its value. If they were happy with an=20
exception being thrown, they wouldn't be using the `optional` version.

Let's not assume that the user has no idea how to use the API.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0aa20bca-079b-4ca8-b744-08bdaeeb8d44%40isocpp.or=
g.

------=_Part_2483_1262497948.1483501938664
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 5:04:22 PM UTC-5, V=
icente J. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 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 03/01/2017 =C3=A0 19:43, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Tuesday, January 3, 2017 at 1:25:20 PM UTC-5, Vicente J.
        Botet Escriba wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div bgcolor=3D"#FFFFFF" text=3D"#000000">
            <div>Le 03/01/2017 =C3=A0 10:56, <a rel=3D"nofollow">m.ce...@gm=
ail.com</a>
              a =C3=A9crit=C2=A0:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">Hi,
                <div><br>
                </div>
                <div>I propose to add a enum_cast function that safely
                  casts int value to a target enum type if int value
                  represents a valid enumerator.</div>
                <div><br>
                </div>
                <div style=3D"border:1px solid rgb(187,187,187);word-wrap:b=
reak-word;background-color:rgb(250,250,250)"><code>
                    <div><span style=3D"color:#008">template</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#008">typename</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#606">Enum</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#606">Int</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>
                        optional</span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#606">Enum</span><span style=3D"color:#660">&gt;</sp=
an><span style=3D"color:#000"> enum_cast</span><span style=3D"color:#660">(=
</span><span style=3D"color:#606">Int</span><span style=3D"color:#000"> val=
ue</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br=
>
                        <br>
                        requires</span><span style=3D"color:#660">:</span><=
span style=3D"color:#000"> is_enum</span><span style=3D"color:#660">&lt;</s=
pan><font color=3D"#000000"><span style=3D"color:#606">Enum</span></font><s=
pan style=3D"color:#660">&gt;,</span><span style=3D"color:#000"> is_integra=
l</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">In=
t</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r>
                        <br>
                      </span><span style=3D"color:#008"></span></div>
                  </code></div>
                <br>
                <div>Why do we want this:<br>
                </div>
                <div>=C2=A0- validation of input data (e.g. coming from use=
r
                  or deserialization).</div>
                <div>=C2=A0- other?</div>
                <div><br>
                </div>
                <div>I know this could be purely library extension if
                  based on reflection, but since we don&#39;t know when we
                  will get reflection,</div>
                <div>and implementation based on reflection may not be
                  optimal,</div>
                <div>I think it should be implemented with compiler
                  support (i.e. via __builtin_* intrinsic).</div>
                <div><br>
                </div>
              </div>
            </blockquote>
            Hi, I believe this could be useful. Library implementers
            could be free to use builtins or reflection once it is
            there.<br>
            <br>
            Now, I believe that we need two kind of functions. One that
            is a cast and that says just that we are casting. It would
            be the same as a static_cast. Something like
            gsl::narrow_cast so that we express better the intent. In
            addition we need the function you are proposing similar to
            gsl::narrow.<br>
            The question is how the function reports errors. If we use
            exceptions, I agree with Nicol that a specific exception
            would be better.<br>
            <br>
            I will then propose <br>
            * enum_cast ~static_cast<br>
          </div>
        </blockquote>
        <div><br>
          What&#39;s the point of `enum_cast`, save the fact that it would
          SFINAE on the given type being an actual enumeration?
          `static_cast` is the standard way of saying &quot;make this integ=
er
          an enum without checking&quot;. I don&#39;t think we need another=
 way
          to spell that.<br>
        </div>
      </div>
    </blockquote>
    What is the point of narrow_cast?</div></blockquote><div><br>... I don&=
#39;t know. But I&#39;m pretty sure it&#39;s not part of the C++ standard, =
so why are you asking?<br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">I believe it is useful to=
 know the
    kind of cast we are using. This helps to inspect the code we
    (others) have written in a more efficient way.</div></blockquote><div><=
br>It&#39;s a static_cast. That&#39;s the kind of cast you&#39;re using.<br=
><br>I have a strong dislike of proliferating non-standard cast functions. =
Pointer-based casts that are equivalent to standard library casts, those ar=
e fine. But inventing a new cast with its own special behavior? Why? <br></=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" t=
ext=3D"#000000">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>=C2=A0</div>
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div bgcolor=3D"#FFFFFF" text=3D"#000000"> * to_enum : throw
            exception if error<br>
            * try_to_enum : returns optional&lt;Enum&gt; or an interface
            based on error_code (like from_chars). status_value and
            expected can be considered also once adopted.<br>
            Do we expect several error conditions?<br>
          </div>
        </blockquote>
        <div><br>
          Well, there&#39;s only one failure state: the given value is not
          in the enumeration. As such, I see no need for using
          complicated objects that store errors; `optional` should be
          sufficient.<br>
        </div>
      </div>
    </blockquote>
    If there is only one error case, yes optional is a good candidate.<br>
    However it would be weird to have a different exception depending on
    whether the user uses to_enum or try_to_enum (or whatever names are
    more appropriated)<br></div></blockquote><div><br>The function returnin=
g an `optional` doesn&#39;t throw an exception. The exception is thrown by =
the improper use of `optional`.<br><br>Remember: the user who asked for an =
`optional` <i>wants the behavior</i> of an `optional`. Which almost certain=
ly means that they&#39;re not going to call `value` without actually checki=
ng its value. If they were happy with an exception being thrown, they would=
n&#39;t be using the `optional` version.<br><br>Let&#39;s not assume that t=
he user has no idea how to use the API.<br></div></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/0aa20bca-079b-4ca8-b744-08bdaeeb8d44%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0aa20bca-079b-4ca8-b744-08bdaeeb8d44=
%40isocpp.org</a>.<br />

------=_Part_2483_1262497948.1483501938664--

------=_Part_2482_1134974176.1483501938664--

.
