Topic: Proposal: underlying_cast


Author: james.a.cooper@gmail.com
Date: Sun, 30 Jul 2017 04:50:41 -0700 (PDT)
Raw View
------=_Part_3238_804273539.1501415441388
Content-Type: multipart/alternative;
 boundary="----=_Part_3239_836813329.1501415441390"

------=_Part_3239_836813329.1501415441390
Content-Type: text/plain; charset="UTF-8"

C++ allows enums to have an underlying type specified. When serialising
enum values it's important to use the correct type.
This proposal is to add a utility function that casts an enum type to its
underlying value. This would make it easier to handle
enum types in function overloads for serialisation. For example:

template <typename T>
std::ostream& write(std::ostream& os, const T& v)
{
    os << std::underlying_cast(v);
    return os;
}


This function would, in the case of enums cast the value to the underlying
type, and in the case of any other type it would do nothing.
One possible implementation:

template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;

template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::
type;

template <typename T>
using NotEnumTypesOnly = typename std::enable_if<!std::is_enum<T>::value, T
>::type;


// For enums do the cast.
template <typename E, typename = EnumTypesOnly<E>>
constexpr UnderlyingType<E> underlying_cast(E e)
{
   return static_cast<UnderlyingType<E>>(e);
}

// For other types do nothing.
template <typename T, typename = NotEnumTypesOnly<T>>
constexpr T underlying_cast(T t)
{
   return t;
}



The reason this is required is that even when the enum type is explicitly
set, it can be ignored during function overloading.
For example:

enum AnEnum : bool { A, B };

//void print(AnEnum) { std::cout << "print(AnEnum)\n"; }
void print(int) { std::cout << "print(int)\n"; }
void print(bool) { std::cout << "print(bool)\n"; }

int main(int argc, char* argv[])
{
    print(A); // Compiler chooses print(int) overload.
    return 0;
}

If, in the above code, the print(AnEnum) overload is removed, the compiler
will choose the print(int) function despite the compiler being told that
the enum is a bool (additionally, if a 'C' value is added to the enum the
compiler will complain).
If this value is being serialised to JSON, for example, this is not the
intended outcome. The following code behaves as the programmer intended

enum AnEnum : bool { A, B };

void print(int) { std::cout << "print(int)\n"; }
void print(bool) { std::cout << "print(bool)\n"; }

int main(int argc, char* argv[])
{
    print(underlying_cast(A)); // Compiler chooses print(bool) overload.
    return 0;
}

--
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/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3%40isocpp.org.

------=_Part_3239_836813329.1501415441390
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">C++ allows enums to have an underlying type specified. Whe=
n serialising enum values it&#39;s important to use the correct type.<br>Th=
is proposal is to add a utility function that casts an enum type to its und=
erlying value. This would make it easier to handle<br>enum types in functio=
n overloads for serialisation. For example:<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"=
styled-by-prettify" style=3D"color: #008;">template</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-p=
rettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-prettif=
y" style=3D"color: #008;">typename</span><span class=3D"styled-by-prettify"=
 style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">&gt;</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br>std</span><span class=3D"styled-by-prettify" style=3D"color=
: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
>ostream</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&a=
mp;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> write<=
/span><span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #000;">std</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"sty=
led-by-prettify" style=3D"color: #000;">ostream</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">&amp;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> os</span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">const</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"> T</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&amp=
;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> v</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">)</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 os </span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">&lt;&lt;</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D"st=
yled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;">underlying_cast</span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;">v</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">);</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> os</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660;">}</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span></=
div></code></div><br><br>This
 function would, in the case of enums cast the value to the underlying=20
type, and in the case of any other type it would do nothing.<br>One possibl=
e implementation:<br><br><div class=3D"prettyprint" style=3D"background-col=
or: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: sol=
id; border-width: 1px; overflow-wrap: break-word;"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=
=3D"color: #008;">template</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><s=
pan class=3D"styled-by-prettify" style=3D"color: #008;">using</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"s=
tyled-by-prettify" style=3D"color: #606;">UnderlyingType</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #008;">typename</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"=
color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;">underlying_type</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #0=
00;">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;=
::</span><span class=3D"styled-by-prettify" style=3D"color: #000;">type</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">;</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #008;">template</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-=
prettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> E</span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">&gt;</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #008;">using</span><span class=3D"styled-by-prettify" style=3D"color: =
#000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #606;">En=
umTypesOnly</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> </span><span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #008;">typename</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;">enable_if</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;">std</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;">is_enum</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;:=
:</span><span class=3D"styled-by-prettify" style=3D"color: #000;">value</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">,</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;"> E</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">&gt;::</span><span class=3D"sty=
led-by-prettify" style=3D"color: #000;">type</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"><br><br></span><span class=3D"styled-by-prettify" =
style=3D"color: #008;">template</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #=
008;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"> T</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span=
><span class=3D"styled-by-prettify" style=3D"color: #008;">using</span><spa=
n class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=
=3D"styled-by-prettify" style=3D"color: #606;">NotEnumTypesOnly</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"styled=
-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">typename</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;">enable_if</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">&lt;!</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;">std</span><span class=3D"styled-by-prettify" style=3D"color: #660;">:=
:</span><span class=3D"styled-by-prettify" style=3D"color: #000;">is_enum</=
span><span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;">T</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #660;">&gt;::</span><span class=3D=
"styled-by-prettify" style=3D"color: #000;">value</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">,</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">&gt;::</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;">type</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000=
;"><br><br><br></span><span class=3D"styled-by-prettify" style=3D"color: #8=
00;">// For enums do the cast.</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"=
color: #008;">template</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #008;">typ=
ename</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> E</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;">,</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #008;">typename</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-=
prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=
=3D"color: #606;">EnumTypesOnly</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;">E</span><span class=3D"styled-by-prettify" style=3D"color: #=
660;">&gt;&gt;</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #008;">co=
nstexpr</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #606;">UnderlyingTy=
pe</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;">E</span><span =
class=3D"styled-by-prettify" style=3D"color: #660;">&gt;</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> underlying_cast</span><span=
 class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D=
"styled-by-prettify" style=3D"color: #000;">E e</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"><br>=C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">static_cast</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #60=
6;">UnderlyingType</span><span class=3D"styled-by-prettify" style=3D"color:=
 #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;&gt=
;(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">e</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"><br><br></span><span class=3D"styled-by-=
prettify" style=3D"color: #800;">// For other types do nothing.</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=
=3D"styled-by-prettify" style=3D"color: #008;">template</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
"> </span><span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span =
class=3D"styled-by-prettify" style=3D"color: #606;">NotEnumTypesOnly</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;">T</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">&gt;&gt;</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-b=
y-prettify" style=3D"color: #008;">constexpr</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> T underlying_cast</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;">T t</span><span class=3D"styled-by-prettif=
y" style=3D"color: #660;">)</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">{</span><span class=3D"styled-by-prettify" style=3D"color: #000=
;"><br>=C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #008;">return</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;"> t</span><span class=3D"styled-by-prettify" style=3D"color: #660;">;<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span></div></cod=
e></div><br><br>The reason this is required is that even when the enum type=
 is explicitly set, it can be ignored during function overloading.<br>For e=
xample:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; overflow-wrap: break-word;"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: =
#008;">enum</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> </span><span class=3D"styled-by-prettify" style=3D"color: #606;">AnEnum</=
span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #660;">:</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #008;">bool</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"> A</span><span class=3D"styled-by-prettify" style=3D"color: #=
660;">,</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> B =
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">};</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><sp=
an class=3D"styled-by-prettify" style=3D"color: #800;">//void print(AnEnum)=
 { std::cout &lt;&lt; &quot;print(AnEnum)\n&quot;; }</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-=
by-prettify" style=3D"color: #008;">void</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" st=
yle=3D"color: #008;">print</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">int</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">)</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-=
by-prettify" style=3D"color: #000;">cout </span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">&lt;&lt;</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #080;">&quot;print(int)\n&quot;</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">}</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #008;">print</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">bool</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">cout </span><span class=3D"styled-by-prettify" style=3D"color: #660;">&=
lt;&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #080;">&quot;print(=
bool)\n&quot;</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> main</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> argc</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008;">=
char</span><span class=3D"styled-by-prettify" style=3D"color: #660;">*</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> argv</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">[])</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">print</span><span class=3D"styled-=
by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #000;">A</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">);</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #800;"=
>// Compiler chooses print(int) overload.</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styl=
ed-by-prettify" style=3D"color: #008;">return</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #066;">0</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">}</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></=
span></div></code></div><br>If,
 in the above code, the print(AnEnum) overload is removed, the compiler=20
