220 30189 <119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6@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 10:43:41 -0800 (PST)
Lines: 273
Approved: news@gmane.org
Message-ID: <119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6@isocpp.org>
References: <efdf2357-00a6-408a-8772-12f99135a880@isocpp.org>
 <a19ed9c6-45c0-e3d7-e92a-06468bff63b7@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1832_42876821.1483469021460"
X-Trace: blaine.gmane.org 1483469026 29736 195.159.176.226 (3 Jan 2017 18:43:46 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 3 Jan 2017 18:43:46 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBXXBV7BQKGQEMUXXJ5I@isocpp.org Tue Jan 03 19:43:41 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBXXBV7BQKGQEMUXXJ5I@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-it0-f72.google.com ([209.85.214.72])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBXXBV7BQKGQEMUXXJ5I@isocpp.org>)
	id 1cOU3e-0006ji-Ng
	for gclcip-std-proposals@m.gmane.org; Tue, 03 Jan 2017 19:43:39 +0100
Original-Received: by mail-it0-f72.google.com with SMTP id n68sf441303432itn.4
        for <gclcip-std-proposals@m.gmane.org>; Tue, 03 Jan 2017 10:43:43 -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=bU4b6yJ61LsRolmyg/At6ij0yu7yJG0HCv1f7vIk59A=;
        b=WGPtCiwNCuIe69SX5R2KM83aRsUnS+DrN/O40bSyxvi7ZvqxoOfchFMy8nIaEL+REj
         XebLwrN3QDkU3iK28nEe5b1xSrYl+dkr5GBcqWy/IdfenIFxnMuPpyJKQWtH3a9DeSpD
         1lEnyBB72ux95dnYGlOE+g1M+WKWmg4hIwXJd1GyKK6pupS8ehNzEH7qqEskIiCfA7iq
         hPK50ZJWoG2ySGaTdonVoyNf2I6wMxwS/WiOEUq1kYGzLfCml02zutYOT8ZrfSP4piT7
         wEQ1bXteqxHxNQRJldjpHvfIxqEsJuNC256YOwcDLWX6B7qhV+xTktlvWuvlnyJ64eZX
         eD0g==
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=bU4b6yJ61LsRolmyg/At6ij0yu7yJG0HCv1f7vIk59A=;
        b=fxj49UoTIXKHV0yGXNXXGPbQkhLz1IzBN4rYYvfxuYAjjjCvIYVHgIUDYorYNNWblp
         GJYHOfQld4Ks3ulMTqomOSc/YaWoZQoTzQEjVHxbmkKQqJ5bNCynSETP55T86XVDyr8Z
         5C99ALcG/Om9zhN6soBTujauMt+d9d2xYMX4PW9jXnuXo+BGBaHo0yVthIQXnp7Tlvkw
         HRdFFj0a9lTGqbJJVaZcbpc90FEG3cm0kXxa96/GOLACw5yguHRd/gTEowNLuEB7/HYG
         IKjk+TRYFV1K93HybpCuJvSFPJ44lT42eg2lovq9bWaWudO6x0QNLrp+xhKCyVRsIs4j
         zkDQ==
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=bU4b6yJ61LsRolmyg/At6ij0yu7yJG0HCv1f7vIk59A=;
        b=KAZnP/LOycYyWOyHY332xu1WdXp2AkaMl++JT4AsHDJRzxt7U5MlBdSbpmDW3RkwVR
         gbcUWKUUOkW4hbcD+XTxNnf28/No1wVQFyu0w7qJK3ENYv7akO98ekBFbp6IB3Oi/0qi
         wzO5SkECtVoTG4pdsnHLktGZxXeO5l3vQ2RKQsVtxtl3WPtSuEd3S62GFT3vW/J1IWnU
         bNpalTESakKRJSKElYQY2r2FQkQ5s3yXBbRu4/W6higuVK/3qVCXVxe2D+H9rf6A0Rl6
         daNB0d/n6CNHMMc7SRwGSXskf3O6RUHo+HmshO9UNfHL/G4Jckz6lchQ9dNhrjU7YgVh
         EU0g==
X-Gm-Message-State: AIkVDXLrVjyReNX0K7fBMDV81ufPEX4mJmVmN63+BlscjYOqpZCldSEafuwNhuss2AW2ew==
X-Received: by 10.36.117.65 with SMTP id y62mr13500245itc.4.1483469022743;
        Tue, 03 Jan 2017 10:43:42 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.53.52 with SMTP id o49ls39689222otc.18.gmail; Tue, 03 Jan
 2017 10:43:42 -0800 (PST)
X-Received: by 10.157.17.3 with SMTP id g3mr2935014ote.8.1483469021990;
        Tue, 03 Jan 2017 10:43:41 -0800 (PST)
In-Reply-To: <a19ed9c6-45c0-e3d7-e92a-06468bff63b7@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:30189
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30189>

