Topic: enum_cast proposal


Author: m.cencora@gmail.com
Date: Tue, 3 Jan 2017 01:56:05 -0800 (PST)
Raw View
------=_Part_2059_164701516.1483437365479
Content-Type: multipart/alternative;
 boundary="----=_Part_2060_263266050.1483437365480"

------=_Part_2060_263266050.1483437365480
Content-Type: text/plain; charset=UTF-8

Hi,

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.

template <typename Enum, typename Int>
optional<Enum> enum_cast(Int value);

requires: is_enum<Enum>, is_integral<Int>

enum color
{
   red = 1,
   green = 200,
   blue = 3
};

static_assert(enum_cast<color>(200u) == color::green);
static_assert(enum_cast<color>(3) == color::blue);
static_assert(enum_cast<color>(4) == 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
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
__builtin_* intrinsic).

Regards,
Maciej

--
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/efdf2357-00a6-408a-8772-12f99135a880%40isocpp.org.

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

<div dir=3D"ltr">Hi,<div><br></div><div>I propose to add a enum_cast functi=
on that safely casts int value to a target enum type if int value represent=
s a valid enumerator.</div><div><br></div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Enum</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>op=
tional</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Enum</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> enum_cast</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Int</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> value</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br>requires</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> is_enum</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><font color=3D"#000000"><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Enum</span></font><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&gt;,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> is_integral</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Int</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">enum</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> color<br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0red </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">1=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0gr=
een </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #066;" class=3D"styled-by-prettify">200</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0blue </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">3</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">static_assert</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">enum_cast</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
">&lt;color&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><font color=3D"#006666"><span style=3D"color: #066;" class=3D"=
styled-by-prettify">200u</span></font><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
color</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by=
-prettify">green</span></font><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">s=
tatic_assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">enum_ca=
st</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;colo=
r&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> color</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">blue</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">st=
atic_assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">enum_cas=
t</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;color=
&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> nullopt</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br></span></div></code></div><div><br></div><div>Th=
is should work for both scoped and unscoped enums.</div><div>For opaque enu=
ms this would only check if value fits in underlying type.<br></div><div><b=
r></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 b=
ased 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 __bu=
iltin_* intrinsic).</div><div><br></div><div>Regards,</div><div>Maciej</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/efdf2357-00a6-408a-8772-12f99135a880%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/efdf2357-00a6-408a-8772-12f99135a880=
%40isocpp.org</a>.<br />

------=_Part_2060_263266050.1483437365480--

------=_Part_2059_164701516.1483437365479--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 12:25:18 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 01:56:05 BRST m.cencora@gmail.com=
 wrote:
> template <typename Enum, typename Int>
> optional<Enum> enum_cast(Int value);
>=20
> requires: is_enum<Enum>, is_integral<Int>
>=20
> enum color
> {
>    red =3D 1,
>    green =3D 200,
>    blue =3D 3
> };

How do you see compilers implementing:

void f(int x)
{
 enum_cast<color>(x);
}

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/1483532086.2yCkjVBYWJ%40tjmaciei-mobl1.

.


Author: m.cencora@gmail.com
Date: Tue, 3 Jan 2017 07:06:10 -0800 (PST)
Raw View
------=_Part_20_332083105.1483455970154
Content-Type: multipart/alternative;
 boundary="----=_Part_21_340188439.1483455970154"

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

W dniu wtorek, 3 stycznia 2017 15:25:25 UTC+1 u=C5=BCytkownik Thiago Maciei=
ra=20
napisa=C5=82:
>
> On ter=C3=A7a-feira, 3 de janeiro de 2017 01:56:05 BRST m.ce...@gmail.com=
=20
> <javascript:> wrote:=20
> > template <typename Enum, typename Int>=20
> > optional<Enum> enum_cast(Int value);=20
> >=20
> > requires: is_enum<Enum>, is_integral<Int>=20
> >=20
> > enum color=20
> > {=20
> >    red =3D 1,=20
> >    green =3D 200,=20
> >    blue =3D 3=20
> > };=20
>
> How do you see compilers implementing:=20
>
> void f(int x)=20
> {=20
>         enum_cast<color>(x);=20
> }=20
>
>

Compiler should synthesize a function like below:

optional<color> enum_cast(int x)
{
    switch(x)
    {
        case red:
        case green:
        case blue:
            return static_cast<color>(x);
        default:
            return nullopt;
    }
}

Of course it could implement it more efficently (as range check instead of=
=20
switch if all enumerators are consecutive integers).

Regards,
Maciej
=20

> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/bb835a83-0f69-4a76-97df-581c2a2ae8d8%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu wtorek, 3 stycznia 2017 15:25:25 UTC+1 u=C5=BCytkow=
nik Thiago Macieira napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On ter=C3=A7a-feira, 3 de janeiro de 2017 01:56:05 BRST <a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"2RMVUOBxCwAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;javascript:&#39;;return true;">m.ce...@gmail.com</a>=
 wrote:
<br>&gt; template &lt;typename Enum, typename Int&gt;
<br>&gt; optional&lt;Enum&gt; enum_cast(Int value);
<br>&gt;=20
<br>&gt; requires: is_enum&lt;Enum&gt;, is_integral&lt;Int&gt;
<br>&gt;=20
<br>&gt; enum color
<br>&gt; {
<br>&gt; =C2=A0 =C2=A0red =3D 1,
<br>&gt; =C2=A0 =C2=A0green =3D 200,
<br>&gt; =C2=A0 =C2=A0blue =3D 3
<br>&gt; };
<br>
<br>How do you see compilers implementing:
<br>
<br>void f(int x)
<br>{
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0enum_cast&lt;color&gt;(=
x);
<br>}
<br>
<br></blockquote><div><br></div><div><br></div><div>Compiler should synthes=
ize a function like below:</div><div><br></div><div class=3D"prettyprint" s=
tyle=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backgr=
ound-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">o=
ptional</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt=
;color&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 enum_cast</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">switch</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">case</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> red</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">case</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> green</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">case</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> blue</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&lt;color&gt;</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">default</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> nullopt</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><div><b=
r></div><div>Of course it could implement it more efficently (as range chec=
k instead of switch if all enumerators are consecutive integers).</div><div=
><br></div><div>Regards,</div><div>Maciej</div><div>=C2=A0<br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;">--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></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/bb835a83-0f69-4a76-97df-581c2a2ae8d8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bb835a83-0f69-4a76-97df-581c2a2ae8d8=
%40isocpp.org</a>.<br />

------=_Part_21_340188439.1483455970154--

------=_Part_20_332083105.1483455970154--

.


Author: "D. B." <db0451@gmail.com>
Date: Tue, 3 Jan 2017 15:08:45 +0000
Raw View
--001a1145b1be6534b50545320b4c
Content-Type: text/plain; charset=UTF-8

Do you expect the handle the common case where people use enums as bitmasks
of different enumerators?

--
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/CACGiwhEKaOnDPVmSi0%3Da5GK-NJ-jsgafm5y9ZY5iOQrNega%2BFA%40mail.gmail.com.

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

<div dir=3D"ltr"><div>Do you expect the handle the common case where people=
 use enums as bitmasks of different enumerators?<br><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/CACGiwhEKaOnDPVmSi0%3Da5GK-NJ-jsgafm5=
y9ZY5iOQrNega%2BFA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwhEKaOnD=
PVmSi0%3Da5GK-NJ-jsgafm5y9ZY5iOQrNega%2BFA%40mail.gmail.com</a>.<br />

--001a1145b1be6534b50545320b4c--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 07:21:36 -0800 (PST)
Raw View
------=_Part_1545_1639964131.1483456896854
Content-Type: multipart/alternative;
 boundary="----=_Part_1546_1710949020.1483456896854"

------=_Part_1546_1710949020.1483456896854
Content-Type: text/plain; charset=UTF-8

On Tuesday, January 3, 2017 at 4:56:05 AM UTC-5, m.ce...@gmail.com wrote:
>
> Hi,
>
> 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.
>

It should not return an `optional`. It should either correctly cast or
*throw*. Why?

Consider how users will use it. You're going to see a lot of people doing
`enum_cast<>().value()`. Which will incur needless copying if the
conversion worked. And if it doesn't work, an exception will be thrown.

What exception will that be? `bad_optional_access`. Which is about as
useless as exceptions get as far as tracking down the problem. A far more
descriptive exception would be `bad_enum_cast`.

I would say that you should provide both APIs: `enum_cast` for conversion
or throwing. And `optional_enum_cast` or somesuch for conversion into an
`optional<enum>`.

--
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/1daf67ad-8ee7-4ad6-937b-027ba6020c14%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, January 3, 2017 at 4:56:05 AM UTC-5, m.ce...@g=
mail.com 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=
">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 enume=
rator.</div></div></blockquote><div><br>It should not return an `optional`.=
 It should either correctly cast or <i>throw</i>. Why?<br><br>Consider how =
users will use it. You&#39;re going to see a lot of people doing `enum_cast=
&lt;&gt;().value()`. Which will incur needless copying if the conversion wo=
rked. And if it doesn&#39;t work, an exception will be thrown.<br><br>What =
exception will that be? `bad_optional_access`. Which is about as useless as=
 exceptions get as far as tracking down the problem. A far more descriptive=
 exception would be `bad_enum_cast`.<br><br>I would say that you should pro=
vide both APIs: `enum_cast` for conversion or throwing. And `optional_enum_=
cast` or somesuch for conversion into an `optional&lt;enum&gt;`.</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/1daf67ad-8ee7-4ad6-937b-027ba6020c14%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1daf67ad-8ee7-4ad6-937b-027ba6020c14=
%40isocpp.org</a>.<br />

------=_Part_1546_1710949020.1483456896854--

------=_Part_1545_1639964131.1483456896854--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 13:56:30 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST m.cencora@gmail.com=
 wrote:
> Compiler should synthesize a function like below:
>=20
> optional<color> enum_cast(int x)
> {
>     switch(x)
>     {
>         case red:
>         case green:
>         case blue:
>             return static_cast<color>(x);
>         default:
>             return nullopt;
>     }
> }

How do you know whether a use of enum_cast is compile-time or whether it is=
=20
runtime?

static_cast is always compile time and always succeeds or produces a=20
compilation error. Therefore, checking at runtime is unnecessary.

dynamic_cast is almost always runtime and its result needs to be checked at=
=20
runtime.

Also, where did that optional come from? If it's going to use optional, the=
n=20
it needs to be a library feature.

> Of course it could implement it more efficently (as range check instead o=
f
> switch if all enumerators are consecutive integers).

One would expect the compilers to be smart enough to do that with a switch=
=20
block that is contiguous. Still, QoI issue.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/2998762.etaySSRi7N%40tjmaciei-mobl1.

.


Author: m.cencora@gmail.com
Date: Tue, 3 Jan 2017 08:02:01 -0800 (PST)
Raw View
------=_Part_2481_525664368.1483459321974
Content-Type: multipart/alternative;
 boundary="----=_Part_2482_36550.1483459321974"

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


W dniu wtorek, 3 stycznia 2017 16:08:47 UTC+1 u=C5=BCytkownik D. B. napisa=
=C5=82:
>
> Do you expect the handle the common case where people use enums as=20
> bitmasks of different enumerators?
>
>
No, I don't think so.

But such a function for sure can be written using enum_cast:
go through each bit and test each one of them with enum_cast.

Regards,
Maciej

--=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/199262c4-406f-4e2e-8ae9-d63829299cf7%40isocpp.or=
g.

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

<div dir=3D"ltr"><br>W dniu wtorek, 3 stycznia 2017 16:08:47 UTC+1 u=C5=BCy=
tkownik D. B. napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div>Do you expect the handle the common case where people us=
e enums as bitmasks of different enumerators?<br><br></div></div></blockquo=
te><div><br></div><div>No, I don&#39;t think so.</div><div><br></div><div>B=
ut such a function for sure can be written using enum_cast:</div><div>go th=
rough each bit and test each one of them with enum_cast.</div><div><br></di=
v><div>Regards,</div><div>Maciej</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/199262c4-406f-4e2e-8ae9-d63829299cf7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/199262c4-406f-4e2e-8ae9-d63829299cf7=
%40isocpp.org</a>.<br />

------=_Part_2482_36550.1483459321974--

------=_Part_2481_525664368.1483459321974--

.


Author: m.cencora@gmail.com
Date: Tue, 3 Jan 2017 08:12:29 -0800 (PST)
Raw View
------=_Part_1183_727352945.1483459949335
Content-Type: multipart/alternative;
 boundary="----=_Part_1184_630430329.1483459949335"

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

W dniu wtorek, 3 stycznia 2017 16:21:37 UTC+1 u=C5=BCytkownik Nicol Bolas=
=20
napisa=C5=82:
>
> On Tuesday, January 3, 2017 at 4:56:05 AM UTC-5, m.ce...@gmail.com wrote:
>>
>> Hi,
>>
>> 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.
>>
>
> It should not return an `optional`. It should either correctly cast or=20
> *throw*. Why?
>
> Consider how users will use it. You're going to see a lot of people doing=
=20
> `enum_cast<>().value()`. Which will incur needless copying if the=20
> conversion worked. And if it doesn't work, an exception will be thrown.
>
> What exception will that be? `bad_optional_access`. Which is about as=20
> useless as exceptions get as far as tracking down the problem. A far more=
=20
> descriptive exception would be `bad_enum_cast`.
>
> I would say that you should provide both APIs: `enum_cast` for conversion=
=20
> or throwing. And `optional_enum_cast` or somesuch for conversion into an=
=20
> `optional<enum>`.
>

At this point I consider chosing a error reporting way bike-shedding.

Let's focus on actual functionality it provides for now:
check if provided int corresponds to any of the enumerators of given enum.

--=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/ea4c8ec9-5f0e-42fb-8928-35bc47e4fd96%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu wtorek, 3 stycznia 2017 16:21:37 UTC+1 u=C5=BCytkow=
nik Nicol Bolas napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr">On Tuesday, January 3, 2017 at 4:56:05 AM UTC-5, <a>m.ce...=
@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r">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 enum=
erator.</div></div></blockquote><div><br>It should not return an `optional`=
.. It should either correctly cast or <i>throw</i>. Why?<br><br>Consider how=
 users will use it. You&#39;re going to see a lot of people doing `enum_cas=