will choose the print(int) function despite the compiler being told that<br=
>the enum is a bool (additionally, if a &#39;C&#39; value is added to the e=
num the compiler will complain).<br>If
 this value is being serialised to JSON, for example, this is not the=20
intended outcome. The following code behaves as the programmer intended<br>=
<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250=
); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px=
; overflow-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: #0=
08;">enum</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> =
</span><span class=3D"styled-by-prettify" style=3D"color: #606;">AnEnum</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span =
class=3D"styled-by-prettify" style=3D"color: #660;">:</span><span class=3D"=
styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by=
-prettify" style=3D"color: #008;">bool</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" styl=
e=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"> A</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">,</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> B </sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">};</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">void</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #008;">print</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #008;">int</span><span class=3D"styled-by-prettify" style=3D"color: #6=
60;">)</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #000;">cout </span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">&lt;&lt;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" =
style=3D"color: #080;">&quot;print(int)\n&quot;</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" styl=
e=3D"color: #660;">}</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> <=
/span><span class=3D"styled-by-prettify" style=3D"color: #008;">print</span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #008;">bool</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">cout </span><span class=3D"styled-by-prettify" style=3D"color: #660;">&=
lt;&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #080;">&quot;print(=
bool)\n&quot;</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> main</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> argc</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008;">=
char</span><span class=3D"styled-by-prettify" style=3D"color: #660;">*</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> argv</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">[])</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">print</span><span class=3D"styled-=
by-prettify" style=3D"color: #660;">(underlying_cast(</span><span class=3D"=
styled-by-prettify" style=3D"color: #000;">A)</span><span class=3D"styled-b=
y-prettify" style=3D"color: #660;">);</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #000;"> // Compiler chooses print(bool) overload.<br>=
=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">return</span><span class=3D"styled-by-prettify" style=3D"color: #000;">=
 </span><span class=3D"styled-by-prettify" style=3D"color: #066;">0</span><=
span class=3D"styled-by-prettify" style=3D"color: #660;">;</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br></span></div></code></div></div></code=
></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/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3=
%40isocpp.org</a>.<br />

------=_Part_3239_836813329.1501415441390--

------=_Part_3238_804273539.1501415441388--

.


Author: Paul Hampson <paul.hampson@pobox.com>
Date: Sun, 30 Jul 2017 07:31:49 -0700 (PDT)
Raw View
------=_Part_3125_1635518279.1501425109224
Content-Type: multipart/alternative;
 boundary="----=_Part_3126_1276230475.1501425109224"

------=_Part_3126_1276230475.1501425109224
Content-Type: text/plain; charset="UTF-8"

On Sunday, 30 July 2017 21:50:41 UTC+10, james.a...@gmail.com wrote:
>
> C++ allows enums to have an underlying type specified. When serialising
> enum values it's important to use the correct type.
>
.....

> The reason this is required is that even when the enum type is explicitly
> set, it can be ignored during function overloading.
> For example:
>
> enum AnEnum : bool { A, B };
>
> //void print(AnEnum) { std::cout << "print(AnEnum)\n"; }
> void print(int) { std::cout << "print(int)\n"; }
> void print(bool) { std::cout << "print(bool)\n"; }
>
> int main(int argc, char* argv[])
> {
>     print(A); // Compiler chooses print(int) overload.
>     return 0;
> }
>
> If, in the above code, the print(AnEnum) overload is removed, the compiler
> will choose the print(int) function despite the compiler being told that
> the enum is a bool (additionally, if a 'C' value is added to the enum the
> compiler will complain).
>

Isn't that incorrect? I understand that [conv.prom]/4
<http://eel.is/c++draft/conv.prom#4> gives:

A prvalue of an unscoped enumeration type whose underlying type is fixed (
[dcl.enum] <http://eel.is/c++draft/dcl.enum>) can be converted to a prvalue
of its underlying type . <http://eel.is/c++draft/conv.prom#4.sentence-1>
Moreover, if integral promotion can be applied to its underlying type, a
prvalue of an unscoped enumeration type whose underlying type is fixed can
also be converted to a prvalue of the promoted underlying type.
<http://eel.is/c++draft/conv.prom#4.sentence-2>
And [conv.prom]/6 <http://eel.is/c++draft/conv.prom#6> gives:
A prvalue of type bool can be converted to a prvalue of type int, with false becoming
zero and true becoming one. <http://eel.is/c++draft/conv.prom#6.sentence-1>

And after the resolution of CWG 1601
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1601> was applied
in C++14
<https://github.com/cplusplus/draft/commit/0d3c1f756edce0eb6c9804ddbd128ba9216da0ed>,
[over.ics.rank]/4.2 <http://eel.is/c++draft/conv.prom#4> gives:

A conversion that promotes an enumeration whose underlying type is fixed to
its underlying type is better than one that promotes to the promoted
underlying type, if the two are different

So it should already be offering both bool (first sentence of
[conv.prom]/4), and int (second sentence of [conv.prom]/4 allowing
operation of [conv.prom]/6). And then [over.ics.rank]/4.2 should choose the
bool as "better" in C++14 onwards.

However, gcc 8 picked 'int', and both clang 4.0 and MSC++ 19.10 picked
"ambiguous", so I might be missing something here.
(https://godbolt.org/g/FZmhHj)

A recently-left (Feb 2017) comment on https://wg21.cmeerw.net/cwg/issue1601
agrees with 'ambiguous', and the discussion
<https://groups.google.com/a/isocpp.org/d/msg/std-discussion/jvtNzjy39Ng/H03tx4xSAbgJ>
that led to CWG1601 seemed to be leaning towards 'ambiguous' too.

====

On the proposal itself, I was wanting an underlying_cast almost exactly as
you described last week, for dealing with logging *scoped* enums through a
printf-style interface. Although I expect a more type-safe interface would
have already done the right thing when presented with an enum in the first
place.

--
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/cc4b9fd9-cb03-4712-9a15-279145f67bcb%40isocpp.org.

------=_Part_3126_1276230475.1501425109224
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, 30 July 2017 21:50:41 UTC+10, james.a...@gmail.=
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">C+=
+ allows enums to have an underlying type specified. When serialising enum =
values it&#39;s important to use the correct type.<br></div></blockquote><d=
iv>....</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
The reason this is required is that even when the enum type is explicitly s=
et, it can be ignored during function overloading.<br>For example:<br><br><=
div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187=
);border-style:solid;border-width:1px"><code><div><span style=3D"color:#008=
">enum</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
AnEnum</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
:</span><span style=3D"color:#000"> </span><span style=3D"color:#008">bool<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"> A</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> B </span><span style=3D"color:#660">};</span><span=
 style=3D"color:#000"><br><br></span><span style=3D"color:#800">//void prin=
t(AnEnum) { std::cout &lt;&lt; &quot;print(AnEnum)\n&quot;; }</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">void</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">print</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#008">int</span><span styl=
e=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">{</span><span style=3D"color:#000"> std</span><span style=3D"co=
lor:#660">::</span><span style=3D"color:#000">cout </span><span style=3D"co=
lor:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"=
color:#080">&quot;print(int)\n&quot;</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">}</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#008">void</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">print</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">bool</span><spa=
n style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">{</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">cout </span><span style=
=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;print(bool)\n&quot;</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">i=
nt</span><span style=3D"color:#000"> main</span><span style=3D"color:#660">=
(</span><span style=3D"color:#008">int</span><span style=3D"color:#000"> ar=
gc</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">char</span><span style=3D"color:#660">*</spa=
n><span style=3D"color:#000"> argv</span><span style=3D"color:#660">[])</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#=
008">print</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">A</span><span style=3D"color:#660">);</span><span style=3D"color:#000">=
 </span><span style=3D"color:#800">// Compiler chooses print(int) overload.=