------=_Part_1832_42876821.1483469021460
Content-Type: multipart/alternative; 
	boundary="----=_Part_1833_311645332.1483469021461"

------=_Part_1833_311645332.1483469021461
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, January 3, 2017 at 1:25:20 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 03/01/2017 =C3=A0 10:56, m.ce...@gmail.com <javascript:> 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>
>
> enum color
> {
>    red =3D 1,
>    green =3D 200,
>    blue =3D 3
> };
>
> static_assert(enum_cast<color>(200u) =3D=3D color::green);
> static_assert(enum_cast<color>(3) =3D=3D color::blue);
> static_assert(enum_cast<color>(4) =3D=3D nullopt);
>
>
> This should work for both scoped and unscoped enums.
> For opaque enums this would only check if value fits in underlying type.
>
> 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, but=
=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 to=
=20
> use builtins or reflection once it is there.
>
> Now, I believe that we need two kind of functions. One that is a cast and=
=20
> that says just that we are casting. It would be the same as a static_cast=
..=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 the=
=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.
=20

> * to_enum : throw exception if error
> * try_to_enum : returns optional<Enum> or an interface based on error_cod=
e=20
> (like from_chars). status_value and expected can be considered also once=
=20
> 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.

--=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/119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6%40isocpp.or=
g.

------=_Part_1833_311645332.1483469021461
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 1:25:20 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 10:56,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"Hr=
se9vd-CwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>m.ce...@gmail.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:break-wor=
d;background-color:rgb(250,250,250)"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#606">Enum</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">typename</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#606">Int</span><span style=3D"colo=
r:#660">&gt;</span><span style=3D"color:#000"><br>
                optional</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#606">Enum</span><span style=3D"color:#660">&gt;</span><span=
 style=3D"color:#000">
                enum_cast</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#606">Int</span><span style=3D"color:#000"> value</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"><br>
                <br>
                requires</span><span style=3D"color:#660">:</span><span sty=
le=3D"color:#000"> is_enum</span><span style=3D"color:#660">&lt;</span><fon=
t color=3D"#000000"><span style=3D"color:#606">Enum</span></font><span styl=
e=3D"color:#660">&gt;,</span><span style=3D"color:#000">
                is_integral</span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#606">Int</span><span style=3D"color:#660">&gt;</span><sp=
an style=3D"color:#000"><br>
                <br>
              </span><span style=3D"color:#008">enum</span><span style=3D"c=
olor:#000"> color<br>
              </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0red </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#066">1</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0green </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#066">200</span=
><span style=3D"color:#660">,</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0blue </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">3</span><s=
pan style=3D"color:#000"><br>
              </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br>
                <br>
              </span><span style=3D"color:#008">static_assert</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">enum_cast</span><spa=
n style=3D"color:#080">&lt;color&gt;</span><span style=3D"color:#660"><wbr>=
(</span><font color=3D"#006666"><span style=3D"color:#066">200u</span></fon=
t><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> color</spa=
n><span style=3D"color:#660">::</span><font color=3D"#000000"><span style=
=3D"color:#000">green</span></font><span style=3D"color:#660">);</span><spa=
n style=3D"color:#000"><br>
              </span><span style=3D"color:#008">static_assert</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">enum_cast</span><spa=
n style=3D"color:#080">&lt;color&gt;</span><span style=3D"color:#660"><wbr>=
(</span><span style=3D"color:#066">3</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=3D</sp=
an><span style=3D"color:#000"> color</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">blue</span><span style=3D"color:#660">);</sp=
an><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">static_assert</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">enum_cast</span><spa=
n style=3D"color:#080">&lt;color&gt;</span><span style=3D"color:#660"><wbr>=
(</span><span style=3D"color:#066">4</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=3D</sp=
an><span style=3D"color:#000"> nullopt</span><span style=3D"color:#660">);<=
/span><span style=3D"color:#000"><br>
                <br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>This should work for both scoped and unscoped enums.</div>
        <div>For opaque enums this would only check if value fits in
          underlying type.<br>
        </div>
        <div><br>
        </div>
        <div>Why do we want this:<br>
        </div>
        <div>=C2=A0- validation of input data (e.g. coming from user 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,</di=
v>
        <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=20
the given type being an actual enumeration? `static_cast` is the=20
standard way of saying &quot;make this integer an enum without checking&quo=
t;. I=20
don&#39;t think we need another way to spell that.<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#00000=
0">
    * 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>W=
ell, there&#39;s only one failure state: the given value is not in the enum=
eration. As such, I see no need for using complicated objects that store er=
rors; `optional` should be sufficient.<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/119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6=
%40isocpp.org</a>.<br />

------=_Part_1833_311645332.1483469021461--

------=_Part_1832_42876821.1483469021460--

.