t&lt;&gt;().value()`. Which will incur needless copying if the conversion w=
orked. And if it doesn&#39;t work, an exception will be thrown.<br><br>What=
 exception will that be? `bad_optional_access`. Which is about as useless a=
s exceptions get as far as tracking down the problem. A far more descriptiv=
e exception would be `bad_enum_cast`.<br><br>I would say that you should pr=
ovide both APIs: `enum_cast` for conversion or throwing. And `optional_enum=
_cast` or somesuch for conversion into an `optional&lt;enum&gt;`.</div></di=
v></blockquote><div><br></div><div>At this point I consider chosing a error=
 reporting way bike-shedding.</div><div><br></div><div>Let&#39;s focus on a=
ctual functionality it provides for now:</div><div>check if provided int co=
rresponds to any of the enumerators of given enum.</div><div><br></div></di=
v>

<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/ea4c8ec9-5f0e-42fb-8928-35bc47e4fd96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ea4c8ec9-5f0e-42fb-8928-35bc47e4fd96=
%40isocpp.org</a>.<br />

------=_Part_1184_630430329.1483459949335--

------=_Part_1183_727352945.1483459949335--

.


Author: m.cencora@gmail.com
Date: Tue, 3 Jan 2017 08:22:52 -0800 (PST)
Raw View
------=_Part_1219_699239157.1483460572939
Content-Type: multipart/alternative;
 boundary="----=_Part_1220_5047470.1483460572939"

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

W dniu wtorek, 3 stycznia 2017 16:56:35 UTC+1 u=C5=BCytkownik Thiago Maciei=
ra=20
napisa=C5=82:
>
> On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST m.ce...@gmail.com=
=20
> <javascript:> wrote:=20
> > Compiler should synthesize a function like below:=20
> >=20
> > optional<color> enum_cast(int x)=20
> > {=20
> >     switch(x)=20
> >     {=20
> >         case red:=20
> >         case green:=20
> >         case blue:=20
> >             return static_cast<color>(x);=20
> >         default:=20
> >             return nullopt;=20
> >     }=20
> > }=20
>
> How do you know whether a use of enum_cast is compile-time or whether it=
=20
> is=20
> runtime?=20
>
>
I don't know and I don't care. The function should be constexpr to support=
=20
both cases.=20
=20

> static_cast is always compile time and always succeeds or produces a=20
> compilation error. Therefore, checking at runtime is unnecessary.=20
>
> dynamic_cast is almost always runtime and its result needs to be checked=
=20
> at=20
> runtime.=20
>
> Also, where did that optional come from? If it's going to use optional,=
=20
> then=20
> it needs to be a library feature.=20
>

Just a first idea on dealing with failure cases. Not really important at=20
this point.

What I'd like to hear now is whether anyone else would find such a=20
functionality useful?
Do you consider it a good idea to put it into C++ standard/library?
=20

>
> > Of course it could implement it more efficently (as range check instead=
=20
> of=20
> > switch if all enumerators are consecutive integers).=20
>
> One would expect the compilers to be smart enough to do that with a switc=
h=20
> block that is contiguous. Still, QoI issue.=20
>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d4b84145-05e8-452f-ba08-dae9bbe34e04%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu wtorek, 3 stycznia 2017 16:56:35 UTC+1 u=C5=BCytkow=
nik Thiago Macieira napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST <a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"3-AvBdp2CwAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;javascript:&#39;;return true;">m.ce...@gmail.com</a>=
 wrote:
<br>&gt; Compiler should synthesize a function like below:
<br>&gt;=20
<br>&gt; optional&lt;color&gt; enum_cast(int x)
<br>&gt; {
<br>&gt; =C2=A0 =C2=A0 switch(x)
<br>&gt; =C2=A0 =C2=A0 {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 case red:
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 case green:
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 case blue:
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return static_cast&lt;co=
lor&gt;(x);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 default:
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return nullopt;
<br>&gt; =C2=A0 =C2=A0 }
<br>&gt; }
<br>
<br>How do you know whether a use of enum_cast is compile-time or whether i=
t is=20
<br>runtime?
<br>
<br></blockquote><div><br></div><div>I don&#39;t know and I don&#39;t care.=
 The function should be constexpr to support both cases.=C2=A0</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">static_cast is alw=
ays compile time and always succeeds or produces a=20
<br>compilation error. Therefore, checking at runtime is unnecessary.
<br>
<br>dynamic_cast is almost always runtime and its result needs to be checke=
d at=20
<br>runtime.
<br>
<br>Also, where did that optional come from? If it&#39;s going to use optio=
nal, then=20
<br>it needs to be a library feature.
<br></blockquote><div><br></div><div>Just a first idea on dealing with fail=
ure cases. Not really important at this point.</div><div><br></div><div>Wha=
t I&#39;d like to hear now is whether anyone else would find such a functio=
nality useful?</div><div>Do you consider it a good idea to put it into C++ =
standard/library?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">
<br>&gt; Of course it could implement it more efficently (as range check in=
stead of
<br>&gt; switch if all enumerators are consecutive integers).
<br>
<br>One would expect the compilers to be smart enough to do that with a swi=
tch=20
<br>block that is contiguous. Still, QoI issue.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></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/d4b84145-05e8-452f-ba08-dae9bbe34e04%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d4b84145-05e8-452f-ba08-dae9bbe34e04=
%40isocpp.org</a>.<br />

------=_Part_1220_5047470.1483460572939--

------=_Part_1219_699239157.1483460572939--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 3 Jan 2017 18:53:02 +0100
Raw View
Le 03/01/2017 =C3=A0 16:56, Thiago Macieira a =C3=A9crit :
> On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST m.cencora@gmail.c=
om wrote:
>
> Also, where did that optional come from? If it's going to use optional, t=
hen
> it needs to be a library feature.
I'm not for the optional return type, but we have already a lot of cases=20
where syntactic sugar as range-based for loop and structure binding=20
depends on library.
So I'm not sure this could be an argument against optional.

Vicente

--=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/85e681ea-20cb-5d87-d337-6b472e35eb11%40wanadoo.f=
r.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 3 Jan 2017 19:25:18 +0100
Raw View
This is a multi-part message in MIME format.
--------------BB00DC1B62BA3E31F9F197A6
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 03/01/2017 =C3=A0 10:56, m.cencora@gmail.com a =C3=A9crit :
> Hi,
>
> 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<typenameEnum,typenameInt>
> optional<Enum>enum_cast(Intvalue);
>
> requires:is_enum<Enum>,is_integral<Int>
>
> enumcolor
> {
>    red =3D1,
>    green =3D200,
>    blue =3D3
> };
>
> static_assert(enum_cast<color>(200u)=3D=3Dcolor::green);
> static_assert(enum_cast<color>(3)=3D=3Dcolor::blue);
> static_assert(enum_cast<color>(4)=3D=3Dnullopt);
>
> |
>
> 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,=20
> but 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=20
to use builtins or reflection once it is there.

Now, I believe that we need two kind of functions. One that is a cast=20
and that says just that we are casting. It would be the same as a=20
static_cast. Something like gsl::narrow_cast so that we express better=20
the intent. In addition we need the function you are proposing similar=20
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
* enum_cast ~static_cast
* 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=20
considered also once adopted.
Do we expect several error conditions?

The fist is just a library solution. For the last two, we would need a=20
compiler builtin or reflection so that both can be easily and=20
efficiently implemented.

My 2cts.
Vicente

P.S. I don't expect this to be available before reflection, so an=20
implementation using the current reflection (see github) interface=20
should be welcome. This could be important to balance the compiler effort.

--=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/a19ed9c6-45c0-e3d7-e92a-06468bff63b7%40wanadoo.f=
r.

--------------BB00DC1B62BA3E31F9F197A6
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 03/01/2017 =C3=A0 10:56,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:m.cencora@gmail.=
com">m.cencora@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:efdf2357-00a6-408a-8772-12f99135a880@isocpp.org"
      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 class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187,
          187); word-wrap: break-word; background-color: rgb(250, 250,
          250);"><code class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #008;" class=3D"styled-by-prettify">typenam=
e</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Enum</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">typenam=
e</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Int</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                optional</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">&lt;</span><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Enum</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                enum_cast</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">(</span><span style=3D"color:
                #606;" class=3D"styled-by-prettify">Int</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> value<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                <br>
                requires</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">:</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"> is_enum</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><font
                color=3D"#000000"><span style=3D"color: #606;"
                  class=3D"styled-by-prettify">Enum</span></font><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;,</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                is_integral</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">&lt;</span><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Int</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                <br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">enum</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> color<=
br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">{</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0red </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0green </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #066;" class=3D"styled-by-prettify">200</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0blue </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #066;" class=3D"styled-by-prettify">3</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">};</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">static_assert</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">enum_ca=
st</span><span
                style=3D"color: #080;" class=3D"styled-by-prettify">&lt;col=
or&gt;</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><font
                color=3D"#006666"><span style=3D"color: #066;"
                  class=3D"styled-by-prettify">200u</span></font><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> color<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><font
                color=3D"#000000"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify">green</span></font><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">static_assert</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">enum_ca=
st</span><span
                style=3D"color: #080;" class=3D"styled-by-prettify">&lt;col=
or&gt;</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">3</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> color<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">blue</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">static_assert</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">enum_ca=
st</span><span
                style=3D"color: #080;" class=3D"styled-by-prettify">&lt;col=
or&gt;</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">4</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> nullop=
t</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><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'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>
    * 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>
    <br>
    The fist is just a library solution. For the last two, we would need
    a compiler builtin or reflection so that both can be easily and
    efficiently implemented.<br>
    <br>
    My 2cts.<br>
    Vicente <br>
    <br>
    P.S. I don't expect this to be available before reflection, so an
    implementation using the current reflection (see github) interface
    should be welcome. This could be important to balance the compiler
    effort.<br>
  </body>
</html>

<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/a19ed9c6-45c0-e3d7-e92a-06468bff63b7%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a19ed9c6-45c0-e3d7-e92a-06468bff63b7=
%40wanadoo.fr</a>.<br />

--------------BB00DC1B62BA3E31F9F197A6--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 10:43:41 -0800 (PST)
Raw View
------=_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--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 17:09:14 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 18:53:02 BRST Vicente J. Botet Es=
criba=20
wrote:
> Le 03/01/2017 =C3=A0 16:56, Thiago Macieira a =C3=A9crit :
> > On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST m.cencora@gmail=
..com
> > wrote:
> >=20
> > Also, where did that optional come from? If it's going to use optional,
> > then it needs to be a library feature.
>=20
> I'm not for the optional return type, but we have already a lot of cases
> where syntactic sugar as range-based for loop and structure binding
> depends on library.
> So I'm not sure this could be an argument against optional.

Those are quite different things. In fact, they show how to *not* depend on=
=20
the library in the first place. Ranged fors and structured bindings only=20
require that functions called begin, end, and get exist. So I can add any=
=20
function of my own with those names and it will work. And structured bindin=
gs=20
are very specifically *not* a std::tuple. They're something different.

So enum_cast could return an optional-like opaque type defined by the compi=
ler=20
(like structured bindings and lambdas) which can be converted to std::optio=
nal=20
on construction.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/2225413.PkzHcSPZVx%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 17:12:34 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 08:22:52 BRST m.cencora@gmail.com=
 wrote:
> > How do you know whether a use of enum_cast is compile-time or whether i=
t
> > is
> > runtime?
>=20
> I don't know and I don't care. The function should be constexpr to suppor=
t
> both cases.

Well, I think people may care. A constexpr invocation has zero cost at=20
runtime, since it will have failed to convert by producing an error message=
,=20
or it will succeed by becoming a no-op (like static_cast, minus pointer=20
adjustment). But a non-constexpr invocation will have a runtime cost.

> What I'd like to hear now is whether anyone else would find such a
> functionality useful?
> Do you consider it a good idea to put it into C++ standard/library?

Maybe you should rename it to mean a check if the value is a valid enumerat=
or=20
and drop the "cast" part.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/42463446.MPeEFdAbRV%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 17:15:30 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 10:43:41 BRST Nicol Bolas wrote:
> What's the point of `enum_cast`, save the fact that it would SFINAE on th=
e
> given type being an actual enumeration? `static_cast` is the standard way
> of saying "make this integer an enum without checking". I don't think we
> need another way to spell that.

One of two ways. You can always just use the enumeration in constructor sty=
le:

 Enum(1)  <=3D>  static_cast<Enum>(1)

This is a matter of coding convention.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/3331793.xtn2M5fU71%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 11:59:46 -0800 (PST)
Raw View
------=_Part_2653_46906257.1483473586093
Content-Type: multipart/alternative;
 boundary="----=_Part_2654_514702518.1483473586094"

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



On Tuesday, January 3, 2017 at 2:09:19 PM UTC-5, Thiago Macieira wrote:
>
> On ter=C3=A7a-feira, 3 de janeiro de 2017 18:53:02 BRST Vicente J. Botet=
=20
> Escriba=20
> wrote:=20
> > Le 03/01/2017 =C3=A0 16:56, Thiago Macieira a =C3=A9crit :=20
> > > On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST m.ce...@gmail=
..com=20
> <javascript:>=20
> > > wrote:=20
> > >=20
> > > Also, where did that optional come from? If it's going to use=20
> optional,=20
> > > then it needs to be a library feature.=20
> >=20
> > I'm not for the optional return type, but we have already a lot of case=
s=20
> > where syntactic sugar as range-based for loop and structure binding=20
> > depends on library.=20
> > So I'm not sure this could be an argument against optional.=20
>
> Those are quite different things. In fact, they show how to *not* depend=
=20
> on=20
> the library in the first place. Ranged fors and structured bindings only=
=20
> require that functions called begin, end, and get exist. So I can add any=
=20
> function of my own with those names and it will work. And structured=20
> bindings=20
> are very specifically *not* a std::tuple. They're something different.=20
>
> So enum_cast could return an optional-like opaque type defined by the=20
> compiler=20
> (like structured bindings and lambdas) which can be converted to=20
> std::optional=20
> on construction.
>

First, a correction. Structured binding does not deal in an "opaque type=20
defined by the compiler". It deals in exactly whatever type the=20
initializing expression resolves to. So long as the type has the specified=
=20
characteristics or provides the interface required, it will work. But the=
=20
compiler is not inventing some type behind-the-scenes.

Further, I think your analogy is rather wrongheaded. Ranges and product=20
types are categories of types provided by the user. The language is=20
defining mechanisms for the user to provide a type which can be consumed by=
=20
the language. `enum_cast` is not like that at all. It *returns* a type,=20
based on basic values provided by the user. For the optional-version of it,=
=20
that type would have all of the properties of `optional`.

Lastly, having `enum_cast` work via some compiler-defined type is rather=20
extreme for something as simplistic as this, don't you think? There are=20
only so many ways to implement an "optional", and you can define implicit=
=20
conversions from `std::optional` type to yours with little penalty. The=20
conversion can even be `constexpr`, just like `std::optional`, so you would=
=20
suffer no loss of performance in constexpr contexts.

--=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/7d89ec43-c691-44d8-bcb5-74dcda9eb493%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 2:09:19 PM UTC-5, T=
hiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On ter=C3=
=A7a-feira, 3 de janeiro de 2017 18:53:02 BRST Vicente J. Botet Escriba=20
<br>wrote:
<br>&gt; Le 03/01/2017 =C3=A0 16:56, Thiago Macieira a =C3=A9crit :
<br>&gt; &gt; On ter=C3=A7a-feira, 3 de janeiro de 2017 07:06:10 BRST <a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"qB3FkV6BCwAJ"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return t=
rue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">m.ce...@gm=
ail.com</a>
<br>&gt; &gt; wrote:
<br>&gt; &gt;=20
<br>&gt; &gt; Also, where did that optional come from? If it&#39;s going to=
 use optional,
<br>&gt; &gt; then it needs to be a library feature.
<br>&gt;=20
<br>&gt; I&#39;m not for the optional return type, but we have already a lo=
t of cases
<br>&gt; where syntactic sugar as range-based for loop and structure bindin=
g
<br>&gt; depends on library.
<br>&gt; So I&#39;m not sure this could be an argument against optional.
<br>
<br>Those are quite different things. In fact, they show how to *not* depen=
d on=20
<br>the library in the first place. Ranged fors and structured bindings onl=
y=20
<br>require that functions called begin, end, and get exist. So I can add a=
ny=20
<br>function of my own with those names and it will work. And structured bi=
ndings=20
<br>are very specifically *not* a std::tuple. They&#39;re something differe=
nt.
<br>
<br>So enum_cast could return an optional-like opaque type defined by the c=
ompiler=20
<br>(like structured bindings and lambdas) which can be converted to std::o=
ptional=20
<br>on construction.<br></blockquote><div><br>First, a correction. Structur=
ed binding does not deal in an &quot;opaque type defined by the compiler&qu=
ot;. It deals in exactly whatever type the initializing expression resolves=
 to. So long as the type has the specified characteristics or provides the =
interface required, it will work. But the compiler is not inventing some ty=
pe behind-the-scenes.<br><br>Further, I think your analogy is rather wrongh=
eaded. Ranges and product types are categories of types provided by the use=
r. The language is defining mechanisms for the user to provide a type which=
 can be consumed by the language. `enum_cast` is not like that at all. It <=
i>returns</i> a type, based on basic values provided by the user. For the o=
ptional-version of it, that type would have all of the properties of `optio=
nal`.<br><br>Lastly, having `enum_cast` work via some compiler-defined type=
 is rather extreme for something as simplistic as this, don&#39;t you think=
? There are only so many ways to implement an &quot;optional&quot;, and you=
 can define implicit conversions from `std::optional` type to yours with li=
ttle penalty. The conversion can even be `constexpr`, just like `std::optio=
nal`, so you would suffer no loss of performance in constexpr contexts.<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/7d89ec43-c691-44d8-bcb5-74dcda9eb493%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7d89ec43-c691-44d8-bcb5-74dcda9eb493=
%40isocpp.org</a>.<br />

------=_Part_2654_514702518.1483473586094--

------=_Part_2653_46906257.1483473586093--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 3 Jan 2017 23:04:07 +0100
Raw View
This is a multi-part message in MIME format.
--------------C1C7E62816EDEEF8C649CDE1
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

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=20
> Escriba wrote:
>
>     Le 03/01/2017 =C3=A0 10:56, m.ce...@gmail.com <javascript:> a =C3=A9c=
rit :
>>     Hi,
>>
>>     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.
>>
>>     |
>>     template<typenameEnum,typenameInt>
>>     optional<Enum>enum_cast(Intvalue);
>>
>>     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, but 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
>>     __builtin_* intrinsic).
>>
>     Hi, I believe this could be useful. Library implementers could be
>     free to use builtins or reflection once it is there.
>
>     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.
>     The question is how the function reports errors. If we use
>     exceptions, I agree with Nicol that a specific exception would be
>     better.
>
>     I will then propose
>     * enum_cast ~static_cast
>
>
> What'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 "make this integer an enum without checking". I=20
> don't think we need another way to spell that.
What is the point of narrow_cast? I believe it is useful to know the=20
kind of cast we are using. This helps to inspect the code we (others)=20
have written in a more efficient way.
>
>     * to_enum : throw exception if error
>     * try_to_enum : returns optional<Enum> or an interface based on
>     error_code (like from_chars). status_value and expected can be
>     considered 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)


Vicente

--=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/53189e5e-b1cf-0411-c87e-542822dbd4c0%40wanadoo.f=
r.

--------------C1C7E62816EDEEF8C649CDE1
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 03/01/2017 =C3=A0 19:43, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6@isocpp.org"
      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.8ex;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 moz-do-not-send=3D"true"
                href=3D"javascript:" target=3D"_blank"
                gdf-obfuscated-mailto=3D"Hrse9vd-CwAJ" rel=3D"nofollow"
                onmousedown=3D"this.href=3D'javascript:';return true;"
                onclick=3D"this.href=3D'javascript:';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-word;background-color:rg=
b(250,250,250)"><code>
                    <div><span style=3D"color:#008">template</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#660">&lt;</span><span
                        style=3D"color:#008">typename</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#606">Enum</span><span
                        style=3D"color:#660">,</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#008">typename</span><span
                        style=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;</span><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"> value</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;</span><font
                        color=3D"#000000"><span style=3D"color:#606">Enum</=
span></font><span
                        style=3D"color:#660">&gt;,</span><span
                        style=3D"color:#000"> is_integral</span><span
                        style=3D"color:#660">&lt;</span><span
                        style=3D"color:#606">Int</span><span
                        style=3D"color:#660">&gt;</span><span
                        style=3D"color:#000"><br>
                        <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'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'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 "make this integer
          an enum without checking". I don't think we need another way
          to spell that.<br>
        </div>
      </div>
    </blockquote>
    What is the point of narrow_cast? 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. <br>
    <blockquote
      cite=3D"mid:119a6ed9-e6b1-4c8c-b9b1-5152f7c7a3d6@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>=C2=A0</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" 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'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>
    <br>
    <br>
    Vicente<br>
  </body>
</html>

<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/53189e5e-b1cf-0411-c87e-542822dbd4c0%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/53189e5e-b1cf-0411-c87e-542822dbd4c0=
%40wanadoo.fr</a>.<br />

--------------C1C7E62816EDEEF8C649CDE1--

.


Author: gmisocpp@gmail.com
Date: Tue, 3 Jan 2017 15:01:15 -0800 (PST)
Raw View
------=_Part_5498_84607148.1483484476010
Content-Type: multipart/alternative;
 boundary="----=_Part_5499_667225547.1483484476010"

------=_Part_5499_667225547.1483484476010
Content-Type: text/plain; charset=UTF-8


How about:

enum class trafflic_light{ unknown, reg, yellow, green };

traffic_light = traffic_light::unknown; // My default.
bool success = make_enum(light, x); // Does not set light on failure. X of
any integral type
if (!success)
 throw std::logic_error("Error: Expected a value compatible with a
traffic_light enum.");
if (light == traffic_light::green)
 cpp20_you_are_our_only_hope();

// make_enum - Standard special funciton. Make this available in C too.


On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com wrote:

> Hi,
>
> 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.
>
> template <typename Enum, typename Int>
> optional<Enum> enum_cast(Int value);
>
> requires: is_enum<Enum>, is_integral<Int>
>
> enum color
> {
>    red = 1,
>    green = 200,
>    blue = 3
> };
>
> static_assert(enum_cast<color>(200u) == color::green);
> static_assert(enum_cast<color>(3) == color::blue);
> static_assert(enum_cast<color>(4) == 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
> 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
> __builtin_* intrinsic).
>
> Regards,
> Maciej
>

--
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/e6c43713-ad62-4a5e-8eda-23c59bb67dd9%40isocpp.org.

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

<div dir=3D"ltr"><div><br></div><div>How about:</div><div><br></div><p>enum=
 class trafflic_light{ unknown, reg, yellow, green };</p><div><br></div><di=
v>traffic_light =3D traffic_light::unknown; // My default.<br>bool success =
=3D make_enum(light, x); // Does not set light on failure. X of any integra=
l type<br>if (!success)<br>=C2=A0throw std::logic_error(&quot;Error: Expect=
ed a value=C2=A0compatible=C2=A0with a traffic_light enum.&quot;);<br>if (l=
ight =3D=3D traffic_light::green)<br>=C2=A0cpp20_you_are_our_only_hope();</=
div><div><br></div><div><div>// make_enum - Standard special funciton. Make=
 this available in C too.</div><br><br>On Tuesday, January 3, 2017 at 10:56=
:05 PM UTC+13, m.ce...@gmail.com wrote:</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-colo=
r: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"><=
div dir=3D"ltr">Hi,<div><br></div><div>I propose to add a enum_cast functio=
n 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 rg=
b(187, 187, 187); border-image: none; -ms-word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0, 136=
);">template</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 13=
6);">typename</span><span style=3D"color: rgb(0, 0, 0);"> </span><span styl=
e=3D"color: rgb(102, 0, 102);">Enum</span><span style=3D"color: rgb(102, 10=
2, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D=
"color: rgb(0, 0, 136);">typename</span><span style=3D"color: rgb(0, 0, 0);=
"> </span><span style=3D"color: rgb(102, 0, 102);">Int</span><span style=3D=
"color: rgb(102, 102, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0);">=
<br>optional</span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><spa=
n style=3D"color: rgb(102, 0, 102);">Enum</span><span style=3D"color: rgb(1=
02, 102, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0);"> enum_cast</s=
pan><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: =
rgb(102, 0, 102);">Int</span><span style=3D"color: rgb(0, 0, 0);"> value</s=
pan><span style=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color:=
 rgb(0, 0, 0);"><br><br>requires</span><span style=3D"color: rgb(102, 102, =
0);">:</span><span style=3D"color: rgb(0, 0, 0);"> is_enum</span><span styl=
e=3D"color: rgb(102, 102, 0);">&lt;</span><font color=3D"#000000"><span sty=
le=3D"color: rgb(102, 0, 102);">Enum</span></font><span style=3D"color: rgb=
(102, 102, 0);">&gt;,</span><span style=3D"color: rgb(0, 0, 0);"> is_integr=
al</span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D=
"color: rgb(102, 0, 102);">Int</span><span style=3D"color: rgb(102, 102, 0)=
;">&gt;</span><span style=3D"color: rgb(0, 0, 0);"><br><br></span><span sty=
le=3D"color: rgb(0, 0, 136);">enum</span><span style=3D"color: rgb(0, 0, 0)=
;"> color<br></span><span style=3D"color: rgb(102, 102, 0);">{</span><span =
style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0red </span><span style=3D"c=
olor: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </=
span><span style=3D"color: rgb(0, 102, 102);">1</span><span style=3D"color:=
 rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0=
 =C2=A0green </span><span style=3D"color: rgb(102, 102, 0);">=3D</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 102, =
102);">200</span><span style=3D"color: rgb(102, 102, 0);">,</span><span sty=
le=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0blue </span><span style=3D"col=
or: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </sp=
an><span style=3D"color: rgb(0, 102, 102);">3</span><span style=3D"color: r=
gb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">};</span>=
<span style=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"color: r=
gb(0, 0, 136);">static_assert</span><span style=3D"color: rgb(102, 102, 0);=
">(</span><span style=3D"color: rgb(0, 0, 0);">enum_cast</span><span style=
=3D"color: rgb(0, 136, 0);">&lt;color&gt;</span><span style=3D"color: rgb(1=
02, 102, 0);"><wbr>(</span><font color=3D"#006666"><span style=3D"color: rg=
b(0, 102, 102);">200u</span></font><span style=3D"color: rgb(102, 102, 0);"=
>)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color:=
 rgb(102, 102, 0);">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> colo=
r</span><span style=3D"color: rgb(102, 102, 0);">::</span><font color=3D"#0=
00000"><span style=3D"color: rgb(0, 0, 0);">green</span></font><span style=
=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"=
><br></span><span style=3D"color: rgb(0, 0, 136);">static_assert</span><spa=
n style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0=
, 0);">enum_cast</span><span style=3D"color: rgb(0, 136, 0);">&lt;color&gt;=
</span><span style=3D"color: rgb(102, 102, 0);"><wbr>(</span><span style=3D=
"color: rgb(0, 102, 102);">3</span><span style=3D"color: rgb(102, 102, 0);"=
>)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color:=
 rgb(102, 102, 0);">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> colo=
r</span><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"co=
lor: rgb(0, 0, 0);">blue</span><span style=3D"color: rgb(102, 102, 0);">);<=
/span><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color:=
 rgb(0, 0, 136);">static_assert</span><span style=3D"color: rgb(102, 102, 0=
);">(</span><span style=3D"color: rgb(0, 0, 0);">enum_cast</span><span styl=
e=3D"color: rgb(0, 136, 0);">&lt;color&gt;</span><span style=3D"color: rgb(=
102, 102, 0);"><wbr>(</span><span style=3D"color: rgb(0, 102, 102);">4</spa=
n><span style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rg=
b(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">=3D=3D</span>=
<span style=3D"color: rgb(0, 0, 0);"> nullopt</span><span style=3D"color: r=
gb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br><br></s=
pan></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 va=
lue fits in underlying type.<br></div><div><br></div><div>Why do we want th=
is:<br></div><div>=C2=A0- validation of input data (e.g. coming from user o=
r deserialization).</div><div>=C2=A0- other?</div><div><br></div><div>I kno=
w 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 imp=
lemented with compiler support (i.e. via __builtin_* intrinsic).</div><div>=
<br></div><div>Regards,</div><div>Maciej</div></div></blockquote></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/e6c43713-ad62-4a5e-8eda-23c59bb67dd9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e6c43713-ad62-4a5e-8eda-23c59bb67dd9=
%40isocpp.org</a>.<br />

------=_Part_5499_667225547.1483484476010--

------=_Part_5498_84607148.1483484476010--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 03 Jan 2017 21:14:56 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 11:59:46 BRST Nicol Bolas wrote:
> Lastly, having `enum_cast` work via some compiler-defined type is rather
> extreme for something as simplistic as this, don't you think? There are
> only so many ways to implement an "optional", and you can define implicit
> conversions from `std::optional` type to yours with little penalty. The
> conversion can even be `constexpr`, just like `std::optional`, so you wou=
ld
> suffer no loss of performance in constexpr contexts.

Anything that is a compiler feature (a builtin or a core language expressio=
n)=20
needs to be able to choose between std::optional, std::experimental::option=
al=20
and std::__1::optional by just changing #includes.

A library solution needs not.

It seems to me that a library solution wrapping a compiler builtin intrinsi=
c=20
is the only solution possible. And using reflection actually matches that=
=20
requirement, albeit indirectly.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/6951935.9LYeBEmE6C%40tjmaciei-mobl1.

.


Author: gmisocpp@gmail.com
Date: Tue, 3 Jan 2017 15:48:25 -0800 (PST)
Raw View
------=_Part_7355_748560630.1483487305094
Content-Type: multipart/alternative;
 boundary="----=_Part_7356_407506877.1483487305094"

------=_Part_7356_407506877.1483487305094
Content-Type: text/plain; charset=UTF-8


Just considering my earlier make_enum comment further, The ultimate minimum
for C++ is surely this?:

traffic_light light{}; // whatever default.
bool guaranteed_success = std::can_cast_enum<traffic_light>(x);
if (guaranteed_success)
 light = reinterpret_cast<traffic_light>(x);
// else error condition.

It separates the validity check from the conversion and then you can build
whatever on that, i.e. assign, atomic assign, etc.
This seems more C++ like, but forgets C, which probably people feel is not
a concern anyway.
But other wise some special C and C++ syntax like
 can_cast_enum(traffic_light, x) would seem to cover both languages if
that's desirable.


On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com wrote:

> Hi,
>
> 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.
>
> template <typename Enum, typename Int>
> optional<Enum> enum_cast(Int value);
>
> requires: is_enum<Enum>, is_integral<Int>
>
> enum color
> {
>    red = 1,
>    green = 200,
>    blue = 3
> };
>
> static_assert(enum_cast<color>(200u) == color::green);
> static_assert(enum_cast<color>(3) == color::blue);
> static_assert(enum_cast<color>(4) == 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
> 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
> __builtin_* intrinsic).
>
> Regards,
> Maciej
>

--
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/1d5db671-8ee9-49dc-937d-10a20f48fe73%40isocpp.org.

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

<div dir=3D"ltr"><div><br></div><div>Just considering my earlier make_enum =
comment further, The ultimate minimum for C++ is surely this?:</div><div><b=
r></div><div>traffic_light light{}; // whatever default.<br>bool guaranteed=
_success =3D std::can_cast_enum&lt;traffic_light&gt;(x);</div><div>if (guar=
anteed_success)<br>=C2=A0light =3D reinterpret_cast&lt;traffic_light&gt;(x)=
;</div><div>// else error condition.</div><div><br></div><div>It separates =
the validity check from the conversion and then you can build whatever on t=
hat, i.e. assign, atomic assign, etc.</div><div>This seems more C++ like, b=
ut forgets C, which probably people feel is not a concern anyway.</div><div=
>But other wise=C2=A0some special C=C2=A0and C++ syntax like =C2=A0can_cast=
_enum(traffic_light, x)=C2=A0would seem to cover both languages if that&#39=
;s desirable.</div><div><br><br>On Tuesday, January 3, 2017 at 10:56:05 PM =
UTC+13, m.ce...@gmail.com wrote:</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(=
204, 204, 204); border-left-width: 1px; border-left-style: solid;"><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 vali=
d enumerator.</div><div><br></div><div style=3D"border: 1px solid rgb(187, =
187, 187); border-image: none; -ms-word-wrap: break-word; background-color:=
 rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0, 136);">tem=
plate</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"col=
or: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 136);">ty=
pename</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"co=
lor: rgb(102, 0, 102);">Enum</span><span style=3D"color: rgb(102, 102, 0);"=
>,</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color:=
 rgb(0, 0, 136);">typename</span><span style=3D"color: rgb(0, 0, 0);"> </sp=
an><span style=3D"color: rgb(102, 0, 102);">Int</span><span style=3D"color:=
 rgb(102, 102, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0);"><br>opt=
ional</span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><span style=
=3D"color: rgb(102, 0, 102);">Enum</span><span style=3D"color: rgb(102, 102=
, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0);"> enum_cast</span><sp=
an style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102=
, 0, 102);">Int</span><span style=3D"color: rgb(0, 0, 0);"> value</span><sp=
an style=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0,=
 0, 0);"><br><br>requires</span><span style=3D"color: rgb(102, 102, 0);">:<=
/span><span style=3D"color: rgb(0, 0, 0);"> is_enum</span><span style=3D"co=
lor: rgb(102, 102, 0);">&lt;</span><font color=3D"#000000"><span style=3D"c=
olor: rgb(102, 0, 102);">Enum</span></font><span style=3D"color: rgb(102, 1=
02, 0);">&gt;,</span><span style=3D"color: rgb(0, 0, 0);"> is_integral</spa=
n><span style=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color:=
 rgb(102, 0, 102);">Int</span><span style=3D"color: rgb(102, 102, 0);">&gt;=
</span><span style=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"c=
olor: rgb(0, 0, 136);">enum</span><span style=3D"color: rgb(0, 0, 0);"> col=
or<br></span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=
=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0red </span><span style=3D"color:=
 rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span>=
<span style=3D"color: rgb(0, 102, 102);">1</span><span style=3D"color: rgb(=
102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=
=A0green </span><span style=3D"color: rgb(102, 102, 0);">=3D</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 102, 102)=
;">200</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=
=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0blue </span><span style=3D"color=
: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span=
><span style=3D"color: rgb(0, 102, 102);">3</span><span style=3D"color: rgb=
(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">};</span><s=
pan style=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"color: rgb=
(0, 0, 136);">static_assert</span><span style=3D"color: rgb(102, 102, 0);">=
(</span><span style=3D"color: rgb(0, 0, 0);">enum_cast</span><span style=3D=
"color: rgb(0, 136, 0);">&lt;color&gt;</span><span style=3D"color: rgb(102,=
 102, 0);"><wbr>(</span><font color=3D"#006666"><span style=3D"color: rgb(0=
, 102, 102);">200u</span></font><span style=3D"color: rgb(102, 102, 0);">)<=
/span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rg=
b(102, 102, 0);">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> color</=
span><span style=3D"color: rgb(102, 102, 0);">::</span><font color=3D"#0000=
00"><span style=3D"color: rgb(0, 0, 0);">green</span></font><span style=3D"=
color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br=
></span><span style=3D"color: rgb(0, 0, 136);">static_assert</span><span st=
yle=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0)=
;">enum_cast</span><span style=3D"color: rgb(0, 136, 0);">&lt;color&gt;</sp=
an><span style=3D"color: rgb(102, 102, 0);"><wbr>(</span><span style=3D"col=
or: rgb(0, 102, 102);">3</span><span style=3D"color: rgb(102, 102, 0);">)</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> color</s=
pan><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color:=
 rgb(0, 0, 0);">blue</span><span style=3D"color: rgb(102, 102, 0);">);</spa=
n><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb=
(0, 0, 136);">static_assert</span><span style=3D"color: rgb(102, 102, 0);">=
(</span><span style=3D"color: rgb(0, 0, 0);">enum_cast</span><span style=3D=
"color: rgb(0, 136, 0);">&lt;color&gt;</span><span style=3D"color: rgb(102,=
 102, 0);"><wbr>(</span><span style=3D"color: rgb(0, 102, 102);">4</span><s=
pan style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0,=
 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">=3D=3D</span><spa=
n style=3D"color: rgb(0, 0, 0);"> nullopt</span><span style=3D"color: rgb(1=
02, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><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 de=
serialization).</div><div>=C2=A0- other?</div><div><br></div><div>I know th=
is could be purely library extension if based on reflection, but since we d=
on&#39;t know when we will get reflection,</div><div>and implementation bas=
ed on reflection may not be optimal,</div><div>I think it should be impleme=
nted with compiler support (i.e. via __builtin_* intrinsic).</div><div><br>=
</div><div>Regards,</div><div>Maciej</div></div></blockquote></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/1d5db671-8ee9-49dc-937d-10a20f48fe73%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1d5db671-8ee9-49dc-937d-10a20f48fe73=
%40isocpp.org</a>.<br />

------=_Part_7356_407506877.1483487305094--

------=_Part_7355_748560630.1483487305094--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 19:43:33 -0800 (PST)
Raw View
------=_Part_2648_1779129782.1483501413787
Content-Type: multipart/alternative;
 boundary="----=_Part_2649_1755174923.1483501413787"

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



On Tuesday, January 3, 2017 at 6:15:02 PM UTC-5, Thiago Macieira wrote:
>
> On ter=C3=A7a-feira, 3 de janeiro de 2017 11:59:46 BRST Nicol Bolas wrote=
:=20
> > Lastly, having `enum_cast` work via some compiler-defined type is rathe=
r=20
> > extreme for something as simplistic as this, don't you think? There are=
=20
> > only so many ways to implement an "optional", and you can define=20
> implicit=20
> > conversions from `std::optional` type to yours with little penalty. The=
=20
> > conversion can even be `constexpr`, just like `std::optional`, so you=
=20
> would=20
> > suffer no loss of performance in constexpr contexts.=20
>
> Anything that is a compiler feature (a builtin or a core language=20
> expression)=20
> needs to be able to choose between std::optional,=20
> std::experimental::optional=20
> and std::__1::optional by just changing #includes.
>

.... why? std::experimental::optional isn't part of the standard. And I have=
=20
no idea what `std::__1::optional` is.

--=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/8e7586fb-a121-4045-8f1e-a1399e229521%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 6:15:02 PM UTC-5, T=
hiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On ter=C3=
=A7a-feira, 3 de janeiro de 2017 11:59:46 BRST Nicol Bolas wrote:
<br>&gt; Lastly, having `enum_cast` work via some compiler-defined type is =
rather
<br>&gt; extreme for something as simplistic as this, don&#39;t you think? =
There are
<br>&gt; only so many ways to implement an &quot;optional&quot;, and you ca=
n define implicit
<br>&gt; conversions from `std::optional` type to yours with little penalty=
.. The
<br>&gt; conversion can even be `constexpr`, just like `std::optional`, so =
you would
<br>&gt; suffer no loss of performance in constexpr contexts.
<br>
<br>Anything that is a compiler feature (a builtin or a core language expre=
ssion)=20
<br>needs to be able to choose between std::optional, std::experimental::op=
tional=20
<br>and std::__1::optional by just changing #includes.<br></blockquote><div=
><br>... why? std::experimental::optional isn&#39;t part of the standard. A=
nd I have no idea what `std::__1::optional` is.<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/8e7586fb-a121-4045-8f1e-a1399e229521%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8e7586fb-a121-4045-8f1e-a1399e229521=
%40isocpp.org</a>.<br />

------=_Part_2649_1755174923.1483501413787--

------=_Part_2648_1779129782.1483501413787--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 19:52:18 -0800 (PST)
Raw View
------=_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--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jan 2017 19:58:52 -0800 (PST)
Raw View
------=_Part_1189_1966822393.1483502332996
Content-Type: multipart/alternative;
 boundary="----=_Part_1190_1757428033.1483502332996"

------=_Part_1190_1757428033.1483502332996
Content-Type: text/plain; charset=UTF-8

On Tuesday, January 3, 2017 at 6:01:16 PM UTC-5, gmis...@gmail.com wrote:
>
>
> How about:
>
> enum class trafflic_light{ unknown, reg, yellow, green };
>
> traffic_light = traffic_light::unknown; // My default.
> bool success = make_enum(light, x); // Does not set light on failure. X of
> any integral type
>

No, that requires the existence of `light`. C++ has too many APIs that
needlessly require live objects already; we don't need another one.

On Tuesday, January 3, 2017 at 6:48:25 PM UTC-5, gmis...@gmail.com wrote:
>
>
> Just considering my earlier make_enum comment further, The ultimate
> minimum for C++ is surely this?:
>
> traffic_light light{}; // whatever default.
> bool guaranteed_success = std::can_cast_enum<traffic_light>(x);
> if (guaranteed_success)
>  light = reinterpret_cast<traffic_light>(x);
> // else error condition.
>
> It separates the validity check from the conversion
>

That's actually a pretty good idea. Of course, there should be
"higher-level" functionality like a direct `enum_cast` that throws and so
forth, as discussed. But this way, people have the lowest-level tools to
build their own functionality on top of the basic question.

--
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/621e1d86-492b-4ecc-96ba-4e0b74dfcb4e%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, January 3, 2017 at 6:01:16 PM UTC-5, gmis...@g=
mail.com 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><br></div><div>How about:</div><div><br></div><p>enum class trafflic=
_light{ unknown, reg, yellow, green };</p><div><br></div><div>traffic_light=
 =3D traffic_light::unknown; // My default.<br>bool success =3D make_enum(l=
ight, x); // Does not set light on failure. X of any integral type<br></div=
></div></blockquote><br>No,
 that requires the existence of `light`. C++ has too many APIs that=20
needlessly require live objects already; we don&#39;t need another one.<br>=
<br>On Tuesday, January 3, 2017 at 6:48:25 PM UTC-5, gmis...@gmail.com wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></=
div><div>Just considering my earlier make_enum comment further, The ultimat=
e minimum for C++ is surely this?:</div><div><br></div><div>traffic_light l=
ight{}; // whatever default.<br>bool guaranteed_success =3D std::can_cast_e=
num&lt;traffic_<wbr>light&gt;(x);</div><div>if (guaranteed_success)<br>=C2=
=A0light =3D reinterpret_cast&lt;traffic_<wbr>light&gt;(x);</div><div>// el=
se error condition.</div><div><br></div><div>It separates the validity chec=
k from the conversion</div></div></blockquote><div><br>That&#39;s actually =
a pretty good idea. Of course, there should be &quot;higher-level&quot; fun=
ctionality like a direct `enum_cast` that throws and so forth, as discussed=
.. But this way, people have the lowest-level tools to build their own funct=
ionality on top of the basic question.</div><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/621e1d86-492b-4ecc-96ba-4e0b74dfcb4e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/621e1d86-492b-4ecc-96ba-4e0b74dfcb4e=
%40isocpp.org</a>.<br />

------=_Part_1190_1757428033.1483502332996--

------=_Part_1189_1966822393.1483502332996--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 4 Jan 2017 08:13:30 +0100
Raw View
Le 04/01/2017 =C3=A0 00:48, gmisocpp@gmail.com a =C3=A9crit :
>
> Just considering my earlier make_enum comment further, The ultimate=20
> minimum for C++ is surely this?:
>
> traffic_light light{}; // whatever default.
> bool guaranteed_success =3D std::can_cast_enum<traffic_light>(x);
> if (guaranteed_success)
>  light =3D reinterpret_cast<traffic_light>(x);
> // else error condition.
>
> It separates the validity check from the conversion and then you can=20
> build whatever on that, i.e. assign, atomic assign, etc.
> This seems more C++ like, but forgets C, which probably people feel is=20
> not a concern anyway.
> But other wise some special C and C++ syntax like=20
>  can_cast_enum(traffic_light, x) would seem to cover both languages if=20
> that's desirable.
Yes, this is the good interface :)

I'm all for a proposal of this minimal interface, even if I would add a=20
enum_cast synonym of static_cast.
It is clear from the previous code that there is no problem with the=20
cast and using the same name would surely help

     const traffic_light light =3D (std::can_enum_cast<traffic_light>(x))=
=20
? std::enum_cast<traffic_light>(x)  :=20
throw_bad_enum_cast<traffic_light>(x);

Note that throw_bad_enum_cast is not proposed. It is only and example to=20
show the interface allows the use of safe conversions expressions.

We could see later what can be built on top of it and what could be on=20
the standard.

Vicente

--=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/87adf165-dd56-e16f-e4ab-c14931921540%40wanadoo.f=
r.

.


Author: m.cencora@gmail.com
Date: Wed, 4 Jan 2017 00:44:09 -0800 (PST)
Raw View
------=_Part_2725_666972437.1483519450024
Content-Type: multipart/alternative;
 boundary="----=_Part_2726_901685433.1483519450024"

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

W dniu wtorek, 3 stycznia 2017 20:12:38 UTC+1 u=C5=BCytkownik Thiago Maciei=
ra=20
napisa=C5=82:
>
> On ter=C3=A7a-feira, 3 de janeiro de 2017 08:22:52 BRST m.ce...@gmail.com=
=20
> <javascript:> wrote:=20
> > > How do you know whether a use of enum_cast is compile-time or whether=
=20
> it=20
> > > is=20
> > > runtime?=20
> >=20
> > I don't know and I don't care. The function should be constexpr to=20
> support=20
> > both cases.=20
>
> Well, I think people may care. A constexpr invocation has zero cost at=20
> runtime, since it will have failed to convert by producing an error=20
> message,=20
> or it will succeed by becoming a no-op (like static_cast, minus pointer=
=20
> adjustment). But a non-constexpr invocation will have a runtime cost.=20
>

Well of course it will have runtime cost in non-constexpr invocation, the
whole point of this function is to perform validation at runtime.
Constexpr support is just an addition.
=20

> > What I'd like to hear now is whether anyone else would find such a=20
> > functionality useful?=20
> > Do you consider it a good idea to put it into C++ standard/library?=20
>
> Maybe you should rename it to mean a check if the value is a valid=20
> enumerator=20
> and drop the "cast" part.=20
>

I thought about it, but I see no use case for just a check.
In all the use cases I can think of user wants the cast after the check.

Do you have a example in mind where such a check without a cast later
would be useful?
=20

>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1730f9cb-837d-4af3-a771-107e21de0adc%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu wtorek, 3 stycznia 2017 20:12:38 UTC+1 u=C5=BCytkow=
nik Thiago Macieira napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On ter=C3=A7a-feira, 3 de janeiro de 2017 08:22:52 BRST <a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"duJh4IyBCwAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;javascript:&#39;;return true;">m.ce...@gmail.com</a>=
 wrote:
<br>&gt; &gt; How do you know whether a use of enum_cast is compile-time or=
 whether it
<br>&gt; &gt; is
<br>&gt; &gt; runtime?
<br>&gt;=20
<br>&gt; I don&#39;t know and I don&#39;t care. The function should be cons=
texpr to support
<br>&gt; both cases.
<br>
<br>Well, I think people may care. A constexpr invocation has zero cost at=
=20
<br>runtime, since it will have failed to convert by producing an error mes=
sage,=20
<br>or it will succeed by becoming a no-op (like static_cast, minus pointer=
=20
<br>adjustment). But a non-constexpr invocation will have a runtime cost.
<br></blockquote><div><br></div><div>Well of course it will have runtime co=
st in non-constexpr invocation, the</div><div>whole point of this function =
is to perform validation at runtime.</div><div>Constexpr support is just an=
 addition.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">&gt; What I&#39;d like to hear now is whether anyone else would find suc=
h a
<br>&gt; functionality useful?
<br>&gt; Do you consider it a good idea to put it into C++ standard/library=
?
<br>
<br>Maybe you should rename it to mean a check if the value is a valid enum=
erator=20
<br>and drop the &quot;cast&quot; part.
<br></blockquote><div><br></div><div>I thought about it, but I see no use c=
ase for just a check.</div><div>In all the use cases I can think of user wa=
nts the cast after the check.</div><div><br></div><div>Do you have a exampl=
e in mind where such a check without a cast later</div><div>would be useful=
?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></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/1730f9cb-837d-4af3-a771-107e21de0adc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1730f9cb-837d-4af3-a771-107e21de0adc=
%40isocpp.org</a>.<br />

------=_Part_2726_901685433.1483519450024--

------=_Part_2725_666972437.1483519450024--

.


Author: m.cencora@gmail.com
Date: Wed, 4 Jan 2017 00:47:22 -0800 (PST)
Raw View
------=_Part_2430_1124105057.1483519643033
Content-Type: multipart/alternative;
 boundary="----=_Part_2431_595074273.1483519643034"

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

W dniu =C5=9Broda, 4 stycznia 2017 00:48:25 UTC+1 u=C5=BCytkownik gmis...@g=
mail.com=20
napisa=C5=82:
>
>
> Just considering my earlier make_enum comment further, The ultimate=20
> minimum for C++ is surely this?:
>
> traffic_light light{}; // whatever default.
> bool guaranteed_success =3D std::can_cast_enum<traffic_light>(x);
> if (guaranteed_success)
>  light =3D reinterpret_cast<traffic_light>(x);
> // else error condition.
>
> It separates the validity check from the conversion and then you can buil=
d=20
> whatever on that, i.e. assign, atomic assign, etc.
> This seems more C++ like, but forgets C, which probably people feel is no=
t=20
> a concern anyway.
> But other wise some special C and C++ syntax like=20
>  can_cast_enum(traffic_light, x) would seem to cover both languages if=20
> that's desirable.
>
>
How would that can_cast_enum work in C without function overloading or=20
templates?
=20

>
> On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com=20
> wrote:
>
>> Hi,
>>
>> 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, 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).
>>
>> Regards,
>> Maciej
>>
>

--=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/a38d1aa8-d461-4f70-81e7-abe36c36bb07%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu =C5=9Broda, 4 stycznia 2017 00:48:25 UTC+1 u=C5=BCy=
tkownik gmis...@gmail.com napisa=C5=82:<blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><br></div><div>Just considering my earlier m=
ake_enum comment further, The ultimate minimum for C++ is surely this?:</di=
v><div><br></div><div>traffic_light light{}; // whatever default.<br>bool g=
uaranteed_success =3D std::can_cast_enum&lt;traffic_<wbr>light&gt;(x);</div=
><div>if (guaranteed_success)<br>=C2=A0light =3D reinterpret_cast&lt;traffi=
c_<wbr>light&gt;(x);</div><div>// else error condition.</div><div><br></div=
><div>It separates the validity check from the conversion and then you can =
build whatever on that, i.e. assign, atomic assign, etc.</div><div>This see=
ms more C++ like, but forgets C, which probably people feel is not a concer=
n anyway.</div><div>But other wise=C2=A0some special C=C2=A0and C++ syntax =
like =C2=A0can_cast_enum(traffic_light, x)=C2=A0would seem to cover both la=
nguages if that&#39;s desirable.</div><div><br></div></div></blockquote><di=
v><br></div><div>How would that can_cast_enum work in C without function ov=
erloading or templates?</div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div><br>On Tuesday, January 3, 2017 at 10=
:56:05 PM UTC+13, <a>m.ce...@gmail.com</a> wrote:</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-lef=
t-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><di=
v 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(1=
87,187,187);background-color:rgb(250,250,250)"><code><div><span style=3D"co=
lor:rgb(0,0,136)">template</span><span style=3D"color:rgb(0,0,0)"> </span><=
span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0=
,136)">typename</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,0,102)">Enum</span><span style=3D"color:rgb(102,102,0)">,=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">typename</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,0,102)">Int</span><span style=3D"color:rgb(102,102,0)">&g=
t;</span><span style=3D"color:rgb(0,0,0)"><br>optional</span><span style=3D=
"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)">Enum=
</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color=
:rgb(0,0,0)"> enum_cast</span><span style=3D"color:rgb(102,102,0)">(</span>=
<span style=3D"color:rgb(102,0,102)">Int</span><span style=3D"color:rgb(0,0=
,0)"> value</span><span style=3D"color:rgb(102,102,0)">);</span><span style=
=3D"color:rgb(0,0,0)"><br><br>requires</span><span style=3D"color:rgb(102,1=
02,0)">:</span><span style=3D"color:rgb(0,0,0)"> is_enum</span><span style=
=3D"color:rgb(102,102,0)">&lt;</span><font color=3D"#000000"><span style=3D=
"color:rgb(102,0,102)">Enum</span></font><span style=3D"color:rgb(102,102,0=
)">&gt;,</span><span style=3D"color:rgb(0,0,0)"> is_integral</span><span st=
yle=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)=
">Int</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"=
color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">enum</s=
pan><span style=3D"color:rgb(0,0,0)"> color<br></span><span style=3D"color:=
rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0r=
ed </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)">1</span><span s=
tyle=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0green </span><span style=3D"color:rgb(102,102,0)">=3D</span><s=
pan style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)"=
>200</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"colo=
r:rgb(0,0,0)"><br>=C2=A0 =C2=A0blue </span><span style=3D"color:rgb(102,102=
,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(0,102,102)">3</span><span style=3D"color:rgb(0,0,0)"><br></span><span=
 style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><=
br><br></span><span style=3D"color:rgb(0,0,136)">static_assert</span><span =
style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">enu=
m_cast</span><span style=3D"color:rgb(0,136,0)">&lt;color&gt;</span><span s=
tyle=3D"color:rgb(102,102,0)"><wbr>(</span><font color=3D"#006666"><span st=
yle=3D"color:rgb(0,102,102)">200u</span></font><span style=3D"color:rgb(102=
,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D=3D</span><span style=3D"color:rgb(0,0,0)"> color</s=
pan><span style=3D"color:rgb(102,102,0)">::</span><font color=3D"#000000"><=
span style=3D"color:rgb(0,0,0)">green</span></font><span style=3D"color:rgb=
(102,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br></span><span sty=
le=3D"color:rgb(0,0,136)">static_assert</span><span style=3D"color:rgb(102,=
102,0)">(</span><span style=3D"color:rgb(0,0,0)">enum_cast</span><span styl=
e=3D"color:rgb(0,136,0)">&lt;color&gt;</span><span style=3D"color:rgb(102,1=
02,0)"><wbr>(</span><span style=3D"color:rgb(0,102,102)">3</span><span styl=
e=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(102,102,0)">=3D=3D</span><span style=3D"color:rgb=
(0,0,0)"> color</span><span style=3D"color:rgb(102,102,0)">::</span><span s=
tyle=3D"color:rgb(0,0,0)">blue</span><span style=3D"color:rgb(102,102,0)">)=
;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rg=
b(0,0,136)">static_assert</span><span style=3D"color:rgb(102,102,0)">(</spa=
n><span style=3D"color:rgb(0,0,0)">enum_cast</span><span style=3D"color:rgb=
(0,136,0)">&lt;color&gt;</span><span style=3D"color:rgb(102,102,0)"><wbr>(<=
/span><span style=3D"color:rgb(0,102,102)">4</span><span style=3D"color:rgb=
(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">=3D=3D</span><span style=3D"color:rgb(0,0,0)"> nu=
llopt</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"co=
lor:rgb(0,0,0)"><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 da=
ta (e.g. coming from user or deserialization).</div><div>=C2=A0- other?</di=
v><div><br></div><div>I know this could be purely library extension if base=
d 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><d=
iv>I think it should be implemented with compiler support (i.e. via __built=
in_* intrinsic).</div><div><br></div><div>Regards,</div><div>Maciej</div></=
div></blockquote></div></blockquote></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/a38d1aa8-d461-4f70-81e7-abe36c36bb07%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a38d1aa8-d461-4f70-81e7-abe36c36bb07=
%40isocpp.org</a>.<br />

------=_Part_2431_595074273.1483519643034--

------=_Part_2430_1124105057.1483519643033--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 04 Jan 2017 12:29:35 -0200
Raw View
On quarta-feira, 4 de janeiro de 2017 00:44:09 BRST m.cencora@gmail.com wrote:
> I thought about it, but I see no use case for just a check.
> In all the use cases I can think of user wants the cast after the check.
>
> Do you have a example in mind where such a check without a cast later
> would be useful?

The problem is that a cast that can fail needs a way out. dynamic_cast can
fail by returning nullptr (for pointers) or by throwing std::bad_cast (for
references).

So you need to find a way to report that failure.

And I don't want exceptions in my code.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--
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/64617344.0Ggdhq6B90%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 04 Jan 2017 12:33:18 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 19:43:33 BRST Nicol Bolas wrote:
> > Anything that is a compiler feature (a builtin or a core language
> > expression)
> > needs to be able to choose between std::optional,
> > std::experimental::optional
> > and std::__1::optional by just changing #includes.
>=20
> ... why? std::experimental::optional isn't part of the standard. And I ha=
ve
> no idea what `std::__1::optional` is.

That's exactly the point: you don't know what the actual "optional" class's=
=20
full name is. Therefore, a language feature should not reference a strict=
=20
class name.

I know std::initializer_list has already broken this rule but there were=20
mitigating factors:
 1) it's a class that only the compiler can create in the first place
 2) it didn't exist prior to the feature that referenced it, so compiler an=
d=20
library writers could cooperate, unlike optional
 3) there aren't many ways to store an array of items, but there is a=20
discussion on how to store a type and its presence flag

Ditto for std::type_info.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/3252047.kbLLhmVhCu%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 04 Jan 2017 12:34:19 -0200
Raw View
On ter=C3=A7a-feira, 3 de janeiro de 2017 15:48:25 BRST gmisocpp@gmail.com =
wrote:
> This seems more C++ like, but forgets C, which probably people feel is no=
t
> a concern anyway.

It's not.

C enums are ints.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/3890510.xK3BGRGEk0%40tjmaciei-mobl1.

.


Author: m.cencora@gmail.com
Date: Wed, 4 Jan 2017 07:20:11 -0800 (PST)
Raw View
------=_Part_2811_1217587467.1483543211405
Content-Type: multipart/alternative;
 boundary="----=_Part_2812_1123395632.1483543211405"

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

W dniu =C5=9Broda, 4 stycznia 2017 15:30:12 UTC+1 u=C5=BCytkownik Thiago Ma=
cieira=20
napisa=C5=82:
>
> On quarta-feira, 4 de janeiro de 2017 00:44:09 BRST m.ce...@gmail.com=20
> <javascript:> wrote:=20
> > I thought about it, but I see no use case for just a check.=20
> > In all the use cases I can think of user wants the cast after the check=
..=20
> >=20
> > Do you have a example in mind where such a check without a cast later=
=20
> > would be useful?=20
>
> The problem is that a cast that can fail needs a way out. dynamic_cast ca=
n=20
> fail by returning nullptr (for pointers) or by throwing std::bad_cast (fo=
r=20
> references).=20
>
> So you need to find a way to report that failure.=20
>
> And I don't want exceptions in my code.=20
>

That's exactly the reason why I have proposed to return optional<T>.

Why do you want to use some compiler invented type instead?
If enum_cast is a function in standard library, why can't it use another
type from same library?

Regards,
Maciej
=20

>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d03061cc-7442-4e10-9313-a3394afa11e3%40isocpp.or=
g.

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

<div dir=3D"ltr">W dniu =C5=9Broda, 4 stycznia 2017 15:30:12 UTC+1 u=C5=BCy=
tkownik Thiago Macieira napisa=C5=82:<blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;">On quarta-feira, 4 de janeiro de 2017 00:44:09 BRST <a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"FbyBq7fACwAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;javascript:&#39;;return true;">m.ce...@gmail.com</a>=
 wrote:
<br>&gt; I thought about it, but I see no use case for just a check.
<br>&gt; In all the use cases I can think of user wants the cast after the =
check.
<br>&gt;=20
<br>&gt; Do you have a example in mind where such a check without a cast la=
ter
<br>&gt; would be useful?
<br>
<br>The problem is that a cast that can fail needs a way out. dynamic_cast =
can=20
<br>fail by returning nullptr (for pointers) or by throwing std::bad_cast (=
for=20
<br>references).
<br>
<br>So you need to find a way to report that failure.
<br>
<br>And I don&#39;t want exceptions in my code.
<br></blockquote><div><br></div><div>That&#39;s exactly the reason why I ha=
ve proposed to return optional&lt;T&gt;.</div><div><br></div><div>Why do yo=
u want to use some compiler invented type instead?</div><div>If enum_cast i=
s a function in standard library, why can&#39;t it use another</div><div>ty=
pe from same library?</div><div><br></div><div>Regards,</div><div>Maciej</d=
iv><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></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/d03061cc-7442-4e10-9313-a3394afa11e3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d03061cc-7442-4e10-9313-a3394afa11e3=
%40isocpp.org</a>.<br />

------=_Part_2812_1123395632.1483543211405--

------=_Part_2811_1217587467.1483543211405--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 04 Jan 2017 14:16:08 -0200
Raw View
On quarta-feira, 4 de janeiro de 2017 07:20:11 BRST m.cencora@gmail.com wrote:
> Why do you want to use some compiler invented type instead?
> If enum_cast is a function in standard library, why can't it use another
> type from same library?

Then it is a function in the standard library. That means it needs to be based
on something else to perform the check, like reflection.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--
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/10490049.adee8Rr8fZ%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 4 Jan 2017 08:33:28 -0800 (PST)
Raw View
------=_Part_4063_1935462667.1483547608425
Content-Type: multipart/alternative;
 boundary="----=_Part_4064_689798405.1483547608425"

------=_Part_4064_689798405.1483547608425
Content-Type: text/plain; charset=UTF-8



On Wednesday, January 4, 2017 at 11:16:17 AM UTC-5, Thiago Macieira wrote:
>
> On quarta-feira, 4 de janeiro de 2017 07:20:11 BRST m.ce...@gmail.com
> <javascript:> wrote:
> > Why do you want to use some compiler invented type instead?
> > If enum_cast is a function in standard library, why can't it use another
> > type from same library?
>
> Then it is a function in the standard library. That means it needs to be
> based
> on something else to perform the check, like reflection.
>

There are plenty of functions in the standard library whose implementations
rely on compiler-specific features. You wouldn't be able to implement most
of the type traits without compiler intrinsic or some compiler-specific
knowledge. You can't implement `type_info` or `initializer_list` without
the compiler being involved. And so forth.

This would simply be one more compiler-based construct. Once we get
compile-time reflection, implementations could become platform-neutral
(though the compiler-equivalent would probably still get faster).

But how the function gets implemented ultimately has nothing to do with
having it return `std::optional`.


>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>

--
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/8747ddc6-c416-44b9-a8a0-b3a00f835c05%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Wednesday, January 4, 2017 at 11:16:17 AM UTC-5=
, Thiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On qua=
rta-feira, 4 de janeiro de 2017 07:20:11 BRST <a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"nmfexIHGCwAJ" rel=3D"nofollow" onmous=
edown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;javascript:&#39;;return true;">m.ce...@gmail.com</a> wrote:
<br>&gt; Why do you want to use some compiler invented type instead?
<br>&gt; If enum_cast is a function in standard library, why can&#39;t it u=
se another
<br>&gt; type from same library?
<br>
<br>Then it is a function in the standard library. That means it needs to b=
e based=20
<br>on something else to perform the check, like reflection.<br></blockquot=
e><div><br>There are plenty of functions in the standard library whose impl=
ementations rely on compiler-specific features. You wouldn&#39;t be able to=
 implement most of the type traits without compiler intrinsic or some compi=
ler-specific knowledge. You can&#39;t implement `type_info` or `initializer=
_list` without the compiler being involved. And so forth.<br><br>This would=
 simply be one more compiler-based construct. Once we get compile-time refl=
ection, implementations could become platform-neutral (though the compiler-=
equivalent would probably still get faster).<br><br>But how the function ge=
ts implemented ultimately has nothing to do with having it return `std::opt=
ional`.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br></blockquote></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/8747ddc6-c416-44b9-a8a0-b3a00f835c05%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8747ddc6-c416-44b9-a8a0-b3a00f835c05=
%40isocpp.org</a>.<br />

------=_Part_4064_689798405.1483547608425--

------=_Part_4063_1935462667.1483547608425--

.


Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Wed, 4 Jan 2017 20:28:38 +0100
Raw View
For what it is worth, I have a small utility library for enumerations
(not to elegant, requiring a macro to define the machinery) where you
- among other stuff has two functions available that does what you
want

1) to_enum<Enum>(int x):
Returns the corresponding enum or an unspecified but valid value.
2) is_enum<Enum>(int x)
Returns true if x represents a valid enum.

Thus, If we have the definition

enum color
{
   red = 1,
   green = 200,
   blue = 3
};

is_enum<color>(100) would return false and to_enum<color>(100) would
return either red, green or blue.

This approach is in my opinion better than forcing some
error-reporting mechanism such as returning an optional or throwing an
error.

/Peter

On Wed, Jan 4, 2017 at 5:33 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>
>
> On Wednesday, January 4, 2017 at 11:16:17 AM UTC-5, Thiago Macieira wrote:
>>
>> On quarta-feira, 4 de janeiro de 2017 07:20:11 BRST m.ce...@gmail.com
>> wrote:
>> > Why do you want to use some compiler invented type instead?
>> > If enum_cast is a function in standard library, why can't it use another
>> > type from same library?
>>
>> Then it is a function in the standard library. That means it needs to be
>> based
>> on something else to perform the check, like reflection.
>
>
> There are plenty of functions in the standard library whose implementations
> rely on compiler-specific features. You wouldn't be able to implement most
> of the type traits without compiler intrinsic or some compiler-specific
> knowledge. You can't implement `type_info` or `initializer_list` without the
> compiler being involved. And so forth.
>
> This would simply be one more compiler-based construct. Once we get
> compile-time reflection, implementations could become platform-neutral
> (though the compiler-equivalent would probably still get faster).
>
> But how the function gets implemented ultimately has nothing to do with
> having it return `std::optional`.
>
>>
>>
>> --
>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>    Software Architect - Intel Open Source Technology Center
>>
> --
> 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/8747ddc6-c416-44b9-a8a0-b3a00f835c05%40isocpp.org.

--
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/CANPtknw9s4%2BtKU5SKbuPHRQKbbLdN1Xt8HGa_OiRa%3D_-rEiYbQ%40mail.gmail.com.

.


Author: gmisocpp@gmail.com
Date: Tue, 10 Jan 2017 04:48:59 -0800 (PST)
Raw View
------=_Part_2523_1149900171.1484052539792
Content-Type: multipart/alternative;
 boundary="----=_Part_2524_1908813640.1484052539793"

------=_Part_2524_1908813640.1484052539793
Content-Type: text/plain; charset=UTF-8



On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com wrote:
>
> Hi,
>
> 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.
>
> template <typename Enum, typename Int>
> optional<Enum> enum_cast(Int value);
>
> requires: is_enum<Enum>, is_integral<Int>
>
> enum color
> {
>    red = 1,
>    green = 200,
>    blue = 3
> };
>
> static_assert(enum_cast<color>(200u) == color::green);
> static_assert(enum_cast<color>(3) == color::blue);
> static_assert(enum_cast<color>(4) == 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
> 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
> __builtin_* intrinsic).
>
> Regards,
> Maciej
>


I was thinking some more about this proposal. I really think the
functionality you suggest is a good idea.
I hope you proceed with a proposal. If you decide not to let me know.

I hope this post assists you with your proposal. My suggestions are for
your proposal to look something like this:

In <utility> I think add:

bool template<typename E, typename V> is_enum( V ev )
{
 // compiler magic:
 // Calling this routine causes the compiler to generate or a call a routine
 // that returns true if the value ev matches one of the enum E's
 // values. otherwise false.
}

// Users call this routine to convert an integer to an enum.
They call this if they aren't sure about their conversion data
// and don't mind exceptions and want simple like std::to_string
// They might expect such a function to be present.
// Though to be fair I'm not sure we should encourage this?
// They should get good error messages.
template<typename E, typename V> E to_enum_or_throw(V ev)
{
 if (is_enum<E>(ev))
  return static_cast<E>(ev);
 throw make_bad_enum<E,V>(ev);
}

template<typename E> class to_enum_result
{
public:
 E enum_value;
 bool is_valid;
};

// Call this if you can't use/afford exceptions. It seems optimal?
template<typename E, typename V> to_enum_result<E> to_enum( V ev ) noexcept
{
  if (is_enum<E, V>(ev))
    return to_enum_result<E>{true,static_cast<E>(ev)};
  return to_enum_result<E>{false, E{}};
}

// if is_valid returns false after to_enum, the user can use these routines
to get good error
// messages / report how they wish when they wish:

// Some type that holds the largest enum value ever possible.
using std::any_enum_value = unspecified;

class bad_enum
{
public:
   std::any_any_enum_value bad_enum_value;
   std::string enum_type_name;
};

template<typename E, typename V> std::bad_enum make_bad_enum(V ev)
{
 // Use some compiler magic to get the name of the name of the enum type E.
 // Use it to construct a message like:
 // '{ev}' is not a legal value for an enum of type '{E}'
 return std::range_error(msg);
}


Note in all methods:
* constrain E to only be an enum or enum class type.
* constrain V to only accept integral types.

Observations
------------

* is_enum() is there for people who just need to check validity and no more.
and saves the user writing redudant boiler plate code that the compiler
does better.
* to_enum_or_throw() is there for people who find simple works for them.
its name makes it clear that exceptions can happen.
* to_enum() is there for people who need performance and without exceptions.
* We don't depend on optional.
* Means <utility> isn't dependent on optional if we put it there.
* make_bad_enum avoids making bad_enum a template.
* make_bad_enum gives us good error messages and better than
bad_optional_access.
* make_bad_enum means we can create an error class for reporting elsewhere
- we don't have to throw it.
* make_bad_enum means we don't expose any get enum_type_name function the
reflection people will reproduce.
* make_bad_enum gives people flexibility to throw when they are ready
instead of forcing a throw as soon as conversion fails.
* Might play well with structured bindings.

Main choices:
* We could model this on optional i.e. include has_value etc. but it seems
simpler not to. Either way is fine to me.
I'm not sure such safety is warranted and from_chars/to_chars is pretty
simple too so I went that way.
* The caller has all the utilities here to build that or work with optional
directly - whatever they need.
* I think being able to get good error messages on failure is important.
This tries to enable making decent errors available no matter what method
or is used.
 i.e. include the enum type name and bad value in the error.
* I've used std::range_error as the exception type for failure but another
may be appropriate.
bad_enum as an exception type contains the value that was bad and the type
name that it failed to convert to.
This would allow people to extract the values to construct their own error
messages (perhaps in other languages like French etc.).

If std::bad_enum is too much API, that could be dropped for just
std::range_error or something as long a it contains
a full description of the error I think that's fine.

I'd like to know what you and the Committee's disposition towards these
ideas and views. Hope this helps.

Thanks
GM

--
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/57258435-5d82-48e7-8ed7-3c38682418fb%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13,=
 m.ce...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204=
); border-left-width: 1px; border-left-style: solid;"><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); bo=
rder-image: none; -ms-word-wrap: break-word; background-color: rgb(250, 250=
, 250);"><code><div><span style=3D"color: rgb(0, 0, 136);">template</span><=
span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, =
102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 136);">typename</span>=
<span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102,=
 0, 102);">Enum</span><span style=3D"color: rgb(102, 102, 0);">,</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 13=
6);">typename</span><span style=3D"color: rgb(0, 0, 0);"> </span><span styl=
e=3D"color: rgb(102, 0, 102);">Int</span><span style=3D"color: rgb(102, 102=
, 0);">&gt;</span><span style=3D"color: rgb(0, 0, 0);"><br>optional</span><=
span style=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rg=
b(102, 0, 102);">Enum</span><span style=3D"color: rgb(102, 102, 0);">&gt;</=
span><span style=3D"color: rgb(0, 0, 0);"> enum_cast</span><span style=3D"c=
olor: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102);">I=
nt</span><span style=3D"color: rgb(0, 0, 0);"> value</span><span style=3D"c=
olor: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br>=
<br>requires</span><span style=3D"color: rgb(102, 102, 0);">:</span><span s=
tyle=3D"color: rgb(0, 0, 0);"> is_enum</span><span style=3D"color: rgb(102,=
 102, 0);">&lt;</span><font color=3D"#000000"><span style=3D"color: rgb(102=
, 0, 102);">Enum</span></font><span style=3D"color: rgb(102, 102, 0);">&gt;=
,</span><span style=3D"color: rgb(0, 0, 0);"> is_integral</span><span style=
=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(102, 0, =
102);">Int</span><span style=3D"color: rgb(102, 102, 0);">&gt;</span><span =
style=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"color: rgb(0, =
0, 136);">enum</span><span style=3D"color: rgb(0, 0, 0);"> color<br></span>=
<span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(=
0, 0, 0);"><br>=C2=A0 =C2=A0red </span><span style=3D"color: rgb(102, 102, =
0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"=
color: rgb(0, 102, 102);">1</span><span style=3D"color: rgb(102, 102, 0);">=
,</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0green </span>=
<span style=3D"color: rgb(102, 102, 0);">=3D</span><span style=3D"color: rg=
b(0, 0, 0);"> </span><span style=3D"color: rgb(0, 102, 102);">200</span><sp=
an style=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, =
0, 0);"><br>=C2=A0 =C2=A0blue </span><span style=3D"color: rgb(102, 102, 0)=
;">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"co=
lor: rgb(0, 102, 102);">3</span><span style=3D"color: rgb(0, 0, 0);"><br></=
span><span style=3D"color: rgb(102, 102, 0);">};</span><span style=3D"color=
: rgb(0, 0, 0);"><br><br></span><span style=3D"color: rgb(0, 0, 136);">stat=
ic_assert</span><span style=3D"color: rgb(102, 102, 0);">(</span><span styl=
e=3D"color: rgb(0, 0, 0);">enum_cast</span><span style=3D"color: rgb(0, 136=
, 0);">&lt;color&gt;</span><span style=3D"color: rgb(102, 102, 0);"><wbr>(<=
/span><font color=3D"#006666"><span style=3D"color: rgb(0, 102, 102);">200u=
</span></font><span style=3D"color: rgb(102, 102, 0);">)</span><span style=
=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">=
=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> color</span><span style=
=3D"color: rgb(102, 102, 0);">::</span><font color=3D"#000000"><span style=
=3D"color: rgb(0, 0, 0);">green</span></font><span style=3D"color: rgb(102,=
 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span s=
tyle=3D"color: rgb(0, 0, 136);">static_assert</span><span style=3D"color: r=
gb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">enum_cast</s=
pan><span style=3D"color: rgb(0, 136, 0);">&lt;color&gt;</span><span style=
=3D"color: rgb(102, 102, 0);"><wbr>(</span><span style=3D"color: rgb(0, 102=
, 102);">3</span><span style=3D"color: rgb(102, 102, 0);">)</span><span sty=
le=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);=
">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);"> color</span><span styl=
e=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0, 0);=
">blue</span><span style=3D"color: rgb(102, 102, 0);">);</span><span style=
=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);"=
>static_assert</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
 style=3D"color: rgb(0, 0, 0);">enum_cast</span><span style=3D"color: rgb(0=
, 136, 0);">&lt;color&gt;</span><span style=3D"color: rgb(102, 102, 0);"><w=
br>(</span><span style=3D"color: rgb(0, 102, 102);">4</span><span style=3D"=
color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </s=
pan><span style=3D"color: rgb(102, 102, 0);">=3D=3D</span><span style=3D"co=
lor: rgb(0, 0, 0);"> nullopt</span><span style=3D"color: rgb(102, 102, 0);"=
>);</span><span style=3D"color: rgb(0, 0, 0);"><br><br></span></div></code>=
</div><div><br></div><div>This should work for both scoped and unscoped enu=
ms.</div><div>For opaque enums this would only check if value fits in under=
lying 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 p=
urely library extension if based on reflection, but since we don&#39;t know=
 when we will get reflection,</div><div>and implementation based on reflect=
ion may not be optimal,</div><div>I think it should be implemented with com=
piler support (i.e. via __builtin_* intrinsic).</div><div><br></div><div>Re=
gards,</div><div>Maciej</div></div></blockquote><div><br></div><div><br></d=
iv><div>I was thinking some more about this proposal. I really think the fu=
nctionality you suggest=C2=A0is a good idea.</div><div>I hope you proceed w=
ith a proposal.=C2=A0If you decide not to let me know.</div><div><br></div>=
<div>I hope this post assists you with your proposal.=C2=A0My suggestions a=
re for your proposal to look something like this:</div><div><br></div><div>=
In &lt;utility&gt; I think add:</div><div><br></div><div>bool template&lt;t=
ypename E, typename V&gt; is_enum( V ev )</div><div>{</div><div>=C2=A0// co=
mpiler=C2=A0magic:</div><div>=C2=A0// Calling this routine causes the compi=
ler to generate or a call a routine</div><div>=C2=A0// that returns true if=
 the value ev matches one of the enum E&#39;s</div><div>=C2=A0// values. ot=
herwise false.</div><div>}</div><div><br></div><div>// Users call this rout=
ine to convert an integer to an enum.</div><div>They call this if they=C2=
=A0aren&#39;t sure about=C2=A0their conversion data</div><div>// and don&#3=
9;t mind exceptions and want simple like std::to_string</div><div>// They m=
ight expect such a function to be present.</div><div>// Though to be fair I=
&#39;m not sure we should encourage this?</div><div>//=C2=A0They should get=
 good error messages.</div><div>template&lt;typename E, typename V&gt; E to=
_enum_or_throw(V ev)</div><div>{</div><div>=C2=A0if (is_enum&lt;E&gt;(ev))<=
/div><div>=C2=A0=C2=A0return static_cast&lt;E&gt;(ev);</div><div>=C2=A0thro=
w make_bad_enum&lt;E,V&gt;(ev);=C2=A0</div><div>}</div><div><br></div><div>=
<div>template&lt;typename E&gt; class to_enum_result</div><div>{</div><div>=
public:</div><div>=C2=A0E enum_value;</div><div>=C2=A0bool is_valid;</div><=
div>};</div><div><br></div></div><div>// Call this if you can&#39;t use/aff=
ord exceptions. It seems optimal?</div><div>template&lt;typename E, typenam=
e V&gt; to_enum_result&lt;E&gt; to_enum( V ev ) noexcept</div><div>{</div><=
div>=C2=A0 if (is_enum&lt;E, V&gt;(ev))</div><div>=C2=A0=C2=A0=C2=A0 return=
 to_enum_result&lt;E&gt;{true,static_cast&lt;E&gt;(ev)};</div><div>=C2=A0 r=
eturn to_enum_result&lt;E&gt;{false, E{}};</div><div>}</div><div><br></div>=
<div>// if is_valid=C2=A0returns false after to_enum, the user can use thes=
e routines to get good error</div><div>// messages / report how they wish w=
hen they wish:</div><div><br></div><div><div><div>// Some type that holds t=
he largest enum value ever possible.</div><div><div>using std::any_enum_val=
ue =3D unspecified;</div><div><br></div></div></div><div>class bad_enum</di=
v><div>{</div><div>public:</div><div>=C2=A0=C2=A0=C2=A0std::any_any_enum_va=
lue bad_enum_value;</div><div>=C2=A0=C2=A0 std::string enum_type_name;<br>}=
;</div><div>=C2=A0</div>template&lt;typename E, typename V&gt; std::bad_enu=
m make_bad_enum(V ev)</div><div>{</div><div>=C2=A0// Use some compiler magi=
c to get the name of the name of the=C2=A0enum type=C2=A0E.</div><div>=C2=
=A0// Use it to construct a message like:</div><div>=C2=A0// &#39;{ev}&#39;=
 is not a legal value for an enum of type &#39;{E}&#39;</div><div>=C2=A0ret=
urn std::range_error(msg);</div><div>}</div><div><br></div><div><br></div><=
div><div>Note in all methods:</div><div>* constrain E to only be an enum or=
 enum class type.</div><div>* constrain V to only accept integral types.</d=
iv><div><br></div></div><div>Observations</div><div>------------</div><div>=
<br></div><div>* is_enum() is there for people who just need to check valid=
ity and no more.</div><div>and saves the user writing redudant boiler plate=
 code that the compiler does better.</div><div>* to_enum_or_throw() is ther=
e for people who find simple works for them.</div><div>its name makes it cl=
ear that exceptions can happen.</div><div>* to_enum() is there for people w=
ho need performance and without exceptions.</div><div>* We don&#39;t depend=
 on optional.</div><div>* Means &lt;utility&gt; isn&#39;t dependent on opti=
onal if we put it there.</div><div><div>* make_bad_enum avoids making bad_e=
num a template.</div>* make_bad_enum gives us good error messages and bette=
r than bad_optional_access.</div><div>*=C2=A0make_bad_enum means=C2=A0we ca=
n=C2=A0create an=C2=A0error class=C2=A0for reporting elsewhere -=C2=A0we do=
n&#39;t have to throw it.</div><div>*=C2=A0make_bad_enum means we don&#39;t=
 expose any get enum_type_name function the reflection people will reproduc=
e.</div><div>* make_bad_enum gives people flexibility to throw when they ar=
e ready instead of forcing a throw as soon as conversion fails.</div><div>*=
 Might play well with structured bindings.</div><div><br></div><div>Main ch=
oices:</div><div>*=C2=A0We could=C2=A0model this on optional=C2=A0i.e. incl=
ude=C2=A0has_value etc.=C2=A0but it=C2=A0seems simpler not to. Either way i=
s fine to me.</div><div>I&#39;m not sure such safety is warranted and=C2=A0=
from_chars/to_chars is pretty simple too so I went that way.</div><div><div=
>* The=C2=A0caller has all the utilities here to build that or work with=C2=
=A0optional directly -=C2=A0whatever=C2=A0they need.</div><div>* I think=C2=
=A0being able to get=C2=A0good error messages on failure is important.</div=
><div>This tries to=C2=A0enable making decent errors available no matter wh=
at method or=C2=A0is used.</div><div>=C2=A0i.e. include the enum type name =
and bad value in the error.</div></div><div>* I&#39;ve=C2=A0used std::range=
_error as the exception type=C2=A0for failure but another may be appropriat=
e.</div><div>bad_enum as an exception=C2=A0type=C2=A0contains the value tha=
t was bad and the type name that it failed to convert to.</div><div>This=C2=
=A0would allow people to extract the values to construct their own error me=
ssages (perhaps in other languages like French etc.).</div><div><br></div><=
div>If std::bad_enum is too much API, that could be dropped for just std::r=
ange_error or something as long a it contains</div><div>a full description =
of the error I think that&#39;s fine.</div><div><br></div><div>I&#39;d like=
 to know what you and the=C2=A0Committee&#39;s disposition towards=C2=A0the=
se ideas and views. Hope this helps.</div><div><br></div><div>Thanks</div><=
div>GM</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/57258435-5d82-48e7-8ed7-3c38682418fb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/57258435-5d82-48e7-8ed7-3c38682418fb=
%40isocpp.org</a>.<br />

------=_Part_2524_1908813640.1484052539793--

------=_Part_2523_1149900171.1484052539792--

.


Author: m.cencora@gmail.com
Date: Tue, 10 Jan 2017 07:31:07 -0800 (PST)
Raw View
------=_Part_1640_282778673.1484062268061
Content-Type: multipart/alternative;
 boundary="----=_Part_1641_1102541637.1484062268062"

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


W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik gmis...@gmai=
l.com=20
napisa=C5=82:
>
>
>
> On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com=20
> wrote:
>>
>> Hi,
>>
>> 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, 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).
>>
>> Regards,
>> Maciej
>>
>
>
> I was thinking some more about this proposal. I really think the=20
> functionality you suggest is a good idea.
> I hope you proceed with a proposal. If you decide not to let me know.
>

I'll try to create a first draft after I get some more comments w.r.t to=20
exceptions.
For sure baseline API must be exception-free.
Do we really want to additionally support API that throws on error?
I'm rather inclined to leave it out - similarly as in to_chars/from_chars.
=20

>
> I hope this post assists you with your proposal. My suggestions are for=
=20
> your proposal to look something like this:
>
> In <utility> I think add:
>
> bool template<typename E, typename V> is_enum( V ev )
> {
>  // compiler magic:
>  // Calling this routine causes the compiler to generate or a call a=20
> routine
>  // that returns true if the value ev matches one of the enum E's
>  // values. otherwise false.
> }
>

'is_enum' name is already used in type_traits header.
Also is_enum seems redundant to me, since to_enum already reports
if convertion succeeded instead of:
if (is_enum<MyEnum>(139))

you could write:
if (to_enum<MyEnum>(139).is_valid)

or even:
if (to_enum<MyEnum>(139))
if we add explicit bool convertion operator for to_enum_result.



> // Users call this routine to convert an integer to an enum.
> They call this if they aren't sure about their conversion data
> // and don't mind exceptions and want simple like std::to_string
> // They might expect such a function to be present.
> // Though to be fair I'm not sure we should encourage this?
> // They should get good error messages.
> template<typename E, typename V> E to_enum_or_throw(V ev)
> {
>  if (is_enum<E>(ev))
>   return static_cast<E>(ev);
>  throw make_bad_enum<E,V>(ev);=20
> }
>
> template<typename E> class to_enum_result
> {
> public:
>  E enum_value;
>  bool is_valid;
> };
>
> // Call this if you can't use/afford exceptions. It seems optimal?
> template<typename E, typename V> to_enum_result<E> to_enum( V ev ) noexce=
pt
> {
>   if (is_enum<E, V>(ev))
>     return to_enum_result<E>{true,static_cast<E>(ev)};
>   return to_enum_result<E>{false, E{}};
> }
>
> // if is_valid returns false after to_enum, the user can use these=20
> routines to get good error
> // messages / report how they wish when they wish:
>

As there is only one possible reason why the to_enum failed
(integer didn't match any enumerator of target enumeration type)=20
I see no reason for following functions and classes.


> // Some type that holds the largest enum value ever possible.
> using std::any_enum_value =3D unspecified;
>
> class bad_enum
> {
> public:
>    std::any_any_enum_value bad_enum_value;
>    std::string enum_type_name;
> };
> =20
> template<typename E, typename V> std::bad_enum make_bad_enum(V ev)
> {
>  // Use some compiler magic to get the name of the name of the enum type =
E.
>  // Use it to construct a message like:
>  // '{ev}' is not a legal value for an enum of type '{E}'
>  return std::range_error(msg);
> }
>


>
> Note in all methods:
> * constrain E to only be an enum or enum class type.
> * constrain V to only accept integral types.
>
> Observations
> ------------
>
> * is_enum() is there for people who just need to check validity and no=20
> more.
> and saves the user writing redudant boiler plate code that the compiler=
=20
> does better.
> * to_enum_or_throw() is there for people who find simple works for them.
> its name makes it clear that exceptions can happen.
> * to_enum() is there for people who need performance and without=20
> exceptions.
>
=20

> * We don't depend on optional.=20
>
* Means <utility> isn't dependent on optional if we put it there.
> * make_bad_enum avoids making bad_enum a template.
> * make_bad_enum gives us good error messages and better than=20
> bad_optional_access.
> * make_bad_enum means we can create an error class for reporting elsewher=
e=20
> - we don't have to throw it.
> * make_bad_enum means we don't expose any get enum_type_name function the=
=20
> reflection people will reproduce.
> * make_bad_enum gives people flexibility to throw when they are ready=20
> instead of forcing a throw as soon as conversion fails.
> * Might play well with structured bindings.
> =20
>
Main choices:
> * We could model this on optional i.e. include has_value etc. but it seem=
s=20
> simpler not to. Either way is fine to me.
> I'm not sure such safety is warranted and from_chars/to_chars is pretty=
=20
> simple too so I went that way.
>

As committee already stated their preference in from_chars/to_chars case,=
=20
consider me convinced.
I will use 'to_enum_result' in draft.
Also I'll use 'to_enum' as function name to match 'to_chars' convention.
=20

> * The caller has all the utilities here to build that or work=20
> with optional directly - whatever they need.
> * I think being able to get good error messages on failure is important.
> This tries to enable making decent errors available no matter what method=
=20
> or is used.
>  i.e. include the enum type name and bad value in the error.=20
>
* I've used std::range_error as the exception type for failure but another=
=20
> may be appropriate.
> bad_enum as an exception type contains the value that was bad and the typ=
e=20
> name that it failed to convert to.
> This would allow people to extract the values to construct their own erro=
r=20
> messages (perhaps in other languages like French etc.).
>
> If std::bad_enum is too much API, that could be dropped for just=20
> std::range_error or something as long a it contains
> a full description of the error I think that's fine.
>

> I'd like to know what you and the Committee's disposition towards these=
=20
> ideas and views. Hope this helps.
>


Thanks for your valuable input.

Regards,
Maciej
=20

>
> Thanks
> GM
>

--=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/a35d9f20-9e4f-4789-b7e5-5cb08f99e6bd%40isocpp.or=
g.

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

<div dir=3D"ltr"><br>W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BC=
ytkownik gmis...@gmail.com napisa=C5=82:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><br><br>On Tuesday, January 3, 2017 at 10:56:05 =
PM UTC+13, <a>m.ce...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(2=
04,204,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr"=
>Hi,<div><br></div><div>I propose to add a enum_cast function that safely c=
asts int value to a target enum type if int value represents a valid enumer=
ator.</div><div><br></div><div style=3D"border:1px solid rgb(187,187,187);b=
ackground-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,1=
36)">template</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D=
"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)">typena=
me</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,0,102)">Enum</span><span style=3D"color:rgb(102,102,0)">,</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">typena=
me</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,0,102)">Int</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span=
 style=3D"color:rgb(0,0,0)"><br>optional</span><span style=3D"color:rgb(102=
,102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)">Enum</span><span s=
tyle=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"> =
enum_cast</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D=
"color:rgb(102,0,102)">Int</span><span style=3D"color:rgb(0,0,0)"> value</s=
pan><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(=
0,0,0)"><br><br>requires</span><span style=3D"color:rgb(102,102,0)">:</span=
><span style=3D"color:rgb(0,0,0)"> is_enum</span><span style=3D"color:rgb(1=
02,102,0)">&lt;</span><font color=3D"#000000"><span style=3D"color:rgb(102,=
0,102)">Enum</span></font><span style=3D"color:rgb(102,102,0)">&gt;,</span>=
<span style=3D"color:rgb(0,0,0)"> is_integral</span><span style=3D"color:rg=
b(102,102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)">Int</span><sp=
an style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0=
)"><br><br></span><span style=3D"color:rgb(0,0,136)">enum</span><span style=
=3D"color:rgb(0,0,0)"> color<br></span><span style=3D"color:rgb(102,102,0)"=
>{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0red </span><span=
 style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)">=
 </span><span style=3D"color:rgb(0,102,102)">1</span><span style=3D"color:r=
gb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0gr=
een </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)">200</span><spa=
n style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"><=
br>=C2=A0 =C2=A0blue </span><span style=3D"color:rgb(102,102,0)">=3D</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102=
)">3</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color=
:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br><br></span><=
span style=3D"color:rgb(0,0,136)">static_assert</span><span style=3D"color:=
rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">enum_cast</span><s=
pan style=3D"color:rgb(0,136,0)">&lt;color&gt;</span><span style=3D"color:r=
gb(102,102,0)"><wbr>(</span><font color=3D"#006666"><span style=3D"color:rg=
b(0,102,102)">200u</span></font><span style=3D"color:rgb(102,102,0)">)</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102=
,0)">=3D=3D</span><span style=3D"color:rgb(0,0,0)"> color</span><span style=
=3D"color:rgb(102,102,0)">::</span><font color=3D"#000000"><span style=3D"c=
olor:rgb(0,0,0)">green</span></font><span style=3D"color:rgb(102,102,0)">);=
</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb=
(0,0,136)">static_assert</span><span style=3D"color:rgb(102,102,0)">(</span=
><span style=3D"color:rgb(0,0,0)">enum_cast</span><span style=3D"color:rgb(=
0,136,0)">&lt;color&gt;</span><span style=3D"color:rgb(102,102,0)"><wbr>(</=
span><span style=3D"color:rgb(0,102,102)">3</span><span style=3D"color:rgb(=
102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D=
"color:rgb(102,102,0)">=3D=3D</span><span style=3D"color:rgb(0,0,0)"> color=
</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:r=
gb(0,0,0)">blue</span><span style=3D"color:rgb(102,102,0)">);</span><span s=
tyle=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)">sta=
tic_assert</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,0)">enum_cast</span><span style=3D"color:rgb(0,136,0)">&l=
t;color&gt;</span><span style=3D"color:rgb(102,102,0)"><wbr>(</span><span s=
tyle=3D"color:rgb(0,102,102)">4</span><span style=3D"color:rgb(102,102,0)">=
)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">=3D=3D</span><span style=3D"color:rgb(0,0,0)"> nullopt</span><sp=
an style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(0,0,0)"=
><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 d=
o 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></di=
v><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 im=
plementation based on reflection may not be optimal,</div><div>I think it s=
hould be implemented with compiler support (i.e. via __builtin_* intrinsic)=
..</div><div><br></div><div>Regards,</div><div>Maciej</div></div></blockquot=
e><div><br></div><div><br></div><div>I was thinking some more about this pr=
oposal. I really think the functionality you suggest=C2=A0is a good idea.</=
div><div>I hope you proceed with a proposal.=C2=A0If you decide not to let =
me know.</div></div></blockquote><div><br></div><div>I&#39;ll try to create=
 a first draft after I get some more comments w.r.t to exceptions.</div><di=
v>For sure baseline API must be exception-free.</div><div>Do we really want=
 to additionally support API that throws on error?</div><div>I&#39;m rather=
 inclined to leave it out - similarly as in to_chars/from_chars.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><br></div><div>I hope this post assists you with your proposal.=C2=A0My=
 suggestions are for your proposal to look something like this:</div><div><=
br></div><div>In &lt;utility&gt; I think add:</div><div><br></div><div>bool=
 template&lt;typename E, typename V&gt; is_enum( V ev )</div><div>{</div><d=
iv>=C2=A0// compiler=C2=A0magic:</div><div>=C2=A0// Calling this routine ca=
uses the compiler to generate or a call a routine</div><div>=C2=A0// that r=
eturns true if the value ev matches one of the enum E&#39;s</div><div>=C2=
=A0// values. otherwise false.</div><div>}</div></div></blockquote><div><br=
></div><div>&#39;is_enum&#39; name is already used in type_traits header.<b=
r></div><div>Also is_enum seems redundant to me, since to_enum already repo=
rts</div><div>if convertion succeeded instead of:</div><div><div class=3D"p=
rettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break=
-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">is_enum</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">MyEnum</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">139</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">))</span></div></code></div><br></div><=
div>you could write:</div><div><div class=3D"prettyprint" style=3D"border: =
1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(=
250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">to_enum</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">MyEnum</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;(</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">139</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">).</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
is_valid</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)<=
/span></div></code></div><br></div><div>or even:</div><div><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">to_enum</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">MyEnum</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #066;" class=3D"styled-by-prettify">139</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">))</span></div></code></div>if we add ex=
plicit bool convertion operator for to_enum_result.</div><div><br></div><di=
v><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><br></div><div>// Users call this routine to convert an integer to an e=
num.</div><div>They call this if they=C2=A0aren&#39;t sure about=C2=A0their=
 conversion data</div><div>// and don&#39;t mind exceptions and want simple=
 like std::to_string</div><div>// They might expect such a function to be p=
resent.</div><div>// Though to be fair I&#39;m not sure we should encourage=
 this?</div><div>//=C2=A0They should get good error messages.</div><div>tem=
plate&lt;typename E, typename V&gt; E to_enum_or_throw(V ev)</div><div>{</d=
iv><div>=C2=A0if (is_enum&lt;E&gt;(ev))</div><div>=C2=A0=C2=A0return static=
_cast&lt;E&gt;(ev);</div><div>=C2=A0throw make_bad_enum&lt;E,V&gt;(ev);=C2=
=A0</div><div>}</div><div><br></div><div><div>template&lt;typename E&gt; cl=
ass to_enum_result</div><div>{</div><div>public:</div><div>=C2=A0E enum_val=
ue;</div><div>=C2=A0bool is_valid;</div><div>};</div><div><br></div></div><=
div>// Call this if you can&#39;t use/afford exceptions. It seems optimal?<=
/div><div>template&lt;typename E, typename V&gt; to_enum_result&lt;E&gt; to=
_enum( V ev ) noexcept</div><div>{</div><div>=C2=A0 if (is_enum&lt;E, V&gt;=
(ev))</div><div>=C2=A0=C2=A0=C2=A0 return to_enum_result&lt;E&gt;{true,stat=
ic_<wbr>cast&lt;E&gt;(ev)};</div><div>=C2=A0 return to_enum_result&lt;E&gt;=
{false, E{}};</div><div>}</div><div><br></div><div>// if is_valid=C2=A0retu=
rns false after to_enum, the user can use these routines to get good error<=
/div><div>// messages / report how they wish when they wish:</div></div></b=
lockquote><div><br></div><div>As there is only one possible reason why the =
to_enum failed<br></div><div>(integer didn&#39;t match any enumerator of ta=
rget enumeration type)=C2=A0</div><div>I see no reason for following functi=
ons and classes.</div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div><br></div><div><div><div>// Some type that hol=
ds the largest enum value ever possible.</div><div><div>using std::any_enum=
_value =3D unspecified;</div><div><br></div></div></div><div>class bad_enum=
</div><div>{</div><div>public:</div><div>=C2=A0=C2=A0=C2=A0std::any_any_enu=
m_value bad_enum_value;</div><div>=C2=A0=C2=A0 std::string enum_type_name;<=
br>};</div><div>=C2=A0</div>template&lt;typename E, typename V&gt; std::bad=
_enum make_bad_enum(V ev)</div><div>{</div><div>=C2=A0// Use some compiler =
magic to get the name of the name of the=C2=A0enum type=C2=A0E.</div><div>=
=C2=A0// Use it to construct a message like:</div><div>=C2=A0// &#39;{ev}&#=
39; is not a legal value for an enum of type &#39;{E}&#39;</div><div>=C2=A0=
return std::range_error(msg);</div><div>}</div></div></blockquote><div><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><b=
r></div><div><br></div><div><div>Note in all methods:</div><div>* constrain=
 E to only be an enum or enum class type.</div><div>* constrain V to only a=
ccept integral types.</div><div><br></div></div><div>Observations</div><div=
>------------</div><div><br></div><div>* is_enum() is there for people who =
just need to check validity and no more.</div><div>and saves the user writi=
ng redudant boiler plate code that the compiler does better.</div><div>* to=
_enum_or_throw() is there for people who find simple works for them.</div><=
div>its name makes it clear that exceptions can happen.</div><div>* to_enum=
() is there for people who need performance and without exceptions.</div></=
div></blockquote><div>=C2=A0</div><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>* We don&#39;t depend on optional.=C2=A0</div><=
/div></blockquote><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"><div>* Means &lt;utility&gt; isn&#39;t dependent on optional if we put=
 it there.</div><div><div>* make_bad_enum avoids making bad_enum a template=
..</div>* make_bad_enum gives us good error messages and better than bad_opt=
ional_access.</div><div>*=C2=A0make_bad_enum means=C2=A0we can=C2=A0create =
an=C2=A0error class=C2=A0for reporting elsewhere -=C2=A0we don&#39;t have t=
o throw it.</div><div>*=C2=A0make_bad_enum means we don&#39;t expose any ge=
t enum_type_name function the reflection people will reproduce.</div><div>*=
 make_bad_enum gives people flexibility to throw when they are ready instea=
d of forcing a throw as soon as conversion fails.</div><div>* Might play we=
ll with structured bindings.</div><div>=C2=A0<br></div></div></blockquote><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><di=
v>Main choices:</div><div>*=C2=A0We could=C2=A0model this on optional=C2=A0=
i.e. include=C2=A0has_value etc.=C2=A0but it=C2=A0seems simpler not to. Eit=
her way is fine to me.</div><div>I&#39;m not sure such safety is warranted =
and=C2=A0from_chars/to_chars is pretty simple too so I went that way.</div>=
</div></blockquote><div><br></div><div>As committee already stated their pr=
eference in from_chars/to_chars case, consider me convinced.</div><div>I wi=
ll use &#39;to_enum_result&#39; in draft.</div><div>Also I&#39;ll use &#39;=
to_enum&#39; as function name to match &#39;to_chars&#39; convention.</div>=
<div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div>* The=C2=A0caller has all the utilities here to build that or=
 work with=C2=A0optional directly -=C2=A0whatever=C2=A0they need.</div><div=
>* I think=C2=A0being able to get=C2=A0good error messages on failure is im=
portant.</div><div>This tries to=C2=A0enable making decent errors available=
 no matter what method or=C2=A0is used.</div><div>=C2=A0i.e. include the en=
um type name and bad value in the error.=C2=A0</div></div></div></blockquot=
e><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>* I&#3=
9;ve=C2=A0used std::range_error as the exception type=C2=A0for failure but =
another may be appropriate.</div><div>bad_enum as an exception=C2=A0type=C2=
=A0contains the value that was bad and the type name that it failed to conv=
ert to.</div><div>This=C2=A0would allow people to extract the values to con=
struct their own error messages (perhaps in other languages like French etc=
..).</div><div><br></div><div>If std::bad_enum is too much API, that could b=
e dropped for just std::range_error or something as long a it contains</div=
><div>a full description of the error I think that&#39;s fine.</div></div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><br></div><div>I&#39;d like to know what you and the=C2=A0Committee&#39=
;s disposition towards=C2=A0these ideas and views. Hope this helps.</div></=
div></blockquote><div><br></div><div><br></div><div><div>Thanks for your va=
luable input.</div><div><br></div><div>Regards,</div><div>Maciej</div></div=
><div>=C2=A0</div><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"><div><br></div><div>Thanks</div><div>GM</div></div></blockquote></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/a35d9f20-9e4f-4789-b7e5-5cb08f99e6bd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a35d9f20-9e4f-4789-b7e5-5cb08f99e6bd=
%40isocpp.org</a>.<br />

------=_Part_1641_1102541637.1484062268062--

------=_Part_1640_282778673.1484062268061--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 10 Jan 2017 10:49:28 -0500
Raw View
On 2017-01-10 10:31, m.cencora@gmail.com 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).

--
Matthew

--
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/58750288.5080004%40gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 10 Jan 2017 08:20:11 -0800 (PST)
Raw View
------=_Part_5088_1591528047.1484065211089
Content-Type: multipart/alternative;
 boundary="----=_Part_5089_1816503418.1484065211089"

------=_Part_5089_1816503418.1484065211089
Content-Type: text/plain; charset=UTF-8

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. If you want an API to throw, you want it
to throw a *meaningful* exception type, not the same kind of exception that
20 other APIs throw.

So yes, we really do need to support a throwing API. I say we should have 3
interfaces:

* `can_enum_cast`: specifies whether the value is in an enumeration. This
is where the compiler magic comes in, of course.
* `enum_cast`: Converts to the enumeration type, or throws if it cannot.
* `enum_cast_opt`: Returns an `optional<Enum>`.

The first allows you to build whatever tools you want. But we have default
tools for C++'s standard mechanisms: throwing and `optional`.

--
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/e85f0d46-f244-42fe-a276-b4e18b3d627f%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, January 10, 2017 at 10:49:34 AM UTC-5, Matthew=
 Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2017-01-10 1=
0:31, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"BG=
0SGbfzBQAJ" 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> wrote:
<br>&gt; For sure baseline API must be exception-free.
<br>&gt; Do we really want to additionally support API that throws on error=
?
<br>
<br>I *really* hope we can use something like std::expected; this is a
<br>textbook use case for that, and makes it trivial to have a
<br>throw-on-error API (just grab the value from the expected without
<br>checking it first; this will turn around and throw if the value is not
<br>there).<br></blockquote><div><br>But the fact that it&#39;s throwing th=
e wrong exception makes it useless from an exception handling perspective. =
If you want an API to throw, you want it to throw a <i>meaningful</i> excep=
tion type, not the same kind of exception that 20 other APIs throw.<br><br>=
So yes, we really do need to support a throwing API. I say we should have 3=
 interfaces:<br><br>* `can_enum_cast`: specifies whether the value is in an=
 enumeration. This is where the compiler magic comes in, of course.<br>* `e=