</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor:#008">return</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">0</span><span style=3D"color:#660">;</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#0=
00"><br></span></div></code></div><br>If,
 in the above code, the print(AnEnum) overload is removed, the compiler=20
will choose the print(int) function despite the compiler being told that<br=
>the enum is a bool (additionally, if a &#39;C&#39; value is added to the e=
num the compiler will complain).</div></blockquote><div><br></div><div>Isn&=
#39;t that incorrect? I understand that=C2=A0<a href=3D"http://eel.is/c++dr=
aft/conv.prom#4">[conv.prom]/4</a> gives:</div><div><br></div><div><div cla=
ss=3D"para" id=3D"4" style=3D"background-color: rgb(201, 251, 201); margin-=
bottom: 0.6em; margin-top: 0.6em; text-align: justify; color: rgb(0, 0, 0);=
 font-family: serif; font-size: medium;"><div id=3D"4.sentence-1" class=3D"=
sentence" style=3D"display: inline;">A prvalue of an unscoped enumeration t=
ype whose underlying type is fixed (<a href=3D"http://eel.is/c++draft/dcl.e=
num">[dcl.enum]</a>) can be converted to a prvalue of its underlying type=
=C2=A0<a class=3D"hidden_link" href=3D"http://eel.is/c++draft/conv.prom#4.s=
entence-1" style=3D"color: inherit;">.</a></div><div id=3D"4.sentence-2" cl=
ass=3D"sentence" style=3D"display: inline;">Moreover, if integral promotion=
 can be applied to its underlying type, a prvalue of an unscoped enumeratio=
n type whose underlying type is fixed can also be converted to a prvalue of=
 the promoted underlying type<a class=3D"hidden_link" href=3D"http://eel.is=
/c++draft/conv.prom#4.sentence-2" style=3D"color: inherit;">.</a></div></di=
v><div>And <a href=3D"http://eel.is/c++draft/conv.prom#6">[conv.prom]/6</a>=
 gives:</div><div><span style=3D"color: rgb(0, 0, 0); font-family: serif; f=
ont-size: medium; text-align: justify; background-color: rgb(201, 251, 201)=
;">A prvalue of type=C2=A0</span><span class=3D"texttt" style=3D"font-famil=
y: monospace; color: rgb(0, 0, 0); text-align: justify; background-color: r=
gb(201, 251, 201);">bool</span><span style=3D"color: rgb(0, 0, 0); font-fam=
ily: serif; font-size: medium; text-align: justify; background-color: rgb(2=
01, 251, 201);">=C2=A0can be converted to a prvalue of type=C2=A0</span><sp=
an class=3D"texttt" style=3D"font-family: monospace; color: rgb(0, 0, 0); t=
ext-align: justify; background-color: rgb(201, 251, 201);">int</span><span =
style=3D"color: rgb(0, 0, 0); font-family: serif; font-size: medium; text-a=
lign: justify; background-color: rgb(201, 251, 201);">, with=C2=A0</span><s=
pan class=3D"texttt" style=3D"font-family: monospace; color: rgb(0, 0, 0); =
text-align: justify; background-color: rgb(201, 251, 201);">false</span><sp=
an style=3D"color: rgb(0, 0, 0); font-family: serif; font-size: medium; tex=
t-align: justify; background-color: rgb(201, 251, 201);">=C2=A0becoming zer=
o and=C2=A0</span><span class=3D"texttt" style=3D"font-family: monospace; c=
olor: rgb(0, 0, 0); text-align: justify; background-color: rgb(201, 251, 20=
1);">true</span><span style=3D"color: rgb(0, 0, 0); font-family: serif; fon=
t-size: medium; text-align: justify; background-color: rgb(201, 251, 201);"=
>=C2=A0becoming one</span><a class=3D"hidden_link" href=3D"http://eel.is/c+=
+draft/conv.prom#6.sentence-1" style=3D"color: inherit; font-family: serif;=
 font-size: medium; text-align: justify; background-color: rgb(201, 251, 20=
1);">.</a><br></div><div><br></div><div>And after the resolution of=C2=A0<a=
 href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1601"=
>CWG 1601</a>=C2=A0was <a href=3D"https://github.com/cplusplus/draft/commit=
/0d3c1f756edce0eb6c9804ddbd128ba9216da0ed">applied in C++14</a>, <a href=3D=
"http://eel.is/c++draft/conv.prom#4">[over.ics.rank]/4.2</a> gives:</div><d=
iv><br></div><div><span style=3D"color: rgb(0, 0, 0); font-family: serif; f=
ont-size: medium; text-align: justify; background-color: rgb(201, 251, 201)=
;">A conversion that promotes an enumeration whose underlying type is fixed=
 to its underlying type is better than one that promotes to the promoted un=
derlying type, if the two are different</span><br></div><div><br></div><div=
>So it should already be offering both bool (first sentence of [conv.prom]/=
4), and int (second sentence of [conv.prom]/4 allowing operation of [conv.p=
rom]/6). And then [over.ics.rank]/4.2 should choose the bool as &quot;bette=
r&quot; in C++14 onwards.</div><div><br></div><div>However, gcc 8 picked &#=
39;int&#39;, and both clang 4.0 and MSC++ 19.10 picked &quot;ambiguous&quot=
;, so I might be missing something here. (https://godbolt.org/g/FZmhHj)</di=
v><div><br></div><div>A recently-left (Feb 2017) comment on=C2=A0https://wg=
21.cmeerw.net/cwg/issue1601 agrees with &#39;ambiguous&#39;, and the <a hre=
f=3D"https://groups.google.com/a/isocpp.org/d/msg/std-discussion/jvtNzjy39N=
g/H03tx4xSAbgJ">discussion</a> that led to CWG1601 seemed to be leaning tow=
ards &#39;ambiguous&#39; too.</div><div><br></div><div>=3D=3D=3D=3D</div><d=
iv><br></div><div>On the proposal itself, I was wanting an <font face=3D"co=
urier new, monospace">underlying_cast</font> almost exactly as you describe=
d last week, for dealing with logging *scoped* enums through a printf-style=
 interface. Although I expect a more type-safe interface would have already=
 done the right thing when presented with an enum in the first place.</div>=
<div class=3D"para" id=3D"5" style=3D"margin-bottom: 0.6em; margin-top: 0.6=
em; text-align: justify; color: rgb(0, 0, 0); font-family: serif; font-size=
: medium;"><div class=3D"marginalizedparent" style=3D"position: relative; l=
eft: -5em;"></div></div></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/cc4b9fd9-cb03-4712-9a15-279145f67bcb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cc4b9fd9-cb03-4712-9a15-279145f67bcb=
%40isocpp.org</a>.<br />

------=_Part_3126_1276230475.1501425109224--

------=_Part_3125_1635518279.1501425109224--

.


Author: Paul Hampson <paul.hampson@pobox.com>
Date: Sun, 30 Jul 2017 07:35:25 -0700 (PDT)
Raw View
------=_Part_3335_948021419.1501425325670
Content-Type: multipart/alternative;
 boundary="----=_Part_3336_2075601527.1501425325670"

------=_Part_3336_2075601527.1501425325670
Content-Type: text/plain; charset="UTF-8"

On Monday, 31 July 2017 00:31:49 UTC+10, Paul Hampson wrote:


> However, gcc 8 picked 'int', and both clang 4.0 and MSC++ 19.10 picked
> "ambiguous", so I might be missing something here. (
> https://godbolt.org/g/FZmhHj)
>
> A recently-left (Feb 2017) comment on
> https://wg21.cmeerw.net/cwg/issue1601 agrees with 'ambiguous', and the
> discussion
> <https://groups.google.com/a/isocpp.org/d/msg/std-discussion/jvtNzjy39Ng/H03tx4xSAbgJ>
> that led to CWG1601 seemed to be leaning towards 'ambiguous' too.
>
https://stackoverflow.com/a/34336157/166389 says I'm right about this, and
all the compilers are wrong.

Or at least that my confirmation bias is good at cherry-picking Google
results on Stackoverflow.

--
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/ea740118-78c1-4984-9cc9-3a447e439e59%40isocpp.org.

------=_Part_3336_2075601527.1501425325670
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, 31 July 2017 00:31:49 UTC+10, Paul Hampson  wro=
te:<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;"><div dir=
=3D"ltr"><div><div></div><div>However, gcc 8 picked &#39;int&#39;, and both=
 clang 4.0 and MSC++ 19.10 picked &quot;ambiguous&quot;, so I might be miss=
ing something here. (<a href=3D"https://godbolt.org/g/FZmhHj" target=3D"_bl=
ank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.co=
m/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FFZmhHj\x26sa\x3dD\x26sntz\x3d1\x=
26usg\x3dAFQjCNEElkfXignYKHP8MsDrJvE60D7V2w&#39;;return true;" onclick=3D"t=
his.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2=
Fg%2FFZmhHj\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEElkfXignYKHP8MsDrJvE60=
D7V2w&#39;;return true;">https://godbolt.org/g/FZmhHj</a>)</div><div><br></=
div><div>A recently-left (Feb 2017) comment on=C2=A0<a href=3D"https://wg21=
..cmeerw.net/cwg/issue1601" target=3D"_blank" rel=3D"nofollow" onmousedown=
=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwg21.cme=
erw.net%2Fcwg%2Fissue1601\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGkH-whBcw=
vzgr3BVrfVfasyHoaBg&#39;;return true;" onclick=3D"this.href=3D&#39;https://=
www.google.com/url?q\x3dhttps%3A%2F%2Fwg21.cmeerw.net%2Fcwg%2Fissue1601\x26=
sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGkH-whBcwvzgr3BVrfVfasyHoaBg&#39;;retu=
rn true;">https://wg21.cmeerw.net/<wbr>cwg/issue1601</a> agrees with &#39;a=
mbiguous&#39;, and the <a href=3D"https://groups.google.com/a/isocpp.org/d/=
msg/std-discussion/jvtNzjy39Ng/H03tx4xSAbgJ" target=3D"_blank" rel=3D"nofol=
low" onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org=
/d/msg/std-discussion/jvtNzjy39Ng/H03tx4xSAbgJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-discu=
ssion/jvtNzjy39Ng/H03tx4xSAbgJ&#39;;return true;">discussion</a> that led t=
o CWG1601 seemed to be leaning towards &#39;ambiguous&#39; too.</div><div s=
tyle=3D"margin-bottom:0.6em;margin-top:0.6em;text-align:justify;color:rgb(0=
,0,0);font-family:serif;font-size:medium"></div></div></div></blockquote><d=
iv>https://stackoverflow.com/a/34336157/166389 says I&#39;m right about thi=
s, and all the compilers are wrong.</div><div><br></div><div>Or at least th=
at my confirmation bias is good at cherry-picking Google results on Stackov=
erflow.</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/ea740118-78c1-4984-9cc9-3a447e439e59%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ea740118-78c1-4984-9cc9-3a447e439e59=
%40isocpp.org</a>.<br />

------=_Part_3336_2075601527.1501425325670--

------=_Part_3335_948021419.1501425325670--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Sun, 30 Jul 2017 09:20:17 -0700
Raw View
On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
> C++ allows enums to have an underlying type specified. When serialising
> enum values it's important to use the correct type.
> This proposal is to add a utility function that casts an enum type to its
> underlying value. This would make it easier to handle
> enum types in function overloads for serialisation. For example:
>
> template <typename T>
> std::ostream& write(std::ostream& os, const T& v)
> {
>     os << std::underlying_cast(v);
>     return os;
> }

Yes on the convenience, but "underlying_cast" is the wrong name because this
does not look like a regular cast.

Something like "std::underlying_value" might be better.

--
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/2570492.NpxuI0RVu0%40tjmaciei-mobl1.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 30 Jul 2017 19:34:21 +0300
Raw View
On 30 July 2017 at 19:20, Thiago Macieira <thiago@macieira.org> wrote:
> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>> C++ allows enums to have an underlying type specified. When serialising
>> enum values it's important to use the correct type.
>> This proposal is to add a utility function that casts an enum type to its
>> underlying value. This would make it easier to handle
>> enum types in function overloads for serialisation. For example:
>>
>> template <typename T>
>> std::ostream& write(std::ostream& os, const T& v)
>> {
>>     os << std::underlying_cast(v);
>>     return os;
>> }
>
> Yes on the convenience, but "underlying_cast" is the wrong name because this
> does not look like a regular cast.
>
> Something like "std::underlying_value" might be better.

Perhaps we should change std::underlying_type to be an identity type
for non-enums.

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

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Sun, 30 Jul 2017 18:37:18 +0200
Raw View
2017-07-30 18:34 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> On 30 July 2017 at 19:20, Thiago Macieira <thiago@macieira.org> wrote:
>> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>>> C++ allows enums to have an underlying type specified. When serialising
>>> enum values it's important to use the correct type.
>>> This proposal is to add a utility function that casts an enum type to its
>>> underlying value. This would make it easier to handle
>>> enum types in function overloads for serialisation. For example:
>>>
>>> template <typename T>
>>> std::ostream& write(std::ostream& os, const T& v)
>>> {
>>>     os << std::underlying_cast(v);
>>>     return os;
>>> }
>>
>> Yes on the convenience, but "underlying_cast" is the wrong name because this
>> does not look like a regular cast.
>>
>> Something like "std::underlying_value" might be better.
>
> Perhaps we should change std::underlying_type to be an identity type
> for non-enums.

Not for all of them, please. The term underlying type exists also for
wchar_t, char16_t, and char32_t and is different from the identity
type.

- Daniel

--
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/CAGNvRgDSBrxKcdDcxL%3DM60e%3DxNcTufZPAgeSAW0adpR_yAkeYQ%40mail.gmail.com.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 30 Jul 2017 19:58:19 +0300
Raw View
On 30 July 2017 at 19:37, Daniel Kr=C3=BCgler <daniel.kruegler@gmail.com> w=
rote:
> 2017-07-30 18:34 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com=
>:
>> On 30 July 2017 at 19:20, Thiago Macieira <thiago@macieira.org> wrote:
>>> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>>>> C++ allows enums to have an underlying type specified. When serialisin=
g
>>>> enum values it's important to use the correct type.
>>>> This proposal is to add a utility function that casts an enum type to =
its
>>>> underlying value. This would make it easier to handle
>>>> enum types in function overloads for serialisation. For example:
>>>>
>>>> template <typename T>
>>>> std::ostream& write(std::ostream& os, const T& v)
>>>> {
>>>>     os << std::underlying_cast(v);
>>>>     return os;
>>>> }
>>>
>>> Yes on the convenience, but "underlying_cast" is the wrong name because=
 this
>>> does not look like a regular cast.
>>>
>>> Something like "std::underlying_value" might be better.
>>
>> Perhaps we should change std::underlying_type to be an identity type
>> for non-enums.
>
> Not for all of them, please. The term underlying type exists also for
> wchar_t, char16_t, and char32_t and is different from the identity
> type.


I'm not talking about any particular term, but the trait. It's
ill-formed to use it for a non-enum type today.
I suppose having it return a non-identity type for the types you
mentioned would be remotely plausible.

--=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/CAFk2RUaQ-BG4%2By0N2GiEDsVNLBUsb2-_bmgid6%3DqcEt=
5N0e_Mw%40mail.gmail.com.

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Sun, 30 Jul 2017 19:05:26 +0200
Raw View
2017-07-30 18:58 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> On 30 July 2017 at 19:37, Daniel Kr=C3=BCgler <daniel.kruegler@gmail.com>=
 wrote:
>> 2017-07-30 18:34 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.co=
m>:
>>> On 30 July 2017 at 19:20, Thiago Macieira <thiago@macieira.org> wrote:
>>>> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>>>>> C++ allows enums to have an underlying type specified. When serialisi=
ng
>>>>> enum values it's important to use the correct type.
>>>>> This proposal is to add a utility function that casts an enum type to=
 its
>>>>> underlying value. This would make it easier to handle
>>>>> enum types in function overloads for serialisation. For example:
>>>>>
>>>>> template <typename T>
>>>>> std::ostream& write(std::ostream& os, const T& v)
>>>>> {
>>>>>     os << std::underlying_cast(v);
>>>>>     return os;
>>>>> }
>>>>
>>>> Yes on the convenience, but "underlying_cast" is the wrong name becaus=
e this
>>>> does not look like a regular cast.
>>>>
>>>> Something like "std::underlying_value" might be better.
>>>
>>> Perhaps we should change std::underlying_type to be an identity type
>>> for non-enums.
>>
>> Not for all of them, please. The term underlying type exists also for
>> wchar_t, char16_t, and char32_t and is different from the identity
>> type.
>
>
> I'm not talking about any particular term, but the trait.

I do as well.

> It's
> ill-formed to use it for a non-enum type today.

I know.

> I suppose having it return a non-identity type for the types you
> mentioned would be remotely plausible.

I wanted to ensure that we did no unintentionally define it as
identity for non-enum types exactly due to the mentioned types for
which the trait is currently not defined but where the term underling
type has already a well-defined meaning.

- Daniel

--=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/CAGNvRgDH%3Deef%3DTWoXor1MedUw9xBzm3bgSZKqsREN_-=
qaxTC_w%40mail.gmail.com.

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Sun, 30 Jul 2017 19:15:56 +0200
Raw View
2017-07-30 19:05 GMT+02:00 Daniel Kr=C3=BCgler <daniel.kruegler@gmail.com>:
> 2017-07-30 18:58 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com=
>:
>> On 30 July 2017 at 19:37, Daniel Kr=C3=BCgler <daniel.kruegler@gmail.com=
> wrote:
>>> 2017-07-30 18:34 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.c=
om>:
>>>> On 30 July 2017 at 19:20, Thiago Macieira <thiago@macieira.org> wrote:
>>>>> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>>>>>> C++ allows enums to have an underlying type specified. When serialis=
ing
>>>>>> enum values it's important to use the correct type.
>>>>>> This proposal is to add a utility function that casts an enum type t=
o its
>>>>>> underlying value. This would make it easier to handle
>>>>>> enum types in function overloads for serialisation. For example:
>>>>>>
>>>>>> template <typename T>
>>>>>> std::ostream& write(std::ostream& os, const T& v)
>>>>>> {
>>>>>>     os << std::underlying_cast(v);
>>>>>>     return os;
>>>>>> }
>>>>>
>>>>> Yes on the convenience, but "underlying_cast" is the wrong name becau=
se this
>>>>> does not look like a regular cast.
>>>>>
>>>>> Something like "std::underlying_value" might be better.
>>>>
>>>> Perhaps we should change std::underlying_type to be an identity type
>>>> for non-enums.
>>>
>>> Not for all of them, please. The term underlying type exists also for
>>> wchar_t, char16_t, and char32_t and is different from the identity
>>> type.
>>
>>
>> I'm not talking about any particular term, but the trait.
>
> I do as well.
>
>> It's
>> ill-formed to use it for a non-enum type today.
>
> I know.
>
>> I suppose having it return a non-identity type for the types you
>> mentioned would be remotely plausible.
>
> I wanted to ensure that we did no unintentionally define it as
> identity for non-enum types exactly due to the mentioned types for
> which the trait is currently not defined but where the term underling
> type has already a well-defined meaning.

In addition to that, one *could* possibly consider to define
underlying_type<char> to result in either signed char or unsigned
char, because of

"In any particular implementation, a plain char object can take on
either the same values as a signed char or an
unsigned char; which one is implementation-defined."

I'm not sticking very strongly to that additional mapping possibility,
but I think that a proposing paper should mention that possibility,
even if it decides to reject that idea.

> - Daniel

--=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/CAGNvRgBKgRHW7Y0g7%2Bv6BPu6YUNUUi6DbmypaTX6b0c9S=
oUFKg%40mail.gmail.com.

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Mon, 31 Jul 2017 02:38:22 +0200
Raw View
On Sun, Jul 30, 2017 at 04:50:41AM -0700, james.a.cooper@gmail.com wrote:
> C++ allows enums to have an underlying type specified. When serialising
> enum values it's important to use the correct type.
> This proposal is to add a utility function that casts an enum type to its
> underlying value. This would make it easier to handle
> enum types in function overloads for serialisation. For example:
>
> template <typename T>
> std::ostream& write(std::ostream& os, const T& v)
> {
>     os << std::underlying_cast(v);
>     return os;
> }
>
>
> This function would, in the case of enums cast the value to the underlying
> type, and in the case of any other type it would do nothing.
>
> One possible implementation:
>
> template <typename E>
> using UnderlyingType = typename std::underlying_type<E>::type;

What about recursive enums?

enum foo : int { value1 = 4096 };
enum bar : foo { value2 = 4095 };

What does std::underlying_type<bar>::type resolve to?

/MF

--
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/20170731003821.GA7900%40noemi.bahnhof.se.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 30 Jul 2017 17:43:29 -0700 (PDT)
Raw View
------=_Part_3649_911313278.1501461809434
Content-Type: multipart/alternative;
 boundary="----=_Part_3650_846813795.1501461809434"

------=_Part_3650_846813795.1501461809434
Content-Type: text/plain; charset="UTF-8"



On Sunday, July 30, 2017 at 8:38:28 PM UTC-4, Magnus Fromreide wrote:
>
> On Sun, Jul 30, 2017 at 04:50:41AM -0700, james.a...@gmail.com
> <javascript:> wrote:
> > C++ allows enums to have an underlying type specified. When serialising
> > enum values it's important to use the correct type.
> > This proposal is to add a utility function that casts an enum type to
> its
> > underlying value. This would make it easier to handle
> > enum types in function overloads for serialisation. For example:
> >
> > template <typename T>
> > std::ostream& write(std::ostream& os, const T& v)
> > {
> >     os << std::underlying_cast(v);
> >     return os;
> > }
> >
> >
> > This function would, in the case of enums cast the value to the
> underlying
> > type, and in the case of any other type it would do nothing.
> >
> > One possible implementation:
> >
> > template <typename E>
> > using UnderlyingType = typename std::underlying_type<E>::type;
>
> What about recursive enums?
>
> enum foo : int { value1 = 4096 };
> enum bar : foo { value2 = 4095 };
>
> What does std::underlying_type<bar>::type resolve to?
>

Nothing, because `bar` is ill-formed:

> The type-specifier-seq of an enum-base shall name an integral type; any
cv-qualification is ignored

Enumeration types are not "integral type"s.


>
> /MF
>

--
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/b7df0078-2395-4def-bd73-fd708083969d%40isocpp.org.

------=_Part_3650_846813795.1501461809434
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, July 30, 2017 at 8:38:28 PM UTC-4, Magn=
us Fromreide wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sun, Jul=
 30, 2017 at 04:50:41AM -0700, <a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"HUFVxtHFAQAJ" rel=3D"nofollow" onmousedown=3D"this.h=
ref=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javas=
cript:&#39;;return true;">james.a...@gmail.com</a> wrote:
<br>&gt; C++ allows enums to have an underlying type specified. When serial=
ising=20
<br>&gt; enum values it&#39;s important to use the correct type.
<br>&gt; This proposal is to add a utility function that casts an enum type=
 to its=20
<br>&gt; underlying value. This would make it easier to handle
<br>&gt; enum types in function overloads for serialisation. For example:
<br>&gt;=20
<br>&gt; template &lt;typename T&gt;
<br>&gt; std::ostream&amp; write(std::ostream&amp; os, const T&amp; v)
<br>&gt; {
<br>&gt; =C2=A0 =C2=A0 os &lt;&lt; std::underlying_cast(v);
<br>&gt; =C2=A0 =C2=A0 return os;
<br>&gt; }
<br>&gt;=20
<br>&gt;=20
<br>&gt; This function would, in the case of enums cast the value to the un=
derlying=20
<br>&gt; type, and in the case of any other type it would do nothing.
<br>&gt;=20
<br>&gt; One possible implementation:
<br>&gt;=20
<br>&gt; template &lt;typename E&gt;
<br>&gt; using UnderlyingType =3D typename std::underlying_type&lt;E&gt;::t=
ype;
<br>
<br>What about recursive enums?
<br>
<br>enum foo : int { value1 =3D 4096 };
<br>enum bar : foo { value2 =3D 4095 };
<br>
<br>What does std::underlying_type&lt;bar&gt;::<wbr>type resolve to?
<br></blockquote><div><br>Nothing, because `bar` is ill-formed:<br><br>&gt;=
 The type-specifier-seq of an enum-base shall name an integral type; any cv=
-qualification is ignored<br><br>Enumeration types are not &quot;integral t=
ype&quot;s.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>/MF
<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/b7df0078-2395-4def-bd73-fd708083969d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b7df0078-2395-4def-bd73-fd708083969d=
%40isocpp.org</a>.<br />

------=_Part_3650_846813795.1501461809434--

------=_Part_3649_911313278.1501461809434--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 2 Aug 2017 13:33:25 +0200
Raw View
This is a multi-part message in MIME format.
--------------456D88599976B7BA492A1A36
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit :
> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>> C++ allows enums to have an underlying type specified. When serialising
>> enum values it's important to use the correct type.
>> This proposal is to add a utility function that casts an enum type to it=
s
>> underlying value. This would make it easier to handle
>> enum types in function overloads for serialisation. For example:
>>
>> template <typename T>
>> std::ostream& write(std::ostream& os, const T& v)
>> {
>>      os << std::underlying_cast(v);
>>      return os;
>> }
> Yes on the convenience, but "underlying_cast" is the wrong name because t=
his
> does not look like a regular cast.
>
> Something like "std::underlying_value" might be better.
>
I've used underlying(v) to get the underlying value in some of my=20
libraries that wrap other types to build opaque types.

I've as well used underlying_cast to static_cast the underlying value to=20
another type that works with static cast

     template <class U, class T>
     U underlying_cast(T const& v)
     {
       return static_cast<U>(underlying(v));
     }


This would be part of a library proposal for strong/opaque types.


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/aa4104f9-5a29-c1d9-22ac-1dfa9cad8d18%40wanadoo.f=
r.

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

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 30/07/2017 =C3=A0 18:20, Thiago Macie=
ira
      a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite" cite=3D"mid:2570492.NpxuI0RVu0@tjmaciei-mobl1=
">
      <pre wrap=3D"">On Sunday, 30 July 2017 04:50:41 PDT <a class=3D"moz-t=
xt-link-abbreviated" href=3D"mailto:james.a.cooper@gmail.com">james.a.coope=
r@gmail.com</a> wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">C++ allows enums to have an underlying type specifie=
d. When serialising
enum values it's important to use the correct type.
This proposal is to add a utility function that casts an enum type to its
underlying value. This would make it easier to handle
enum types in function overloads for serialisation. For example:

template &lt;typename T&gt;
std::ostream&amp; write(std::ostream&amp; os, const T&amp; v)
{
    os &lt;&lt; std::underlying_cast(v);
    return os;
}
</pre>
      </blockquote>
      <pre wrap=3D"">
Yes on the convenience, but "underlying_cast" is the wrong name because thi=
s=20
does not look like a regular cast.

Something like "std::underlying_value" might be better.

</pre>
    </blockquote>
    <p><font size=3D"+1">I've used underlying(v) to get the underlying
        value in some of my libraries that wrap other types to build
        opaque types.</font></p>
    <p><font size=3D"+1">I've as well used underlying_cast to static_cast
        the underlying value to another type that works with static cast<br=
>
      </font></p>
    <p><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template &lt;class U, class T&g=
t;<br>
        =C2=A0=C2=A0=C2=A0 U underlying_cast(T const&amp; v)<br>
        =C2=A0=C2=A0=C2=A0 {<br>
        =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return static_cast&lt;U&gt;(underlyi=
ng(v));<br>
        =C2=A0=C2=A0=C2=A0 }<br>
      </font></p>
    <p><font size=3D"+1"><br>
      </font></p>
    <p><font size=3D"+1">This would be part of a library proposal for
        strong/opaque types.<br>
      </font></p>
    <p><font size=3D"+1"><br>
      </font></p>
    <p><font size=3D"+1">Vicente</font><br>
    </p>
  </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/aa4104f9-5a29-c1d9-22ac-1dfa9cad8d18%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/aa4104f9-5a29-c1d9-22ac-1dfa9cad8d18=
%40wanadoo.fr</a>.<br />

--------------456D88599976B7BA492A1A36--

.


Author: John McFarlane <john@mcfarlane.name>
Date: Wed, 02 Aug 2017 15:21:42 +0000
Raw View
--94eb2c0defc0dd65860555c6d24f
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, Aug 2, 2017 at 4:33 AM Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:

> Le 30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit :
>
> On Sunday, 30 July 2017 04:50:41 PDT james.a.cooper@gmail.com wrote:
>
> C++ allows enums to have an underlying type specified. When serialising
> enum values it's important to use the correct type.
> This proposal is to add a utility function that casts an enum type to its
> underlying value. This would make it easier to handle
> enum types in function overloads for serialisation. For example:
>
> template <typename T>
> std::ostream& write(std::ostream& os, const T& v)
> {
>     os << std::underlying_cast(v);
>     return os;
> }
>
> Yes on the convenience, but "underlying_cast" is the wrong name because t=
his
> does not look like a regular cast.
>
> Something like "std::underlying_value" might be better.
>
>
> I've used underlying(v) to get the underlying value in some of my
> libraries that wrap other types to build opaque types.
>
> I've as well used underlying_cast to static_cast the underlying value to
> another type that works with static cast
>
>     template <class U, class T>
>     U underlying_cast(T const& v)
>     {
>       return static_cast<U>(underlying(v));
>     }
>
>
> This would be part of a library proposal for strong/opaque types.
>
Question: If wrapped types are being considered, would anyone consider
`chrono::duration::rep` to be the underlying type of `chrono::duration` or
it is something else?  Because if the former, then `to_rep` from P0675
serves a similar purpose.

> 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/aa4104f9-5a2=
9-c1d9-22ac-1dfa9cad8d18%40wanadoo.fr
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aa4104f9-5a=
29-c1d9-22ac-1dfa9cad8d18%40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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/CABPJVnSrvKQPXqRPDju8PnnXv_M6%2B3EuPCuqMkMb9QigC=
-6fTQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Aug 2,=
 2017 at 4:33 AM Vicente J. Botet Escriba &lt;<a href=3D"mailto:vicente.bot=
et@wanadoo.fr">vicente.botet@wanadoo.fr</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"m_8705335493861418200moz-cite-prefix">Le 30/07/2017 =C3=
=A0 18:20, Thiago Macieira
      a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <pre>On Sunday, 30 July 2017 04:50:41 PDT <a class=3D"m_8705335493861=
418200moz-txt-link-abbreviated" href=3D"mailto:james.a.cooper@gmail.com" ta=
rget=3D"_blank">james.a.cooper@gmail.com</a> wrote:
</pre>
      <blockquote type=3D"cite">
        <pre>C++ allows enums to have an underlying type specified. When se=
rialising
enum values it&#39;s important to use the correct type.
This proposal is to add a utility function that casts an enum type to its
underlying value. This would make it easier to handle
enum types in function overloads for serialisation. For example:

template &lt;typename T&gt;
std::ostream&amp; write(std::ostream&amp; os, const T&amp; v)
{
    os &lt;&lt; std::underlying_cast(v);
    return os;
}
</pre>
      </blockquote>
      <pre>Yes on the convenience, but &quot;underlying_cast&quot; is the w=
rong name because this=20
does not look like a regular cast.

Something like &quot;std::underlying_value&quot; might be better.

</pre>
    </blockquote>
    </div><div text=3D"#000000" bgcolor=3D"#FFFFFF"><p><font size=3D"+1">I&=
#39;ve used underlying(v) to get the underlying
        value in some of my libraries that wrap other types to build
        opaque types.</font></p>
    <p><font size=3D"+1">I&#39;ve as well used underlying_cast to static_ca=
st
        the underlying value to another type that works with static cast<br=
>
      </font></p>
    <p><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template &lt;class U, class T&g=
t;<br>
        =C2=A0=C2=A0=C2=A0 U underlying_cast(T const&amp; v)<br>
        =C2=A0=C2=A0=C2=A0 {<br>
        =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return static_cast&lt;U&gt;(underlyi=
ng(v));<br>
        =C2=A0=C2=A0=C2=A0 }<br>
      </font></p>
    <p><font size=3D"+1"><br>
      </font></p>
    <p><font size=3D"+1">This would be part of a library proposal for
        strong/opaque types.<br></font></p></div></blockquote><div text=3D"=
#000000" bgcolor=3D"#FFFFFF">Question: If wrapped types are being considere=
d, would anyone consider `chrono::duration::rep` to be the underlying type =
of `chrono::duration` or it is something else?=C2=A0 Because if the former,=
 then `to_rep` from P0675 serves a similar purpose. <br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div text=3D"#000000" bgcolor=3D"#FFFFFF"><p><font size=
=3D"+1">
      </font></p><font size=3D"+1">Vicente</font><br>
   =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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/aa4104f9-5a29-c1d9-22ac-1dfa9cad8d18%=
40wanadoo.fr?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aa4104f9-5a29-=
c1d9-22ac-1dfa9cad8d18%40wanadoo.fr</a>.<br>
</blockquote></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/CABPJVnSrvKQPXqRPDju8PnnXv_M6%2B3EuPC=
uqMkMb9QigC-6fTQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CABPJVnSrvKQPXq=
RPDju8PnnXv_M6%2B3EuPCuqMkMb9QigC-6fTQ%40mail.gmail.com</a>.<br />

--94eb2c0defc0dd65860555c6d24f--

.


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

Le 02/08/2017 =C3=A0 17:21, John McFarlane a =C3=A9crit :
> On Wed, Aug 2, 2017 at 4:33 AM Vicente J. Botet Escriba=20
> <vicente.botet@wanadoo.fr <mailto:vicente.botet@wanadoo.fr>> wrote:
>
>     Le 30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit :
>>     On Sunday, 30 July 2017 04:50:41 PDTjames.a.cooper@gmail.com <mailto=
:james.a.cooper@gmail.com>  wrote:
>>>     C++ allows enums to have an underlying type specified. When seriali=
sing
>>>     enum values it's important to use the correct type.
>>>     This proposal is to add a utility function that casts an enum type =
to its
>>>     underlying value. This would make it easier to handle
>>>     enum types in function overloads for serialisation. For example:
>>>
>>>     template <typename T>
>>>     std::ostream& write(std::ostream& os, const T& v)
>>>     {
>>>          os << std::underlying_cast(v);
>>>          return os;
>>>     }
>>     Yes on the convenience, but "underlying_cast" is the wrong name beca=
use this
>>     does not look like a regular cast.
>>
>>     Something like "std::underlying_value" might be better.
>>
>     I've used underlying(v) to get the underlying value in some of my
>     libraries that wrap other types to build opaque types.
>
>     I've as well used underlying_cast to static_cast the underlying
>     value to another type that works with static cast
>
>         template <class U, class T>
>         U underlying_cast(T const& v)
>         {
>           return static_cast<U>(underlying(v));
>         }
>
>
>     This would be part of a library proposal for strong/opaque types.
>
> Question: If wrapped types are being considered, would anyone consider=20
> `chrono::duration::rep` to be the underlying type of=20
> `chrono::duration` or it is something else?  Because if the former,=20
> then `to_rep` from P0675 serves a similar purpose.
For me chrono::duration::rep is the underlying type an underlying type=20
is something that works not only for numeric types. Your to_rep<T>()(v)=20
function object is similar as underlying_cast<T>(v). Just wondering why=20
do you need a function object.



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/db80d22b-15d6-0995-fa22-3e99eb745269%40wanadoo.f=
r.

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

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 02/08/2017 =C3=A0 17:21, John McFarla=
ne a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite"
cite=3D"mid:CABPJVnSrvKQPXqRPDju8PnnXv_M6+3EuPCuqMkMb9QigC-6fTQ@mail.gmail.=
com">
      <div dir=3D"ltr">
        <div class=3D"gmail_quote">
          <div dir=3D"ltr">On Wed, Aug 2, 2017 at 4:33 AM Vicente J. Botet
            Escriba &lt;<a href=3D"mailto:vicente.botet@wanadoo.fr"
              moz-do-not-send=3D"true">vicente.botet@wanadoo.fr</a>&gt;
            wrote:<br>
          </div>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <div class=3D"m_8705335493861418200moz-cite-prefix">Le
                30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit=C2=A0=
:<br>
              </div>
              <blockquote type=3D"cite">
                <pre>On Sunday, 30 July 2017 04:50:41 PDT <a class=3D"m_870=
5335493861418200moz-txt-link-abbreviated" href=3D"mailto:james.a.cooper@gma=
il.com" target=3D"_blank" moz-do-not-send=3D"true">james.a.cooper@gmail.com=
</a> wrote:
</pre>
                <blockquote type=3D"cite">
                  <pre>C++ allows enums to have an underlying type specifie=
d. When serialising
enum values it's important to use the correct type.
This proposal is to add a utility function that casts an enum type to its
underlying value. This would make it easier to handle
enum types in function overloads for serialisation. For example:

template &lt;typename T&gt;
std::ostream&amp; write(std::ostream&amp; os, const T&amp; v)
{
    os &lt;&lt; std::underlying_cast(v);
    return os;
}
</pre>
                </blockquote>
                <pre>Yes on the convenience, but "underlying_cast" is the w=
rong name because this=20
does not look like a regular cast.

Something like "std::underlying_value" might be better.

</pre>
              </blockquote>
            </div>
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <p><font size=3D"+1">I've used underlying(v) to get the
                  underlying value in some of my libraries that wrap
                  other types to build opaque types.</font></p>
              <p><font size=3D"+1">I've as well used underlying_cast to
                  static_cast the underlying value to another type that
                  works with static cast<br>
                </font></p>
              <p><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template &lt;class U,=
 class T&gt;<br>
                  =C2=A0=C2=A0=C2=A0 U underlying_cast(T const&amp; v)<br>
                  =C2=A0=C2=A0=C2=A0 {<br>
                  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return static_cast&lt;U&gt=
;(underlying(v));<br>
                  =C2=A0=C2=A0=C2=A0 }<br>
                </font></p>
              <p><font size=3D"+1"><br>
                </font></p>
              <p><font size=3D"+1">This would be part of a library
                  proposal for strong/opaque types.<br>
                </font></p>
            </div>
          </blockquote>
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">Question: If wrapped
            types are being considered, would anyone consider
            `chrono::duration::rep` to be the underlying type of
            `chrono::duration` or it is something else?=C2=A0 Because if th=
e
            former, then `to_rep` from P0675 serves a similar purpose. <br>
          </div>
        </div>
      </div>
    </blockquote>
    For me chrono::duration::rep is the underlying type an underlying
    type is something that works not only for numeric types. Your
    to_rep&lt;T&gt;()(v) function object is similar as underlying_cast&lt;T=
&gt;(v).
    Just wondering why do you need a function object.<br>
    <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/db80d22b-15d6-0995-fa22-3e99eb745269%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/db80d22b-15d6-0995-fa22-3e99eb745269=
%40wanadoo.fr</a>.<br />

--------------131504E697C54933521C39FB--

.


Author: John McFarlane <john@mcfarlane.name>
Date: Wed, 02 Aug 2017 19:05:42 +0000
Raw View
--001a11477fd2f299eb0555c9f3ad
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wed, Aug 2, 2017, 10:54 Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:

> Le 02/08/2017 =C3=A0 17:21, John McFarlane a =C3=A9crit :
>
> On Wed, Aug 2, 2017 at 4:33 AM Vicente J. Botet Escriba <
> vicente.botet@wanadoo.fr> wrote:
>
>> Le 30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit :
>>
>> I've used underlying(v) to get the underlying value in some of my
>> libraries that wrap other types to build opaque types.
>>
>> I've as well used underlying_cast to static_cast the underlying value to
>> another type that works with static cast
>>
>>     template <class U, class T>
>>     U underlying_cast(T const& v)
>>     {
>>       return static_cast<U>(underlying(v));
>>     }
>>
>>
>> This would be part of a library proposal for strong/opaque types.
>>
> Question: If wrapped types are being considered, would anyone consider
> `chrono::duration::rep` to be the underlying type of `chrono::duration` o=
r
> it is something else?  Because if the former, then `to_rep` from P0675
> serves a similar purpose.
>
> For me chrono::duration::rep is the underlying type an underlying type is
> something that works not only for numeric types. Your to_rep<T>()(v)
> function object is similar as underlying_cast<T>(v). Just wondering why d=
o
> you need a function object.
>
> I'm not wed to a function object.  A requirement is that the user can
customize this for their own types.

John

--=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/CABPJVnT%3DJ1u1HWsQG%3DJT8wZNi%3DZkaU%2B5Vy9m2LJ=
CbSBFXTsV7A%40mail.gmail.com.

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

<div dir=3D"ltr">On Wed, Aug 2, 2017, 10:54 Vicente J. Botet Escriba &lt;<a=
 href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vicente.botet@w=
anadoo.fr</a>&gt; wrote:<br><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"m_5414817119334568313m_8086787294418470163moz-cite-prefix=
">Le 02/08/2017 =C3=A0 17:21, John McFarlane a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_quote">
          <div dir=3D"ltr">On Wed, Aug 2, 2017 at 4:33 AM Vicente J. Botet
            Escriba &lt;<a href=3D"mailto:vicente.botet@wanadoo.fr" target=
=3D"_blank">vicente.botet@wanadoo.fr</a>&gt;
            wrote:<br>
          </div>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <div class=3D"m_5414817119334568313m_8086787294418470163m_870=
5335493861418200moz-cite-prefix">Le
                30/07/2017 =C3=A0 18:20, Thiago Macieira a =C3=A9crit=C2=A0=
:<br>
              </div>
             =20
            </div>
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <p><font size=3D"+1">I&#39;ve used underlying(v) to get the
                  underlying value in some of my libraries that wrap
                  other types to build opaque types.</font></p>
              <p><font size=3D"+1">I&#39;ve as well used underlying_cast to
                  static_cast the underlying value to another type that
                  works with static cast<br>
                </font></p>
              <p><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template &lt;class U,=
 class T&gt;<br>
                  =C2=A0=C2=A0=C2=A0 U underlying_cast(T const&amp; v)<br>
                  =C2=A0=C2=A0=C2=A0 {<br>
                  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return static_cast&lt;U&gt=
;(underlying(v));<br>
                  =C2=A0=C2=A0=C2=A0 }<br>
                </font></p>
              <p><font size=3D"+1"><br>
                </font></p>
              <p><font size=3D"+1">This would be part of a library
                  proposal for strong/opaque types.<br>
                </font></p>
            </div>
          </blockquote>
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">Question: If wrapped
            types are being considered, would anyone consider
            `chrono::duration::rep` to be the underlying type of
            `chrono::duration` or it is something else?=C2=A0 Because if th=
e
            former, then `to_rep` from P0675 serves a similar purpose. <br>
          </div>
        </div>
      </div>
    </blockquote></div><div text=3D"#000000" bgcolor=3D"#FFFFFF">
    For me chrono::duration::rep is the underlying type an underlying
    type is something that works not only for numeric types. Your
    to_rep&lt;T&gt;()(v) function object is similar as underlying_cast&lt;T=
&gt;(v).
    Just wondering why do you need a function object.</div><div text=3D"#00=
0000" bgcolor=3D"#FFFFFF"><br></div></blockquote><div>I&#39;m not wed to a =
function object.=C2=A0 A requirement is that the user can customize this fo=
r their own types.<br></div><br></div><div class=3D"gmail_quote">John<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/CABPJVnT%3DJ1u1HWsQG%3DJT8wZNi%3DZkaU=
%2B5Vy9m2LJCbSBFXTsV7A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CABPJVnT%=
3DJ1u1HWsQG%3DJT8wZNi%3DZkaU%2B5Vy9m2LJCbSBFXTsV7A%40mail.gmail.com</a>.<br=
 />

--001a11477fd2f299eb0555c9f3ad--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 2 Aug 2017 23:54:09 +0200
Raw View
This is a multi-part message in MIME format.
--------------893A3C2320E9565A2BBC615D
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 02/08/2017 =C3=A0 21:05, John McFarlane a =C3=A9crit :
> On Wed, Aug 2, 2017, 10:54 Vicente J. Botet Escriba=20
> <vicente.botet@wanadoo.fr <mailto:vicente.botet@wanadoo.fr>> wrote:
>
>     Le 02/08/2017 =C3=A0 17:21, John McFarlane a =C3=A9crit :
>>
>>
>>
>>     Question: If wrapped types are being considered, would anyone
>>     consider `chrono::duration::rep` to be the underlying type of
>>     `chrono::duration` or it is something else?  Because if the
>>     former, then `to_rep` from P0675 serves a similar purpose.
>     For me chrono::duration::rep is the underlying type an underlying
>     type is something that works not only for numeric types. Your
>     to_rep<T>()(v) function object is similar as
>     underlying_cast<T>(v). Just wondering why do you need a function
>     object.
>
> I'm not wed to a function object.  A requirement is that the user can=20
> customize this for their own types.
>
>
Of course.


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/39572179-b3fe-bce3-3815-df3e9d0b2264%40wanadoo.f=
r.

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

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 02/08/2017 =C3=A0 21:05, John McFarla=
ne a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite"
cite=3D"mid:CABPJVnT=3DJ1u1HWsQG=3DJT8wZNi=3DZkaU+5Vy9m2LJCbSBFXTsV7A@mail.=
gmail.com">
      <div dir=3D"ltr">On Wed, Aug 2, 2017, 10:54 Vicente J. Botet Escriba
        &lt;<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank"
          moz-do-not-send=3D"true">vicente.botet@wanadoo.fr</a>&gt; wrote:<=
br>
        <div class=3D"gmail_quote">
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text=3D"#000000" bgcolor=3D"#FFFFFF">
              <div
                class=3D"m_5414817119334568313m_8086787294418470163moz-cite=
-prefix">Le
                02/08/2017 =C3=A0 17:21, John McFarlane a =C3=A9crit=C2=A0:=
<br>
              </div>
              <blockquote type=3D"cite">
                <div dir=3D"ltr">
                  <div class=3D"gmail_quote">
                    <div dir=3D"ltr"><br>
                    </div>
                    <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div text=3D"#000000" bgcolor=3D"#FFFFFF">
                        <div
class=3D"m_5414817119334568313m_8086787294418470163m_8705335493861418200moz=
-cite-prefix"><br>
                        </div>
                      </div>
                      <div text=3D"#000000" bgcolor=3D"#FFFFFF"><br>
                      </div>
                    </blockquote>
                    <div text=3D"#000000" bgcolor=3D"#FFFFFF">Question: If
                      wrapped types are being considered, would anyone
                      consider `chrono::duration::rep` to be the
                      underlying type of `chrono::duration` or it is
                      something else?=C2=A0 Because if the former, then
                      `to_rep` from P0675 serves a similar purpose. <br>
                    </div>
                  </div>
                </div>
              </blockquote>
            </div>
            <div text=3D"#000000" bgcolor=3D"#FFFFFF"> For me
              chrono::duration::rep is the underlying type an underlying
              type is something that works not only for numeric types.
              Your to_rep&lt;T&gt;()(v) function object is similar as
              underlying_cast&lt;T&gt;(v). Just wondering why do you
              need a function object.</div>
            <div text=3D"#000000" bgcolor=3D"#FFFFFF"><br>
            </div>
          </blockquote>
          <div>I'm not wed to a function object.=C2=A0 A requirement is tha=
t
            the user can customize this for their own types.<br>
          </div>
          <br>
        </div>
        <div class=3D"gmail_quote"><br>
        </div>
      </div>
    </blockquote>
    <p>Of course.</p>
    <p><br>
    </p>
    <p>Vicente<br>
    </p>
  </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/39572179-b3fe-bce3-3815-df3e9d0b2264%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/39572179-b3fe-bce3-3815-df3e9d0b2264=
%40wanadoo.fr</a>.<br />

--------------893A3C2320E9565A2BBC615D--

.