num_cast`: Converts to the enumeration type, or throws if it cannot.<br>* `=
enum_cast_opt`: Returns an `optional&lt;Enum&gt;`.<br><br>The first allows =
you to build whatever tools you want. But we have default tools for C++&#39=
;s standard mechanisms: throwing and `optional`.<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/e85f0d46-f244-42fe-a276-b4e18b3d627f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e85f0d46-f244-42fe-a276-b4e18b3d627f=
%40isocpp.org</a>.<br />

------=_Part_5089_1816503418.1484065211089--

------=_Part_5088_1591528047.1484065211089--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 10 Jan 2017 11:59:13 -0500
Raw View
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.

> * `enum_cast`: Converts to the enumeration type, or throws if it cannot.
> * `enum_cast_opt`: Returns an `optional<Enum>`.

These can be combined with no loss of function into one API that returns
a std::expected or similar.

--
Matthew

--
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/587512E1.1050708%40gmail.com.

.


Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Tue, 10 Jan 2017 18:01:45 +0100
Raw View
Nicols proposal is very similar to mine, except that I do not have an
enum_cast_opt. And I do not really see a reason to have this option.
I believe that noone would use that option. Why write

std::optional<Enum> e = enum_opt_cast<Enum>(x);
if (e)
{
    normal processing
}
else
{
    handle conversion failure
}

instead of

if (is_enum<Enum>(e))
{
    Enum e = to_enum<Enum>(x);
    normal processing
}
else
{
    handle conversion failure
}
?
Things to consider when implementing:

What do you do if you have an enum with some same_valued elements
(enum E { ea = 0, eb = 0})? My implementation forbids this.
It could also be useful to have an ordinal position:

enum E
{
 ea = 1000,
 eb = -1000,
 ec = 32
};

static_assert(to_ordinal<Enum>(ea) == 0,"??");
static_assert(to_ordinal<Enum>(eb) == 1,"??");
static_assert(to_ordinal<Enum>(ec) == 2,"??");

I have found uses for this in my code.

/Peter

On Tue, Jan 10, 2017 at 5:20 PM, Nicol Bolas <jmckesson@gmail.com> 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 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. If you want an API to throw, you want it to
> throw a meaningful exception type, not the same kind of exception that 20
> other APIs throw.
>
> So yes, we really do need to support a throwing API. I say we should have 3
> interfaces:
>
> * `can_enum_cast`: specifies whether the value is in an enumeration. This is
> where the compiler magic comes in, of course.
> * `enum_cast`: Converts to the enumeration type, or throws if it cannot.
> * `enum_cast_opt`: Returns an `optional<Enum>`.
>
> The first allows you to build whatever tools you want. But we have default
> tools for C++'s standard mechanisms: throwing and `optional`.
>
> --
> 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/e85f0d46-f244-42fe-a276-b4e18b3d627f%40isocpp.org.

--
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/CANPtknwzegDLrDFrMoc5U9Z1y52PBZAC2BtQ%3DiS6Eur2A6f7NQ%40mail.gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 10 Jan 2017 13:31:07 -0500
Raw View
On 2017-01-10 12:01, Peter Koch Larsen wrote:
> What do you do if you have an enum with some same_valued elements
> (enum E { ea = 0, eb = 0})? My implementation forbids this.

Why?

  E x = ea;
  assert(x == eb); // will succeed

Such a prohibition makes some sense when converting an enum to a string
(or to its ordinal), but there is no problem when converting an int to
an enum (or a string to an enum, for that matter).

--
Matthew

--
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/5875286B.7040604%40gmail.com.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 10 Jan 2017 19:49:01 +0100
Raw View
This is a multi-part message in MIME format.
--------------5BE1BAD55E64866D1B74C1D4
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 10/01/2017 =C3=A0 16:31, m.cencora@gmail.com a =C3=A9crit :
>
> W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik=20
> gmis...@gmail.com napisa=C5=82:
>
>
>
>     On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13,
>     m.ce...@gmail.com wrote:
>
>         Hi,
>
>
> I'll try to create a first draft after I get some more comments w.r.t=20
> to exceptions.
> For sure baseline API must be exception-free.
> Do we really want to additionally support API that throws on error?
> I'm rather inclined to leave it out - similarly as in to_chars/from_chars=
..
>
>
>     I hope this post assists you with your proposal. My suggestions
>     are for your proposal to look something like this:
>
>     In <utility> I think add:
>
>     bool template<typename E, typename V> is_enum( V ev )
>     {
>      // compiler magic:
>      // Calling this routine causes the compiler to generate or a call
>     a routine
>      // that returns true if the value ev matches one of the enum E's
>      // values. otherwise false.
>     }
>
>
> 'is_enum' name is already used in type_traits header.
> Also is_enum seems redundant to me, since to_enum already reports
> if convertion succeeded instead of:
> |
> if(is_enum<MyEnum>(139))
> |
>
> you could write:
> |
> if(to_enum<MyEnum>(139).is_valid)
> |
>
> or even:
> |
> if(to_enum<MyEnum>(139))
> |
> if we add explicit bool convertion operator for to_enum_result.
>
>
I believe we need two checking functions:
* is_enumerator : checks if the explicit conversion from the integer is=20
one of the explicit enumerators
* is_in_enum_range: checks if the integer is in the range of valid=20
values. This is the precondition of the static_cast.

IIUC when the underlying type is explicit, the range of values are the=20
range of the underlying type. However when the underlying type is=20
implicit the range goes from the min to the max of the values of the=20
enumerators.

Until we don't have an enum that restrict the validity of the values to=20
his explicit enumerators, the range check seems to be useful at least to=20
avoid UB.

It is easy to build then whatever we want on top of these checks.
to_enum: throw exception
to_enum_or
try_to_enum: return optional or whatever is more appropriated.

Having good names for both check variants will surely take some time.

Note that we don't know yet if expected<T,E> will throw bad_expected or E.

I believe we can start by a proposal that includes only the checks and=20
surface the possible usage.

Vicente

P.S. Both checks can be built on top of the static reflection interface.

--=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/e779f1ca-8f05-7eda-72c8-89a9a5215c62%40wanadoo.f=
r.

--------------5BE1BAD55E64866D1B74C1D4
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 10/01/2017 =C3=A0 16:31,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:m.cencora@gmail.=
com">m.cencora@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:a35d9f20-9e4f-4789-b7e5-5cb08f99e6bd@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik
        <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:gmis...@gmail.=
com">gmis...@gmail.com</a> napisa=C5=82:
        <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"><br>
            <br>
            On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, <a
              moz-do-not-send=3D"true">m.ce...@gmail.com</a> wrote:
            <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width=
:1px;border-left-style:solid">
              <div dir=3D"ltr">Hi,
                <div><br>
                </div>
              </div>
            </blockquote>
          </div>
        </blockquote>
        <br>
        <div>I'll try to create a first draft after I get some more
          comments w.r.t to exceptions.</div>
        <div>For sure baseline API must be exception-free.</div>
        <div>Do we really want to additionally support API that throws
          on error?</div>
        <div>I'm rather inclined to leave it out - similarly as in
          to_chars/from_chars.</div>
        <div>=C2=A0</div>
        <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><br>
            </div>
            <div>I hope this post assists you with your proposal.=C2=A0My
              suggestions are for your proposal to look something like
              this:</div>
            <div><br>
            </div>
            <div>In &lt;utility&gt; I think add:</div>
            <div><br>
            </div>
            <div>bool template&lt;typename E, typename V&gt; is_enum( V
              ev )</div>
            <div>{</div>
            <div>=C2=A0// compiler=C2=A0magic:</div>
            <div>=C2=A0// Calling this routine causes the compiler to
              generate or a call a routine</div>
            <div>=C2=A0// that returns true if the value ev matches one of
              the enum E's</div>
            <div>=C2=A0// values. otherwise false.</div>
            <div>}</div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>'is_enum' name is already used in type_traits header.<br>
        </div>
        <div>Also is_enum seems redundant to me, since to_enum already
          reports</div>
        <div>if convertion succeeded instead of:</div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">if</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">is_en=
um</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">MyEnu=
m</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(=
</span><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">139</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">))</s=
pan></div>
            </code></div>
          <br>
        </div>
        <div>you could write:</div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">if</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">to_en=
um</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">MyEnu=
m</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(=
</span><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">139</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">).</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">is_va=
lid</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an></div>
            </code></div>
          <br>
        </div>
        <div>or even:</div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">if</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">to_en=
um</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">MyEnu=
m</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(=
</span><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">139</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">))</s=
pan></div>
            </code></div>
          if we add explicit bool convertion operator for
          to_enum_result.</div>
        <div><br>
        </div>
        <div><br>
        </div>
      </div>
    </blockquote>
    I believe we need two checking functions:<br>
    * is_enumerator : checks if the explicit conversion from the integer
    is one of the explicit enumerators<br>
    * is_in_enum_range: checks if the integer is in the range of valid
    values. This is the precondition of the static_cast.<br>
    <br>
    IIUC when the underlying type is explicit, the range of values are
    the range of the underlying type. However when the underlying type
    is implicit the range goes from the min to the max of the values of
    the enumerators.<br>
    <br>
    Until we don't have an enum that restrict the validity of the values
    to his explicit enumerators, the range check seems to be useful at
    least to avoid UB.<br>
    <br>
    It is easy to build then whatever we want on top of these checks.<br>
    to_enum: throw exception<br>
    to_enum_or<br>
    try_to_enum: return optional or whatever is more appropriated.<br>
    <br>
    Having good names for both check variants will surely take some
    time.<br>
    <br>
    Note that we don't know yet if expected&lt;T,E&gt; will throw
    bad_expected or E.<br>
    <br>
    I believe we can start by a proposal that includes only the checks
    and surface the possible usage.<br>
    <br>
    Vicente <br>
    <br>
    P.S. Both checks can be built on top of the static reflection
    interface.<br>
  </body>
</html>

<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/e779f1ca-8f05-7eda-72c8-89a9a5215c62%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e779f1ca-8f05-7eda-72c8-89a9a5215c62=
%40wanadoo.fr</a>.<br />

--------------5BE1BAD55E64866D1B74C1D4--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 10 Jan 2017 20:00:27 +0100
Raw View
Le 10/01/2017 =C3=A0 18:01, Peter Koch Larsen a =C3=A9crit :
> Nicols proposal is very similar to mine, except that I do not have an
> enum_cast_opt. And I do not really see a reason to have this option.
> I believe that noone would use that option. Why write
>
> std::optional<Enum> e =3D enum_opt_cast<Enum>(x);
Because optional is a monad and you can do much more than checking for=20
whether it is present?
Anyway, all these functions could be defined in top of the checks.
> if (e)
> {
>      normal processing
> }
> else
> {
>      handle conversion failure
> }
>
> instead of
>
> if (is_enum<Enum>(e))
> {
>      Enum e =3D to_enum<Enum>(x);
>      normal processing
> }
> else
> {
>      handle conversion failure
> }
> ?
> Things to consider when implementing:
>
> What do you do if you have an enum with some same_valued elements
> (enum E { ea =3D 0, eb =3D 0})? My implementation forbids this.
What is the advantage to forbidding it.
> It could also be useful to have an ordinal position:
>
> enum E
> {
>   ea =3D 1000,
>   eb =3D -1000,
>   ec =3D 32
> };
>
> static_assert(to_ordinal<Enum>(ea) =3D=3D 0,"??");
> static_assert(to_ordinal<Enum>(eb) =3D=3D 1,"??");
> static_assert(to_ordinal<Enum>(ec) =3D=3D 2,"??");
I'm working on a proposal on ordinal types. We can consider that an enum=20
having all the enumerators different is an ordinal type if we consider=20
only these enumerators are valid. We could as well consider that any=20
Integral type is an ordinal type.
This proposal will include also the value associated to a position and=20
on top of that ordinal_array, ordinal_set and ordinal_range.

https://github.com/viboes/std-make/tree/master/include/experimental/fundame=
ntal/v3/ordinal

Vicente

--=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/edb1413c-5a47-39ff-0c17-587a27ca86f8%40wanadoo.f=
r.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 10 Jan 2017 11:09:42 -0800 (PST)
Raw View
------=_Part_1667_1998639733.1484075382524
Content-Type: multipart/alternative;
 boundary="----=_Part_1668_1585808523.1484075382525"

------=_Part_1668_1585808523.1484075382525
Content-Type: text/plain; charset=UTF-8

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.

--
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/d974c090-2898-4397-8d42-bbc1682158c7%40isocpp.org.

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

<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: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2017-01-10 1=
1:20, Nicol 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>

<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/d974c090-2898-4397-8d42-bbc1682158c7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d974c090-2898-4397-8d42-bbc1682158c7=
%40isocpp.org</a>.<br />

------=_Part_1668_1585808523.1484075382525--

------=_Part_1667_1998639733.1484075382524--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 10 Jan 2017 11:30:40 -0800 (PST)
Raw View
------=_Part_718_171003813.1484076640633
Content-Type: multipart/alternative;
 boundary="----=_Part_719_1784432563.1484076640633"

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



On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com <javascript:> a =C3=A9crit =
:
>
>
> W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik=20
> gmis...@gmail.com napisa=C5=82:=20
>>
>>
>>
>> On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com=20
>> wrote:=20
>>>
>>> Hi,=20
>>>
>>>
> I'll try to create a first draft after I get some more comments w.r.t to=
=20
> exceptions.
> For sure baseline API must be exception-free.
> Do we really want to additionally support API that throws on error?
> I'm rather inclined to leave it out - similarly as in to_chars/from_chars=
..
> =20
>
>>
>> I hope this post assists you with your proposal. My suggestions are for=
=20
>> your proposal to look something like this:
>>
>> In <utility> I think add:
>>
>> bool template<typename E, typename V> is_enum( V ev )
>> {
>>  // compiler magic:
>>  // Calling this routine causes the compiler to generate or a call a=20
>> routine
>>  // that returns true if the value ev matches one of the enum E's
>>  // values. otherwise false.
>> }
>>
>
> 'is_enum' name is already used in type_traits header.
> Also is_enum seems redundant to me, since to_enum already reports
> if convertion succeeded instead of:
> if (is_enum<MyEnum>(139))
>
> you could write:
> if (to_enum<MyEnum>(139).is_valid)
>
> or even:
> if (to_enum<MyEnum>(139))
> if we add explicit bool convertion operator for to_enum_result.
>
>
> I believe we need two checking functions:
> * is_enumerator : checks if the explicit conversion from the integer is=
=20
> one of the explicit enumerators
> * is_in_enum_range: checks if the integer is in the range of valid values=
..=20
> This is the precondition of the static_cast.
>
> IIUC when the underlying type is explicit, the range of values are the=20
> range of the underlying type. However when the underlying type is implici=
t=20
> the range goes from the min to the max of the values of the enumerators.
>

Right, but `is_enumerator` is a functional superset of `is_in_enum_range`.=
=20
Do people really need to ask *only* if a value is in the range of an=20
enumerator?

--=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/24e58aad-ecbc-4c83-a21b-de56ea4c1db0%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, =
Vicente J. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 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 10/01/2017 =C3=A0 16:31,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"H0=
6U3IL9BQAJ" 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"><br>
        W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik
        <a>gmis...@gmail.com</a> napisa=C5=82:
        <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
          <div dir=3D"ltr"><br>
            <br>
            On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, <a>m.ce...@g=
mail.com</a> wrote:
            <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:=
1px;border-left-style:solid">
              <div dir=3D"ltr">Hi,
                <div><br>
                </div>
              </div>
            </blockquote>
          </div>
        </blockquote>
        <br>
        <div>I&#39;ll try to create a first draft after I get some more
          comments w.r.t to exceptions.</div>
        <div>For sure baseline API must be exception-free.</div>
        <div>Do we really want to additionally support API that throws
          on error?</div>
        <div>I&#39;m rather inclined to leave it out - similarly as in
          to_chars/from_chars.</div>
        <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 dir=3D"ltr">
            <div><br>
            </div>
            <div>I hope this post assists you with your proposal.=C2=A0My
              suggestions are for your proposal to look something like
              this:</div>
            <div><br>
            </div>
            <div>In &lt;utility&gt; I think add:</div>
            <div><br>
            </div>
            <div>bool template&lt;typename E, typename V&gt; is_enum( V
              ev )</div>
            <div>{</div>
            <div>=C2=A0// compiler=C2=A0magic:</div>
            <div>=C2=A0// Calling this routine causes the compiler to
              generate or a call a routine</div>
            <div>=C2=A0// that returns true if the value ev matches one of
              the enum E&#39;s</div>
            <div>=C2=A0// values. otherwise false.</div>
            <div>}</div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>&#39;is_enum&#39; name is already used in type_traits header.<=
br>
        </div>
        <div>Also is_enum seems redundant to me, since to_enum already
          reports</div>
        <div>if convertion succeeded instead of:</div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">if</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">is_enum</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span style=3D"co=
lor:#066">139</span><span style=3D"color:#660">))</span></div>
            </code></div>
          <br>
        </div>
        <div>you could write:</div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">if</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">to_enum</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span style=3D"co=
lor:#066">139</span><span style=3D"color:#660">).</span><span style=3D"colo=
r:#000">is_valid</span><span style=3D"color:#660"><wbr>)</span></div>
            </code></div>
          <br>
        </div>
        <div>or even:</div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">if</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">to_enum</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span style=3D"co=
lor:#066">139</span><span style=3D"color:#660">))</span></div>
            </code></div>
          if we add explicit bool convertion operator for
          to_enum_result.</div>
        <div><br>
        </div>
        <div><br>
        </div>
      </div>
    </blockquote>
    I believe we need two checking functions:<br>
    * is_enumerator : checks if the explicit conversion from the integer
    is one of the explicit enumerators<br>
    * is_in_enum_range: checks if the integer is in the range of valid
    values. This is the precondition of the static_cast.<br>
    <br>
    IIUC when the underlying type is explicit, the range of values are
    the range of the underlying type. However when the underlying type
    is implicit the range goes from the min to the max of the values of
    the enumerators.<br></div></blockquote><div><br>Right, but `is_enumerat=
or` is a functional superset of `is_in_enum_range`. Do people really need t=
o ask <i>only</i> if a value is in the range of an enumerator?<br></div></d=
iv>

<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/24e58aad-ecbc-4c83-a21b-de56ea4c1db0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/24e58aad-ecbc-4c83-a21b-de56ea4c1db0=
%40isocpp.org</a>.<br />

------=_Part_719_1784432563.1484076640633--

------=_Part_718_171003813.1484076640633--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 10 Jan 2017 23:26:08 +0100
Raw View
This is a multi-part message in MIME format.
--------------BF1F89400088942B4377F680
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit :
>
>
> On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
>     Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com <javascript:> a =C3=A9c=
rit :
>>
>>     W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik
>>     gmis...@gmail.com napisa=C5=82:
>>
>>
>>
>>         On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13,
>>         m.ce...@gmail.com wrote:
>>
>>             Hi,
>>
>>
>>     I'll try to create a first draft after I get some more comments
>>     w.r.t to exceptions.
>>     For sure baseline API must be exception-free.
>>     Do we really want to additionally support API that throws on error?
>>     I'm rather inclined to leave it out - similarly as in
>>     to_chars/from_chars.
>>
>>
>>         I hope this post assists you with your proposal. My
>>         suggestions are for your proposal to look something like this:
>>
>>         In <utility> I think add:
>>
>>         bool template<typename E, typename V> is_enum( V ev )
>>         {
>>          // compiler magic:
>>          // Calling this routine causes the compiler to generate or a
>>         call a routine
>>          // that returns true if the value ev matches one of the enum E'=
s
>>          // values. otherwise false.
>>         }
>>
>>
>>     'is_enum' name is already used in type_traits header.
>>     Also is_enum seems redundant to me, since to_enum already reports
>>     if convertion succeeded instead of:
>>     |
>>     if(is_enum<MyEnum>(139))
>>     |
>>
>>     you could write:
>>     |
>>     if(to_enum<MyEnum>(139).is_valid)
>>     |
>>
>>     or even:
>>     |
>>     if(to_enum<MyEnum>(139))
>>     |
>>     if we add explicit bool convertion operator for to_enum_result.
>>
>>
>     I believe we need two checking functions:
>     * is_enumerator : checks if the explicit conversion from the
>     integer is one of the explicit enumerators
>     * is_in_enum_range: checks if the integer is in the range of valid
>     values. This is the precondition of the static_cast.
>
>     IIUC when the underlying type is explicit, the range of values are
>     the range of the underlying type. However when the underlying type
>     is implicit the range goes from the min to the max of the values
>     of the enumerators.
>
>
> Right, but `is_enumerator` is a functional superset of=20
> `is_in_enum_range`. Do people really need to ask /only/ if a value is=20
> in the range of an enumerator?
I don't follow you. You surely wanted to say subset

The standard says in 7.2/8 :

     6.

        8 For an enumeration whose underlying type is fixed, the values
        of the enumeration are the values of the underlying type.
        Otherwise, for an enumeration where emin is the smallest
        enumerator and emax is the largest, the values of the
        enumeration are the values in the range bmin to bmax, defined as
        follows: Let K be 1 for a two=E2=80=99s complement representation a=
nd 0
        for a ones=E2=80=99 complement or sign-magnitude representation. bm=
ax is
        the smallest value greater than or equal to max(|emin| =E2=88=92 K,
        |emax|) and equal to 2M =E2=88=92 1, where M is a non-negative inte=
ger.
        bmin is zero if emin is non-negative and =E2=88=92(bmax + K) otherw=
ise.
        The size of the smallest bit-field large enough to hold all the
        values of the enumeration type is max(M,1) if bmin is zero and M
        + 1 otherwise. *It is possible to define an enumeration that has
        values not defined by any of its enumerators.* If the
        enumerator-list is empty, the values of the enumeration are as
        if the enumeration had a single enumerator with value 0.

    C++ International Standa

For me enumerators are any one of the named enum values. This set is a=20
subset  not a superset of the range of valid values.

As I said, until we don't have enums that consists only of the=20
enumerators, there would be always the need to check if a value is a=20
valid value for the enumeration.

We could define a class that accepts only the enumerators as valid=20
values, but the language enums can accept more values.
This is way I believe that the two checks are needed.

I don't know why the new C++11 enum with an explicit underlying type=20
have a different range of valid values.
I'll be interested in knowing the rationale.

Vicente

--=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/040e99e3-8f07-409f-3a47-ebdfb2bfb465%40wanadoo.f=
r.

--------------BF1F89400088942B4377F680
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 10/01/2017 =C3=A0 20:30, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:24e58aad-ecbc-4c83-a21b-de56ea4c1db0@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J.
        Botet Escriba wrote:
        <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" text=3D"#000000">
            <div>Le 10/01/2017 =C3=A0 16:31, <a moz-do-not-send=3D"true"
                href=3D"javascript:" target=3D"_blank"
                gdf-obfuscated-mailto=3D"H06U3IL9BQAJ" rel=3D"nofollow"
                onmousedown=3D"this.href=3D'javascript:';return true;"
                onclick=3D"this.href=3D'javascript:';return true;">m.ce...@=
gmail.com</a>
              a =C3=A9crit=C2=A0:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr"><br>
                W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1
                u=C5=BCytkownik <a moz-do-not-send=3D"true">gmis...@gmail.c=
om</a>
                napisa=C5=82:
                <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"><br>
                    <br>
                    On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, <a
                      moz-do-not-send=3D"true">m.ce...@gmail.com</a>
                    wrote:
                    <blockquote class=3D"gmail_quote" style=3D"margin:0px
                      0px 0px
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width=
:1px;border-left-style:solid">
                      <div dir=3D"ltr">Hi,
                        <div><br>
                        </div>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
                <br>
                <div>I'll try to create a first draft after I get some
                  more comments w.r.t to exceptions.</div>
                <div>For sure baseline API must be exception-free.</div>
                <div>Do we really want to additionally support API that
                  throws on error?</div>
                <div>I'm rather inclined to leave it out - similarly as
                  in to_chars/from_chars.</div>
                <div>=C2=A0</div>
                <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><br>
                    </div>
                    <div>I hope this post assists you with your
                      proposal.=C2=A0My suggestions are for your proposal t=
o
                      look something like this:</div>
                    <div><br>
                    </div>
                    <div>In &lt;utility&gt; I think add:</div>
                    <div><br>
                    </div>
                    <div>bool template&lt;typename E, typename V&gt;
                      is_enum( V ev )</div>
                    <div>{</div>
                    <div>=C2=A0// compiler=C2=A0magic:</div>
                    <div>=C2=A0// Calling this routine causes the compiler =
to
                      generate or a call a routine</div>
                    <div>=C2=A0// that returns true if the value ev matches
                      one of the enum E's</div>
                    <div>=C2=A0// values. otherwise false.</div>
                    <div>}</div>
                  </div>
                </blockquote>
                <div><br>
                </div>
                <div>'is_enum' name is already used in type_traits
                  header.<br>
                </div>
                <div>Also is_enum seems redundant to me, since to_enum
                  already reports</div>
                <div>if convertion succeeded instead of:</div>
                <div>
                  <div style=3D"border:1px solid
                    rgb(187,187,187);word-wrap:break-word;background-color:=
rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span
                          style=3D"color:#000"> </span><span
                          style=3D"color:#660">(</span><span
                          style=3D"color:#000">is_enum</span><span
                          style=3D"color:#660">&lt;</span><span
                          style=3D"color:#606">MyEnum</span><span
                          style=3D"color:#660">&gt;(</span><span
                          style=3D"color:#066">139</span><span
                          style=3D"color:#660">))</span></div>
                    </code></div>
                  <br>
                </div>
                <div>you could write:</div>
                <div>
                  <div style=3D"border:1px solid
                    rgb(187,187,187);word-wrap:break-word;background-color:=
rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span
                          style=3D"color:#000"> </span><span
                          style=3D"color:#660">(</span><span
                          style=3D"color:#000">to_enum</span><span
                          style=3D"color:#660">&lt;</span><span
                          style=3D"color:#606">MyEnum</span><span
                          style=3D"color:#660">&gt;(</span><span
                          style=3D"color:#066">139</span><span
                          style=3D"color:#660">).</span><span
                          style=3D"color:#000">is_valid</span><span
                          style=3D"color:#660"><wbr>)</span></div>
                    </code></div>
                  <br>
                </div>
                <div>or even:</div>
                <div>
                  <div style=3D"border:1px solid
                    rgb(187,187,187);word-wrap:break-word;background-color:=
rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span
                          style=3D"color:#000"> </span><span
                          style=3D"color:#660">(</span><span
                          style=3D"color:#000">to_enum</span><span
                          style=3D"color:#660">&lt;</span><span
                          style=3D"color:#606">MyEnum</span><span
                          style=3D"color:#660">&gt;(</span><span
                          style=3D"color:#066">139</span><span
                          style=3D"color:#660">))</span></div>
                    </code></div>
                  if we add explicit bool convertion operator for
                  to_enum_result.</div>
                <div><br>
                </div>
                <div><br>
                </div>
              </div>
            </blockquote>
            I believe we need two checking functions:<br>
            * is_enumerator : checks if the explicit conversion from the
            integer is one of the explicit enumerators<br>
            * is_in_enum_range: checks if the integer is in the range of
            valid values. This is the precondition of the static_cast.<br>
            <br>
            IIUC when the underlying type is explicit, the range of
            values are the range of the underlying type. However when
            the underlying type is implicit the range goes from the min
            to the max of the values of the enumerators.<br>
          </div>
        </blockquote>
        <div><br>
          Right, but `is_enumerator` is a functional superset of
          `is_in_enum_range`. Do people really need to ask <i>only</i>
          if a value is in the range of an enumerator?<br>
        </div>
      </div>
    </blockquote>
    I don't follow you. You surely wanted to say subset<br>
    <br>
    The standard says in 7.2/8 :
    <blockquote>
      <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8">
      <div class=3D"page" title=3D"Page 190">
        <div class=3D"layoutArea">
          <div class=3D"column">
            <ol start=3D"6" style=3D"list-style-type: none">
              <li>
                <p><span style=3D"font-size: 7.000000pt; font-family:
                    'LMRoman7'; vertical-align: 2.000000pt">8 =C2=A0</span>=
<span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">For an enumeration whose underlying
                    type is fixed, the values of the enumeration are the
                    values of the
                    underlying type. Otherwise, for an enumeration where
                  </span><span style=3D"font-size: 10.000000pt;
                    font-family: 'LMMathItalic10'">e</span><span
                    style=3D"font-size: 7.000000pt; font-family:
                    'LMRoman7'; font-style: italic; vertical-align:
                    -1.000000pt">min </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">is the
                    smallest enumerator and </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">e</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMRoman7'; font-style:
                    italic; vertical-align: -1.000000pt">max </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is the
                    largest, the values of the enumeration are the
                    values in the range </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">b</span><sp=
an
                    style=3D"font-size: 7.000000pt; font-family:
                    'LMMathItalic7'; vertical-align: -1.000000pt">min </spa=
n><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">to </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">b</span><sp=
an
                    style=3D"font-size: 7.000000pt; font-family:
                    'LMMathItalic7'; vertical-align: -1.000000pt">max</span=
><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">, defined as follows: Let </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">K
                  </span><span style=3D"font-size: 10.000000pt;
                    font-family: 'LMRoman10'">be 1 for a two=E2=80=99s
                    complement representation and 0 for a ones=E2=80=99
                    complement or sign-magnitude representation.
                  </span><span style=3D"font-size: 10.000000pt;
                    font-family: 'LMMathItalic10'">b</span><span
                    style=3D"font-size: 7.000000pt; font-family:
                    'LMMathItalic7'; vertical-align: -1.000000pt">max </spa=
n><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is the smallest value greater than or
                    equal to </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">max</span><=
span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">(</span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathSymbols10'">|</span><s=
pan
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">e</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: -1.000000pt">min</span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathSymbols10'">| =E2=88=92 </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">K, </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathSymbols10'">|</span><s=
pan
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">e</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: -1.000000pt">max</span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathSymbols10'">|</span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">) </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">and equal to </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">2</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: 4.000000pt">M </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathSymbols10'">=E2=88=92 </span><span style=3D"font=
-size:
                    10.000000pt; font-family: 'LMRoman10'">1</span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">, where
                  </span><span style=3D"font-size: 10.000000pt;
                    font-family: 'LMMathItalic10'">M </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is a non-negative integer. </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">b</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: -1.000000pt">min </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is zero if </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">e</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: -1.000000pt">min </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is non-negative and </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathSymbols10'">=E2=88=92</span><span style=3D"font-=
size:
                    10.000000pt; font-family: 'LMRoman10'">(</span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">b</span><span style=3D"font-size:
                    7.000000pt; font-family: 'LMMathItalic7';
                    vertical-align: -1.000000pt">max </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">+ </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">K</span><sp=
an
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">) </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">otherwise.
                    The size of
                    the smallest bit-field large enough to hold all the
                    values of the enumeration type is </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">max</span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">(</span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMMathItalic10'">M,</span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">1) </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">if </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">b</span><sp=
an
                    style=3D"font-size: 7.000000pt; font-family:
                    'LMMathItalic7'; vertical-align: -1.000000pt">min </spa=
n><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is
                    zero and </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMMathItalic10'">M </span><s=
pan
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">+ 1 </span><span style=3D"font-size:
                    10.000000pt; font-family: 'LMRoman10'">otherwise. <b>It
                      is possible to define an enumeration that has
                      values not defined by any of its
                      enumerators.</b> If the </span><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'; font-style: italic">enumerator-list </span=
><span
                    style=3D"font-size: 10.000000pt; font-family:
                    'LMRoman10'">is empty, the values of the enumeration
                    are as if the enumeration had a
                    single enumerator with value 0.
                  </span></p>
              </li>
            </ol>
          </div>
        </div>
      </div>
      <title>C++ International Standa</title>
      <br>
    </blockquote>
    For me enumerators are any one of the named enum values. This set is
    a subset=C2=A0 not a superset of the range of valid values.<br>
    <br>
    As I said, until we don't have enums that consists only of the
    enumerators, there would be always the need to check if a value is a
    valid value for the enumeration.<br>
    <br>
    We could define a class that accepts only the enumerators as valid
    values, but the language enums can accept more values.<br>
    This is way I believe that the two checks are needed.<br>
    <br>
    I don't know why the new C++11 enum with an explicit underlying type
    have a different range of valid values.<br>
    I'll be interested in knowing the rationale.<br>
    <br>
    Vicente<br>
  </body>
</html>

<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/040e99e3-8f07-409f-3a47-ebdfb2bfb465%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/040e99e3-8f07-409f-3a47-ebdfb2bfb465=
%40wanadoo.fr</a>.<br />

--------------BF1F89400088942B4377F680--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 10 Jan 2017 15:06:56 -0800 (PST)
Raw View
------=_Part_1712_1528224376.1484089616543
Content-Type: multipart/alternative;
 boundary="----=_Part_1713_2094802392.1484089616544"

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

On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit :
>
> On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J. Botet Escrib=
a=20
> wrote:=20
>>
>> Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com a =C3=A9crit :
>>
>>
>> W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik=20
>> gmis...@gmail.com napisa=C5=82:=20
>>>
>>>
>>>
>>> On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com=20
>>> wrote:=20
>>>>
>>>> Hi,=20
>>>>
>>>>
>> I'll try to create a first draft after I get some more comments w.r.t to=
=20
>> exceptions.
>> For sure baseline API must be exception-free.
>> Do we really want to additionally support API that throws on error?
>> I'm rather inclined to leave it out - similarly as in to_chars/from_char=
s.
>> =20
>>
>>>
>>> I hope this post assists you with your proposal. My suggestions are for=
=20
>>> your proposal to look something like this:
>>>
>>> In <utility> I think add:
>>>
>>> bool template<typename E, typename V> is_enum( V ev )
>>> {
>>>  // compiler magic:
>>>  // Calling this routine causes the compiler to generate or a call a=20
>>> routine
>>>  // that returns true if the value ev matches one of the enum E's
>>>  // values. otherwise false.
>>> }
>>>
>>
>> 'is_enum' name is already used in type_traits header.
>> Also is_enum seems redundant to me, since to_enum already reports
>> if convertion succeeded instead of:
>> if (is_enum<MyEnum>(139))
>>
>> you could write:
>> if (to_enum<MyEnum>(139).is_valid)
>>
>> or even:
>> if (to_enum<MyEnum>(139))
>> if we add explicit bool convertion operator for to_enum_result.
>>
>>
>> I believe we need two checking functions:
>> * is_enumerator : checks if the explicit conversion from the integer is=
=20
>> one of the explicit enumerators
>> * is_in_enum_range: checks if the integer is in the range of valid=20
>> values. This is the precondition of the static_cast.
>>
>> IIUC when the underlying type is explicit, the range of values are the=
=20
>> range of the underlying type. However when the underlying type is implic=
it=20
>> the range goes from the min to the max of the values of the enumerators.
>>
>
> Right, but `is_enumerator` is a functional superset of `is_in_enum_range`=
..=20
> Do people really need to ask *only* if a value is in the range of an=20
> enumerator?
>
> I don't follow you. You surely wanted to say subset
>

Yes, I did. My mistake.
=20

>
> The standard says in 7.2/8 :=20
>
>
>    1.=20
>   =20
>    8  For an enumeration whose underlying type is fixed, the values of=20
>    the enumeration are the values of the underlying type. Otherwise, for =
an=20
>    enumeration where emin is the smallest enumerator and emax is the=20
>    largest, the values of the enumeration are the values in the range bmi=
n=20
>    to bmax, defined as follows: Let K be 1 for a two=E2=80=99s complement=
=20
>    representation and 0 for a ones=E2=80=99 complement or sign-magnitude=
=20
>    representation. bmax is the smallest value greater than or equal to ma=
x
>    (|emin| =E2=88=92 K, |emax|) and equal to 2M =E2=88=92 1, where M is a=
 non-negative=20
>    integer. bmin is zero if emin is non-negative and =E2=88=92(bmax + K) =
otherwise.=20
>    The size of the smallest bit-field large enough to hold all the values=
 of=20
>    the enumeration type is max(M,1) if bmin is zero and M + 1 otherwise. =
*It=20
>    is possible to define an enumeration that has values not defined by an=
y of=20
>    its enumerators.* If the enumerator-list is empty, the values of the=
=20
>    enumeration are as if the enumeration had a single enumerator with val=
ue 0.=20
>   =20
>
> For me enumerators are any one of the named enum values. This set is a=20
> subset  not a superset of the range of valid values.
>
> As I said, until we don't have enums that consists only of the=20
> enumerators, there would be always the need to check if a value is a vali=
d=20
> value for the enumeration.
>
=20
>
We could define a class that accepts only the enumerators as valid values,=
=20
> but the language enums can accept more values.
> This is way I believe that the two checks are needed.
>

Here's the thing.

There are enumerations that have a fixed underlying type (`enum class`es=20
use `int` by default), and there are enumerations that have an implied=20
underlying type (ie: non-`class` enums without a specified type).

The question I have to ask is this: if you have an integer, why do you need=
=20
to know if it will fit within the range of an enum with an implied=20
underlying type? What problem are you trying to solve? What code are you=20
trying to write?

If the enum has a fixed underlying type, then you might need to know the=20
range because you're using the enum as an ad-hoc strongly typed integer. I=
=20
personally despise this obvious abuse of a language feature, but C++17 has=
=20
effectively canonized it, so there it is. Alternatively, you may be using=
=20
that enum as a bitfield.

The thing is, that is a solved problem: get the underlying type with=20
`std::underlying_type_t<E>`. That, and its corresponding `numeric_limits`=
=20
will tell you everything you need to know about the range of that=20
enumeration.

But if the enum has an implied underlying type, then why would you need to=
=20
know if a particular integer (which does not match any enumerator) is=20
within the valid range for that enum? What are you trying to do that you=20
need to do this?

If you don't have a problem to be solved with such a function, then there's=
=20
really no point in adding one.

I don't know why the new C++11 enum with an explicit underlying type have a=
=20
> different range of valid values.
> I'll be interested in knowing the rationale.
>

Because enums are integers. That's the rationale.

--=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/1841091b-9f97-4724-9f95-3193c0fb94fb%40isocpp.or=
g.

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

<div dir=3D"ltr">On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente =
J. Botet 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 10/01/2017 =C3=A0 20:30, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vi=
cente 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 10/01/2017 =C3=A0 16:31, <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"><br>
                W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1
                u=C5=BCytkownik <a>gmis...@gmail.com</a>
                napisa=C5=82:
                <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"><br>
                    <br>
                    On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, <a>m=
..ce...@gmail.com</a>
                    wrote:
                    <blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-lef=
t-width:1px;border-left-style:solid">
                      <div dir=3D"ltr">Hi,
                        <div><br>
                        </div>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
                <br>
                <div>I&#39;ll try to create a first draft after I get some
                  more comments w.r.t to exceptions.</div>
                <div>For sure baseline API must be exception-free.</div>
                <div>Do we really want to additionally support API that
                  throws on error?</div>
                <div>I&#39;m rather inclined to leave it out - similarly as
                  in to_chars/from_chars.</div>
                <div>=C2=A0</div>
                <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><br>
                    </div>
                    <div>I hope this post assists you with your
                      proposal.=C2=A0My suggestions are for your proposal t=
o
                      look something like this:</div>
                    <div><br>
                    </div>
                    <div>In &lt;utility&gt; I think add:</div>
                    <div><br>
                    </div>
                    <div>bool template&lt;typename E, typename V&gt;
                      is_enum( V ev )</div>
                    <div>{</div>
                    <div>=C2=A0// compiler=C2=A0magic:</div>
                    <div>=C2=A0// Calling this routine causes the compiler =
to
                      generate or a call a routine</div>
                    <div>=C2=A0// that returns true if the value ev matches
                      one of the enum E&#39;s</div>
                    <div>=C2=A0// values. otherwise false.</div>
                    <div>}</div>
                  </div>
                </blockquote>
                <div><br>
                </div>
                <div>&#39;is_enum&#39; name is already used in type_traits
                  header.<br>
                </div>
                <div>Also is_enum seems redundant to me, since to_enum
                  already reports</div>
                <div>if convertion succeeded instead of:</div>
                <div>
                  <div style=3D"border:1px solid rgb(187,187,187);word-wrap=
:break-word;background-color:rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">is_enum</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span s=
tyle=3D"color:#066">139</span><span style=3D"color:#660">))</span></div>
                    </code></div>
                  <br>
                </div>
                <div>you could write:</div>
                <div>
                  <div style=3D"border:1px solid rgb(187,187,187);word-wrap=
:break-word;background-color:rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">to_enum</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span s=
tyle=3D"color:#066">139</span><span style=3D"color:#660">).</span><span sty=
le=3D"color:#000">is_valid</span><span style=3D"color:#660"><wbr>)</span></=
div>
                    </code></div>
                  <br>
                </div>
                <div>or even:</div>
                <div>
                  <div style=3D"border:1px solid rgb(187,187,187);word-wrap=
:break-word;background-color:rgb(250,250,250)"><code>
                      <div><span style=3D"color:#008">if</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">to_enum</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><span s=
tyle=3D"color:#066">139</span><span style=3D"color:#660">))</span></div>
                    </code></div>
                  if we add explicit bool convertion operator for
                  to_enum_result.</div>
                <div><br>
                </div>
                <div><br>
                </div>
              </div>
            </blockquote>
            I believe we need two checking functions:<br>
            * is_enumerator : checks if the explicit conversion from the
            integer is one of the explicit enumerators<br>
            * is_in_enum_range: checks if the integer is in the range of
            valid values. This is the precondition of the static_cast.<br>
            <br>
            IIUC when the underlying type is explicit, the range of
            values are the range of the underlying type. However when
            the underlying type is implicit the range goes from the min
            to the max of the values of the enumerators.<br>
          </div>
        </blockquote>
        <div><br>
          Right, but `is_enumerator` is a functional superset of
          `is_in_enum_range`. Do people really need to ask <i>only</i>
          if a value is in the range of an enumerator?<br>
        </div>
      </div>
    </blockquote>
    I don&#39;t follow you. You surely wanted to say subset<br></div></bloc=
kquote><div><br>Yes, I did. My mistake.<br>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <br>
    The standard says in 7.2/8 :
    <blockquote>
     =20
      <div title=3D"Page 190">
        <div>
          <div>
            <ol start=3D"6" style=3D"list-style-type:none">
              <li>
                <p><span style=3D"font-size:7.000000pt;font-family:&#39;LMR=
oman7&#39;;vertical-align:2.000000pt">8 =C2=A0</span><span style=3D"font-si=
ze:10.000000pt;font-family:&#39;LMRoman10&#39;">For an enumeration whose un=
derlying
                    type is fixed, the values of the enumeration are the
                    values of the
                    underlying type. Otherwise, for an enumeration where
                  </span><span style=3D"font-size:10.000000pt;font-family:&=
#39;LMMathItalic10&#39;">e</span><span style=3D"font-size:7.000000pt;font-f=
amily:&#39;LMRoman7&#39;;font-style:italic;vertical-align:-1.000000pt">min =
</span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;=
">is the
                    smallest enumerator and </span><span style=3D"font-size=
:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><span style=3D"f=
ont-size:7.000000pt;font-family:&#39;LMRoman7&#39;;font-style:italic;vertic=
al-align:-1.000000pt">max </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is the
                    largest, the values of the enumeration are the
                    values in the range </span><span style=3D"font-size:10.=
000000pt;font-family:&#39;LMMathItalic10&#39;">b</span><span style=3D"font-=
size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.00000=
0pt">min </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRom=
an10&#39;">to </span><span style=3D"font-size:10.000000pt;font-family:&#39;=
LMMathItalic10&#39;">b</span><span style=3D"font-size:7.000000pt;font-famil=
y:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt">max</span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">, defined as fol=
lows: Let </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMMa=
thItalic10&#39;">K
                  </span><span style=3D"font-size:10.000000pt;font-family:&=
#39;LMRoman10&#39;">be 1 for a two=E2=80=99s
                    complement representation and 0 for a ones=E2=80=99
                    complement or sign-magnitude representation.
                  </span><span style=3D"font-size:10.000000pt;font-family:&=
#39;LMMathItalic10&#39;">b</span><span style=3D"font-size:7.000000pt;font-f=
amily:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt">max </span><span =
style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">is the smal=
lest value greater than or
                    equal to </span><span style=3D"font-size:10.000000pt;fo=
nt-family:&#39;LMMathItalic10&#39;">max</span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMRoman10&#39;">(</span><span style=3D"font-size:1=
0.000000pt;font-family:&#39;LMMathSymbols10&#39;">|</span><span style=3D"fo=
nt-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><span sty=
le=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-ali=
gn:-1.000000pt">min</span><span style=3D"font-size:10.000000pt;font-family:=
&#39;LMMathSymbols10&#39;">| =E2=88=92 </span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMMathItalic10&#39;">K, </span><span style=3D"font=
-size:10.000000pt;font-family:&#39;LMMathSymbols10&#39;">|</span><span styl=
e=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><s=
pan style=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;verti=
cal-align:-1.000000pt">max</span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathSymbols10&#39;">|</span><span style=3D"font-size:10.00000=
0pt;font-family:&#39;LMRoman10&#39;">) </span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMRoman10&#39;">and equal to </span><span style=3D=
"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">2</span><span style=
=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align=
:4.000000pt">M </span><span style=3D"font-size:10.000000pt;font-family:&#39=
;LMMathSymbols10&#39;">=E2=88=92 </span><span style=3D"font-size:10.000000p=
t;font-family:&#39;LMRoman10&#39;">1</span><span style=3D"font-size:10.0000=
00pt;font-family:&#39;LMRoman10&#39;">, where
                  </span><span style=3D"font-size:10.000000pt;font-family:&=
#39;LMMathItalic10&#39;">M </span><span style=3D"font-size:10.000000pt;font=
-family:&#39;LMRoman10&#39;">is a non-negative integer. </span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">b</span><sp=
an style=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertic=
al-align:-1.000000pt">min </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is zero if </span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMMathItalic10&#39;">e</span><span style=3D"font-s=
ize:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.000000=
pt">min </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoma=
n10&#39;">is non-negative and </span><span style=3D"font-size:10.000000pt;f=
ont-family:&#39;LMMathSymbols10&#39;">=E2=88=92</span><span style=3D"font-s=
ize:10.000000pt;font-family:&#39;LMRoman10&#39;">(</span><span style=3D"fon=
t-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">b</span><span styl=
e=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-alig=
n:-1.000000pt">max </span><span style=3D"font-size:10.000000pt;font-family:=
&#39;LMRoman10&#39;">+ </span><span style=3D"font-size:10.000000pt;font-fam=
ily:&#39;LMMathItalic10&#39;">K</span><span style=3D"font-size:10.000000pt;=
font-family:&#39;LMRoman10&#39;">) </span><span style=3D"font-size:10.00000=
0pt;font-family:&#39;LMRoman10&#39;">otherwise.
                    The size of
                    the smallest bit-field large enough to hold all the
                    values of the enumeration type is </span><span style=3D=
"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">max</span><spa=
n style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">(</span><=
span style=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">M=
,</span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39=
;">1) </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman1=
0&#39;">if </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMM=
athItalic10&#39;">b</span><span style=3D"font-size:7.000000pt;font-family:&=
#39;LMMathItalic7&#39;;vertical-align:-1.000000pt">min </span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">is
                    zero and </span><span style=3D"font-size:10.000000pt;fo=
nt-family:&#39;LMMathItalic10&#39;">M </span><span style=3D"font-size:10.00=
0000pt;font-family:&#39;LMRoman10&#39;">+ 1 </span><span style=3D"font-size=
:10.000000pt;font-family:&#39;LMRoman10&#39;">otherwise. <b>It
                      is possible to define an enumeration that has
                      values not defined by any of its
                      enumerators.</b> If the </span><span style=3D"font-si=
ze:10.000000pt;font-family:&#39;LMRoman10&#39;;font-style:italic">enumerato=
r-list </span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman=
10&#39;">is empty, the values of the enumeration
                    are as if the enumeration had a
                    single enumerator with value 0.
                  </span></p>
              </li>
            </ol>
          </div>
        </div>
      </div>
     =20
      <br>
    </blockquote>
    For me enumerators are any one of the named enum values. This set is
    a subset=C2=A0 not a superset of the range of valid values.<br>
    <br>
    As I said, until we don&#39;t have enums that consists only of the
    enumerators, there would be always the need to check if a value is a
    valid value for the enumeration.<br></div></blockquote><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px soli=
d rgb(204, 204, 204); padding-left: 1ex;"><div>=C2=A0</div></blockquote><di=
v></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"#FFFFF=
F" text=3D"#000000">
   =20
    We could define a class that accepts only the enumerators as valid
    values, but the language enums can accept more values.<br>
    This is way I believe that the two checks are needed.<br></div></blockq=
uote><div><br>Here&#39;s the thing.<br><br>There are enumerations that have=
 a fixed underlying type (`enum class`es use `int` by default), and there a=
re enumerations that have an implied underlying type (ie: non-`class` enums=
 without a specified type).<br><br>The question I have to ask is this: if y=
ou have an integer, why do you need to know if it will fit within the range=
 of an enum with an implied underlying type? What problem are you trying to=
 solve? What code are you trying to write?<br><br>If the enum has a fixed u=
nderlying type, then you might need to know the range because you&#39;re us=
ing the enum as an ad-hoc strongly typed integer. I personally despise this=
 obvious abuse of a language feature, but C++17 has effectively canonized i=
t, so there it is. Alternatively, you may be using that enum as a bitfield.=
<br><br>The thing is, that is a solved problem: get the underlying type wit=
h `std::underlying_type_t&lt;E&gt;`. That, and its corresponding `numeric_l=
imits` will tell you everything you need to know about the range of that en=
umeration.<br><br>But if the enum has an implied underlying type, then why =
would you need to know if a particular integer (which does not match any en=
umerator) is within the valid range for that enum? What are you trying to d=
o that you need to do this?<br><br>If you don&#39;t have a problem to be so=
lved with such a function, then there&#39;s really no point in adding one.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#=
FFFFFF" text=3D"#000000">
   =20
    I don&#39;t know why the new C++11 enum with an explicit underlying typ=
e
    have a different range of valid values.<br>
    I&#39;ll be interested in knowing the rationale.<br></div></blockquote>=
<div><br>Because enums are integers. That&#39;s the rationale.<br></div></d=
iv>

<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/1841091b-9f97-4724-9f95-3193c0fb94fb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1841091b-9f97-4724-9f95-3193c0fb94fb=
%40isocpp.org</a>.<br />

------=_Part_1713_2094802392.1484089616544--

------=_Part_1712_1528224376.1484089616543--

.


Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Wed, 11 Jan 2017 08:58:03 +0100
Raw View
On Tue, Jan 10, 2017 at 7:31 PM, Matthew Woehlke
<mwoehlke.floss@gmail.com> wrote:
> On 2017-01-10 12:01, Peter Koch Larsen wrote:
>> What do you do if you have an enum with some same_valued elements
>> (enum E { ea = 0, eb = 0})? My implementation forbids this.
>
> Why?
>
>   E x = ea;
>   assert(x == eb); // will succeed
>
> Such a prohibition makes some sense when converting an enum to a string
> (or to its ordinal), but there is no problem when converting an int to
> an enum (or a string to an enum, for that matter).

This is exactly my problem. I partially use my library in to do this
stuff, and it could be confusing for the user if you serialize as ea
and get eb back. I also have a bitset class (enum_bitset<Enum>), where
I as a template parameter define if i set the bit depending on the
underlying enums ordinal values or by its underlying integral value.
In neither case do I see any use of having two enums with the same
value.
Also, I do not see a reason in have two enums with the same value.
Before my library, I would have two underlying enums with the same
value in two situations: To have a count (e.g. enum color {
red,green,blue, color_count = blue} or to name bit-sets enum state {
created = 1, received = 2, sent = 4, active = created}). These reasons
are both gone now.

/Peter


>
> --
> Matthew
>

--
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/CANPtknxx9BXfwLagcO1ucu4pwi6PS6ewrdPzQsqOXgPUGuR-og%40mail.gmail.com.

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jan 2017 02:40:40 -0800 (PST)
Raw View
------=_Part_908_1718716083.1484131240466
Content-Type: multipart/alternative;
 boundary="----=_Part_909_809093216.1484131240467"

------=_Part_909_809093216.1484131240467
Content-Type: text/plain; charset=UTF-8



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?

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?

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.

But what am I missing?
Thanks

--
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/216fe26f-2155-42b4-9350-cb4c7f4e9f4a%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Wednesday, January 11, 2017 at 8:09:42 AM UTC+1=
3, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px=
 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); b=
order-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr">On Tuesd=
ay, January 10, 2017 at 11:59:16 AM UTC-5, Matthew Woehlke wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1=
ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-l=
eft-style: solid;">On 2017-01-10 11:20, Nicol 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=A0string/char array=C2=A0&quot;=
my:;traffic_light&quot;.</div><div><br></div><div>It would then create a st=
ring of the info an give you an exception object back that you could then t=
hrow or do whatever with.</div><div>so given namespace my { enum class traf=
fic_light { stop, careful, go };=C2=A0} }</div><div>make_enum&lt;traffic_li=
ght&gt;(3) would produce an exception where what() would return an array wi=
th</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><br></div><div>s=
td::range_error was ok with me as that could be constructed with a string a=
nd the type more reflected the problem.</div><div><br></div><div>What&#39;s=
 wrong with this in your opinion?</div><div><br></div><div>A bad_enum=C2=A0=
class would have allowed an internal char=C2=A0buffer of=C2=A0fixed size to=
 be used because we know what length string worst case we are storing here =
if that was the problem.</div><div><br></div><div>But what am I missing?</d=
iv><div>Thanks</div><div><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/216fe26f-2155-42b4-9350-cb4c7f4e9f4a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/216fe26f-2155-42b4-9350-cb4c7f4e9f4a=
%40isocpp.org</a>.<br />

------=_Part_909_809093216.1484131240467--

------=_Part_908_1718716083.1484131240466--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 11 Jan 2017 10:23:52 -0500
Raw View
On 2017-01-11 02:58, Peter Koch Larsen wrote:
> On Tue, Jan 10, 2017 at 7:31 PM, Matthew Woehlke wrote:
>> On 2017-01-10 12:01, Peter Koch Larsen wrote:
>>> What do you do if you have an enum with some same_valued elements
>>> (enum E { ea = 0, eb = 0})? My implementation forbids this.
>>
>> Why?
>>
>>   E x = ea;
>>   assert(x == eb); // will succeed
>>
>> Such a prohibition makes some sense when converting an enum to a string
>> (or to its ordinal), but there is no problem when converting an int to
>> an enum (or a string to an enum, for that matter).
>
> This is exactly my problem. I partially use my library in to do this
> stuff, and it could be confusing for the user if you serialize as ea
> and get eb back.

....but you will *also* get `ea` back. The values `ea` and `eb` are not
distinguishable when represented as either the enum nor as an integer
(via value cast). They are only distinguishable as strings or ordinals.

If that isn't what you want, don't give your enum multiple identifiers
with the same value in the first place.

> I also have a bitset class (enum_bitset<Enum>), where
> I as a template parameter define if i set the bit depending on the
> underlying enums ordinal values or by its underlying integral value.
> In neither case do I see any use of having two enums with the same
> value.
> Also, I do not see a reason in have two enums with the same value.

So just *don't do that*. But don't artificially nerf your proposed
feature for people that *do* find that useful.

In your above example, the integer 0 is a member of the set of valid
values of `E`. The cast should succeed. Remember, you aren't changing
the value representation, you're just changing the *type*.

--
Matthew

--
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/58764E08.10000%40gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Jan 2017 09:16:58 -0800 (PST)
Raw View
------=_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--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 11 Jan 2017 19:52:08 +0100
Raw View
This is a multi-part message in MIME format.
--------------B0E4ED9DE0FEA910FFB5435C
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
> On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
>     Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit :
>>     On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J.
>>     Botet Escriba wrote:
>>
>>         Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com a =C3=A9crit :
>>>
>>>         W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik
>>>         gmis...@gmail.com napisa=C5=82:
>>>
>>>
>>>
>>>             On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13,
>>>             m.ce...@gmail.com wrote:
>>>
>>>                 Hi,
>>>
>>>
>>>         I'll try to create a first draft after I get some more
>>>         comments w.r.t to exceptions.
>>>         For sure baseline API must be exception-free.
>>>         Do we really want to additionally support API that throws on
>>>         error?
>>>         I'm rather inclined to leave it out - similarly as in
>>>         to_chars/from_chars.
>>>
>>>
>>>             I hope this post assists you with your proposal. My
>>>             suggestions are for your proposal to look something like
>>>             this:
>>>
>>>             In <utility> I think add:
>>>
>>>             bool template<typename E, typename V> is_enum( V ev )
>>>             {
>>>              // compiler magic:
>>>              // Calling this routine causes the compiler to generate
>>>             or a call a routine
>>>              // that returns true if the value ev matches one of the
>>>             enum E's
>>>              // values. otherwise false.
>>>             }
>>>
>>>
>>>         'is_enum' name is already used in type_traits header.
>>>         Also is_enum seems redundant to me, since to_enum already
>>>         reports
>>>         if convertion succeeded instead of:
>>>         |
>>>         if(is_enum<MyEnum>(139))
>>>         |
>>>
>>>         you could write:
>>>         |
>>>         if(to_enum<MyEnum>(139).is_valid)
>>>         |
>>>
>>>         or even:
>>>         |
>>>         if(to_enum<MyEnum>(139))
>>>         |
>>>         if we add explicit bool convertion operator for to_enum_result.
>>>
>>>
>>         I believe we need two checking functions:
>>         * is_enumerator : checks if the explicit conversion from the
>>         integer is one of the explicit enumerators
>>         * is_in_enum_range: checks if the integer is in the range of
>>         valid values. This is the precondition of the static_cast.
>>
>>         IIUC when the underlying type is explicit, the range of
>>         values are the range of the underlying type. However when the
>>         underlying type is implicit the range goes from the min to
>>         the max of the values of the enumerators.
>>
>>
>>     Right, but `is_enumerator` is a functional superset of
>>     `is_in_enum_range`. Do people really need to ask /only/ if a
>>     value is in the range of an enumerator?
>     I don't follow you. You surely wanted to say subset
>
>
> Yes, I did. My mistake.
>
>
>     The standard says in 7.2/8 :
>
>         6.
>
>             8 For an enumeration whose underlying type is fixed, the
>             values of the enumeration are the values of the underlying
>             type. Otherwise, for an enumeration where emin is the
>             smallest enumerator and emax is the largest, the values of
>             the enumeration are the values in the range bmin to bmax,
>             defined as follows: Let K be 1 for a two=E2=80=99s complement
>             representation and 0 for a ones=E2=80=99 complement or
>             sign-magnitude representation. bmax is the smallest value
>             greater than or equal to max(|emin| =E2=88=92 K, |emax|) and =
equal
>             to 2M =E2=88=92 1, where M is a non-negative integer. bmin is=
 zero
>             if emin is non-negative and =E2=88=92(bmax + K) otherwise. Th=
e
>             size of the smallest bit-field large enough to hold all
>             the values of the enumeration type is max(M,1) if bmin is
>             zero and M + 1 otherwise. *It is possible to define an
>             enumeration that has values not defined by any of its
>             enumerators.* If the enumerator-list is empty, the values
>             of the enumeration are as if the enumeration had a single
>             enumerator with value 0.
>
>
>     For me enumerators are any one of the named enum values. This set
>     is a subset  not a superset of the range of valid values.
>
>     As I said, until we don't have enums that consists only of the
>     enumerators, there would be always the need to check if a value is
>     a valid value for the enumeration.
>
>     We could define a class that accepts only the enumerators as valid
>     values, but the language enums can accept more values.
>     This is way I believe that the two checks are needed.
>
>
> Here's the thing.
>
> There are enumerations that have a fixed underlying type (`enum=20
> class`es use `int` by default), and there are enumerations that have=20
> an implied underlying type (ie: non-`class` enums without a specified=20
> type).
What is important is the range of values.
>
> The question I have to ask is this: if you have an integer, why do you=20
> need to know if it will fit within the range of an enum with an=20
> implied underlying type?
Because initializing the enum with an integer out of range is UB.
> What problem are you trying to solve? What code are you trying to write?
>
> If the enum has a fixed underlying type, then you might need to know=20
> the range because you're using the enum as an ad-hoc strongly typed=20
> integer.
Right.
> I personally despise this obvious abuse of a language feature, but=20
> C++17 has effectively canonized it, so there it is. Alternatively, you=20
> may be using that enum as a bitfield.
>
> The thing is, that is a solved problem: get the underlying type with=20
> `std::underlying_type_t<E>`. That, and its corresponding=20
> `numeric_limits` will tell you everything you need to know about the=20
> range of that enumeration.
I don't want to solve problems that are already solved. We don't need=20
any modification on the compiler to solve this case, but if it solve the=20
more dificult case it could  solve this as well.
>
> But if the enum has an implied underlying type, then why would you=20
> need to know if a particular integer (which does not match any=20
> enumerator) is within the valid range for that enum?
Because this is legal. I can assign it a value on the specified range.=20
That's all. If I want my code to be outside the UB world I should be=20
able to check on the conditions. I can of course do it for each=20
particular case, but what we are talking of here is about what the=20
compiler could do for us in a generic way.
> What are you trying to do that you need to do this?
This is not a use case I would write myself, but I've see it a lot of=20
times. When you use enums as flags of an bitset
enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};

The valid enumerators  don't correspond to the valid range, that in this=20
case is any value between 0 and 8.
>
> If you don't have a problem to be solved with such a function, then=20
> there's really no point in adding one.
I was sure you will ask and say this ;-)
>
>     I don't know why the new C++11 enum with an explicit underlying
>     type have a different range of valid values.
>     I'll be interested in knowing the rationale.
>
>
> Because enums are integers. That's the rationale.
I believe that you didn't understood my question. Let me see with an=20
example.
What is the difference between

     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};

and

     enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04,=
 ALL=20
0x08};
?

X has a valid range 0..N, while Y has a valid range 0..255.

Why do we need this difference? Why forcing the underlying type changes=20
the range of valid values?

Vicente

--=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/214358e3-699e-f804-4289-14472559a51a%40wanadoo.f=
r.

--------------B0E4ED9DE0FEA910FFB5435C
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 11/01/2017 =C3=A0 00:06, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5,
        Vicente J. Botet Escriba wrote:
        <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" text=3D"#000000">
            <div>Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit=C2=A0=
:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Tuesday, January 10, 2017 at 1:49:05 PM
                UTC-5, Vicente J. Botet Escriba wrote:
                <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" text=3D"#000000">
                    <div>Le 10/01/2017 =C3=A0 16:31, <a
                        moz-do-not-send=3D"true" rel=3D"nofollow">m.ce...@g=
mail.com</a>
                      a =C3=A9crit=C2=A0:<br>
                    </div>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr"><br>
                        W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1
                        u=C5=BCytkownik <a moz-do-not-send=3D"true">gmis...=
@gmail.com</a>
                        napisa=C5=82:
                        <blockquote class=3D"gmail_quote"
                          style=3D"margin:0;margin-left:0.8ex;border-left:1=
px
                          #ccc solid;padding-left:1ex">
                          <div dir=3D"ltr"><br>
                            <br>
                            On Tuesday, January 3, 2017 at 10:56:05 PM
                            UTC+13, <a moz-do-not-send=3D"true">m.ce...@gma=
il.com</a>
                            wrote:
                            <blockquote class=3D"gmail_quote"
                              style=3D"margin:0px 0px 0px
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width=
:1px;border-left-style:solid">
                              <div dir=3D"ltr">Hi,
                                <div><br>
                                </div>
                              </div>
                            </blockquote>
                          </div>
                        </blockquote>
                        <br>
                        <div>I'll try to create a first draft after I
                          get some more comments w.r.t to exceptions.</div>
                        <div>For sure baseline API must be
                          exception-free.</div>
                        <div>Do we really want to additionally support
                          API that throws on error?</div>
                        <div>I'm rather inclined to leave it out -
                          similarly as in to_chars/from_chars.</div>
                        <div>=C2=A0</div>
                        <blockquote class=3D"gmail_quote"
                          style=3D"margin:0;margin-left:0.8ex;border-left:1=
px
                          #ccc solid;padding-left:1ex">
                          <div dir=3D"ltr">
                            <div><br>
                            </div>
                            <div>I hope this post assists you with your
                              proposal.=C2=A0My suggestions are for your
                              proposal to look something like this:</div>
                            <div><br>
                            </div>
                            <div>In &lt;utility&gt; I think add:</div>
                            <div><br>
                            </div>
                            <div>bool template&lt;typename E, typename
                              V&gt; is_enum( V ev )</div>
                            <div>{</div>
                            <div>=C2=A0// compiler=C2=A0magic:</div>
                            <div>=C2=A0// Calling this routine causes the
                              compiler to generate or a call a routine</div=
>
                            <div>=C2=A0// that returns true if the value ev
                              matches one of the enum E's</div>
                            <div>=C2=A0// values. otherwise false.</div>
                            <div>}</div>
                          </div>
                        </blockquote>
                        <div><br>
                        </div>
                        <div>'is_enum' name is already used in
                          type_traits header.<br>
                        </div>
                        <div>Also is_enum seems redundant to me, since
                          to_enum already reports</div>
                        <div>if convertion succeeded instead of:</div>
                        <div>
                          <div style=3D"border:1px solid
                            rgb(187,187,187);word-wrap:break-word;backgroun=
d-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n
                                  style=3D"color:#000"> </span><span
                                  style=3D"color:#660">(</span><span
                                  style=3D"color:#000">is_enum</span><span
                                  style=3D"color:#660">&lt;</span><span
                                  style=3D"color:#606">MyEnum</span><span
                                  style=3D"color:#660">&gt;(</span><span
                                  style=3D"color:#066">139</span><span
                                  style=3D"color:#660">))</span></div>
                            </code></div>
                          <br>
                        </div>
                        <div>you could write:</div>
                        <div>
                          <div style=3D"border:1px solid
                            rgb(187,187,187);word-wrap:break-word;backgroun=
d-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n
                                  style=3D"color:#000"> </span><span
                                  style=3D"color:#660">(</span><span
                                  style=3D"color:#000">to_enum</span><span
                                  style=3D"color:#660">&lt;</span><span
                                  style=3D"color:#606">MyEnum</span><span
                                  style=3D"color:#660">&gt;(</span><span
                                  style=3D"color:#066">139</span><span
                                  style=3D"color:#660">).</span><span
                                  style=3D"color:#000">is_valid</span><span
                                  style=3D"color:#660"><wbr>)</span></div>
                            </code></div>
                          <br>
                        </div>
                        <div>or even:</div>
                        <div>
                          <div style=3D"border:1px solid
                            rgb(187,187,187);word-wrap:break-word;backgroun=
d-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n
                                  style=3D"color:#000"> </span><span
                                  style=3D"color:#660">(</span><span
                                  style=3D"color:#000">to_enum</span><span
                                  style=3D"color:#660">&lt;</span><span
                                  style=3D"color:#606">MyEnum</span><span
                                  style=3D"color:#660">&gt;(</span><span
                                  style=3D"color:#066">139</span><span
                                  style=3D"color:#660">))</span></div>
                            </code></div>
                          if we add explicit bool convertion operator
                          for to_enum_result.</div>
                        <div><br>
                        </div>
                        <div><br>
                        </div>
                      </div>
                    </blockquote>
                    I believe we need two checking functions:<br>
                    * is_enumerator : checks if the explicit conversion
                    from the integer is one of the explicit enumerators<br>
                    * is_in_enum_range: checks if the integer is in the
                    range of valid values. This is the precondition of
                    the static_cast.<br>
                    <br>
                    IIUC when the underlying type is explicit, the range
                    of values are the range of the underlying type.
                    However when the underlying type is implicit the
                    range goes from the min to the max of the values of
                    the enumerators.<br>
                  </div>
                </blockquote>
                <div><br>
                  Right, but `is_enumerator` is a functional superset of
                  `is_in_enum_range`. Do people really need to ask <i>only<=
/i>
                  if a value is in the range of an enumerator?<br>
                </div>
              </div>
            </blockquote>
            I don't follow you. You surely wanted to say subset<br>
          </div>
        </blockquote>
        <div><br>
          Yes, I did. My mistake.<br>
          =C2=A0</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" text=3D"#000000"> <br>
            The standard says in 7.2/8 :
            <blockquote>
              <div title=3D"Page 190">
                <div>
                  <div>
                    <ol start=3D"6" style=3D"list-style-type:none">
                      <li>
                        <p><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';vertical-align:2.00000=
0pt">8
                            =C2=A0</span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">For
                            an enumeration whose underlying type is
                            fixed, the values of the enumeration are the
                            values of the underlying type. Otherwise,
                            for an enumeration where </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';font-style:italic;vert=
ical-align:-1.000000pt">min
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            the smallest enumerator and </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';font-style:italic;vert=
ical-align:-1.000000pt">max
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            the largest, the values of the enumeration
                            are the values in the range </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">to
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">, defined as
                            follows: Let </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">K
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">be
                            1 for a two=E2=80=99s complement representation=
 and
                            0 for a ones=E2=80=99 complement or sign-magnit=
ude
                            representation. </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            the smallest value greater than or equal to
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">| =E2=88=92 <=
/span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">K, </span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">) </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">and
                            equal to </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">2</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:4.=
000000pt">M
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athSymbols10'">=E2=88=92
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">1</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">, where </span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">M </span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">is a non-negative
                            integer. </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            zero if </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            non-negative and </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athSymbols10'">=E2=88=92</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">+
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">K</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">) </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">otherwise.
                            The size of the smallest bit-field large
                            enough to hold all the values of the
                            enumeration type is </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">M,</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">1) </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">if
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            zero and </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMM=
athItalic10'">M
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">+
                            1 </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">otherwise.
                            <b>It is possible to define an enumeration
                              that has values not defined by any of its
                              enumerators.</b> If the </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10';font-style:italic">enumerator-list
                          </span><span
                            style=3D"font-size:10.000000pt;font-family:'LMR=
oman10'">is
                            empty, the values of the enumeration are as
                            if the enumeration had a single enumerator
                            with value 0. </span></p>
                      </li>
                    </ol>
                  </div>
                </div>
              </div>
              <br>
            </blockquote>
            For me enumerators are any one of the named enum values.
            This set is a subset=C2=A0 not a superset of the range of valid
            values.<br>
            <br>
            As I said, until we don't have enums that consists only of
            the enumerators, there would be always the need to check if
            a value is a valid value for the enumeration.<br>
          </div>
        </blockquote>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px
          0.8ex; border-left: 1px solid rgb(204, 204, 204);
          padding-left: 1ex;">
          <div>=C2=A0</div>
        </blockquote>
        <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" text=3D"#000000"> We could define a clas=
s
            that accepts only the enumerators as valid values, but the
            language enums can accept more values.<br>
            This is way I believe that the two checks are needed.<br>
          </div>
        </blockquote>
        <div><br>
          Here's the thing.<br>
          <br>
          There are enumerations that have a fixed underlying type
          (`enum class`es use `int` by default), and there are
          enumerations that have an implied underlying type (ie:
          non-`class` enums without a specified type).<br>
        </div>
      </div>
    </blockquote>
    What is important is the range of values.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          The question I have to ask is this: if you have an integer,
          why do you need to know if it will fit within the range of an
          enum with an implied underlying type?</div>
      </div>
    </blockquote>
    Because initializing the enum with an integer out of range is UB.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div> What problem are you trying to solve? What code are you
          trying to write?<br>
          <br>
          If the enum has a fixed underlying type, then you might need
          to know the range because you're using the enum as an ad-hoc
          strongly typed integer.</div>
      </div>
    </blockquote>
    Right.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div> I personally despise this obvious abuse of a language
          feature, but C++17 has effectively canonized it, so there it
          is. Alternatively, you may be using that enum as a bitfield.<br>
          <br>
          The thing is, that is a solved problem: get the underlying
          type with `std::underlying_type_t&lt;E&gt;`. That, and its
          corresponding `numeric_limits` will tell you everything you
          need to know about the range of that enumeration.<br>
        </div>
      </div>
    </blockquote>
    I don't want to solve problems that are already solved. We don't
    need any modification on the compiler to solve this case, but if it
    solve the more dificult case it could=C2=A0 solve this as well.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          But if the enum has an implied underlying type, then why would
          you need to know if a particular integer (which does not match
          any enumerator) is within the valid range for that enum?</div>
      </div>
    </blockquote>
    Because this is legal. I can assign it a value on the specified
    range. That's all. If I want my code to be outside the UB world I
    should be able to check on the conditions. I can of course do it for
    each particular case, but what we are talking of here is about what
    the compiler could do for us in a generic way.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div> What are you trying to do that you need to do this?<br>
        </div>
      </div>
    </blockquote>
    This is not a use case I would write myself, but I've see it a lot
    of times. When you use enums as flags of an bitset<br>
    enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};<br>
    <br>
    The valid enumerators=C2=A0 don't correspond to the valid range, that i=
n
    this case is any value between 0 and 8.<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          If you don't have a problem to be solved with such a function,
          then there's really no point in adding one.<br>
        </div>
      </div>
    </blockquote>
    I was sure you will ask and say this ;-)<br>
    <blockquote
      cite=3D"mid:1841091b-9f97-4724-9f95-3193c0fb94fb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><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" text=3D"#000000"> I don't know why the
            new C++11 enum with an explicit underlying type have a
            different range of valid values.<br>
            I'll be interested in knowing the rationale.<br>
          </div>
        </blockquote>
        <div><br>
          Because enums are integers. That's the rationale.<br>
        </div>
      </div>
    </blockquote>
    I believe that you didn't understood my question. Let me see with an
    example. <br>
    What is the difference between<br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x0=
4, ALL 0x08};<br>
    <br>
    and <br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=
=3D0x02, C=3D0x04,
    ALL 0x08};<br>
    ?<br>
    <br>
    X has a valid range 0..N, while Y has a valid range 0..255.<br>
    <br>
    Why do we need this difference? Why forcing the underlying type
    changes the range of valid values?<br>
    <br>
    Vicente<br>
  </body>
</html>

<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/214358e3-699e-f804-4289-14472559a51a%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/214358e3-699e-f804-4289-14472559a51a=
%40wanadoo.fr</a>.<br />

--------------B0E4ED9DE0FEA910FFB5435C--

.


Author: Peter Koch Larsen <peter.koch.larsen@gmail.com>
Date: Wed, 11 Jan 2017 20:23:08 +0100
Raw View
On Wed, Jan 11, 2017 at 4:23 PM, Matthew Woehlke
<mwoehlke.floss@gmail.com> wrote:
> On 2017-01-11 02:58, Peter Koch Larsen wrote:
>> On Tue, Jan 10, 2017 at 7:31 PM, Matthew Woehlke wrote:
>>> On 2017-01-10 12:01, Peter Koch Larsen wrote:
>>>> What do you do if you have an enum with some same_valued elements
>>>> (enum E { ea = 0, eb = 0})? My implementation forbids this.
>>>
>>> Why?
>>>
>>>   E x = ea;
>>>   assert(x == eb); // will succeed
>>>
>>> Such a prohibition makes some sense when converting an enum to a string
>>> (or to its ordinal), but there is no problem when converting an int to
>>> an enum (or a string to an enum, for that matter).
>>
>> This is exactly my problem. I partially use my library in to do this
>> stuff, and it could be confusing for the user if you serialize as ea
>> and get eb back.
>
> ...but you will *also* get `ea` back. The values `ea` and `eb` are not
> distinguishable when represented as either the enum nor as an integer
> (via value cast). They are only distinguishable as strings or ordinals.
>
And?

> If that isn't what you want, don't give your enum multiple identifiers
> with the same value in the first place.

I don't. ;-)

>
>
> So just *don't do that*. But don't artificially nerf your proposed
> feature for people that *do* find that useful.

Well, I have not proposed anything here - perhaps you should reread this thread?
I simply gave an outline as to how I implemented a feature that was
close to what is proposed, and tried to bring to attention some of
the open questions I experienced while doing that.
Personally, I would prefer to not standardize enum_cast. My preference
would be to wait for reflection to be implemented. At that point it
will probably just be a simple library function.

/Peter

--
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/CANPtkny2KM_jOaBb_wB1t0SBh2Sew%2BT2Ht%2BrUv95eXP562JY1A%40mail.gmail.com.

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jan 2017 12:21:41 -0800 (PST)
Raw View
------=_Part_6864_1207080978.1484166101641
Content-Type: multipart/alternative;
 boundary="----=_Part_6865_383276369.1484166101642"

------=_Part_6865_383276369.1484166101642
Content-Type: text/plain; charset=UTF-8


>
> 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?
>

Yes I intended to reply to you, but you are right it would have been better
to reply to someone in less agreement
for what I want to know.


>
> 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.
>

If it had to bet truncated it wouldn't be the end of the world (one hopes!),
I was thinking about avoiding dynamic allocation, but you are probably
right that's a bad idea anyway.

--
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/9df8fc29-d366-4168-9c65-0cae9ffd76d0%40isocpp.org.

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

<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; paddi=
ng-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px=
; border-left-style: solid;"><div dir=3D"ltr"><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-col=
or: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">=
<div dir=3D"ltr"><div>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.</d=
iv><div>so given namespace my { enum class traffic_light { stop, careful, g=
o };=C2=A0} }</div><div>make_enum&lt;traffic_light&gt;(3) would produce an =
exception where what() would return an array with</div><div>&#39;3 is not a=
 valid value for my:;traffic_light&#39;.</div><div><br></div><div>I think t=
his is desirable to just having either an std::bad_optional_access with wha=
t string exactly in?</div></div></blockquote><div><br>Sure, but... I&#39;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&lt;E&gt;`) were a good idea.<br><br>Are you sure you =
intend to be replying to me?<br></div></div></blockquote><div><br></div><di=
v>Yes I=C2=A0intended to reply to you, but you are right it would have been=
 better to reply to someone in less agreement</div><div>for what I want to =
know.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, =
204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><=
div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0p=
x 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-l=
eft-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div></div><div=
>std::range_error was ok with me as that could be constructed with a string=
 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 see =
no reason to use a generic exception when an exception type specific to enu=
meration casting could be employed instead. It&#39;s ultimately more descri=
ptive and obvious what&#39;s going on.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-le=
ft-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: so=
lid;"><div dir=3D"ltr"><div></div><div>A bad_enum=C2=A0class would have all=
owed an internal char=C2=A0buffer of=C2=A0fixed size to be used because we =
know what length string worst case we are storing here if that was the prob=
lem.</div></div></blockquote><br>How? An enumeration can be a member of any=
 number of namespaces and/or classes. Thus its name can be quite long. Whil=
e any particular implementation could use its internal compiler limits to g=
ive it a maximum length, that length would be pretty huge, tens if not hund=
reds of kilobytes long.<br><br>Better to dynamically allocate it than to th=
row such a gargantuan object around.<br></div></blockquote><div><br></div><=
div>If it had to bet truncated it wouldn&#39;t be the end of the world (one=
 hopes!),</div><div>I was thinking about avoiding dynamic allocation,=C2=A0=
but=C2=A0you are probably right that&#39;s a=C2=A0bad idea anyway.</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/9df8fc29-d366-4168-9c65-0cae9ffd76d0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9df8fc29-d366-4168-9c65-0cae9ffd76d0=
%40isocpp.org</a>.<br />

------=_Part_6865_383276369.1484166101642--

------=_Part_6864_1207080978.1484166101641--

.


Author: gmisocpp@gmail.com
Date: Wed, 11 Jan 2017 12:49:57 -0800 (PST)
Raw View
------=_Part_487_1583502401.1484167797668
Content-Type: multipart/alternative;
 boundary="----=_Part_488_455677855.1484167797668"

------=_Part_488_455677855.1484167797668
Content-Type: text/plain; charset=UTF-8


>
>
> What is important is the range of values.
>
>
> The question I have to ask is this: if you have an integer, why do you
> need to know if it will fit within the range of an enum with an implied
> underlying type?
>
> Because initializing the enum with an integer out of range is UB.
>

In my earlier post where I described at length how I thought the API should
be, was there UB in that and if so where?
I'm trying to understand where your UB comments are directed as I'm not
seeing where this happens.


> What problem are you trying to solve? What code are you trying to write?
>
> If the enum has a fixed underlying type, then you might need to know the
> range because you're using the enum as an ad-hoc strongly typed integer.
>
> Right.
>
> I personally despise this obvious abuse of a language feature, but C++17
> has effectively canonized it, so there it is. Alternatively, you may be
> using that enum as a bitfield.
>
> The thing is, that is a solved problem: get the underlying type with
> `std::underlying_type_t<E>`. That, and its corresponding `numeric_limits`
> will tell you everything you need to know about the range of that
> enumeration.
>
> I don't want to solve problems that are already solved. We don't need any
> modification on the compiler to solve this case, but if it solve the more
> dificult case it could  solve this as well.
>

What are you both referring to here? I assumed modifying the compiler was a
requirement to implement is_enum?
Or maybe you know is_enum can already be implemented through meta
programming without a compiler change?
Or maybe you are talking about modifying the language (so still a compiler
change) but so is_enum can implement this feature?


> But if the enum has an implied underlying type, then why would you need to
> know if a particular integer (which does not match any enumerator) is
> within the valid range for that enum?
>
> Because this is legal. I can assign it a value on the specified range.
> That's all. If I want my code to be outside the UB world I should be able
> to check on the conditions. I can of course do it for each particular case,
> but what we are talking of here is about what the compiler could do for us
> in a generic way.
>

The compiler is generating the code so where does generic come into this?

What are you trying to do that you need to do this?
>
> This is not a use case I would write myself, but I've see it a lot of
> times. When you use enums as flags of an bitset
> enum class X { NONE=0, A=0x01, B=0x02, C=0x04, ALL 0x08};
>
> The valid enumerators  don't correspond to the valid range, that in this
> case is any value between 0 and 8.
>
>
> If you don't have a problem to be solved with such a function, then
> there's really no point in adding one.
>
> I was sure you will ask and say this ;-)
>
>
> I don't know why the new C++11 enum with an explicit underlying type have
>> a different range of valid values.
>> I'll be interested in knowing the rationale.
>>
>
> Because enums are integers. That's the rationale.
>
> I believe that you didn't understood my question. Let me see with an
> example.
> What is the difference between
>
>     enum class X { NONE=0, A=0x01, B=0x02, C=0x04, ALL 0x08};
>
> and
>
>     enum class Y : unsigned char { NONE=0, A=0x01, B=0x02, C=0x04, ALL
> 0x08};
> ?
>
> X has a valid range 0..N, while Y has a valid range 0..255.
>
> Why do we need this difference? Why forcing the underlying type changes
> the range of valid values?
>

I had std::any_enum_value in my earlier post and make_bad_enum knew the
type of the enum.
The idea was that those two pieces of information allowed a value to
be constructed that could express any enum as intended.
I'm raising that in case it's helpful to this conversation here but it
might not be because I can't quite follow what problem is being solved here?


>
> Vicente
>

--
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/be99b871-2e8f-4c9b-b9f3-dff8543bc38a%40isocpp.org.

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

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;"><div text=3D"#000000" bgcolor=
=3D"#FFFFFF"><blockquote type=3D"cite"><div dir=3D"ltr"><div><br></div>
       =20
      </div>
    </blockquote>
    What is important is the range of values.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          The question I have to ask is this: if you have an integer,
          why do you need to know if it will fit within the range of an
          enum with an implied underlying type?</div>
      </div>
    </blockquote>
    Because initializing the enum with an integer out of range is UB.<br></=
div></blockquote><div><br></div><div>In my earlier post where I described a=
t length how I thought the API should be, was there UB in that and if so wh=
ere?</div><div>I&#39;m trying to understand where your UB comments are dire=
cted as I&#39;m not seeing where this happens.</div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-lef=
t: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bord=
er-left-style: solid;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> What problem are you trying to solve? What code are you
          trying to write?<br>
          <br>
          If the enum has a fixed underlying type, then you might need
          to know the range because you&#39;re using the enum as an ad-hoc
          strongly typed integer.</div>
      </div>
    </blockquote>
    Right.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> I personally despise this obvious abuse of a language
          feature, but C++17 has effectively canonized it, so there it
          is. Alternatively, you may be using that enum as a bitfield.<br>
          <br>
          The thing is, that is a solved problem: get the underlying
          type with `std::underlying_type_t&lt;E&gt;`. That, and its
          corresponding `numeric_limits` will tell you everything you
          need to know about the range of that enumeration.<br>
        </div>
      </div>
    </blockquote>
    I don&#39;t want to solve problems that are already solved. We don&#39;=
t
    need any modification on the compiler to solve this case, but if it
    solve the more dificult case it could=C2=A0 solve this as well.<br></di=
v></blockquote><div><br></div><div>What=C2=A0are you both=C2=A0referring to=
 here? I assumed=C2=A0modifying the compiler was a requirement to implement=
 is_enum?</div><div><div>Or maybe you know is_enum can=C2=A0already be impl=
emented through meta programming without a compiler change?</div><div>Or ma=
ybe you are talking about modifying the language (so still=C2=A0a compiler =
change) but so is_enum can implement this feature?</div><div><br></div></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; pad=
ding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1=
px; border-left-style: solid;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          But if the enum has an implied underlying type, then why would
          you need to know if a particular integer (which does not match
          any enumerator) is within the valid range for that enum?</div>
      </div>
    </blockquote>
    Because this is legal. I can assign it a value on the specified
    range. That&#39;s all. If I want my code to be outside the UB world I
    should be able to check on the conditions. I can of course do it for
    each particular case, but what we are talking of here is about what
    the compiler could do for us in a generic way.<br></div></blockquote><d=
iv><br></div><div>The compiler is generating the code so=C2=A0where does ge=
neric come into this?</div><div><br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: =
rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"><div=
 text=3D"#000000" bgcolor=3D"#FFFFFF">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> What are you trying to do that you need to do this?<br>
        </div>
      </div>
    </blockquote>
    This is not a use case I would write myself, but I&#39;ve see it a lot
    of times. When you use enums as flags of an bitset<br>
    enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};<br>
    <br>
    The valid enumerators=C2=A0 don&#39;t correspond to the valid range, th=
at in
    this case is any value between 0 and 8.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          If you don&#39;t have a problem to be solved with such a function=
,
          then there&#39;s really no point in adding one.<br>
        </div>
      </div>
    </blockquote>
    I was sure you will ask and say this ;-)<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF"> I don&#39;t know why t=
he
            new C++11 enum with an explicit underlying type have a
            different range of valid values.<br>
            I&#39;ll be interested in knowing the rationale.<br>
          </div>
        </blockquote>
        <div><br>
          Because enums are integers. That&#39;s the rationale.<br>
        </div>
      </div>
    </blockquote>
    I believe that you didn&#39;t understood my question. Let me see with a=
n
    example. <br>
    What is the difference between<br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x0=
4, ALL 0x08};<br>
    <br>
    and <br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=
=3D0x02, C=3D0x04,
    ALL 0x08};<br>
    ?<br>
    <br>
    X has a valid range 0..N, while Y has a valid range 0..255.<br>
    <br>
    Why do we need this difference? Why forcing the underlying type
    changes the range of valid values?<br></div></blockquote><div><br></div=
><div>I had std::any_enum_value in my earlier post and make_bad_enum knew t=
he type of the enum.</div><div>The idea was that those two pieces of inform=
ation allowed=C2=A0a value to be=C2=A0constructed that could express any en=
um as intended.</div><div>I&#39;m=C2=A0raising that in case it&#39;s=C2=A0h=
elpful to this conversation here but it might not be because I can&#39;t qu=
ite follow what problem is being solved here?</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left=
: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; borde=
r-left-style: solid;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <br>
    Vicente<br>
  </div>

</blockquote></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/be99b871-2e8f-4c9b-b9f3-dff8543bc38a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/be99b871-2e8f-4c9b-b9f3-dff8543bc38a=
%40isocpp.org</a>.<br />

------=_Part_488_455677855.1484167797668--

------=_Part_487_1583502401.1484167797668--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Jan 2017 13:21:14 -0800 (PST)
Raw View
------=_Part_3781_1952031667.1484169674856
Content-Type: multipart/alternative;
 boundary="----=_Part_3782_848304554.1484169674858"

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

On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J. Botet=20
Escriba wrote:
>
> Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>
> On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J. Botet Escrib=
a=20
> wrote:=20
>>
>> Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit :
>>
>> On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J. Botet=20
>> Escriba wrote:=20
>>>
>>> Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com a =C3=A9crit :
>>>
>>>
>>> W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1 u=C5=BCytkownik=20
>>> gmis...@gmail.com napisa=C5=82:=20
>>>>
>>>>
>>>>
>>>> On Tuesday, January 3, 2017 at 10:56:05 PM UTC+13, m.ce...@gmail.com=
=20
>>>> wrote:=20
>>>>>
>>>>> Hi,=20
>>>>>
>>>>>
>>> I'll try to create a first draft after I get some more comments w.r.t t=
o=20
>>> exceptions.
>>> For sure baseline API must be exception-free.
>>> Do we really want to additionally support API that throws on error?
>>> I'm rather inclined to leave it out - similarly as in=20
>>> to_chars/from_chars.
>>> =20
>>>
>>>>
>>>> I hope this post assists you with your proposal. My suggestions are fo=
r=20
>>>> your proposal to look something like this:
>>>>
>>>> In <utility> I think add:
>>>>
>>>> bool template<typename E, typename V> is_enum( V ev )
>>>> {
>>>>  // compiler magic:
>>>>  // Calling this routine causes the compiler to generate or a call a=
=20
>>>> routine
>>>>  // that returns true if the value ev matches one of the enum E's
>>>>  // values. otherwise false.
>>>> }
>>>>
>>>
>>> 'is_enum' name is already used in type_traits header.
>>> Also is_enum seems redundant to me, since to_enum already reports
>>> if convertion succeeded instead of:
>>> if (is_enum<MyEnum>(139))
>>>
>>> you could write:
>>> if (to_enum<MyEnum>(139).is_valid)
>>>
>>> or even:
>>> if (to_enum<MyEnum>(139))
>>> if we add explicit bool convertion operator for to_enum_result.
>>>
>>>
>>> I believe we need two checking functions:
>>> * is_enumerator : checks if the explicit conversion from the integer is=
=20
>>> one of the explicit enumerators
>>> * is_in_enum_range: checks if the integer is in the range of valid=20
>>> values. This is the precondition of the static_cast.
>>>
>>> IIUC when the underlying type is explicit, the range of values are the=
=20
>>> range of the underlying type. However when the underlying type is impli=
cit=20
>>> the range goes from the min to the max of the values of the enumerators=
..
>>>
>>
>> Right, but `is_enumerator` is a functional superset of=20
>> `is_in_enum_range`. Do people really need to ask *only* if a value is in=
=20
>> the range of an enumerator?
>>
>> I don't follow you. You surely wanted to say subset
>>
>
> Yes, I did. My mistake.
> =20
>
>>
>> The standard says in 7.2/8 :=20
>>
>>
>>    1.=20
>>   =20
>>    8  For an enumeration whose underlying type is fixed, the values of=
=20
>>    the enumeration are the values of the underlying type. Otherwise, for=
 an=20
>>    enumeration where emin is the smallest enumerator and emax is the=20
>>    largest, the values of the enumeration are the values in the range bm=
in=20
>>    to bmax, defined as follows: Let K be 1 for a two=E2=80=99s complemen=
t=20
>>    representation and 0 for a ones=E2=80=99 complement or sign-magnitude=
=20
>>    representation. bmax is the smallest value greater than or equal to=
=20
>>    max(|emin| =E2=88=92 K, |emax|) and equal to 2M =E2=88=92 1, where M =
is a=20
>>    non-negative integer. bmin is zero if emin is non-negative and =E2=88=
=92(bmax +=20
>>    K) otherwise. The size of the smallest bit-field large enough to hold=
=20
>>    all the values of the enumeration type is max(M,1) if bmin is zero=20
>>    and M + 1 otherwise. *It is possible to define an enumeration that=20
>>    has values not defined by any of its enumerators.* If the enumerator-=
list=20
>>    is empty, the values of the enumeration are as if the enumeration had=
=20
>>    a single enumerator with value 0.=20
>>   =20
>>
>> For me enumerators are any one of the named enum values. This set is a=
=20
>> subset  not a superset of the range of valid values.
>>
>> As I said, until we don't have enums that consists only of the=20
>> enumerators, there would be always the need to check if a value is a val=
id=20
>> value for the enumeration.
>>
> =20
>>
> We could define a class that accepts only the enumerators as valid values=
,=20
>> but the language enums can accept more values.
>> This is way I believe that the two checks are needed.
>>
>
> Here's the thing.
>
> There are enumerations that have a fixed underlying type (`enum class`es=
=20
> use `int` by default), and there are enumerations that have an implied=20
> underlying type (ie: non-`class` enums without a specified type).
>
> What is important is the range of values.
>
>
> The question I have to ask is this: if you have an integer, why do you=20
> need to know if it will fit within the range of an enum with an implied=
=20
> underlying type?
>
> Because initializing the enum with an integer out of range is UB.
>

You're misunderstanding my question.

The situation you describe is one where:

1. You have an integer of arbitrary origin.

2. You want to convert it to an enum type.

3. That integer *does not match* one of the enumerators in that type.

4. The enum type does not have a fixed underlying type.

What goal are you trying to achieve with all this? Or more to the point,=20
why are you incapable of simply giving the enum an underlying type and thus=
=20
making the question moot?

> What problem are you trying to solve? What code are you trying to write?
>
> If the enum has a fixed underlying type, then you might need to know the=
=20
> range because you're using the enum as an ad-hoc strongly typed integer.
>
> Right.
>
> I personally despise this obvious abuse of a language feature, but C++17=
=20
> has effectively canonized it, so there it is. Alternatively, you may be=
=20
> using that enum as a bitfield.
>
> The thing is, that is a solved problem: get the underlying type with=20
> `std::underlying_type_t<E>`. That, and its corresponding `numeric_limits`=
=20
> will tell you everything you need to know about the range of that=20
> enumeration.
>
> I don't want to solve problems that are already solved. We don't need any=
=20
> modification on the compiler to solve this case, but if it solve the more=
=20
> dificult case it could  solve this as well.
>
>
> But if the enum has an implied underlying type, then why would you need t=
o=20
> know if a particular integer (which does not match any enumerator) is=20
> within the valid range for that enum?
>
> Because this is legal. I can assign it a value on the specified range.=20
> That's all. If I want my code to be outside the UB world I should be able=
=20
> to check on the conditions. I can of course do it for each particular cas=
e,=20
> but what we are talking of here is about what the compiler could do for u=
s=20
> in a generic way.
>
> What are you trying to do that you need to do this?
>
> This is not a use case I would write myself, but I've see it a lot of=20
> times. When you use enums as flags of an bitset
> enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
> The valid enumerators  don't correspond to the valid range, that in this=
=20
> case is any value between 0 and 8.
>

But we can already answer that question. `X` is an `enum class`. As such,=
=20
it *always* has a fixed underlying type. If you don't specify one, then it=
=20
shall be `int`, and therefore `X` can legally assume any `int` value.

So the `std::underlying_type`-based solution will work fine.

It should also be noted that the standard-specified range guarantees the=20
ability to use an enum with an implied underlying type as a bitfield. That=
=20
is, if you perform bitwise operations with the enumerators, the results are=
=20
guaranteed to fit in the range. So you have nothing to worry about for that=
=20
use case.

> If you don't have a problem to be solved with such a function, then=20
> there's really no point in adding one.
>
> I was sure you will ask and say this ;-)
>
>
> I don't know why the new C++11 enum with an explicit underlying type have=
=20
>> a different range of valid values.
>> I'll be interested in knowing the rationale.
>>
>
> Because enums are integers. That's the rationale.
>
> I believe that you didn't understood my question. Let me see with an=20
> example.=20
> What is the difference between
>
>     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
> and=20
>
>     enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04=
, ALL=20
> 0x08};
> ?
>
> X has a valid range 0..N, while Y has a valid range 0..255.
>
> Why do we need this difference? Why forcing the underlying type changes=
=20
> the range of valid values?
>

In that case, both have a forced underlying type, as I pointed out above.=
=20
So the reason for the differing ranges of values is obvious.

Now, let's assume you have revised your example to not use `enum class`.=20
`enum X` does not have a fixed underlying type, so its range is determined=
=20
by its enumerators. The reason that is different is because that's how it=
=20
always was before, and there's terribly little reason to change it.

--=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/dbe0b3d3-e7ea-426a-a78d-6681202a4ea7%40isocpp.or=
g.

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

<div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicent=
e J. Botet 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 11/01/2017 =C3=A0 00:06, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Tuesday, January 10, 2017 at 5:26:11 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 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit=C2=A0=
:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Tuesday, January 10, 2017 at 1:49:05 PM
                UTC-5, Vicente J. Botet Escriba wrote:
                <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" text=3D"#000000">
                    <div>Le 10/01/2017 =C3=A0 16:31, <a rel=3D"nofollow">m.=
ce...@gmail.com</a>
                      a =C3=A9crit=C2=A0:<br>
                    </div>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr"><br>
                        W dniu wtorek, 10 stycznia 2017 13:49:00 UTC+1
                        u=C5=BCytkownik <a>gmis...@gmail.com</a>
                        napisa=C5=82:
                        <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"><br>
                            <br>
                            On Tuesday, January 3, 2017 at 10:56:05 PM
                            UTC+13, <a>m.ce...@gmail.com</a>
                            wrote:
                            <blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);bo=
rder-left-width:1px;border-left-style:solid">
                              <div dir=3D"ltr">Hi,
                                <div><br>
                                </div>
                              </div>
                            </blockquote>
                          </div>
                        </blockquote>
                        <br>
                        <div>I&#39;ll try to create a first draft after I
                          get some more comments w.r.t to exceptions.</div>
                        <div>For sure baseline API must be
                          exception-free.</div>
                        <div>Do we really want to additionally support
                          API that throws on error?</div>
                        <div>I&#39;m rather inclined to leave it out -
                          similarly as in to_chars/from_chars.</div>
                        <div>=C2=A0</div>
                        <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><br>
                            </div>
                            <div>I hope this post assists you with your
                              proposal.=C2=A0My suggestions are for your
                              proposal to look something like this:</div>
                            <div><br>
                            </div>
                            <div>In &lt;utility&gt; I think add:</div>
                            <div><br>
                            </div>
                            <div>bool template&lt;typename E, typename
                              V&gt; is_enum( V ev )</div>
                            <div>{</div>
                            <div>=C2=A0// compiler=C2=A0magic:</div>
                            <div>=C2=A0// Calling this routine causes the
                              compiler to generate or a call a routine</div=
>
                            <div>=C2=A0// that returns true if the value ev
                              matches one of the enum E&#39;s</div>
                            <div>=C2=A0// values. otherwise false.</div>
                            <div>}</div>
                          </div>
                        </blockquote>
                        <div><br>
                        </div>
                        <div>&#39;is_enum&#39; name is already used in
                          type_traits header.<br>
                        </div>
                        <div>Also is_enum seems redundant to me, since
                          to_enum already reports</div>
                        <div>if convertion succeeded instead of:</div>
                        <div>
                          <div style=3D"border:1px solid rgb(187,187,187);w=
ord-wrap:break-word;background-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">is_enum</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><=
span style=3D"color:#066">139</span><span style=3D"color:#660">))</span></d=
iv>
                            </code></div>
                          <br>
                        </div>
                        <div>you could write:</div>
                        <div>
                          <div style=3D"border:1px solid rgb(187,187,187);w=
ord-wrap:break-word;background-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">to_enum</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><=
span style=3D"color:#066">139</span><span style=3D"color:#660">).</span><sp=
an style=3D"color:#000">is_valid</span><span style=3D"color:#660"><wbr>)</s=
pan></div>
                            </code></div>
                          <br>
                        </div>
                        <div>or even:</div>
                        <div>
                          <div style=3D"border:1px solid rgb(187,187,187);w=
ord-wrap:break-word;background-color:rgb(250,250,250)"><code>
                              <div><span style=3D"color:#008">if</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">to_enum</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#606">MyEnum</span><span style=3D"color:#660">&gt;(</span><=
span style=3D"color:#066">139</span><span style=3D"color:#660">))</span></d=
iv>
                            </code></div>
                          if we add explicit bool convertion operator
                          for to_enum_result.</div>
                        <div><br>
                        </div>
                        <div><br>
                        </div>
                      </div>
                    </blockquote>
                    I believe we need two checking functions:<br>
                    * is_enumerator : checks if the explicit conversion
                    from the integer is one of the explicit enumerators<br>
                    * is_in_enum_range: checks if the integer is in the
                    range of valid values. This is the precondition of
                    the static_cast.<br>
                    <br>
                    IIUC when the underlying type is explicit, the range
                    of values are the range of the underlying type.
                    However when the underlying type is implicit the
                    range goes from the min to the max of the values of
                    the enumerators.<br>
                  </div>
                </blockquote>
                <div><br>
                  Right, but `is_enumerator` is a functional superset of
                  `is_in_enum_range`. Do people really need to ask <i>only<=
/i>
                  if a value is in the range of an enumerator?<br>
                </div>
              </div>
            </blockquote>
            I don&#39;t follow you. You surely wanted to say subset<br>
          </div>
        </blockquote>
        <div><br>
          Yes, I did. My mistake.<br>
          =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"> <br>
            The standard says in 7.2/8 :
            <blockquote>
              <div title=3D"Page 190">
                <div>
                  <div>
                    <ol start=3D"6" style=3D"list-style-type:none">
                      <li>
                        <p><span style=3D"font-size:7.000000pt;font-family:=
&#39;LMRoman7&#39;;vertical-align:2.000000pt">8
                            =C2=A0</span><span style=3D"font-size:10.000000=
pt;font-family:&#39;LMRoman10&#39;">For
                            an enumeration whose underlying type is
                            fixed, the values of the enumeration are the
                            values of the underlying type. Otherwise,
                            for an enumeration where </span><span style=3D"=
font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><span s=
tyle=3D"font-size:7.000000pt;font-family:&#39;LMRoman7&#39;;font-style:ital=
ic;vertical-align:-1.000000pt">min
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            the smallest enumerator and </span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><sp=
an style=3D"font-size:7.000000pt;font-family:&#39;LMRoman7&#39;;font-style:=
italic;vertical-align:-1.000000pt">max
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            the largest, the values of the enumeration
                            are the values in the range </span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">b</span><sp=
an style=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertic=
al-align:-1.000000pt">min
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">to
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathItalic10&#39;">b</span><span style=3D"font-size:7.000000p=
t;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt">max</span=
><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">, de=
fined as
                            follows: Let </span><span style=3D"font-size:10=
..000000pt;font-family:&#39;LMMathItalic10&#39;">K
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">be
                            1 for a two=E2=80=99s complement representation=
 and
                            0 for a ones=E2=80=99 complement or sign-magnit=
ude
                            representation. </span><span style=3D"font-size=
:10.000000pt;font-family:&#39;LMMathItalic10&#39;">b</span><span style=3D"f=
ont-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.0=
00000pt">max
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            the smallest value greater than or equal to
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathItalic10&#39;">max</span><span style=3D"font-size:10.0000=
00pt;font-family:&#39;LMRoman10&#39;">(</span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMMathSymbols10&#39;">|</span><span style=3D"font-=
size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><span style=
=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align=
:-1.000000pt">min</span><span style=3D"font-size:10.000000pt;font-family:&#=
39;LMMathSymbols10&#39;">| =E2=88=92 </span><span style=3D"font-size:10.000=
000pt;font-family:&#39;LMMathItalic10&#39;">K, </span><span style=3D"font-s=
ize:10.000000pt;font-family:&#39;LMMathSymbols10&#39;">|</span><span style=
=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">e</span><sp=
an style=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertic=
al-align:-1.000000pt">max</span><span style=3D"font-size:10.000000pt;font-f=
amily:&#39;LMMathSymbols10&#39;">|</span><span style=3D"font-size:10.000000=
pt;font-family:&#39;LMRoman10&#39;">) </span><span style=3D"font-size:10.00=
0000pt;font-family:&#39;LMRoman10&#39;">and
                            equal to </span><span style=3D"font-size:10.000=
000pt;font-family:&#39;LMRoman10&#39;">2</span><span style=3D"font-size:7.0=
00000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:4.000000pt">M
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathSymbols10&#39;">=E2=88=92
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">1</span><span style=3D"font-size:10.000000pt;fo=
nt-family:&#39;LMRoman10&#39;">, where </span><span style=3D"font-size:10.0=
00000pt;font-family:&#39;LMMathItalic10&#39;">M </span><span style=3D"font-=
size:10.000000pt;font-family:&#39;LMRoman10&#39;">is a non-negative
                            integer. </span><span style=3D"font-size:10.000=
000pt;font-family:&#39;LMMathItalic10&#39;">b</span><span style=3D"font-siz=
e:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt=
">min
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            zero if </span><span style=3D"font-size:10.0000=
00pt;font-family:&#39;LMMathItalic10&#39;">e</span><span style=3D"font-size=
:7.000000pt;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt"=
>min
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            non-negative and </span><span style=3D"font-siz=
e:10.000000pt;font-family:&#39;LMMathSymbols10&#39;">=E2=88=92</span><span =
style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">(</span><sp=
an style=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">b</=
span><span style=3D"font-size:7.000000pt;font-family:&#39;LMMathItalic7&#39=
;;vertical-align:-1.000000pt">max
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">+
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathItalic10&#39;">K</span><span style=3D"font-size:10.000000=
pt;font-family:&#39;LMRoman10&#39;">) </span><span style=3D"font-size:10.00=
0000pt;font-family:&#39;LMRoman10&#39;">otherwise.
                            The size of the smallest bit-field large
                            enough to hold all the values of the
                            enumeration type is </span><span style=3D"font-=
size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">max</span><span styl=
e=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">(</span><span s=
tyle=3D"font-size:10.000000pt;font-family:&#39;LMMathItalic10&#39;">M,</spa=
n><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;">1) =
</span><span style=3D"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;=
">if
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMMathItalic10&#39;">b</span><span style=3D"font-size:7.000000p=
t;font-family:&#39;LMMathItalic7&#39;;vertical-align:-1.000000pt">min
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            zero and </span><span style=3D"font-size:10.000=
000pt;font-family:&#39;LMMathItalic10&#39;">M
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">+
                            1 </span><span style=3D"font-size:10.000000pt;f=
ont-family:&#39;LMRoman10&#39;">otherwise.
                            <b>It is possible to define an enumeration
                              that has values not defined by any of its
                              enumerators.</b> If the </span><span style=3D=
"font-size:10.000000pt;font-family:&#39;LMRoman10&#39;;font-style:italic">e=
numerator-list
                          </span><span style=3D"font-size:10.000000pt;font-=
family:&#39;LMRoman10&#39;">is
                            empty, the values of the enumeration are as
                            if the enumeration had a single enumerator
                            with value 0. </span></p>
                      </li>
                    </ol>
                  </div>
                </div>
              </div>
              <br>
            </blockquote>
            For me enumerators are any one of the named enum values.
            This set is a subset=C2=A0 not a superset of the range of valid
            values.<br>
            <br>
            As I said, until we don&#39;t have enums that consists only of
            the enumerators, there would be always the need to check if
            a value is a valid value for the enumeration.<br>
          </div>
        </blockquote>
        <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>=C2=A0</div>
        </blockquote>
        <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"> We could define a clas=
s
            that accepts only the enumerators as valid values, but the
            language enums can accept more values.<br>
            This is way I believe that the two checks are needed.<br>
          </div>
        </blockquote>
        <div><br>
          Here&#39;s the thing.<br>
          <br>
          There are enumerations that have a fixed underlying type
          (`enum class`es use `int` by default), and there are
          enumerations that have an implied underlying type (ie:
          non-`class` enums without a specified type).<br>
        </div>
      </div>
    </blockquote>
    What is important is the range of values.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          The question I have to ask is this: if you have an integer,
          why do you need to know if it will fit within the range of an
          enum with an implied underlying type?</div>
      </div>
    </blockquote>
    Because initializing the enum with an integer out of range is UB.<br></=
div></blockquote><div><br>You&#39;re misunderstanding my question.<br><br>T=
he situation you describe is one where:<br><br>1. You have an integer of ar=
bitrary origin.<br><br>2. You want to convert it to an enum type.<br><br>3.=
 That integer <i>does not match</i> one of the enumerators in that type.<br=
><br>4. The enum type does not have a fixed underlying type.<br><br>What go=
al are you trying to achieve with all this? Or more to the point, why are y=
ou incapable of simply giving the enum an underlying type and thus making t=
he question moot?<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v bgcolor=3D"#FFFFFF" text=3D"#000000">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> What problem are you trying to solve? What code are you
          trying to write?<br>
          <br>
          If the enum has a fixed underlying type, then you might need
          to know the range because you&#39;re using the enum as an ad-hoc
          strongly typed integer.</div>
      </div>
    </blockquote>
    Right.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> I personally despise this obvious abuse of a language
          feature, but C++17 has effectively canonized it, so there it
          is. Alternatively, you may be using that enum as a bitfield.<br>
          <br>
          The thing is, that is a solved problem: get the underlying
          type with `std::underlying_type_t&lt;E&gt;`. That, and its
          corresponding `numeric_limits` will tell you everything you
          need to know about the range of that enumeration.<br>
        </div>
      </div>
    </blockquote>
    I don&#39;t want to solve problems that are already solved. We don&#39;=
t
    need any modification on the compiler to solve this case, but if it
    solve the more dificult case it could=C2=A0 solve this as well.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          But if the enum has an implied underlying type, then why would
          you need to know if a particular integer (which does not match
          any enumerator) is within the valid range for that enum?</div>
      </div>
    </blockquote>
    Because this is legal. I can assign it a value on the specified
    range. That&#39;s all. If I want my code to be outside the UB world I
    should be able to check on the conditions. I can of course do it for
    each particular case, but what we are talking of here is about what
    the compiler could do for us in a generic way.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div> What are you trying to do that you need to do this?<br>
        </div>
      </div>
    </blockquote>
    This is not a use case I would write myself, but I&#39;ve see it a lot
    of times. When you use enums as flags of an bitset<br>
    enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};<br>
    <br>
    The valid enumerators=C2=A0 don&#39;t correspond to the valid range, th=
at in
    this case is any value between 0 and 8.<br></div></blockquote><div><br>=
But we can already answer that question. `X` is an `enum class`. As such, i=
t <i>always</i> has a fixed underlying type. If you don&#39;t specify one, =
then it shall be `int`, and therefore `X` can legally assume any `int` valu=
e.<br><br>So the `std::underlying_type`-based solution will work fine.<br><=
br>It should also be noted that the standard-specified range guarantees the=
 ability to use an enum with an implied underlying type as a bitfield. That=
 is, if you perform bitwise operations with the enumerators, the results ar=
e guaranteed to fit in the range. So you have nothing to worry about for th=
at use case.<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgc=
olor=3D"#FFFFFF" text=3D"#000000">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          If you don&#39;t have a problem to be solved with such a function=
,
          then there&#39;s really no point in adding one.<br>
        </div>
      </div>
    </blockquote>
    I was sure you will ask and say this ;-)<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </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"> I don&#39;t know why t=
he
            new C++11 enum with an explicit underlying type have a
            different range of valid values.<br>
            I&#39;ll be interested in knowing the rationale.<br>
          </div>
        </blockquote>
        <div><br>
          Because enums are integers. That&#39;s the rationale.<br>
        </div>
      </div>
    </blockquote>
    I believe that you didn&#39;t understood my question. Let me see with a=
n
    example. <br>
    What is the difference between<br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x0=
4, ALL 0x08};<br>
    <br>
    and <br>
    <br>
    =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=
=3D0x02, C=3D0x04,
    ALL 0x08};<br>
    ?<br>
    <br>
    X has a valid range 0..N, while Y has a valid range 0..255.<br>
    <br>
    Why do we need this difference? Why forcing the underlying type
    changes the range of valid values?<br></div></blockquote><div><br>In th=
at case, both have a forced underlying type, as I pointed out above. So the=
 reason for the differing ranges of values is obvious.<br><br>Now, let&#39;=
s assume you have revised your example to not use `enum class`. `enum X` do=
es not have a fixed underlying type, so its range is determined by its enum=
erators. The reason that is different is because that&#39;s how it always w=
as before, and there&#39;s terribly little reason to change it.<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/dbe0b3d3-e7ea-426a-a78d-6681202a4ea7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dbe0b3d3-e7ea-426a-a78d-6681202a4ea7=
%40isocpp.org</a>.<br />

------=_Part_3782_848304554.1484169674858--

------=_Part_3781_1952031667.1484169674856--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 11 Jan 2017 13:25:48 -0800 (PST)
Raw View
------=_Part_1277_154112377.1484169948202
Content-Type: multipart/alternative;
 boundary="----=_Part_1278_2021335993.1484169948202"

------=_Part_1278_2021335993.1484169948202
Content-Type: text/plain; charset=UTF-8

On Wednesday, January 11, 2017 at 3:49:57 PM UTC-5, gmis...@gmail.com wrote:
>
> I personally despise this obvious abuse of a language feature, but C++17
>> has effectively canonized it, so there it is. Alternatively, you may be
>> using that enum as a bitfield.
>>
>> The thing is, that is a solved problem: get the underlying type with
>> `std::underlying_type_t<E>`. That, and its corresponding `numeric_limits`
>> will tell you everything you need to know about the range of that
>> enumeration.
>>
>> I don't want to solve problems that are already solved. We don't need any
>> modification on the compiler to solve this case, but if it solve the more
>> dificult case it could  solve this as well.
>>
>
> What are you both referring to here? I assumed modifying the compiler was
> a requirement to implement is_enum?
> Or maybe you know is_enum can already be implemented through meta
> programming without a compiler change?
> Or maybe you are talking about modifying the language (so still a compiler
> change) but so is_enum can implement this feature?
>

This conversation is separate from most of the rest of the thread.

The standard defines the difference between the range of values that are
legal for an enum type and the enumerators for that enum. `is_enum` answers
the latter question: is the integer one of the enumerators? What Vicente
wants is an answer to the former question: is the integer's value within
the range of the enumeration?

The reason it's non-trivial to implement yourself is because, for enums
with an implied underlying type, the valid range of the enumeration is
defined by the values of the enumerators, rather than the compiler-selected
underlying type. There's no way to compute that require reflection or
compiler gymnastics.

My main point of contention for the feature is why someone needs to ask it.
I don't feel Vicente has given sufficient justification for it.

--
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/876d94f3-acbd-4279-9708-d6edf6f5b311%40isocpp.org.

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

<div dir=3D"ltr">On Wednesday, January 11, 2017 at 3:49:57 PM 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">
    <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;pad=
ding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;bord=
er-left-style:solid"><div text=3D"#000000" bgcolor=3D"#FFFFFF"><blockquote =
type=3D"cite">
      <div dir=3D"ltr">
        <div> I personally despise this obvious abuse of a language
          feature, but C++17 has effectively canonized it, so there it
          is. Alternatively, you may be using that enum as a bitfield.<br>
          <br>
          The thing is, that is a solved problem: get the underlying
          type with `std::underlying_type_t&lt;E&gt;`. That, and its
          corresponding `numeric_limits` will tell you everything you
          need to know about the range of that enumeration.<br>
        </div>
      </div>
    </blockquote>
    I don&#39;t want to solve problems that are already solved. We don&#39;=
t
    need any modification on the compiler to solve this case, but if it
    solve the more dificult case it could=C2=A0 solve this as well.<br></di=
v></blockquote><div><br></div><div>What=C2=A0are you both=C2=A0referring to=
 here? I assumed=C2=A0modifying the compiler was a requirement to implement=
 is_enum?</div><div><div>Or maybe you know is_enum can=C2=A0already be impl=
emented through meta programming without a compiler change?</div><div>Or ma=
ybe you are talking about modifying the language (so still=C2=A0a compiler =
change) but so is_enum can implement this feature?</div></div></div></block=
quote><div><br>This conversation is separate from most of the rest of the t=
hread.<br><br>The standard defines the difference between the range of valu=
es that are legal for an enum type and the enumerators for that enum. `is_e=
num` answers the latter question: is the integer one of the enumerators? Wh=
at Vicente wants is an answer to the former question: is the integer&#39;s =
value within the range of the enumeration?<br><br>The reason it&#39;s non-t=
rivial to implement yourself is because, for enums with an implied underlyi=
ng type, the valid range of the enumeration is defined by the values of the=
 enumerators, rather than the compiler-selected underlying type. There&#39;=
s no way to compute that require reflection or compiler gymnastics.<br><br>=
My main point of contention for the feature is why someone needs to ask it.=
 I don&#39;t feel Vicente has given sufficient justification for it.<br></d=
iv></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/876d94f3-acbd-4279-9708-d6edf6f5b311%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/876d94f3-acbd-4279-9708-d6edf6f5b311=
%40isocpp.org</a>.<br />

------=_Part_1278_2021335993.1484169948202--

------=_Part_1277_154112377.1484169948202--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 12 Jan 2017 08:27:56 +0100
Raw View
This is a multi-part message in MIME format.
--------------5F826F0C354AB6EF0BC1AF2B
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit :
> On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
>     Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>>     On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J.
>>     Botet Escriba wrote:
>>
>>         Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9crit :
>>>         On Tuesday, January 10, 2017 at 1:49:05 PM UTC-5, Vicente J.
>>>         Botet Escriba wrote:
>>>
>>>             Le 10/01/2017 =C3=A0 16:31, m.ce...@gmail.com a =C3=A9crit =
:
>>>>
>>>>
>>>             I believe we need two checking functions:
>>>             * is_enumerator : checks if the explicit conversion from
>>>             the integer is one of the explicit enumerators
>>>             * is_in_enum_range: checks if the integer is in the
>>>             range of valid values. This is the precondition of the
>>>             static_cast.
>>>
>>>             IIUC when the underlying type is explicit, the range of
>>>             values are the range of the underlying type. However
>>>             when the underlying type is implicit the range goes from
>>>             the min to the max of the values of the enumerators.
>>>
>>>
>>>         Right, but `is_enumerator` is a functional superset of
>>>         `is_in_enum_range`. Do people really need to ask /only/ if a
>>>         value is in the range of an enumerator?
>>
>>
>>         The standard says in 7.2/8 :
>>
>>             6.
>>
>>                 8 For an enumeration whose underlying type is fixed,
>>                 the values of the enumeration are the values of the
>>                 underlying type. Otherwise, for an enumeration where
>>                 emin is the smallest enumerator and emax is the
>>                 largest, the values of the enumeration are the values
>>                 in the range bmin to bmax, defined as follows: Let K
>>                 be 1 for a two=E2=80=99s complement representation and 0=
 for
>>                 a ones=E2=80=99 complement or sign-magnitude representat=
ion.
>>                 bmax is the smallest value greater than or equal to
>>                 max(|emin| =E2=88=92 K, |emax|) and equal to 2M =E2=88=
=92 1, where M
>>                 is a non-negative integer. bmin is zero if emin is
>>                 non-negative and =E2=88=92(bmax + K) otherwise. The size=
 of
>>                 the smallest bit-field large enough to hold all the
>>                 values of the enumeration type is max(M,1) if bmin is
>>                 zero and M + 1 otherwise. *It is possible to define
>>                 an enumeration that has values not defined by any of
>>                 its enumerators.* If the enumerator-list is empty,
>>                 the values of the enumeration are as if the
>>                 enumeration had a single enumerator with value 0.
>>
>>
>>         For me enumerators are any one of the named enum values. This
>>         set is a subset  not a superset of the range of valid values.
>>
>>         As I said, until we don't have enums that consists only of
>>         the enumerators, there would be always the need to check if a
>>         value is a valid value for the enumeration.
>>
>>         We could define a class that accepts only the enumerators as
>>         valid values, but the language enums can accept more values.
>>         This is way I believe that the two checks are needed.
>>
>>
>>     Here's the thing.
>>
>>     There are enumerations that have a fixed underlying type (`enum
>>     class`es use `int` by default), and there are enumerations that
>>     have an implied underlying type (ie: non-`class` enums without a
>>     specified type).
>     What is important is the range of values.
>>
>>     The question I have to ask is this: if you have an integer, why
>>     do you need to know if it will fit within the range of an enum
>>     with an implied underlying type?
>     Because initializing the enum with an integer out of range is UB.
>
>
> You're misunderstanding my question.
>
> The situation you describe is one where:
>
> 1. You have an integer of arbitrary origin.
>
> 2. You want to convert it to an enum type.
>
> 3. That integer /does not match/ one of the enumerators in that type.
>
> 4. The enum type does not have a fixed underlying type.
>
You have described very well the context.
> What goal are you trying to achieve with all this? Or more to the=20
> point, why are you incapable of simply giving the enum an underlying=20
> type and thus making the question moot?
Because the enum is declared in a 3pp library in C++98? or a common part=20
that is shared by an application using C++98 and another using C++2x?
>
>>     What problem are you trying to solve? What code are you trying to
>>     write?
>>
>>     If the enum has a fixed underlying type, then you might need to
>>     know the range because you're using the enum as an ad-hoc
>>     strongly typed integer.
>     Right.
>>     I personally despise this obvious abuse of a language feature,
>>     but C++17 has effectively canonized it, so there it is.
>>     Alternatively, you may be using that enum as a bitfield.
>>
>>     The thing is, that is a solved problem: get the underlying type
>>     with `std::underlying_type_t<E>`. That, and its corresponding
>>     `numeric_limits` will tell you everything you need to know about
>>     the range of that enumeration.
>     I don't want to solve problems that are already solved. We don't
>     need any modification on the compiler to solve this case, but if
>     it solve the more dificult case it could  solve this as well.
>>
>>     But if the enum has an implied underlying type, then why would
>>     you need to know if a particular integer (which does not match
>>     any enumerator) is within the valid range for that enum?
>     Because this is legal. I can assign it a value on the specified
>     range. That's all. If I want my code to be outside the UB world I
>     should be able to check on the conditions. I can of course do it
>     for each particular case, but what we are talking of here is about
>     what the compiler could do for us in a generic way.
>>     What are you trying to do that you need to do this?
>     This is not a use case I would write myself, but I've see it a lot
>     of times. When you use enums as flags of an bitset
>     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
>     The valid enumerators  don't correspond to the valid range, that
>     in this case is any value between 0 and 8.
>
>
> But we can already answer that question. `X` is an `enum class`. As=20
> such, it /always/ has a fixed underlying type. If you don't specify=20
> one, then it shall be `int`, and therefore `X` can legally assume any=20
> `int` value.
 From the text of the standard I send before, the range is not the range=20
of int. Could you point me from where are you concluding this?
Is the same if the enum are not scoped?
>
> So the `std::underlying_type`-based solution will work fine.
>
> It should also be noted that the standard-specified range guarantees=20
> the ability to use an enum with an implied underlying type as a=20
> bitfield. That is, if you perform bitwise operations with the=20
> enumerators, the results are guaranteed to fit in the range. So you=20
> have nothing to worry about for that use case.
>
>>     If you don't have a problem to be solved with such a function,
>>     then there's really no point in adding one.
>     I was sure you will ask and say this ;-)
>>
>>         I don't know why the new C++11 enum with an explicit
>>         underlying type have a different range of valid values.
>>         I'll be interested in knowing the rationale.
>>
>>
>>     Because enums are integers. That's the rationale.
>     I believe that you didn't understood my question. Let me see with
>     an example.
>     What is the difference between
>
>         enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
>     and
>
>         enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D=
0x04,
>     ALL 0x08};
>     ?
>
>     X has a valid range 0..N, while Y has a valid range 0..255.
>
>     Why do we need this difference? Why forcing the underlying type
>     changes the range of valid values?
>
>
> In that case, both have a forced underlying type, as I pointed out=20
> above. So the reason for the differing ranges of values is obvious.
>
> Now, let's assume you have revised your example to not use `enum=20
> class`. `enum X` does not have a fixed underlying type, so its range=20
> is determined by its enumerators. The reason that is different is=20
> because that's how it always was before, and there's terribly little=20
> reason to change it.
I'm not questioning the old C++98 behavior but the new C++11 behavior=20
(if we can say new for C++11)

Vicente

--=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/0a4162ad-62ed-1c26-e210-81000402b193%40wanadoo.f=
r.

--------------5F826F0C354AB6EF0BC1AF2B
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 11/01/2017 =C3=A0 22:21, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:dbe0b3d3-e7ea-426a-a78d-6681202a4ea7@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5,
        Vicente J. Botet Escriba wrote:
        <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" text=3D"#000000">
            <div>Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit=C2=A0=
:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Tuesday, January 10, 2017 at 5:26:11 PM
                UTC-5, Vicente J. Botet Escriba wrote:
                <blockquote class=3D"gmail_quote"
                  style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                  solid;padding-left:1ex">
                  <div>
                    <div>Le 10/01/2017 =C3=A0 20:30, Nicol Bolas a =C3=A9cr=
it=C2=A0:<br>
                    </div>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr">On Tuesday, January 10, 2017 at
                        1:49:05 PM UTC-5, Vicente J. Botet Escriba
                        wrote:
                        <blockquote class=3D"gmail_quote"
                          style=3D"margin:0;margin-left:0.8ex;border-left:1=
px
                          #ccc solid;padding-left:1ex">
                          <div bgcolor=3D"#FFFFFF" text=3D"#000000">
                            <div>Le 10/01/2017 =C3=A0 16:31, <a
                                moz-do-not-send=3D"true" rel=3D"nofollow">m=
..ce...@gmail.com</a>
                              a =C3=A9crit=C2=A0:<br>
                            </div>
                            <blockquote type=3D"cite">
                              <div dir=3D"ltr"><br>
                                <br>
                              </div>
                            </blockquote>
                            I believe we need two checking functions:<br>
                            * is_enumerator : checks if the explicit
                            conversion from the integer is one of the
                            explicit enumerators<br>
                            * is_in_enum_range: checks if the integer is
                            in the range of valid values. This is the
                            precondition of the static_cast.<br>
                            <br>
                            IIUC when the underlying type is explicit,
                            the range of values are the range of the
                            underlying type. However when the underlying
                            type is implicit the range goes from the min
                            to the max of the values of the enumerators.<br=
>
                          </div>
                        </blockquote>
                        <div><br>
                          Right, but `is_enumerator` is a functional
                          superset of `is_in_enum_range`. Do people
                          really need to ask <i>only</i> if a value is
                          in the range of an enumerator?<br>
                        </div>
                      </div>
                    </blockquote>
                    <br>
                    =C2=A0</div>
                </blockquote>
                <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" text=3D"#000000"> <br>
                    The standard says in 7.2/8 :
                    <blockquote>
                      <div title=3D"Page 190">
                        <div>
                          <div>
                            <ol start=3D"6" style=3D"list-style-type:none">
                              <li>
                                <p><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';vertical-align:2.00000=
0pt">8
                                    =C2=A0</span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">For
                                    an enumeration whose underlying type
                                    is fixed, the values of the
                                    enumeration are the values of the
                                    underlying type. Otherwise, for an
                                    enumeration where </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';font-style:italic;vert=
ical-align:-1.000000pt">min
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    the smallest enumerator and </span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMRoman7';font-style:italic;vert=
ical-align:-1.000000pt">max
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    the largest, the values of the
                                    enumeration are the values in the
                                    range </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">to
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">, defined as
                                    follows: Let </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">K
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">be
                                    1 for a two=E2=80=99s complement
                                    representation and 0 for a ones=E2=80=
=99
                                    complement or sign-magnitude
                                    representation. </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    the smallest value greater than or
                                    equal to </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">| =E2=88=92 <=
/span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">K, </span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max</span><span
style=3D"font-size:10.000000pt;font-family:'LMMathSymbols10'">|</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">) </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">and
                                    equal to </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">2</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:4.=
000000pt">M
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathSymbols10'">=E2=88=92
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">1</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">, where </span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">M </span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">is a non-negative
                                    integer. </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    zero if </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">e</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    non-negative and </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathSymbols10'">=E2=88=92</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">max
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">+
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">K</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">) </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">otherwise.
                                    The size of the smallest bit-field
                                    large enough to hold all the values
                                    of the enumeration type is </span><span
style=3D"font-size:10.000000pt;font-family:'LMMathItalic10'">max</span><spa=
n
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">(</span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">M,</span><span
style=3D"font-size:10.000000pt;font-family:'LMRoman10'">1) </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">if
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">b</span><span
style=3D"font-size:7.000000pt;font-family:'LMMathItalic7';vertical-align:-1=
..000000pt">min
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    zero and </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMMathItalic10'">M
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">+
                                    1 </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">otherwise.
                                    <b>It is possible to define an
                                      enumeration that has values not
                                      defined by any of its enumerators.</b=
>
                                    If the </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10';font-style:italic">enumerator-list
                                  </span><span
                                    style=3D"font-size:10.000000pt;font-fam=
ily:'LMRoman10'">is
                                    empty, the values of the enumeration
                                    are as if the enumeration had a
                                    single enumerator with value 0. </span>=
</p>
                              </li>
                            </ol>
                          </div>
                        </div>
                      </div>
                      <br>
                    </blockquote>
                    For me enumerators are any one of the named enum
                    values. This set is a subset=C2=A0 not a superset of th=
e
                    range of valid values.<br>
                    <br>
                    As I said, until we don't have enums that consists
                    only of the enumerators, there would be always the
                    need to check if a value is a valid value for the
                    enumeration.<br>
                  </div>
                </blockquote>
                <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px
                  0px 0.8ex;border-left:1px solid
                  rgb(204,204,204);padding-left:1ex">
                  <div>=C2=A0</div>
                </blockquote>
                <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" text=3D"#000000"> We could defin=
e
                    a class that accepts only the enumerators as valid
                    values, but the language enums can accept more
                    values.<br>
                    This is way I believe that the two checks are
                    needed.<br>
                  </div>
                </blockquote>
                <div><br>
                  Here's the thing.<br>
                  <br>
                  There are enumerations that have a fixed underlying
                  type (`enum class`es use `int` by default), and there
                  are enumerations that have an implied underlying type
                  (ie: non-`class` enums without a specified type).<br>
                </div>
              </div>
            </blockquote>
            What is important is the range of values.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  The question I have to ask is this: if you have an
                  integer, why do you need to know if it will fit within
                  the range of an enum with an implied underlying type?</di=
v>
              </div>
            </blockquote>
            Because initializing the enum with an integer out of range
            is UB.<br>
          </div>
        </blockquote>
        <div><br>
          You're misunderstanding my question.<br>
          <br>
          The situation you describe is one where:<br>
          <br>
          1. You have an integer of arbitrary origin.<br>
          <br>
          2. You want to convert it to an enum type.<br>
          <br>
          3. That integer <i>does not match</i> one of the enumerators
          in that type.<br>
          <br>
          4. The enum type does not have a fixed underlying type.<br>
          <br>
        </div>
      </div>
    </blockquote>
    You have described very well the context.<br>
    <blockquote
      cite=3D"mid:dbe0b3d3-e7ea-426a-a78d-6681202a4ea7@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>What goal are you trying to achieve with all this? Or more
          to the point, why are you incapable of simply giving the enum
          an underlying type and thus making the question moot?<br>
        </div>
      </div>
    </blockquote>
    Because the enum is declared in a 3pp library in C++98? or a common
    part that is shared by an application using C++98 and another using
    C++2x?<br>
    <blockquote
      cite=3D"mid:dbe0b3d3-e7ea-426a-a78d-6681202a4ea7@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <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" text=3D"#000000">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What problem are you trying to solve? What code
                  are you trying to write?<br>
                  <br>
                  If the enum has a fixed underlying type, then you
                  might need to know the range because you're using the
                  enum as an ad-hoc strongly typed integer.</div>
              </div>
            </blockquote>
            Right.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> I personally despise this obvious abuse of a
                  language feature, but C++17 has effectively canonized
                  it, so there it is. Alternatively, you may be using
                  that enum as a bitfield.<br>
                  <br>
                  The thing is, that is a solved problem: get the
                  underlying type with
                  `std::underlying_type_t&lt;E&gt;`. That, and its
                  corresponding `numeric_limits` will tell you
                  everything you need to know about the range of that
                  enumeration.<br>
                </div>
              </div>
            </blockquote>
            I don't want to solve problems that are already solved. We
            don't need any modification on the compiler to solve this
            case, but if it solve the more dificult case it could=C2=A0 sol=
ve
            this as well.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  But if the enum has an implied underlying type, then
                  why would you need to know if a particular integer
                  (which does not match any enumerator) is within the
                  valid range for that enum?</div>
              </div>
            </blockquote>
            Because this is legal. I can assign it a value on the
            specified range. That's all. If I want my code to be outside
            the UB world I should be able to check on the conditions. I
            can of course do it for each particular case, but what we
            are talking of here is about what the compiler could do for
            us in a generic way.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What are you trying to do that you need to do
                  this?<br>
                </div>
              </div>
            </blockquote>
            This is not a use case I would write myself, but I've see it
            a lot of times. When you use enums as flags of an bitset<br>
            enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08=
};<br>
            <br>
            The valid enumerators=C2=A0 don't correspond to the valid range=
,
            that in this case is any value between 0 and 8.<br>
          </div>
        </blockquote>
        <div><br>
          But we can already answer that question. `X` is an `enum
          class`. As such, it <i>always</i> has a fixed underlying
          type. If you don't specify one, then it shall be `int`, and
          therefore `X` can legally assume any `int` value.<br>
        </div>
      </div>
    </blockquote>
    From the text of the standard I send before, the range is not the
    range of int. Could you point me from where are you concluding this?<br=
>
    Is the same if the enum are not scoped?<br>
    <blockquote
      cite=3D"mid:dbe0b3d3-e7ea-426a-a78d-6681202a4ea7@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          So the `std::underlying_type`-based solution will work fine.<br>
          <br>
          It should also be noted that the standard-specified range
          guarantees the ability to use an enum with an implied
          underlying type as a bitfield. That is, if you perform bitwise
          operations with the enumerators, the results are guaranteed to
          fit in the range. So you have nothing to worry about for that
          use case.<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" text=3D"#000000">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> If you don't have a problem to be solved with such
                  a function, then there's really no point in adding
                  one.<br>
                </div>
              </div>
            </blockquote>
            I was sure you will ask and say this ;-)<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><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" text=3D"#000000"> I don't know
                    why the new C++11 enum with an explicit underlying
                    type have a different range of valid values.<br>
                    I'll be interested in knowing the rationale.<br>
                  </div>
                </blockquote>
                <div><br>
                  Because enums are integers. That's the rationale.<br>
                </div>
              </div>
            </blockquote>
            I believe that you didn't understood my question. Let me see
            with an example. <br>
            What is the difference between<br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02,=
 C=3D0x04, ALL
            0x08};<br>
            <br>
            and <br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=
=3D0x01, B=3D0x02,
            C=3D0x04, ALL 0x08};<br>
            ?<br>
            <br>
            X has a valid range 0..N, while Y has a valid range 0..255.<br>
            <br>
            Why do we need this difference? Why forcing the underlying
            type changes the range of valid values?<br>
          </div>
        </blockquote>
        <div><br>
          In that case, both have a forced underlying type, as I pointed
          out above. So the reason for the differing ranges of values is
          obvious.<br>
          <br>
          Now, let's assume you have revised your example to not use
          `enum class`. `enum X` does not have a fixed underlying type,
          so its range is determined by its enumerators. The reason that
          is different is because that's how it always was before, and
          there's terribly little reason to change it.<br>
        </div>
      </div>
    </blockquote>
    I'm not questioning the old C++98 behavior but the new C++11
    behavior (if we can say new for C++11)<br>
    <br>
    Vicente<br>
  </body>
</html>

<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/0a4162ad-62ed-1c26-e210-81000402b193%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0a4162ad-62ed-1c26-e210-81000402b193=
%40wanadoo.fr</a>.<br />

--------------5F826F0C354AB6EF0BC1AF2B--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 12 Jan 2017 08:45:05 +0100
Raw View
This is a multi-part message in MIME format.
--------------3E1E3455E67E5E81844D9169
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 11/01/2017 =C3=A0 21:49, gmisocpp@gmail.com a =C3=A9crit :
>
>>
>     What is important is the range of values.
>>
>>     The question I have to ask is this: if you have an integer, why
>>     do you need to know if it will fit within the range of an enum
>>     with an implied underlying type?
>     Because initializing the enum with an integer out of range is UB.
>
>
> In my earlier post where I described at length how I thought the API=20
> should be, was there UB in that and if so where?
> I'm trying to understand where your UB comments are directed as I'm=20
> not seeing where this happens.
The interface you have proposed doesn't introduce any UB, it avoid it,=20
because the test is over a subset of the valid values for an=20
enumeration. The UB is defined in standard. See the paragraph I=20
mentioned. What I'm saying is that we need a function that checks also=20
exactly for the valid values. Is that so complex to understand.

>>     What problem are you trying to solve? What code are you trying to
>>     write?
>>
>>     If the enum has a fixed underlying type, then you might need to
>>     know the range because you're using the enum as an ad-hoc
>>     strongly typed integer.
>     Right.
>>     I personally despise this obvious abuse of a language feature,
>>     but C++17 has effectively canonized it, so there it is.
>>     Alternatively, you may be using that enum as a bitfield.
>>
>>     The thing is, that is a solved problem: get the underlying type
>>     with `std::underlying_type_t<E>`. That, and its corresponding
>>     `numeric_limits` will tell you everything you need to know about
>>     the range of that enumeration.
>     I don't want to solve problems that are already solved. We don't
>     need any modification on the compiler to solve this case, but if
>     it solve the more dificult case it could  solve this as well.
>
>
> What are you both referring to here?
We are talking here of is_in _enum_rang (or is_valid_enum) by opposition=20
to is_enumerator (your is_enum).
is_valid_enum can be implemented easily with the current=20
meta-programming when the underlying type is explict.
> I assumed modifying the compiler was a requirement to implement is_enum?
I would say that it is easier to maintain if the compiler generates the=20
function. Anyone can define such a function for each enum.
> Or maybe you know is_enum can already be implemented through meta=20
> programming without a compiler change?
It can with enough meta-programming information, as the one the=20
reflection proposal has, yes.
> Or maybe you are talking about modifying the language (so still a=20
> compiler change) but so is_enum can implement this feature?
Are you talking of static reflection here?
>
>>
>>     But if the enum has an implied underlying type, then why would
>>     you need to know if a particular integer (which does not match
>>     any enumerator) is within the valid range for that enum?
>     Because this is legal. I can assign it a value on the specified
>     range. That's all. If I want my code to be outside the UB world I
>     should be able to check on the conditions. I can of course do it
>     for each particular case, but what we are talking of here is about
>     what the compiler could do for us in a generic way.
>
>
> The compiler is generating the code so where does generic come into this?
The words generic way were in opposition to each particular case.
>
>>     What are you trying to do that you need to do this?
>     This is not a use case I would write myself, but I've see it a lot
>     of times. When you use enums as flags of an bitset
>     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
>     The valid enumerators  don't correspond to the valid range, that
>     in this case is any value between 0 and 8.
>>
>>     If you don't have a problem to be solved with such a function,
>>     then there's really no point in adding one.
>     I was sure you will ask and say this ;-)
>>
>>         I don't know why the new C++11 enum with an explicit
>>         underlying type have a different range of valid values.
>>         I'll be interested in knowing the rationale.
>>
>>
>>     Because enums are integers. That's the rationale.
>     I believe that you didn't understood my question. Let me see with
>     an example.
>     What is the difference between
>
>         enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>
>     and
>
>         enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D=
0x04,
>     ALL 0x08};
>     ?
>
>     X has a valid range 0..N, while Y has a valid range 0..255.
>
>     Why do we need this difference? Why forcing the underlying type
>     changes the range of valid values?
>
>
> I had std::any_enum_value in my earlier post and make_bad_enum knew=20
> the type of the enum.
> The idea was that those two pieces of information allowed a value to=20
> be constructed that could express any enum as intended.
> I'm raising that in case it's helpful to this conversation here but it=20
> might not be because I can't quite follow what problem is being solved=20
> here?
It seems that I should not explain myself correctly as people is not=20
understanding the complementary problem I'm raising.

The question is : Does your any_enum_value check for the enumerators=20
values or the valid range of the enumeration?

Vicente

--=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/2884ad60-bfb5-5275-bfd1-e741b22b962f%40wanadoo.f=
r.

--------------3E1E3455E67E5E81844D9169
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 11/01/2017 =C3=A0 21:49,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:gmisocpp@gmail.c=
om">gmisocpp@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px
          0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,
          204); border-left-width: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                </div>
              </div>
            </blockquote>
            What is important is the range of values.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  The question I have to ask is this: if you have an
                  integer, why do you need to know if it will fit within
                  the range of an enum with an implied underlying type?</di=
v>
              </div>
            </blockquote>
            Because initializing the enum with an integer out of range
            is UB.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>In my earlier post where I described at length how I
          thought the API should be, was there UB in that and if so
          where?</div>
        <div>I'm trying to understand where your UB comments are
          directed as I'm not seeing where this happens.</div>
      </div>
    </blockquote>
    The interface you have proposed doesn't introduce any UB, it avoid
    it, because the test is over a subset of the valid values for an
    enumeration. The UB is defined in standard. See the paragraph I
    mentioned. What I'm saying is that we need a function that checks
    also exactly for the valid values. Is that so complex to understand.<br=
>
    <br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>=C2=A0</div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px
          0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,
          204); border-left-width: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What problem are you trying to solve? What code
                  are you trying to write?<br>
                  <br>
                  If the enum has a fixed underlying type, then you
                  might need to know the range because you're using the
                  enum as an ad-hoc strongly typed integer.</div>
              </div>
            </blockquote>
            Right.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> I personally despise this obvious abuse of a
                  language feature, but C++17 has effectively canonized
                  it, so there it is. Alternatively, you may be using
                  that enum as a bitfield.<br>
                  <br>
                  The thing is, that is a solved problem: get the
                  underlying type with
                  `std::underlying_type_t&lt;E&gt;`. That, and its
                  corresponding `numeric_limits` will tell you
                  everything you need to know about the range of that
                  enumeration.<br>
                </div>
              </div>
            </blockquote>
            I don't want to solve problems that are already solved. We
            don't need any modification on the compiler to solve this
            case, but if it solve the more dificult case it could=C2=A0 sol=
ve
            this as well.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>What=C2=A0are you both=C2=A0referring to here? </div>
      </div>
    </blockquote>
    We are talking here of is_in _enum_rang (or is_valid_enum) by
    opposition to is_enumerator (your is_enum).<br>
    is_valid_enum can be implemented easily with the current
    meta-programming when the underlying type is explict.<br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>I assumed=C2=A0modifying the compiler was a requirement to
          implement is_enum?</div>
      </div>
    </blockquote>
    I would say that it is easier to maintain if the compiler generates
    the function. Anyone can define such a function for each enum.<br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>Or maybe you know is_enum can=C2=A0already be implemented
            through meta programming without a compiler change?</div>
        </div>
      </div>
    </blockquote>
    It can with enough meta-programming information, as the one the
    reflection proposal has, yes.<br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>Or maybe you are talking about modifying the language (so
            still=C2=A0a compiler change) but so is_enum can implement this
            feature?</div>
        </div>
      </div>
    </blockquote>
    Are you talking of static reflection here?<br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div><br>
          </div>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px
          0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,
          204); border-left-width: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  But if the enum has an implied underlying type, then
                  why would you need to know if a particular integer
                  (which does not match any enumerator) is within the
                  valid range for that enum?</div>
              </div>
            </blockquote>
            Because this is legal. I can assign it a value on the
            specified range. That's all. If I want my code to be outside
            the UB world I should be able to check on the conditions. I
            can of course do it for each particular case, but what we
            are talking of here is about what the compiler could do for
            us in a generic way.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>The compiler is generating the code so=C2=A0where does generic
          come into this?</div>
      </div>
    </blockquote>
    The words generic way were in opposition to each particular case.<br>
    <blockquote
      cite=3D"mid:be99b871-2e8f-4c9b-b9f3-dff8543bc38a@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px
          0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,
          204); border-left-width: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What are you trying to do that you need to do
                  this?<br>
                </div>
              </div>
            </blockquote>
            This is not a use case I would write myself, but I've see it
            a lot of times. When you use enums as flags of an bitset<br>
            enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08=
};<br>
            <br>
            The valid enumerators=C2=A0 don't correspond to the valid range=
,
            that in this case is any value between 0 and 8.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  If you don't have a problem to be solved with such a
                  function, then there's really no point in adding one.<br>
                </div>
              </div>
            </blockquote>
            I was sure you will ask and say this ;-)<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                </div>
                <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px
                  0px 0.8ex; padding-left: 1ex; border-left-color:
                  rgb(204, 204, 204); border-left-width: 1px;
                  border-left-style: solid;">
                  <div text=3D"#000000" bgcolor=3D"#FFFFFF"> I don't know
                    why the new C++11 enum with an explicit underlying
                    type have a different range of valid values.<br>
                    I'll be interested in knowing the rationale.<br>
                  </div>
                </blockquote>
                <div><br>
                  Because enums are integers. That's the rationale.<br>
                </div>
              </div>
            </blockquote>
            I believe that you didn't understood my question. Let me see
            with an example. <br>
            What is the difference between<br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02,=
 C=3D0x04, ALL
            0x08};<br>
            <br>
            and <br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=
=3D0x01, B=3D0x02,
            C=3D0x04, ALL 0x08};<br>
            ?<br>
            <br>
            X has a valid range 0..N, while Y has a valid range 0..255.<br>
            <br>
            Why do we need this difference? Why forcing the underlying
            type changes the range of valid values?<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>I had std::any_enum_value in my earlier post and
          make_bad_enum knew the type of the enum.</div>
        <div>The idea was that those two pieces of information allowed=C2=
=A0a
          value to be=C2=A0constructed that could express any enum as
          intended.</div>
        <div>I'm=C2=A0raising that in case it's=C2=A0helpful to this conver=
sation
          here but it might not be because I can't quite follow what
          problem is being solved here?</div>
      </div>
    </blockquote>
    It seems that I should not explain myself correctly as people is not
    understanding the complementary problem I'm raising.<br>
    <br>
    The question is : Does your any_enum_value check for the enumerators
    values or the valid range of the enumeration?<br>
    <br>
    Vicente<br>
  </body>
</html>

<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/2884ad60-bfb5-5275-bfd1-e741b22b962f%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2884ad60-bfb5-5275-bfd1-e741b22b962f=
%40wanadoo.fr</a>.<br />

--------------3E1E3455E67E5E81844D9169--

.


Author: gmisocpp@gmail.com
Date: Thu, 12 Jan 2017 03:35:30 -0800 (PST)
Raw View
------=_Part_468_2126305148.1484220930768
Content-Type: multipart/alternative;
 boundary="----=_Part_469_77118346.1484220930769"

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


Hi Vincente

On Thursday, January 12, 2017 at 8:45:08 PM UTC+13, Vicente J. Botet=20
Escriba wrote:

> Le 11/01/2017 =C3=A0 21:49, gmis...@gmail.com <javascript:> a =C3=A9crit =
:
>
>
>> What is important is the range of values.
>>
>>
>> The question I have to ask is this: if you have an integer, why do you=
=20
>> need to know if it will fit within the range of an enum with an implied=
=20
>> underlying type?
>>
>> Because initializing the enum with an integer out of range is UB.
>>
>
> In my earlier post where I described at length how I thought the API=20
> should be, was there UB in that and if so where?
> I'm trying to understand where your UB comments are directed as I'm not=
=20
> seeing where this happens.
>
> The interface you have proposed doesn't introduce any UB, it avoid it,=20
> because the test is over a subset of the valid values for an enumeration.=
=20
> The UB is defined in standard. See the paragraph I mentioned. What I'm=20
> saying is that we need a function that checks also exactly for the valid=
=20
> values. Is that so complex to understand.
>

What made it complex to me was that you said UB and I didn't see any UB.
Yes I agree we need a function to test the enum values. I do not know why=
=20
you feel it's  'subset' of enum values though.
=20

>
> =20
>
>> What problem are you trying to solve? What code are you trying to write?
>>
>> If the enum has a fixed underlying type, then you might need to know the=
=20
>> range because you're using the enum as an ad-hoc strongly typed integer.
>>
>> Right.
>>
>> I personally despise this obvious abuse of a language feature, but C++17=
=20
>> has effectively canonized it, so there it is. Alternatively, you may be=
=20
>> using that enum as a bitfield.
>>
>> The thing is, that is a solved problem: get the underlying type with=20
>> `std::underlying_type_t<E>`. That, and its corresponding `numeric_limits=
`=20
>> will tell you everything you need to know about the range of that=20
>> enumeration.
>>
>> I don't want to solve problems that are already solved. We don't need an=
y=20
>> modification on the compiler to solve this case, but if it solve the mor=
e=20
>> dificult case it could  solve this as well.
>>
>
> What are you both referring to here?=20
>
> We are talking here of is_in _enum_rang (or is_valid_enum) by opposition=
=20
> to is_enumerator (your is_enum).
> is_valid_enum can be implemented easily with the current meta-programming=
=20
> when the underlying type is explict.
>
> I assumed modifying the compiler was a requirement to implement is_enum?
>
> I would say that it is easier to maintain if the compiler generates the=
=20
> function. Anyone can define such a function for each enum.
>
> Or maybe you know is_enum can already be implemented through meta=20
> programming without a compiler change?
>
> It can with enough meta-programming information, as the one the reflectio=
n=20
> proposal has, yes.
>
> Or maybe you are talking about modifying the language (so still a compile=
r=20
> change) but so is_enum can implement this feature?
>
> Are you talking of static reflection here?
>
>
>
>> But if the enum has an implied underlying type, then why would you need=
=20
>> to know if a particular integer (which does not match any enumerator) is=
=20
>> within the valid range for that enum?
>>
>> Because this is legal. I can assign it a value on the specified range.=
=20
>> That's all. If I want my code to be outside the UB world I should be abl=
e=20
>> to check on the conditions. I can of course do it for each particular ca=
se,=20
>> but what we are talking of here is about what the compiler could do for =
us=20
>> in a generic way.
>>
>
> The compiler is generating the code so where does generic come into this?
>
> The words generic way were in opposition to each particular case.
>
>
> What are you trying to do that you need to do this?
>>
>> This is not a use case I would write myself, but I've see it a lot of=20
>> times. When you use enums as flags of an bitset
>> enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>>
>> The valid enumerators  don't correspond to the valid range, that in this=
=20
>> case is any value between 0 and 8.
>>
>>
>> If you don't have a problem to be solved with such a function, then=20
>> there's really no point in adding one.
>>
>> I was sure you will ask and say this ;-)
>>
>>
>> I don't know why the new C++11 enum with an explicit underlying type hav=
e=20
>>> a different range of valid values.
>>> I'll be interested in knowing the rationale.
>>>
>>
>> Because enums are integers. That's the rationale.
>>
>> I believe that you didn't understood my question. Let me see with an=20
>> example.=20
>> What is the difference between
>>
>>     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>>
>> and=20
>>
>>     enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x0=
4, ALL=20
>> 0x08};
>> ?
>>
>> X has a valid range 0..N, while Y has a valid range 0..255.
>>
>> Why do we need this difference? Why forcing the underlying type changes=
=20
>> the range of valid values?
>>
>
> I had std::any_enum_value in my earlier post and make_bad_enum knew the=
=20
> type of the enum.
> The idea was that those two pieces of information allowed a value to=20
> be constructed that could express any enum as intended.
> I'm raising that in case it's helpful to this conversation here but it=20
> might not be because I can't quite follow what problem is being solved he=
re?
>
> It seems that I should not explain myself correctly as people is not=20
> understanding the complementary problem I'm raising.
>
sorry=20

>
> The question is : Does your any_enum_value check for the enumerators=20
> values or the valid range of the enumeration?
>

My std::any_enum_value does not range check or anything, I envisaged it as=
=20
a container that promises to be large enough to hold any enum=20
value possible for an ABI, nothing else. As best as I can tell from looking=
=20
at my earlier post, any_enum_value was left in by mistake from a more=20
complex design where I was thinking where the interface would be more like=
=20
std::optional.

But I didn't recommend that design in the end so I don't think it was used=
=20
because bad_enum isn't used either, I used std::range_error and satisfied=
=20
myself that was ok because the error message would be detailed enough to=20
show what type of enum failed and the value that failed to convert. So=20
a dedicated bad_enum wasn't needed unless we needed to query information=20
out of that. Which I decided we probably didn't.

Hope that helps.

--=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/d2c589d7-15a3-4069-b32e-7b6506438ca7%40isocpp.or=
g.

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

<div dir=3D"ltr"><div><br></div><div>Hi Vincente<br><br>On Thursday, Januar=
y 12, 2017 at 8:45:08 PM UTC+13, Vicente J. Botet Escriba wrote:</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-le=
ft: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bor=
der-left-style: solid;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>Le 11/01/2017 =C3=A0 21:49,
      <a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onc=
lick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascript:=
" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"mvZhyHB2BgAJ"=
>gmis...@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                </div>
              </div>
            </blockquote>
            What is important is the range of values.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  The question I have to ask is this: if you have an
                  integer, why do you need to know if it will fit within
                  the range of an enum with an implied underlying type?</di=
v>
              </div>
            </blockquote>
            Because initializing the enum with an integer out of range
            is UB.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>In my earlier post where I described at length how I
          thought the API should be, was there UB in that and if so
          where?</div>
        <div>I&#39;m trying to understand where your UB comments are
          directed as I&#39;m not seeing where this happens.</div>
      </div>
    </blockquote>
    The interface you have proposed doesn&#39;t introduce any UB, it avoid
    it, because the test is over a subset of the valid values for an
    enumeration. The UB is defined in standard. See the paragraph I
    mentioned. What I&#39;m saying is that we need a function that checks
    also exactly for the valid values. Is that so complex to understand.<br=
></div></blockquote><div><br></div><div>What made it complex to me was that=
 you said UB and I didn&#39;t see any UB.</div><div>Yes I agree we need a f=
unction to test the=C2=A0enum values. I do not know=C2=A0why you feel=C2=A0=
it&#39;s =C2=A0&#39;subset&#39; of enum values though.</div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; pad=
ding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1=
px; border-left-style: solid;"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>=C2=A0</div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What problem are you trying to solve? What code
                  are you trying to write?<br>
                  <br>
                  If the enum has a fixed underlying type, then you
                  might need to know the range because you&#39;re using the
                  enum as an ad-hoc strongly typed integer.</div>
              </div>
            </blockquote>
            Right.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> I personally despise this obvious abuse of a
                  language feature, but C++17 has effectively canonized
                  it, so there it is. Alternatively, you may be using
                  that enum as a bitfield.<br>
                  <br>
                  The thing is, that is a solved problem: get the
                  underlying type with
                  `std::underlying_type_t&lt;E&gt;`. That, and its
                  corresponding `numeric_limits` will tell you
                  everything you need to know about the range of that
                  enumeration.<br>
                </div>
              </div>
            </blockquote>
            I don&#39;t want to solve problems that are already solved. We
            don&#39;t need any modification on the compiler to solve this
            case, but if it solve the more dificult case it could=C2=A0 sol=
ve
            this as well.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>What=C2=A0are you both=C2=A0referring to here? </div>
      </div>
    </blockquote>
    We are talking here of is_in _enum_rang (or is_valid_enum) by
    opposition to is_enumerator (your is_enum).<br>
    is_valid_enum can be implemented easily with the current
    meta-programming when the underlying type is explict.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>I assumed=C2=A0modifying the compiler was a requirement to
          implement is_enum?</div>
      </div>
    </blockquote>
    I would say that it is easier to maintain if the compiler generates
    the function. Anyone can define such a function for each enum.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>Or maybe you know is_enum can=C2=A0already be implemented
            through meta programming without a compiler change?</div>
        </div>
      </div>
    </blockquote>
    It can with enough meta-programming information, as the one the
    reflection proposal has, yes.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>Or maybe you are talking about modifying the language (so
            still=C2=A0a compiler change) but so is_enum can implement this
            feature?</div>
        </div>
      </div>
    </blockquote>
    Are you talking of static reflection here?<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div><br>
          </div>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  But if the enum has an implied underlying type, then
                  why would you need to know if a particular integer
                  (which does not match any enumerator) is within the
                  valid range for that enum?</div>
              </div>
            </blockquote>
            Because this is legal. I can assign it a value on the
            specified range. That&#39;s all. If I want my code to be outsid=
e
            the UB world I should be able to check on the conditions. I
            can of course do it for each particular case, but what we
            are talking of here is about what the compiler could do for
            us in a generic way.<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>The compiler is generating the code so=C2=A0where does generic
          come into this?</div>
      </div>
    </blockquote>
    The words generic way were in opposition to each particular case.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wi=
dth: 1px; border-left-style: solid;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> What are you trying to do that you need to do
                  this?<br>
                </div>
              </div>
            </blockquote>
            This is not a use case I would write myself, but I&#39;ve see i=
t
            a lot of times. When you use enums as flags of an bitset<br>
            enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08=
};<br>
            <br>
            The valid enumerators=C2=A0 don&#39;t correspond to the valid r=
ange,
            that in this case is any value between 0 and 8.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  If you don&#39;t have a problem to be solved with such a
                  function, then there&#39;s really no point in adding one.=
<br>
                </div>
              </div>
            </blockquote>
            I was sure you will ask and say this ;-)<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                </div>
                <blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px =
0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border=
-left-width: 1px; border-left-style: solid;">
                  <div text=3D"#000000" bgcolor=3D"#FFFFFF"> I don&#39;t kn=
ow
                    why the new C++11 enum with an explicit underlying
                    type have a different range of valid values.<br>
                    I&#39;ll be interested in knowing the rationale.<br>
                  </div>
                </blockquote>
                <div><br>
                  Because enums are integers. That&#39;s the rationale.<br>
                </div>
              </div>
            </blockquote>
            I believe that you didn&#39;t understood my question. Let me se=
e
            with an example. <br>
            What is the difference between<br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02,=
 C=3D0x04, ALL
            0x08};<br>
            <br>
            and <br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=
=3D0x01, B=3D0x02,
            C=3D0x04, ALL 0x08};<br>
            ?<br>
            <br>
            X has a valid range 0..N, while Y has a valid range 0..255.<br>
            <br>
            Why do we need this difference? Why forcing the underlying
            type changes the range of valid values?<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>I had std::any_enum_value in my earlier post and
          make_bad_enum knew the type of the enum.</div>
        <div>The idea was that those two pieces of information allowed=C2=
=A0a
          value to be=C2=A0constructed that could express any enum as
          intended.</div>
        <div>I&#39;m=C2=A0raising that in case it&#39;s=C2=A0helpful to thi=
s conversation
          here but it might not be because I can&#39;t quite follow what
          problem is being solved here?</div>
      </div>
    </blockquote>
    It seems that I should not explain myself correctly as people is not
    understanding the complementary problem I&#39;m raising.<br></div></blo=
ckquote><div>sorry=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204=
, 204); border-left-width: 1px; border-left-style: solid;"><div text=3D"#00=
0000" bgcolor=3D"#FFFFFF">
    <br>
    The question is : Does your any_enum_value check for the enumerators
    values or the valid range of the enumeration?<br></div></blockquote><di=
v><br></div><div>My std::any_enum_value does not range check or=C2=A0anythi=
ng, I=C2=A0envisaged it as a container that promises to be large enough to =
hold any enum value=C2=A0possible for an ABI,=C2=A0nothing else. As=C2=A0be=
st as I can tell from looking at my earlier post,=C2=A0any_enum_value=C2=A0=
was left in by mistake=C2=A0from a=C2=A0more complex design=C2=A0where I wa=
s thinking where the interface would be more like std::optional.</div><div>=
<br></div><div>But I didn&#39;t=C2=A0recommend that design in the end=C2=A0=
so I don&#39;t think=C2=A0it was used because bad_enum=C2=A0isn&#39;t used =
either, I used std::range_error and satisfied myself that was ok because th=
e error message would be detailed enough to show what type of enum failed a=
nd the value that failed to convert.=C2=A0So a=C2=A0dedicated bad_enum wasn=
&#39;t needed unless we needed to query information out of that. Which I de=
cided we probably didn&#39;t.</div><div><br></div><div>Hope that helps.<br>=
</div>
 =20

</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/d2c589d7-15a3-4069-b32e-7b6506438ca7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d2c589d7-15a3-4069-b32e-7b6506438ca7=
%40isocpp.org</a>.<br />

------=_Part_469_77118346.1484220930769--

------=_Part_468_2126305148.1484220930768--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 12 Jan 2017 08:07:21 -0800 (PST)
Raw View
------=_Part_732_2122343943.1484237241971
Content-Type: multipart/alternative;
 boundary="----=_Part_733_1307729811.1484237241972"

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



On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit :
>
> On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:=20
>>
>> Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>>
>> On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J. Botet=20
>> Escriba wrote:=20
>>
>>
>> The question I have to ask is this: if you have an integer, why do you=
=20
>> need to know if it will fit within the range of an enum with an implied=
=20
>> underlying type?
>>
>> Because initializing the enum with an integer out of range is UB.
>>
>
> You're misunderstanding my question.
>
> The situation you describe is one where:
>
> 1. You have an integer of arbitrary origin.
>
> 2. You want to convert it to an enum type.
>
> 3. That integer *does not match* one of the enumerators in that type.
>
> 4. The enum type does not have a fixed underlying type.
>
> You have described very well the context.
>
> What goal are you trying to achieve with all this? Or more to the point,=
=20
> why are you incapable of simply giving the enum an underlying type and th=
us=20
> making the question moot?
>
> Because the enum is declared in a 3pp library in C++98? or a common part=
=20
> that is shared by an application using C++98 and another using C++2x?
>

So the enum is in legacy code (one way or another). And the enum is not=20
being used as a true enumeration, but as a general value that may or may=20
not resolve to one of the enumerators. And you're converting an arbitrary=
=20
integer into that enumeration.

Ultimately, I'm not sure that this confluence of issues comes up often=20
enough that we need a mechanism to check for it.

> This is not a use case I would write myself, but I've see it a lot of=20
>> times. When you use enums as flags of an bitset
>> enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>>
>> The valid enumerators  don't correspond to the valid range, that in this=
=20
>> case is any value between 0 and 8.
>>
>
> But we can already answer that question. `X` is an `enum class`. As such,=
=20
> it *always* has a fixed underlying type. If you don't specify one, then=
=20
> it shall be `int`, and therefore `X` can legally assume any `int` value.
>
> From the text of the standard I send before, the range is not the range o=
f=20
> int. Could you point me from where are you concluding this?
>

[dcl.enum]/5:

>  For a scoped enumeration type, the underlying type is int if it is not=
=20
explicitly specified. In both of these cases, the underlying type is said=
=20
to be fixed.

[dcl.enum]/8:

> For an enumeration whose underlying type is fixed, the values of the=20
enumeration are the values of the underlying type.

So the range of a scoped enumeration is *always* the range of its=20
underlying type. Therefore the situation you're talking about can only come=
=20
about by using non-scoped, non-fixed enums.

> I believe that you didn't understood my question. Let me see with an=20
>> example.=20
>> What is the difference between
>>
>>     enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>>
>> and=20
>>
>>     enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x0=
4, ALL=20
>> 0x08};
>> ?
>>
>> X has a valid range 0..N, while Y has a valid range 0..255.
>>
>> Why do we need this difference? Why forcing the underlying type changes=
=20
>> the range of valid values?
>>
>
> In that case, both have a forced underlying type, as I pointed out above.=
=20
> So the reason for the differing ranges of values is obvious.
>
> Now, let's assume you have revised your example to not use `enum class`.=
=20
> `enum X` does not have a fixed underlying type, so its range is determine=
d=20
> by its enumerators. The reason that is different is because that's how it=
=20
> always was before, and there's terribly little reason to change it.
>
> I'm not questioning the old C++98 behavior but the new C++11 behavior (if=
=20
> we can say new for C++11)
>

The C++11 behavior is much simpler: the range of an enum with a fixed=20
underlying type is the range of its fixed underlying type. C++11 did not=20
change the rules for the enum range of an enum without a fixed underlying=
=20
type.

--=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/d4065d2b-f8b7-4b55-ba43-65895c14e0bb%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Thursday, January 12, 2017 at 2:28:00 AM UTC-5,=
 Vicente J. Botet 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 11/01/2017 =C3=A0 22:21, Nicol Bolas a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11 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 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit=C2=A0=
:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Tuesday, January 10, 2017 at 5:26:11 PM
                UTC-5, Vicente J. Botet Escriba wrote:
                </div></blockquote><blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div><br>
                  The question I have to ask is this: if you have an
                  integer, why do you need to know if it will fit within
                  the range of an enum with an implied underlying type?</di=
v>
              </div>
            </blockquote>
            Because initializing the enum with an integer out of range
            is UB.<br>
          </div>
        </blockquote>
        <div><br>
          You&#39;re misunderstanding my question.<br>
          <br>
          The situation you describe is one where:<br>
          <br>
          1. You have an integer of arbitrary origin.<br>
          <br>
          2. You want to convert it to an enum type.<br>
          <br>
          3. That integer <i>does not match</i> one of the enumerators
          in that type.<br>
          <br>
          4. The enum type does not have a fixed underlying type.<br>
          <br>
        </div>
      </div>
    </blockquote>
    You have described very well the context.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>What goal are you trying to achieve with all this? Or more
          to the point, why are you incapable of simply giving the enum
          an underlying type and thus making the question moot?<br>
        </div>
      </div>
    </blockquote>
    Because the enum is declared in a 3pp library in C++98? or a common
    part that is shared by an application using C++98 and another using
    C++2x?<br></div></blockquote><div><br>So the enum is in legacy code (on=
e way or another). And the enum is not being used as a true enumeration, bu=
t as a general value that may or may not resolve to one of the enumerators.=
 And you&#39;re converting an arbitrary integer into that enumeration.<br><=
br>Ultimately, I&#39;m not sure that this confluence of issues comes up oft=
en enough that we need a mechanism to check for it.<br></div><blockquote cl=
ass=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"#000000">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <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">This is not a use case =
I would write myself, but I&#39;ve see it
            a lot of times. When you use enums as flags of an bitset<br>
            enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08=
};<br>
            <br>
            The valid enumerators=C2=A0 don&#39;t correspond to the valid r=
ange,
            that in this case is any value between 0 and 8.<br>
          </div>
        </blockquote>
        <div><br>
          But we can already answer that question. `X` is an `enum
          class`. As such, it <i>always</i> has a fixed underlying
          type. If you don&#39;t specify one, then it shall be `int`, and
          therefore `X` can legally assume any `int` value.<br>
        </div>
      </div>
    </blockquote>
    From the text of the standard I send before, the range is not the
    range of int. Could you point me from where are you concluding this?<br=
></div></blockquote><div><br>[dcl.enum]/5:<br><br>&gt;=C2=A0 For a scoped e=
numeration type, the underlying type is int if it is not explicitly specifi=
ed. In both of these cases, the underlying type is said to be fixed.<br><br=
>[dcl.enum]/8:<br><br>&gt; For an enumeration whose underlying type is fixe=
d, the values of the enumeration are the values of the underlying type.<br>=
<br>So the range of a scoped enumeration is <i>always</i> the range of its =
underlying type. Therefore the situation you&#39;re talking about can only =
come about by using non-scoped, non-fixed enums.<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>
        </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">I believe that you didn=
&#39;t understood my question. Let me see
            with an example. <br>
            What is the difference between<br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=3D0x02,=
 C=3D0x04, ALL
            0x08};<br>
            <br>
            and <br>
            <br>
            =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=3D0, A=
=3D0x01, B=3D0x02,
            C=3D0x04, ALL 0x08};<br>
            ?<br>
            <br>
            X has a valid range 0..N, while Y has a valid range 0..255.<br>
            <br>
            Why do we need this difference? Why forcing the underlying
            type changes the range of valid values?<br>
          </div>
        </blockquote>
        <div><br>
          In that case, both have a forced underlying type, as I pointed
          out above. So the reason for the differing ranges of values is
          obvious.<br>
          <br>
          Now, let&#39;s assume you have revised your example to not use
          `enum class`. `enum X` does not have a fixed underlying type,
          so its range is determined by its enumerators. The reason that
          is different is because that&#39;s how it always was before, and
          there&#39;s terribly little reason to change it.<br>
        </div>
      </div>
    </blockquote>
    I&#39;m not questioning the old C++98 behavior but the new C++11
    behavior (if we can say new for C++11)<br></div></blockquote><div><br>T=
he C++11 behavior is much simpler: the range of an enum with a fixed underl=
ying type  is the range of its fixed underlying type. C++11 did not change =
the rules for the enum range of an enum without a fixed underlying type.<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/d4065d2b-f8b7-4b55-ba43-65895c14e0bb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d4065d2b-f8b7-4b55-ba43-65895c14e0bb=
%40isocpp.org</a>.<br />

------=_Part_733_1307729811.1484237241972--

------=_Part_732_2122343943.1484237241971--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 13 Jan 2017 01:09:26 +0100
Raw View
This is a multi-part message in MIME format.
--------------0574014F174652A2B8233757
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 12/01/2017 =C3=A0 17:07, Nicol Bolas a =C3=A9crit :
>
>
> On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
>     Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit :
>>     On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J.
>>     Botet Escriba wrote:
>>
>>         Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>>>         On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J.
>>>         Botet Escriba wrote:
>>>
>>>         The question I have to ask is this: if you have an integer,
>>>         why do you need to know if it will fit within the range of
>>>         an enum with an implied underlying type?
>>         Because initializing the enum with an integer out of range is UB=
..
>>
>>
>>     You're misunderstanding my question.
>>
>>     The situation you describe is one where:
>>
>>     1. You have an integer of arbitrary origin.
>>
>>     2. You want to convert it to an enum type.
>>
>>     3. That integer /does not match/ one of the enumerators in that type=
..
>>
>>     4. The enum type does not have a fixed underlying type.
>>
>     You have described very well the context.
>>     What goal are you trying to achieve with all this? Or more to the
>>     point, why are you incapable of simply giving the enum an
>>     underlying type and thus making the question moot?
>     Because the enum is declared in a 3pp library in C++98? or a
>     common part that is shared by an application using C++98 and
>     another using C++2x?
>
>
> So the enum is in legacy code (one way or another). And the enum is=20
> not being used as a true enumeration, but as a general value that may=20
> or may not resolve to one of the enumerators. And you're converting an=20
> arbitrary integer into that enumeration.
>
> Ultimately, I'm not sure that this confluence of issues comes up often=20
> enough that we need a mechanism to check for it.
>
>>         This is not a use case I would write myself, but I've see it
>>         a lot of times. When you use enums as flags of an bitset
>>         enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08}=
;
>>
>>         The valid enumerators  don't correspond to the valid range,
>>         that in this case is any value between 0 and 8.
>>
>>
>>     But we can already answer that question. `X` is an `enum class`.
>>     As such, it /always/ has a fixed underlying type. If you don't
>>     specify one, then it shall be `int`, and therefore `X` can
>>     legally assume any `int` value.
>     From the text of the standard I send before, the range is not the
>     range of int. Could you point me from where are you concluding this?
>
>
> [dcl.enum]/5:
>
> >  For a scoped enumeration type, the underlying type is int if it is=20
> not explicitly specified. In both of these cases, the underlying type=20
> is said to be fixed.
>
> [dcl.enum]/8:
>
> > For an enumeration whose underlying type is fixed, the values of the=20
> enumeration are the values of the underlying type.
>
> So the range of a scoped enumeration is /always/ the range of its=20
> underlying type. Therefore the situation you're talking about can only=20
> come about by using non-scoped, non-fixed enums.
Thanks this references clarifies the range of valid values. SO the=20
difference isn't between explicit or not , but between enum and scoped enum=
..
>
>>         I believe that you didn't understood my question. Let me see
>>         with an example.
>>         What is the difference between
>>
>>             enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0=
x08};
>>
>>         and
>>
>>             enum class Y : unsigned char { NONE=3D0, A=3D0x01, B=3D0x02,
>>         C=3D0x04, ALL 0x08};
>>         ?
>>
>>         X has a valid range 0..N, while Y has a valid range 0..255.
>>
>>         Why do we need this difference? Why forcing the underlying
>>         type changes the range of valid values?
>>
>>
>>     In that case, both have a forced underlying type, as I pointed
>>     out above. So the reason for the differing ranges of values is
>>     obvious.
>>
>>     Now, let's assume you have revised your example to not use `enum
>>     class`. `enum X` does not have a fixed underlying type, so its
>>     range is determined by its enumerators. The reason that is
>>     different is because that's how it always was before, and there's
>>     terribly little reason to change it.
>     I'm not questioning the old C++98 behavior but the new C++11
>     behavior (if we can say new for C++11)
>
>
> The C++11 behavior is much simpler: the range of an enum with a fixed=20
> underlying type is the range of its fixed underlying type. C++11 did=20
> not change the rules for the enum range of an enum without a fixed=20
> underlying type.
The C++11 behavior contains the C++98 behavior, so it can not be simpler=20
and in my opinion is weird to have a different behavior :)

Thanks anyway for the clarifications.
Vicente

--=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/b2c10414-ec5d-9bc3-dd7e-48bff6f1fa5e%40wanadoo.f=
r.

--------------0574014F174652A2B8233757
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 12/01/2017 =C3=A0 17:07, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:d4065d2b-f8b7-4b55-ba43-65895c14e0bb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J.
        Botet Escriba wrote:
        <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" text=3D"#000000">
            <div>Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit=C2=A0=
:<br>
            </div>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11
                PM UTC-5, Vicente J. Botet Escriba wrote:
                <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" text=3D"#000000">
                    <div>Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9cr=
it=C2=A0:<br>
                    </div>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr">On Tuesday, January 10, 2017 at
                        5:26:11 PM UTC-5, Vicente J. Botet Escriba
                        wrote: </div>
                    </blockquote>
                    <blockquote type=3D"cite">
                      <div dir=3D"ltr">
                        <div><br>
                          The question I have to ask is this: if you
                          have an integer, why do you need to know if it
                          will fit within the range of an enum with an
                          implied underlying type?</div>
                      </div>
                    </blockquote>
                    Because initializing the enum with an integer out of
                    range is UB.<br>
                  </div>
                </blockquote>
                <div><br>
                  You're misunderstanding my question.<br>
                  <br>
                  The situation you describe is one where:<br>
                  <br>
                  1. You have an integer of arbitrary origin.<br>
                  <br>
                  2. You want to convert it to an enum type.<br>
                  <br>
                  3. That integer <i>does not match</i> one of the
                  enumerators in that type.<br>
                  <br>
                  4. The enum type does not have a fixed underlying
                  type.<br>
                  <br>
                </div>
              </div>
            </blockquote>
            You have described very well the context.<br>
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div>What goal are you trying to achieve with all this?
                  Or more to the point, why are you incapable of simply
                  giving the enum an underlying type and thus making the
                  question moot?<br>
                </div>
              </div>
            </blockquote>
            Because the enum is declared in a 3pp library in C++98? or a
            common part that is shared by an application using C++98 and
            another using C++2x?<br>
          </div>
        </blockquote>
        <div><br>
          So the enum is in legacy code (one way or another). And the
          enum is not being used as a true enumeration, but as a general
          value that may or may not resolve to one of the enumerators.
          And you're converting an arbitrary integer into that
          enumeration.<br>
          <br>
          Ultimately, I'm not sure that this confluence of issues comes
          up often enough that we need a mechanism to check for it.<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" text=3D"#000000">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <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" text=3D"#000000">This is not a
                    use case I would write myself, but I've see it a lot
                    of times. When you use enums as flags of an bitset<br>
                    enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, =
ALL
                    0x08};<br>
                    <br>
                    The valid enumerators=C2=A0 don't correspond to the val=
id
                    range, that in this case is any value between 0 and
                    8.<br>
                  </div>
                </blockquote>
                <div><br>
                  But we can already answer that question. `X` is an
                  `enum class`. As such, it <i>always</i> has a fixed
                  underlying type. If you don't specify one, then it
                  shall be `int`, and therefore `X` can legally assume
                  any `int` value.<br>
                </div>
              </div>
            </blockquote>
            From the text of the standard I send before, the range is
            not the range of int. Could you point me from where are you
            concluding this?<br>
          </div>
        </blockquote>
        <div><br>
          [dcl.enum]/5:<br>
          <br>
          &gt;=C2=A0 For a scoped enumeration type, the underlying type is
          int if it is not explicitly specified. In both of these cases,
          the underlying type is said to be fixed.<br>
          <br>
          [dcl.enum]/8:<br>
          <br>
          &gt; For an enumeration whose underlying type is fixed, the
          values of the enumeration are the values of the underlying
          type.<br>
          <br>
          So the range of a scoped enumeration is <i>always</i> the
          range of its underlying type. Therefore the situation you're
          talking about can only come about by using non-scoped,
          non-fixed enums.<br>
        </div>
      </div>
    </blockquote>
    Thanks this references clarifies the range of valid values. SO the
    difference isn't between explicit or not , but between enum and
    scoped enum.<br>
    <blockquote
      cite=3D"mid:d4065d2b-f8b7-4b55-ba43-65895c14e0bb@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <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" text=3D"#000000">
            <blockquote type=3D"cite">
              <div dir=3D"ltr">
                <div> </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" text=3D"#000000">I believe that
                    you didn't understood my question. Let me see with
                    an example. <br>
                    What is the difference between<br>
                    <br>
                    =C2=A0=C2=A0=C2=A0 enum class X { NONE=3D0, A=3D0x01, B=
=3D0x02, C=3D0x04,
                    ALL 0x08};<br>
                    <br>
                    and <br>
                    <br>
                    =C2=A0=C2=A0=C2=A0 enum class Y : unsigned char { NONE=
=3D0, A=3D0x01,
                    B=3D0x02, C=3D0x04, ALL 0x08};<br>
                    ?<br>
                    <br>
                    X has a valid range 0..N, while Y has a valid range
                    0..255.<br>
                    <br>
                    Why do we need this difference? Why forcing the
                    underlying type changes the range of valid values?<br>
                  </div>
                </blockquote>
                <div><br>
                  In that case, both have a forced underlying type, as I
                  pointed out above. So the reason for the differing
                  ranges of values is obvious.<br>
                  <br>
                  Now, let's assume you have revised your example to not
                  use `enum class`. `enum X` does not have a fixed
                  underlying type, so its range is determined by its
                  enumerators. The reason that is different is because
                  that's how it always was before, and there's terribly
                  little reason to change it.<br>
                </div>
              </div>
            </blockquote>
            I'm not questioning the old C++98 behavior but the new C++11
            behavior (if we can say new for C++11)<br>
          </div>
        </blockquote>
        <div><br>
          The C++11 behavior is much simpler: the range of an enum with
          a fixed underlying type is the range of its fixed underlying
          type. C++11 did not change the rules for the enum range of an
          enum without a fixed underlying type.<br>
        </div>
      </div>
    </blockquote>
    The C++11 behavior contains the C++98 behavior, so it can not be
    simpler and in my opinion is weird to have a different behavior :)<br>
    <br>
    Thanks anyway for the clarifications.<br>
    Vicente<br>
  </body>
</html>

<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/b2c10414-ec5d-9bc3-dd7e-48bff6f1fa5e%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b2c10414-ec5d-9bc3-dd7e-48bff6f1fa5e=
%40wanadoo.fr</a>.<br />

--------------0574014F174652A2B8233757--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 13 Jan 2017 08:54:14 +0100
Raw View
This is a multi-part message in MIME format.
--------------F966C3143431216CDC3D0344
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 13/01/2017 =C3=A0 01:09, Vicente J. Botet Escriba a =C3=A9crit :
> Le 12/01/2017 =C3=A0 17:07, Nicol Bolas a =C3=A9crit :
>>
>>
>> On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J. Botet=20
>> Escriba wrote:
>>
>>     Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit :
>>>     On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J.
>>>     Botet Escriba wrote:
>>>
>>>         Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>>>>         On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente
>>>>         J. Botet Escriba wrote:
>>>>
>>>>         The question I have to ask is this: if you have an integer,
>>>>         why do you need to know if it will fit within the range of
>>>>         an enum with an implied underlying type?
>>>         Because initializing the enum with an integer out of range
>>>         is UB.
>>>
>>>
>>>     You're misunderstanding my question.
>>>
>>>     The situation you describe is one where:
>>>
>>>     1. You have an integer of arbitrary origin.
>>>
>>>     2. You want to convert it to an enum type.
>>>
>>>     3. That integer /does not match/ one of the enumerators in that
>>>     type.
>>>
>>>     4. The enum type does not have a fixed underlying type.
>>>
>>     You have described very well the context.
>>>     What goal are you trying to achieve with all this? Or more to
>>>     the point, why are you incapable of simply giving the enum an
>>>     underlying type and thus making the question moot?
>>     Because the enum is declared in a 3pp library in C++98? or a
>>     common part that is shared by an application using C++98 and
>>     another using C++2x?
>>
>>
>> So the enum is in legacy code (one way or another). And the enum is=20
>> not being used as a true enumeration, but as a general value that may=20
>> or may not resolve to one of the enumerators. And you're converting=20
>> an arbitrary integer into that enumeration.
>>
>> Ultimately, I'm not sure that this confluence of issues comes up=20
>> often enough that we need a mechanism to check for it.
>>
>>>         This is not a use case I would write myself, but I've see it
>>>         a lot of times. When you use enums as flags of an bitset
>>>         enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08=
};
>>>
>>>         The valid enumerators  don't correspond to the valid range,
>>>         that in this case is any value between 0 and 8.
>>>
>>>
>>>     But we can already answer that question. `X` is an `enum class`.
>>>     As such, it /always/ has a fixed underlying type. If you don't
>>>     specify one, then it shall be `int`, and therefore `X` can
>>>     legally assume any `int` value.
>>     From the text of the standard I send before, the range is not the
>>     range of int. Could you point me from where are you concluding this?
>>
>>
>> [dcl.enum]/5:
>>
>> >  For a scoped enumeration type, the underlying type is int if it is=20
>> not explicitly specified. In both of these cases, the underlying type=20
>> is said to be fixed.
>>
>> [dcl.enum]/8:
>>
>> > For an enumeration whose underlying type is fixed, the values of=20
>> the enumeration are the values of the underlying type.
>>
>> So the range of a scoped enumeration is /always/ the range of its=20
>> underlying type. Therefore the situation you're talking about can=20
>> only come about by using non-scoped, non-fixed enums.
> Thanks this references clarifies the range of valid values. SO the=20
> difference isn't between explicit or not , but between enum and scoped=20
> enum.
>
I was wondering if the rationale for the different behavior has=20
something to be with the fact that scoped enums can be forward declared.

enum class X;

X f(int i) {
     return X(i); // we are able to construct them independently of the
}

int main()
{
    X x =3D f(1);
    return static_cast<int>(x);
}

http://melpon.org/wandbox/permlink/LiGCmCNwENTskhtv

Vicente

--=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/c8da1219-1d83-4812-f099-3b270d179ab7%40wanadoo.f=
r.

--------------F966C3143431216CDC3D0344
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/01/2017 =C3=A0 01:09, Vicente J. B=
otet
      Escriba a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:b2c10414-ec5d-9bc3-dd7e-48bff6f1fa5e@wanadoo.fr"
      type=3D"cite">
      <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
      <div class=3D"moz-cite-prefix">Le 12/01/2017 =C3=A0 17:07, Nicol Bola=
s a
        =C3=A9crit=C2=A0:<br>
      </div>
      <blockquote
        cite=3D"mid:d4065d2b-f8b7-4b55-ba43-65895c14e0bb@isocpp.org"
        type=3D"cite">
        <div dir=3D"ltr"><br>
          <br>
          On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J.
          Botet Escriba wrote:
          <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" text=3D"#000000">
              <div>Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit=C2=
=A0:<br>
              </div>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11
                  PM UTC-5, Vicente J. Botet Escriba wrote:
                  <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" text=3D"#000000">
                      <div>Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9=
crit=C2=A0:<br>
                      </div>
                      <blockquote type=3D"cite">
                        <div dir=3D"ltr">On Tuesday, January 10, 2017 at
                          5:26:11 PM UTC-5, Vicente J. Botet Escriba
                          wrote: </div>
                      </blockquote>
                      <blockquote type=3D"cite">
                        <div dir=3D"ltr">
                          <div><br>
                            The question I have to ask is this: if you
                            have an integer, why do you need to know if
                            it will fit within the range of an enum with
                            an implied underlying type?</div>
                        </div>
                      </blockquote>
                      Because initializing the enum with an integer out
                      of range is UB.<br>
                    </div>
                  </blockquote>
                  <div><br>
                    You're misunderstanding my question.<br>
                    <br>
                    The situation you describe is one where:<br>
                    <br>
                    1. You have an integer of arbitrary origin.<br>
                    <br>
                    2. You want to convert it to an enum type.<br>
                    <br>
                    3. That integer <i>does not match</i> one of the
                    enumerators in that type.<br>
                    <br>
                    4. The enum type does not have a fixed underlying
                    type.<br>
                    <br>
                  </div>
                </div>
              </blockquote>
              You have described very well the context.<br>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <div>What goal are you trying to achieve with all
                    this? Or more to the point, why are you incapable of
                    simply giving the enum an underlying type and thus
                    making the question moot?<br>
                  </div>
                </div>
              </blockquote>
              Because the enum is declared in a 3pp library in C++98? or
              a common part that is shared by an application using C++98
              and another using C++2x?<br>
            </div>
          </blockquote>
          <div><br>
            So the enum is in legacy code (one way or another). And the
            enum is not being used as a true enumeration, but as a
            general value that may or may not resolve to one of the
            enumerators. And you're converting an arbitrary integer into
            that enumeration.<br>
            <br>
            Ultimately, I'm not sure that this confluence of issues
            comes up often enough that we need a mechanism to check for
            it.<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" text=3D"#000000">
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <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" text=3D"#000000">This is not a
                      use case I would write myself, but I've see it a
                      lot of times. When you use enums as flags of an
                      bitset<br>
                      enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04=
, ALL
                      0x08};<br>
                      <br>
                      The valid enumerators=C2=A0 don't correspond to the
                      valid range, that in this case is any value
                      between 0 and 8.<br>
                    </div>
                  </blockquote>
                  <div><br>
                    But we can already answer that question. `X` is an
                    `enum class`. As such, it <i>always</i> has a fixed
                    underlying type. If you don't specify one, then it
                    shall be `int`, and therefore `X` can legally assume
                    any `int` value.<br>
                  </div>
                </div>
              </blockquote>
              From the text of the standard I send before, the range is
              not the range of int. Could you point me from where are
              you concluding this?<br>
            </div>
          </blockquote>
          <div><br>
            [dcl.enum]/5:<br>
            <br>
            &gt;=C2=A0 For a scoped enumeration type, the underlying type i=
s
            int if it is not explicitly specified. In both of these
            cases, the underlying type is said to be fixed.<br>
            <br>
            [dcl.enum]/8:<br>
            <br>
            &gt; For an enumeration whose underlying type is fixed, the
            values of the enumeration are the values of the underlying
            type.<br>
            <br>
            So the range of a scoped enumeration is <i>always</i> the
            range of its underlying type. Therefore the situation you're
            talking about can only come about by using non-scoped,
            non-fixed enums.<br>
          </div>
        </div>
      </blockquote>
      Thanks this references clarifies the range of valid values. SO the
      difference isn't between explicit or not , but between enum and
      scoped enum.<br>
      <br>
    </blockquote>
    I was wondering if the rationale for the different behavior has
    something to be with the fact that scoped enums can be forward
    declared.<br>
    <br>
    enum class X;<br>
    <br>
    X f(int i) {<br>
    =C2=A0=C2=A0=C2=A0 return X(i); // we are able to construct them indepe=
ndently of
    the <br>
    }<br>
    <br>
    int main() <br>
    {=C2=A0=C2=A0 <br>
    =C2=A0=C2=A0 X x =3D f(1); <br>
    =C2=A0=C2=A0 return static_cast&lt;int&gt;(x);<br>
    }<br>
    <br>
    <a class=3D"moz-txt-link-freetext" href=3D"http://melpon.org/wandbox/pe=
rmlink/LiGCmCNwENTskhtv">http://melpon.org/wandbox/permlink/LiGCmCNwENTskht=
v</a><br>
    <br>
    Vicente<br>
  </body>
</html>

<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/c8da1219-1d83-4812-f099-3b270d179ab7%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c8da1219-1d83-4812-f099-3b270d179ab7=
%40wanadoo.fr</a>.<br />

--------------F966C3143431216CDC3D0344--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 13 Jan 2017 07:07:06 -0800 (PST)
Raw View
------=_Part_580_700892298.1484320026786
Content-Type: multipart/alternative;
 boundary="----=_Part_581_1904316676.1484320026787"

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



On Friday, January 13, 2017 at 2:54:18 AM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 13/01/2017 =C3=A0 01:09, Vicente J. Botet Escriba a =C3=A9crit :
>
> Le 12/01/2017 =C3=A0 17:07, Nicol Bolas a =C3=A9crit :
>
>
>
> On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J. Botet=20
> Escriba wrote:=20
>>
>> Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit :
>>
>> On Wednesday, January 11, 2017 at 1:52:11 PM UTC-5, Vicente J. Botet=20
>> Escriba wrote:=20
>>>
>>> Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9crit :
>>>
>>> On Tuesday, January 10, 2017 at 5:26:11 PM UTC-5, Vicente J. Botet=20
>>> Escriba wrote:=20
>>>
>>>
>>> The question I have to ask is this: if you have an integer, why do you=
=20
>>> need to know if it will fit within the range of an enum with an implied=
=20
>>> underlying type?
>>>
>>> Because initializing the enum with an integer out of range is UB.
>>>
>>
>> You're misunderstanding my question.
>>
>> The situation you describe is one where:
>>
>> 1. You have an integer of arbitrary origin.
>>
>> 2. You want to convert it to an enum type.
>>
>> 3. That integer *does not match* one of the enumerators in that type.
>>
>> 4. The enum type does not have a fixed underlying type.
>>
>> You have described very well the context.
>>
>> What goal are you trying to achieve with all this? Or more to the point,=
=20
>> why are you incapable of simply giving the enum an underlying type and t=
hus=20
>> making the question moot?
>>
>> Because the enum is declared in a 3pp library in C++98? or a common part=
=20
>> that is shared by an application using C++98 and another using C++2x?
>>
>
> So the enum is in legacy code (one way or another). And the enum is not=
=20
> being used as a true enumeration, but as a general value that may or may=
=20
> not resolve to one of the enumerators. And you're converting an arbitrary=
=20
> integer into that enumeration.
>
> Ultimately, I'm not sure that this confluence of issues comes up often=20
> enough that we need a mechanism to check for it.
>
>> This is not a use case I would write myself, but I've see it a lot of=20
>>> times. When you use enums as flags of an bitset
>>> enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04, ALL 0x08};
>>>
>>> The valid enumerators  don't correspond to the valid range, that in thi=
s=20
>>> case is any value between 0 and 8.
>>>
>>
>> But we can already answer that question. `X` is an `enum class`. As such=
,=20
>> it *always* has a fixed underlying type. If you don't specify one, then=
=20
>> it shall be `int`, and therefore `X` can legally assume any `int` value.
>>
>> From the text of the standard I send before, the range is not the range=
=20
>> of int. Could you point me from where are you concluding this?
>>
>
> [dcl.enum]/5:
>
> >  For a scoped enumeration type, the underlying type is int if it is not=
=20
> explicitly specified. In both of these cases, the underlying type is said=
=20
> to be fixed.
>
> [dcl.enum]/8:
>
> > For an enumeration whose underlying type is fixed, the values of the=20
> enumeration are the values of the underlying type.
>
> So the range of a scoped enumeration is *always* the range of its=20
> underlying type. Therefore the situation you're talking about can only co=
me=20
> about by using non-scoped, non-fixed enums.
>
> Thanks this references clarifies the range of valid values. SO the=20
> difference isn't between explicit or not , but between enum and scoped en=
um.
>
> I was wondering if the rationale for the different behavior has something=
=20
> to be with the fact that scoped enums can be forward declared.
>

Any enum with a fixed underlying type can be forward declared. As such, I=
=20
imagine that the range rules are not unrelated to that.

--=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/a2a01296-f81c-48cf-98f1-52b3af872cef%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Friday, January 13, 2017 at 2:54:18 AM 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 13/01/2017 =C3=A0 01:09, Vicente J. Botet
      Escriba a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
     =20
      <div>Le 12/01/2017 =C3=A0 17:07, Nicol Bolas a
        =C3=A9crit=C2=A0:<br>
      </div>
      <blockquote type=3D"cite">
        <div dir=3D"ltr"><br>
          <br>
          On Thursday, January 12, 2017 at 2:28:00 AM UTC-5, Vicente J.
          Botet Escriba wrote:
          <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" text=3D"#000000">
              <div>Le 11/01/2017 =C3=A0 22:21, Nicol Bolas a =C3=A9crit=C2=
=A0:<br>
              </div>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">On Wednesday, January 11, 2017 at 1:52:11
                  PM UTC-5, Vicente J. Botet Escriba wrote:
                  <blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                    <div bgcolor=3D"#FFFFFF" text=3D"#000000">
                      <div>Le 11/01/2017 =C3=A0 00:06, Nicol Bolas a =C3=A9=
crit=C2=A0:<br>
                      </div>
                      <blockquote type=3D"cite">
                        <div dir=3D"ltr">On Tuesday, January 10, 2017 at
                          5:26:11 PM UTC-5, Vicente J. Botet Escriba
                          wrote: </div>
                      </blockquote>
                      <blockquote type=3D"cite">
                        <div dir=3D"ltr">
                          <div><br>
                            The question I have to ask is this: if you
                            have an integer, why do you need to know if
                            it will fit within the range of an enum with
                            an implied underlying type?</div>
                        </div>
                      </blockquote>
                      Because initializing the enum with an integer out
                      of range is UB.<br>
                    </div>
                  </blockquote>
                  <div><br>
                    You&#39;re misunderstanding my question.<br>
                    <br>
                    The situation you describe is one where:<br>
                    <br>
                    1. You have an integer of arbitrary origin.<br>
                    <br>
                    2. You want to convert it to an enum type.<br>
                    <br>
                    3. That integer <i>does not match</i> one of the
                    enumerators in that type.<br>
                    <br>
                    4. The enum type does not have a fixed underlying
                    type.<br>
                    <br>
                  </div>
                </div>
              </blockquote>
              You have described very well the context.<br>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <div>What goal are you trying to achieve with all
                    this? Or more to the point, why are you incapable of
                    simply giving the enum an underlying type and thus
                    making the question moot?<br>
                  </div>
                </div>
              </blockquote>
              Because the enum is declared in a 3pp library in C++98? or
              a common part that is shared by an application using C++98
              and another using C++2x?<br>
            </div>
          </blockquote>
          <div><br>
            So the enum is in legacy code (one way or another). And the
            enum is not being used as a true enumeration, but as a
            general value that may or may not resolve to one of the
            enumerators. And you&#39;re converting an arbitrary integer int=
o
            that enumeration.<br>
            <br>
            Ultimately, I&#39;m not sure that this confluence of issues
            comes up often enough that we need a mechanism to check for
            it.<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" text=3D"#000000">
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                    <div bgcolor=3D"#FFFFFF" text=3D"#000000">This is not a
                      use case I would write myself, but I&#39;ve see it a
                      lot of times. When you use enums as flags of an
                      bitset<br>
                      enum class X { NONE=3D0, A=3D0x01, B=3D0x02, C=3D0x04=
, ALL
                      0x08};<br>
                      <br>
                      The valid enumerators=C2=A0 don&#39;t correspond to t=
he
                      valid range, that in this case is any value
                      between 0 and 8.<br>
                    </div>
                  </blockquote>
                  <div><br>
                    But we can already answer that question. `X` is an
                    `enum class`. As such, it <i>always</i> has a fixed
                    underlying type. If you don&#39;t specify one, then it
                    shall be `int`, and therefore `X` can legally assume
                    any `int` value.<br>
                  </div>
                </div>
              </blockquote>
              From the text of the standard I send before, the range is
              not the range of int. Could you point me from where are
              you concluding this?<br>
            </div>
          </blockquote>
          <div><br>
            [dcl.enum]/5:<br>
            <br>
            &gt;=C2=A0 For a scoped enumeration type, the underlying type i=
s
            int if it is not explicitly specified. In both of these
            cases, the underlying type is said to be fixed.<br>
            <br>
            [dcl.enum]/8:<br>
            <br>
            &gt; For an enumeration whose underlying type is fixed, the
            values of the enumeration are the values of the underlying
            type.<br>
            <br>
            So the range of a scoped enumeration is <i>always</i> the
            range of its underlying type. Therefore the situation you&#39;r=
e
            talking about can only come about by using non-scoped,
            non-fixed enums.<br>
          </div>
        </div>
      </blockquote>
      Thanks this references clarifies the range of valid values. SO the
      difference isn&#39;t between explicit or not , but between enum and
      scoped enum.<br>
      <br>
    </blockquote>
    I was wondering if the rationale for the different behavior has
    something to be with the fact that scoped enums can be forward
    declared.<br></div></blockquote><div><br>Any enum with a fixed underlyi=
ng type can be forward declared. As such, I imagine that the range rules ar=
e not unrelated to that.<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/a2a01296-f81c-48cf-98f1-52b3af872cef%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a2a01296-f81c-48cf-98f1-52b3af872cef=
%40isocpp.org</a>.<br />

------=_Part_581_1904316676.1484320026787--

------=_Part_580_700892298.1484320026786--

.