Topic: bit_enum


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 10 Jun 2014 03:43:36 -0700 (PDT)
Raw View
------=_Part_260_33468610.1402397016380
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Often, it seems, one needs a number of flags packed into a data type.  An=
=20
example is found in std::ios with eof_bit, fail_bit and bad_bit.
=20
There are a number of existing solutions, each with their own shortcomings:
=20
*bit fields*
The programmer can only refer to a single field at a time.  Sometimes, a=20
few bits may be related and a test needs to be made for any one of them.
There is no underlying type.
There are no bit operations.
There are no subset operations.
=20
*std::bitset*
The bits are unnamed.
The programmer can only refer to a single bit at a time.
The programmer is unable to control the underlying type.
There are no subset operations.
=20
*std::vector<bool>*
The bits are unnamed.
There are no bit operations.
The programmer can only refer to a single bit at a time.
There are no subset operations.
=20
*enums and enum classes*
There are no bit operations.
To use the enumeration as flags, values outside the list of tags are needed=
..
There are no subset operations.
=20
*integer types*
There is a lack of abstraction.
The bits are unnamed.
There are no subset operations.
=20
My proposal is for the introduction of a new type, the bit_enum (or maybe,=
=20
enum_set?) that behaves like enums except for below:
=20
The first tag defaults to 1, not 0.
=20
Succeeding tags default to the next power of 2 greater than the preceding=
=20
tag.
=20
Let T be the bit_enum type, UT be the underlying type and @ be any of &, |=
=20
or ^.  Let the tag values be value[0], value[1], =E2=80=A6 value[n =E2=80=
=93 1], where n is=20
the number of tags, and let *all* =3D value[0] | value[1] | =E2=80=A6 value=
[n =E2=80=93 1].
=20
The following functions should be defined:
=20
 constexpr inline T operator@(T a, T b) {                                  =
=20
                return static_cast<T>(static_cast<UT>(a) @ static_cast<UT>(=
b
));                                                                        =
=20
                                                                           =
=20
                                                                          =
=20
}

=20
=20
 constexpr inline T operator@=3D(T &a, T b) {                              =
  =20
                                                                           =
=20
                                                                           =
=20
                                     =20
  return reinterpret_cast<T &>(reinterpret_cast<UT &>(a) @=3D static_cast<U=
T>(
b));                                                                      =
=20
                                                                           =
=20
                                                                           =
=20
}

=20
=20
 constexpr inline T operator~(T a) {
  return static_cast<T>(static_cast<UT>(a) ^ static_cast<UT>(all));
}

=20
Explicit static_casting to/from UT are allowed.
=20
=20
 constexpr inline bool operator=3D=3D(T a, T b) {         =20
  return static_cast<UT>(a) =3D=3D static_cast<UT>(b);         =20
}

=20
=20
 constexpr inline bool operator!=3D(T a, T b) {          =20
  return !(a =3D=3D b);          =20
}

=20
=20
 constexpr inline bool operator<=3D(T a, T b) {           =20
  return (a & ~b) =3D=3D static_cast<T>(0);           =20
}

=20
=20
 const inline bool operator<(T a, T b) {            =20
  return a <=3D b && a !=3D b;            =20
}

=20
=20
 const inline bool operator>=3D(T a, T b) {             =20
  return b <=3D a;             =20
}

=20
=20
 const inline bool operator>(T a, T b) {              =20
  return b < a;              =20
}

=20
=20
 const inline operator bool(T a) {               =20
  return static_cast<UT>(a);               =20
}

=20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr"><DIV>Often, it seems, one needs a number of flags packed i=
nto a data type.&nbsp; An example is found in std::ios with eof_bit, fail_b=
it and bad_bit.</DIV>
<DIV>&nbsp;</DIV>
<DIV>There are a number of existing solutions, each with their own shortcom=
ings:</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>bit fields</STRONG></DIV>
<DIV>The programmer can only refer to a single field at a time.&nbsp; Somet=
imes, a few bits may be related and a test needs to be made for any one of =
them.</DIV>
<DIV>There is no underlying type.</DIV>
<DIV>There are no bit operations.</DIV>
<DIV>There are no subset operations.</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>std::bitset</STRONG></DIV>
<DIV>The bits are unnamed.</DIV>
<DIV>The programmer can only refer to a single bit at a time.</DIV>
<DIV>The programmer is unable to control the underlying type.</DIV>
<DIV>There are no subset operations.</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>std::vector&lt;bool&gt;</STRONG></DIV>
<DIV>The bits are unnamed.</DIV>
<DIV>There are no bit operations.</DIV>
<DIV>The programmer can only refer to a single bit at a time.</DIV>
<DIV>There are no subset operations.</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>enums and enum classes</STRONG></DIV>
<DIV>There are no bit operations.</DIV>
<DIV>To use the enumeration as flags, values outside the list of tags are n=
eeded.</DIV>
<DIV>There are no subset operations.</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>integer types</STRONG></DIV>
<DIV>There is a lack of abstraction.</DIV>
<DIV>The bits are unnamed.</DIV>
<DIV>There are no subset operations.</DIV>
<DIV>&nbsp;</DIV>
<DIV>My proposal is for the introduction of a new type, the bit_enum (or ma=
ybe, enum_set?) that behaves like enums except for below:</DIV>
<DIV>&nbsp;</DIV>
<DIV>The first tag defaults to 1, not 0.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Succeeding tags default to the next power of 2 greater than the preced=
ing tag.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Let T be the bit_enum type, UT be the underlying type and&nbsp;@ be an=
y of &amp;, | or ^.&nbsp; Let the tag values be value[0], value[1], =E2=80=
=A6 value[n =E2=80=93 1], where n is the number of tags, and let <EM>all</E=
M> =3D value[0] | value[1] | =E2=80=A6 value[n =E2=80=93 1].</DIV>
<DIV>&nbsp;</DIV>
<DIV>The following functions should be defined:</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T </SPAN><A hr=
ef=3D"mailto:operator@(T"><SPAN style=3D"COLOR: #008" class=3Dstyled-by-pre=
ttify>operator</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify=
>@(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>T</SPAN></=
A><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> a</SPAN><SPAN sty=
le=3D"COLOR: #660" class=3Dstyled-by-prettify>,</SPAN><SPAN style=3D"COLOR:=
 #000" class=3Dstyled-by-prettify> T b</SPAN><SPAN style=3D"COLOR: #660" cl=
ass=3Dstyled-by-prettify>)</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled=
-by-prettify> </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify=
>{</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettif=
y>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SP=
AN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>static_cast</SPAN=
><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN st=
yle=3D"COLOR: #000" class=3Dstyled-by-prettify>T</SPAN><SPAN style=3D"COLOR=
: #660" class=3Dstyled-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #008" =
class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: #660" cl=
ass=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=3Dsty=
led-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pret=
tify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>a</=
SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN s=
tyle=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLO=
R: #660" class=3Dstyled-by-prettify>@</SPAN><SPAN style=3D"COLOR: #000" cla=
ss=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-=
by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by=
-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify=
>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&gt;(</SPA=
N><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>b</SPAN><SPAN styl=
e=3D"COLOR: #660" class=3Dstyled-by-prettify>));</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<BR></=
SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>}</SPAN></DIV><=
/CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T </SPAN><A hr=
ef=3D"mailto:operator@=3D(T"><SPAN style=3D"COLOR: #008" class=3Dstyled-by-=
prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prett=
ify>@=3D(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>T</S=
PAN></A><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPA=
N style=3D"COLOR: #660" class=3Dstyled-by-prettify>&amp;</SPAN><SPAN style=
=3D"COLOR: #000" class=3Dstyled-by-prettify>a</SPAN><SPAN style=3D"COLOR: #=
660" class=3Dstyled-by-prettify>,</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify> T b</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled=
-by-prettify>)</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify=
> </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>{</SPAN><SP=
AN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify=
> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>reinterpret=
_cast</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SP=
AN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>T </SPAN><SPAN st=
yle=3D"COLOR: #660" class=3Dstyled-by-prettify>&amp;&gt;(</SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>reinterpret_cast</SPAN><SPAN st=
yle=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"CO=
LOR: #000" class=3Dstyled-by-prettify>UT </SPAN><SPAN style=3D"COLOR: #660"=
 class=3Dstyled-by-prettify>&amp;&gt;(</SPAN><SPAN style=3D"COLOR: #000" cl=
ass=3Dstyled-by-prettify>a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled=
-by-prettify>)</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify=
> </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>@=3D</SPAN>=
<SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=
=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" cla=
ss=3Dstyled-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dsty=
led-by-prettify>b</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prett=
ify>));</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp;&nbsp;<BR></SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T </SPAN><SPAN=
 style=3D"COLOR: #008" class=3Dstyled-by-prettify>operator</SPAN><SPAN styl=
e=3D"COLOR: #660" class=3Dstyled-by-prettify>~(</SPAN><SPAN style=3D"COLOR:=
 #000" class=3Dstyled-by-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" cla=
ss=3Dstyled-by-prettify>)</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-=
by-prettify>&nbsp;{</SPAN></DIV>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #000" class=3Dstyled-by-p=
rettify>&nbsp;&nbsp;</SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-pr=
ettify>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>static_cast<=
/SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SP=
AN style=3D"COLOR: #000" class=3Dstyled-by-prettify>T</SPAN><SPAN style=3D"=
COLOR: #660" class=3Dstyled-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #=
008" class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: #66=
0" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-b=
y-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-pretti=
fy>a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><=
SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #660" class=3Dstyled-by-prettify>^</SPAN><SPAN style=3D"COLOR: #=
000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" class=
=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: #660" class=
=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled=
-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettif=
y>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>all</S=
PAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>));<BR></SPAN><S=
PAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>}</SPAN></DIV></CODE><=
/DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>Explicit static_casting to/from UT are allowed.</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN s=
tyle=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"C=
OLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" =
class=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=
=3Dstyled-by-prettify>=3D=3D(</SPAN><SPAN style=3D"COLOR: #000" class=3Dsty=
led-by-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pre=
ttify>,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b</=
SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN s=
tyle=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLO=
R: #660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" cla=
ss=3Dstyled-by-prettify> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<BR>&nbsp; </SPA=
N><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>return</SPAN><SPAN=
 style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"CO=
LOR: #008" class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLO=
R: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" =
class=3Dstyled-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dsty=
led-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-p=
rettify>a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</S=
PAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN st=
yle=3D"COLOR: #660" class=3Dstyled-by-prettify>=3D=3D</SPAN><SPAN style=3D"=
COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008"=
 class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: #660" c=
lass=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=3Dst=
yled-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pre=
ttify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>b<=
/SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>);</SPAN><SPAN=
 style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp;<BR></SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify=
>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN s=
tyle=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"C=
OLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" =
class=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=
=3Dstyled-by-prettify>!=3D(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyle=
d-by-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prett=
ify>,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b</SP=
AN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN sty=
le=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR:=
 #660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-b=
y-prettify>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>!(</SPAN=
><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>a </SPAN><SPAN styl=
e=3D"COLOR: #660" class=3Dstyled-by-prettify>=3D=3D</SPAN><SPAN style=3D"CO=
LOR: #000" class=3Dstyled-by-prettify> b</SPAN><SPAN style=3D"COLOR: #660" =
class=3Dstyled-by-prettify>);</SPAN><SPAN style=3D"COLOR: #000" class=3Dsty=
led-by-prettify> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<BR></SPAN><SPAN s=
tyle=3D"COLOR: #660" class=3Dstyled-by-prettify>}</SPAN></DIV></CODE></DIV>=
<BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>constexpr</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prett=
ify> </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</=
SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN s=
tyle=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"C=
OLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" =
class=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=
=3Dstyled-by-prettify>&lt;=3D(</SPAN><SPAN style=3D"COLOR: #000" class=3Dst=
yled-by-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pr=
ettify>,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b<=
/SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN =
style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COL=
OR: #660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" cl=
ass=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR: #008" class=
=3Dstyled-by-prettify>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyl=
ed-by-prettify> </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pretti=
fy>(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>a </SPAN>=
<SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&amp;</SPAN><SPAN st=
yle=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR=
: #660" class=3Dstyled-by-prettify>~</SPAN><SPAN style=3D"COLOR: #000" clas=
s=3Dstyled-by-prettify>b</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-b=
y-prettify>)</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> =
</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>=3D=3D</SPAN>=
<SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=
=3D"COLOR: #660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify>T</SPAN><SPAN style=3D"COLOR: #660" clas=
s=3Dstyled-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #066" class=3Dstyl=
ed-by-prettify>0</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pretti=
fy>);</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<BR></SPAN><SPAN style=3D"COLOR: #660" cl=
ass=3Dstyled-by-prettify>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>const</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</SPAN=
><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" clas=
s=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>&lt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by=
-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>=
,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b</SPAN><=
SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN style=
=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #=
660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR: #008" clas=
s=3Dstyled-by-prettify>return</SPAN><SPAN style=3D"COLOR: #000" class=3Dsty=
led-by-prettify> a </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pre=
ttify>&lt;=3D</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 b </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>&amp;&amp;=
</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> a </SPAN><SP=
AN style=3D"COLOR: #660" class=3Dstyled-by-prettify>!=3D</SPAN><SPAN style=
=3D"COLOR: #000" class=3Dstyled-by-prettify> b</SPAN><SPAN style=3D"COLOR: =
#660" class=3Dstyled-by-prettify>;</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<BR><=
/SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>}</SPAN></DIV>=
</CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>const</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</SPAN=
><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" clas=
s=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>&gt;=3D(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled=
-by-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-pretti=
fy>,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b</SPA=
N><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN styl=
e=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: =
#660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR: #008=
" class=3Dstyled-by-prettify>return</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify> b </SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-=
by-prettify>&lt;=3D</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-pre=
ttify> a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>;</SP=
AN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp;<BR></SPAN><SPAN style=3D"COLOR: #660" clas=
s=3Dstyled-by-prettify>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>const</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</SPAN=
><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" clas=
s=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by=
-prettify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>=
,</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> T b</SPAN><=
SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</SPAN><SPAN style=
=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #=
660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR: #000" class=
=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp; </SPAN><SPAN style=3D"COLOR=
: #008" class=3Dstyled-by-prettify>return</SPAN><SPAN style=3D"COLOR: #000"=
 class=3Dstyled-by-prettify> b </SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-=
prettify> a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>;<=
/SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<BR></SPAN><SPAN style=3D"COLOR: #=
660" class=3Dstyled-by-prettify>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV style=3D"BORDER-BOTTOM: #bbb 1px solid; BORDER-LEFT: #bbb 1px solid; B=
ACKGROUND-COLOR: #fafafa; WORD-WRAP: break-word; BORDER-TOP: #bbb 1px solid=
; BORDER-RIGHT: #bbb 1px solid" class=3Dprettyprint><CODE class=3Dprettypri=
nt>
<DIV class=3Dsubprettyprint><SPAN style=3D"COLOR: #008" class=3Dstyled-by-p=
rettify>const</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify>=
 </SPAN><SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>inline</SPAN=
><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=
=3D"COLOR: #008" class=3Dstyled-by-prettify>operator</SPAN><SPAN style=3D"C=
OLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR: #008" =
class=3Dstyled-by-prettify>bool</SPAN><SPAN style=3D"COLOR: #660" class=3Ds=
tyled-by-prettify>(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-pre=
ttify>T a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>)</S=
PAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN st=
yle=3D"COLOR: #660" class=3Dstyled-by-prettify>{</SPAN><SPAN style=3D"COLOR=
: #000" class=3Dstyled-by-prettify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp; </SPAN><=
SPAN style=3D"COLOR: #008" class=3Dstyled-by-prettify>return</SPAN><SPAN st=
yle=3D"COLOR: #000" class=3Dstyled-by-prettify> </SPAN><SPAN style=3D"COLOR=
: #008" class=3Dstyled-by-prettify>static_cast</SPAN><SPAN style=3D"COLOR: =
#660" class=3Dstyled-by-prettify>&lt;</SPAN><SPAN style=3D"COLOR: #000" cla=
ss=3Dstyled-by-prettify>UT</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled=
-by-prettify>&gt;(</SPAN><SPAN style=3D"COLOR: #000" class=3Dstyled-by-pret=
tify>a</SPAN><SPAN style=3D"COLOR: #660" class=3Dstyled-by-prettify>);</SPA=
N><SPAN style=3D"COLOR: #000" class=3Dstyled-by-prettify> &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<BR></SPAN><SPAN style=3D"COLOR: #660=
" class=3Dstyled-by-prettify>}</SPAN></DIV></CODE></DIV><BR>
<DIV>&nbsp;</DIV></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_260_33468610.1402397016380--

.


Author: "dgutson ." <danielgutson@gmail.com>
Date: Tue, 10 Jun 2014 10:37:07 -0300
Raw View
FWIW, I faced a similar problem several years ago so I made a library
you made want to look at:
https://code.google.com/p/mili/source/browse/mili/bitwise_enums.h

I'm not saying that a language support is not needed, just that
looking at what can be done from a library is worth looking.

Cheers,

    Daniel.

On Tue, Jun 10, 2014 at 7:43 AM, Douglas Boffey
<douglas.boffey@gmail.com> wrote:
> Often, it seems, one needs a number of flags packed into a data type.  An
> example is found in std::ios with eof_bit, fail_bit and bad_bit.
>
> There are a number of existing solutions, each with their own shortcoming=
s:
>
> bit fields
> The programmer can only refer to a single field at a time.  Sometimes, a =
few
> bits may be related and a test needs to be made for any one of them.
> There is no underlying type.
> There are no bit operations.
> There are no subset operations.
>
> std::bitset
> The bits are unnamed.
> The programmer can only refer to a single bit at a time.
> The programmer is unable to control the underlying type.
> There are no subset operations.
>
> std::vector<bool>
> The bits are unnamed.
> There are no bit operations.
> The programmer can only refer to a single bit at a time.
> There are no subset operations.
>
> enums and enum classes
> There are no bit operations.
> To use the enumeration as flags, values outside the list of tags are need=
ed.
> There are no subset operations.
>
> integer types
> There is a lack of abstraction.
> The bits are unnamed.
> There are no subset operations.
>
> My proposal is for the introduction of a new type, the bit_enum (or maybe=
,
> enum_set?) that behaves like enums except for below:
>
> The first tag defaults to 1, not 0.
>
> Succeeding tags default to the next power of 2 greater than the preceding
> tag.
>
> Let T be the bit_enum type, UT be the underlying type and @ be any of &, =
|
> or ^.  Let the tag values be value[0], value[1], =E2=80=A6 value[n =E2=80=
=93 1], where n is
> the number of tags, and let all =3D value[0] | value[1] | =E2=80=A6 value=
[n =E2=80=93 1].
>
> The following functions should be defined:
>
> constexpr inline T operator@(T a, T b) {
> return static_cast<T>(static_cast<UT>(a) @ static_cast<UT>(b));
> }
>
>
>
> constexpr inline T operator@=3D(T &a, T b) {
>   return reinterpret_cast<T &>(reinterpret_cast<UT &>(a) @=3D
> static_cast<UT>(b));
> }
>
>
>
> constexpr inline T operator~(T a) {
>   return static_cast<T>(static_cast<UT>(a) ^ static_cast<UT>(all));
> }
>
>
> Explicit static_casting to/from UT are allowed.
>
>
> constexpr inline bool operator=3D=3D(T a, T b) {
>   return static_cast<UT>(a) =3D=3D static_cast<UT>(b);
> }
>
>
>
> constexpr inline bool operator!=3D(T a, T b) {
>   return !(a =3D=3D b);
> }
>
>
>
> constexpr inline bool operator<=3D(T a, T b) {
>   return (a & ~b) =3D=3D static_cast<T>(0);
> }
>
>
>
> const inline bool operator<(T a, T b) {
>   return a <=3D b && a !=3D b;
> }
>
>
>
> const inline bool operator>=3D(T a, T b) {
>   return b <=3D a;
> }
>
>
>
> const inline bool operator>(T a, T b) {
>   return b < a;
> }
>
>
>
> const inline operator bool(T a) {
>   return static_cast<UT>(a);
> }
>
>
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.



--=20
Who=E2=80=99s got the sweetest disposition?
One guess, that=E2=80=99s who?
Who=E2=80=99d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Tue, 10 Jun 2014 21:45:09 +0800
Raw View
--Apple-Mail=_106B133C-15C5-48F4-8BFD-37A64EBF4D5C
Content-Type: text/plain; charset=ISO-8859-1


On 2014-06-10, at 6:43 PM, Douglas Boffey <douglas.boffey@gmail.com> wrote:

> enums and enum classes
> There are no bit operations.
> To use the enumeration as flags, values outside the list of tags are needed.
> There are no subset operations.

See my StackOverflow answer to "How does one use an enum class as a set of flags?" for a library-style facility. In bullet summary form,

Generic operator overloads are provided for enumerations marked as bitsets.
A trait flag marks the enumeration as such.
Enum values are bit indexes but bitwise operations produce bitset values.
Bitset values are derived from std::bitset.

Other answers there provide lighter-weight, non-template alternatives. But, if you have more than a few enumeration types with special properties (bitsets, easy conversion by unary +, working as indexes), having such trait-based library can really pay off.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--Apple-Mail=_106B133C-15C5-48F4-8BFD-37A64EBF4D5C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;06&ndash;10, at 6:43 PM, Douglas Boffey &lt;<a href=3D"mailto:douglas=
..boffey@gmail.com">douglas.boffey@gmail.com</a>&gt; wrote:</div><br class=
=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><=
div><strong>enums and enum classes</strong></div>
<div>There are no bit operations.</div>
<div>To use the enumeration as flags, values outside the list of tags are n=
eeded.</div>
<div>There are no subset operations.</div></div></blockquote><div><br></div=
><div>See my StackOverflow answer to "<a href=3D"http://stackoverflow.com/q=
/18553843/153285">How does one use an enum class as a set of flags?</a>&rdq=
uo; for a library-style facility. In bullet summary form,</div><div><br></d=
iv><div><ul class=3D"MailOutline"><li>Generic operator overloads are provid=
ed for enumerations marked as bitsets.</li><li>A trait flag marks the enume=
ration as such.</li><li>Enum values are bit indexes but bitwise operations =
produce bitset values.</li><li>Bitset values are derived from std::bitset.<=
/li></ul><div><br></div><div>Other answers there provide lighter-weight, no=
n-template alternatives. But, if you have more than a few enumeration types=
 with special properties (bitsets, easy conversion by unary +, working as i=
ndexes), having such trait-based library can really pay off.</div><div><br>=
</div></div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_106B133C-15C5-48F4-8BFD-37A64EBF4D5C--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 10 Jun 2014 13:43:09 -0400
Raw View
On 2014-06-10 06:43, Douglas Boffey wrote:
> Often, it seems, one needs a number of flags packed into a data type.  An=
=20
> example is found in std::ios with eof_bit, fail_bit and bad_bit.
> =20
> My proposal is for the introduction of a new type, the bit_enum (or maybe=
,=20
> enum_set?) that behaves like enums except for below:
> =20
> The first tag defaults to 1, not 0.
> =20
> Succeeding tags default to the next power of 2 greater than the preceding=
=20
> tag.
> =20
> Let T be the bit_enum type, UT be the underlying type and @ be any of &, =
|=20
> or ^.  Let the tag values be value[0], value[1], =E2=80=A6 value[n =E2=80=
=93 1], where n is=20
> the number of tags, and let *all* =3D value[0] | value[1] | =E2=80=A6 val=
ue[n =E2=80=93 1].

Personally, I'd attack this as two (three) problems.

The first requires a language extension to change the default value
assignment of an enum. (Although I wonder how useful this actually is...
it's convenience, undisputably, but there are potential drawbacks, and
the value add is low).

The second can be a library-only change to create a std::flags class.

A recommended third would be a way to make enum values accessible in
another scope, e.g. 'using enum':

  enum class /* bitwise */ MyFlag
  {
    A,
    B,
    C,
  };

  class MyFlags : std::flags<MyFlag>
  {
    using enum MyFlag; // A, etc. now in scope of MyFlags
    static auto AB =3D A | B; // AB has type std::flags<MyFlag>
  };

(Subclassing may be an issue; with template inheritance, partial
specialization may be preferable. However, the above should suffice to
communicate the general idea. In particular, making the flag enum only
individual flags, and placing convenience flag combinations in the flags
type.)

Note that 'using enum' should be usable from any scope, including
global, local, and namespaces.

See
https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/G1_ocEwi=
qsE
(and
https://groups.google.com/a/isocpp.org/group/std-proposals/attach/c061369a0=
16e9e7e/c++1y-std-flags.h?part=3D0.1&authuser=3D0)
for previous discussion and my suggestion on the library implementation.

(See also David Krauss's library; I didn't look, but it sounds like he
has a better approach to providing the global operators...)

>  constexpr inline bool operator<=3D(T a, T b) {           =20
>   return (a & ~b) =3D=3D static_cast<T>(0);           =20
> }

I'm not sure that ordering operations make sense. (Only if you need to
use them as keys in e.g. std::map.) I don't see that there is a logical
meaning to an ordering comparison of flags.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Wed, 11 Jun 2014 04:48:42 -0700 (PDT)
Raw View
------=_Part_3834_11300000.1402487322948
Content-Type: text/plain; charset=UTF-8


>
> >  constexpr inline bool operator<=(T a, T b) {
> >   return (a & ~b) == static_cast<T>(0);
> > }
>
> I'm not sure that ordering operations make sense. (Only if you need to
> use them as keys in e.g. std::map.) I don't see that there is a logical
> meaning to an ordering comparison of flags.
>
> The way I defined operator<= etc. was to mirror subset operations.

>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-le=
ft: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bor=
der-left-style: solid;" class=3D"gmail_quote">&gt; &nbsp;constexpr inline b=
ool operator&lt;=3D(T a, T b) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<br>&gt; &nbsp; return (a &amp; ~b) =3D=3D static_cast&lt;T&gt;(0); &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<br>&gt; }
<br>
<br>I'm not sure that ordering operations make sense. (Only if you need to
<br>use them as keys in e.g. std::map.) I don't see that there is a logical
<br>meaning to an ordering comparison of flags.
<br>
<br></blockquote><div>The way I defined operator&lt;=3D&nbsp;etc. was to mi=
rror subset operations.</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex=
; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wid=
th: 1px; border-left-style: solid;" class=3D"gmail_quote">&nbsp;</blockquot=
e></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_3834_11300000.1402487322948--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 11 Jun 2014 14:11:50 -0400
Raw View
On 2014-06-11 07:48, Douglas Boffey wrote:
>>>  constexpr inline bool operator<=(T a, T b) {
>>>   return (a & ~b) == static_cast<T>(0);
>>> }
>>
>> I'm not sure that ordering operations make sense. (Only if you need to
>> use them as keys in e.g. std::map.) I don't see that there is a logical
>> meaning to an ordering comparison of flags.
>>
> The way I defined operator<= etc. was to mirror subset operations.

Ah. Um... that seems very confusing. (And also like it could break badly
if one does in fact try to use flags as a std::map key.)

If these operations are felt to be needed, I would strongly encourage
using named member functions instead, e.g. contains().

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: adrien courdavault <adrien59cadri@gmail.com>
Date: Mon, 2 Feb 2015 02:55:43 -0800 (PST)
Raw View
------=_Part_246_1668759177.1422874543392
Content-Type: multipart/alternative;
 boundary="----=_Part_247_699058019.1422874543392"

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

Hello

I agree with the problem list, but I think the solmution here is maybe more=
=20
interesting for bit masks with typed enums:

https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bit=
fields.html

which requires only the include of a header in the enum class header and a=
=20
definition for SFINAE to specify if the overloads of bitwise operators=20
should be implemented for the type.

Also, I would say that when I use typed enum I often need to declare C=20
arrays, or std::arrays, and access those.
In which case maybe there could be a solution of the same kind.

there is always the std::underlying_type<> anyway

Best

Le mardi 10 juin 2014 12:43:36 UTC+2, Douglas Boffey a =C3=A9crit :
>
> Often, it seems, one needs a number of flags packed into a data type.  An=
=20
> example is found in std::ios with eof_bit, fail_bit and bad_bit.
> =20
> There are a number of existing solutions, each with their own shortcoming=
s:
> =20
> *bit fields*
> The programmer can only refer to a single field at a time.  Sometimes, a=
=20
> few bits may be related and a test needs to be made for any one of them.
> There is no underlying type.
> There are no bit operations.
> There are no subset operations.
> =20
> *std::bitset*
> The bits are unnamed.
> The programmer can only refer to a single bit at a time.
> The programmer is unable to control the underlying type.
> There are no subset operations.
> =20
> *std::vector<bool>*
> The bits are unnamed.
> There are no bit operations.
> The programmer can only refer to a single bit at a time.
> There are no subset operations.
> =20
> *enums and enum classes*
> There are no bit operations.
> To use the enumeration as flags, values outside the list of tags are=20
> needed.
> There are no subset operations.
> =20
> *integer types*
> There is a lack of abstraction.
> The bits are unnamed.
> There are no subset operations.
> =20
> My proposal is for the introduction of a new type, the bit_enum (or maybe=
,=20
> enum_set?) that behaves like enums except for below:
> =20
> The first tag defaults to 1, not 0.
> =20
> Succeeding tags default to the next power of 2 greater than the preceding=
=20
> tag.
> =20
> Let T be the bit_enum type, UT be the underlying type and @ be any of &, =
|=20
> or ^.  Let the tag values be value[0], value[1], =E2=80=A6 value[n =E2=80=
=93 1], where n is=20
> the number of tags, and let *all* =3D value[0] | value[1] | =E2=80=A6 val=
ue[n =E2=80=93 1].
> =20
> The following functions should be defined:
> =20
>  constexpr inline T operator@(T <javascript:> a, T b) {                  =
=20
>                                 return static_cast<T>(static_cast<UT>(a) =
@=20
> static_cast<UT>(b));                                                    =
=20
>                                                                          =
  =20
>                                                                          =
  =20
>                   =20
> }
>
> =20
> =20
>  constexpr inline T operator@=3D(T <javascript:> &a, T b) {              =
  =20
>                                                                          =
  =20
>                                                                          =
  =20
>                                                      =20
>   return reinterpret_cast<T &>(reinterpret_cast<UT &>(a) @=3D static_cast=
<UT
> >(b));                                                                  =
=20
>                                                                          =
  =20
>                                                                          =
  =20
>    =20
> }
>
> =20
> =20
>  constexpr inline T operator~(T a) {
>   return static_cast<T>(static_cast<UT>(a) ^ static_cast<UT>(all));
> }
>
> =20
> Explicit static_casting to/from UT are allowed.
> =20
> =20
>  constexpr inline bool operator=3D=3D(T a, T b) {         =20
>   return static_cast<UT>(a) =3D=3D static_cast<UT>(b);         =20
> }
>
> =20
> =20
>  constexpr inline bool operator!=3D(T a, T b) {          =20
>   return !(a =3D=3D b);          =20
> }
>
> =20
> =20
>  constexpr inline bool operator<=3D(T a, T b) {           =20
>   return (a & ~b) =3D=3D static_cast<T>(0);           =20
> }
>
> =20
> =20
>  const inline bool operator<(T a, T b) {            =20
>   return a <=3D b && a !=3D b;            =20
> }
>
> =20
> =20
>  const inline bool operator>=3D(T a, T b) {             =20
>   return b <=3D a;             =20
> }
>
> =20
> =20
>  const inline bool operator>(T a, T b) {              =20
>   return b < a;              =20
> }
>
> =20
> =20
>  const inline operator bool(T a) {               =20
>   return static_cast<UT>(a);               =20
> }
>
> =20
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr">Hello<div><br></div><div>I agree with the problem list, bu=
t I think the solmution here is maybe more interesting for bit masks with t=
yped enums:</div><div><br></div><div>https://www.justsoftwaresolutions.co.u=
k/cplusplus/using-enum-classes-as-bitfields.html<br><br>which requires only=
 the include of a header in the enum class header and a definition for SFIN=
AE to specify if the overloads of bitwise operators should be implemented f=
or the type.<br><br>Also, I would say that when I use typed enum I often ne=
ed to declare C arrays, or std::arrays, and access those.</div><div>In whic=
h case maybe there could be a solution of the same kind.</div><div><br></di=
v><div>there is always the std::underlying_type&lt;&gt; anyway</div><div><b=
r></div><div>Best<br><br>Le mardi 10 juin 2014 12:43:36 UTC+2, Douglas Boff=
ey a =C3=A9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>Often, it seems, one needs a number of flags packed into a da=
ta type.&nbsp; An example is found in std::ios with eof_bit, fail_bit and b=
ad_bit.</div>
<div>&nbsp;</div>
<div>There are a number of existing solutions, each with their own shortcom=
ings:</div>
<div>&nbsp;</div>
<div><strong>bit fields</strong></div>
<div>The programmer can only refer to a single field at a time.&nbsp; Somet=
imes, a few bits may be related and a test needs to be made for any one of =
them.</div>
<div>There is no underlying type.</div>
<div>There are no bit operations.</div>
<div>There are no subset operations.</div>
<div>&nbsp;</div>
<div><strong>std::bitset</strong></div>
<div>The bits are unnamed.</div>
<div>The programmer can only refer to a single bit at a time.</div>
<div>The programmer is unable to control the underlying type.</div>
<div>There are no subset operations.</div>
<div>&nbsp;</div>
<div><strong>std::vector&lt;bool&gt;</strong></div>
<div>The bits are unnamed.</div>
<div>There are no bit operations.</div>
<div>The programmer can only refer to a single bit at a time.</div>
<div>There are no subset operations.</div>
<div>&nbsp;</div>
<div><strong>enums and enum classes</strong></div>
<div>There are no bit operations.</div>
<div>To use the enumeration as flags, values outside the list of tags are n=
eeded.</div>
<div>There are no subset operations.</div>
<div>&nbsp;</div>
<div><strong>integer types</strong></div>
<div>There is a lack of abstraction.</div>
<div>The bits are unnamed.</div>
<div>There are no subset operations.</div>
<div>&nbsp;</div>
<div>My proposal is for the introduction of a new type, the bit_enum (or ma=
ybe, enum_set?) that behaves like enums except for below:</div>
<div>&nbsp;</div>
<div>The first tag defaults to 1, not 0.</div>
<div>&nbsp;</div>
<div>Succeeding tags default to the next power of 2 greater than the preced=
ing tag.</div>
<div>&nbsp;</div>
<div>Let T be the bit_enum type, UT be the underlying type and&nbsp;@ be an=
y of &amp;, | or ^.&nbsp; Let the tag values be value[0], value[1], =E2=80=
=A6 value[n =E2=80=93 1], where n is the number of tags, and let <em>all</e=
m> =3D value[0] | value[1] | =E2=80=A6 value[n =E2=80=93 1].</div>
<div>&nbsp;</div>
<div>The following functions should be defined:</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 T </span><a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"LvpxkHv4Ld0J" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:'=
;return true;" onclick=3D"this.href=3D'javascript:';return true;"><span sty=
le=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">@(</span><span =
style=3D"COLOR:#000">T</span></a><span style=3D"COLOR:#000"> a</span><span =
style=3D"COLOR:#660">,</span><span style=3D"COLOR:#000"> T b</span><span st=
yle=3D"COLOR:#660">)</span><span style=3D"COLOR:#000"> </span><span style=
=3D"COLOR:#660">{</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; </span><span style=3D"COLOR:#008">return</span><span style=3D"COLOR:#000"=
> </span><span style=3D"COLOR:#008">static_cast</span><span style=3D"COLOR:=
#660">&lt;</span><span style=3D"COLOR:#000">T</span><span style=3D"COLOR:#6=
60">&gt;(</span><span style=3D"COLOR:#008">static_cast</span><span style=3D=
"COLOR:#660">&lt;</span><span style=3D"COLOR:#000">UT</span><span style=3D"=
COLOR:#660">&gt;<wbr>(</span><span style=3D"COLOR:#000">a</span><span style=
=3D"COLOR:#660">)</span><span style=3D"COLOR:#000"> </span><span style=3D"C=
OLOR:#660">@</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:=
#008">static_cast</span><span style=3D"COLOR:#660">&lt;</span><span style=
=3D"COLOR:#000">UT</span><span style=3D"COLOR:#660">&gt;(</span><span style=
=3D"COLOR:#000">b</span><span style=3D"COLOR:#660">));</span><span style=3D=
"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br></span><span style=3D"CO=
LOR:#660">}</span></div></code></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 T </span><a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"LvpxkHv4Ld0J" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:'=
;return true;" onclick=3D"this.href=3D'javascript:';return true;"><span sty=
le=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">@=3D(</span><sp=
an style=3D"COLOR:#000">T</span></a><span style=3D"COLOR:#000"> </span><spa=
n style=3D"COLOR:#660">&amp;</span><span style=3D"COLOR:#000">a</span><span=
 style=3D"COLOR:#660">,</span><span style=3D"COLOR:#000"> T b</span><span s=
tyle=3D"COLOR:#660">)</span><span style=3D"COLOR:#000"> </span><span style=
=3D"COLOR:#660">{</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp;&nbsp;<br>&nbsp; </span><span style=3D"COLOR:#008">return</span><span st=
yle=3D"COLOR:#000"> </span><span style=3D"COLOR:#008">reinterpret_cast</spa=
n><span style=3D"COLOR:#660">&lt;</span><span style=3D"COLOR:#000">T </span=
><span style=3D"COLOR:#660">&amp;&gt;(</span><span style=3D"COLOR:#008">rei=
nterpret_cast</span><span style=3D"COLOR:#660">&lt;</span><span style=3D"CO=
LOR:#000">UT </span><span style=3D"COLOR:#660">&amp;&gt;(</span><span style=
=3D"COLOR:#000">a</span><span style=3D"COLOR:#660">)</span><span style=3D"C=
OLOR:#000"> </span><span style=3D"COLOR:#660">@=3D</span><span style=3D"COL=
OR:#000"> </span><span style=3D"COLOR:#008">static_cast</span><span style=
=3D"COLOR:#660">&lt;</span><span style=3D"COLOR:#000">UT</span><span style=
=3D"COLOR:#660">&gt;(</span><span style=3D"COLOR:#000">b</span><span style=
=3D"COLOR:#660">));</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp;&nbsp;<br></span><span style=3D"COLOR:#660">}</span></div></code></div=
><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 T </span><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#6=
60">~(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660=
">)</span><span style=3D"COLOR:#000">&nbsp;{</span></div>
<div><span style=3D"COLOR:#000">&nbsp;&nbsp;</span><span style=3D"COLOR:#00=
8">return</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#00=
8">static_cast</span><span style=3D"COLOR:#660">&lt;</span><span style=3D"C=
OLOR:#000">T</span><span style=3D"COLOR:#660">&gt;(</span><span style=3D"CO=
LOR:#008">static_cast</span><span style=3D"COLOR:#660">&lt;</span><span sty=
le=3D"COLOR:#000">UT</span><span style=3D"COLOR:#660">&gt;<wbr>(</span><spa=
n style=3D"COLOR:#000">a</span><span style=3D"COLOR:#660">)</span><span sty=
le=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">^</span><span style=3D=
"COLOR:#000"> </span><span style=3D"COLOR:#008">static_cast</span><span sty=
le=3D"COLOR:#660">&lt;</span><span style=3D"COLOR:#000">UT</span><span styl=
e=3D"COLOR:#660">&gt;(</span><span style=3D"COLOR:#000">all</span><span sty=
le=3D"COLOR:#660">));<br></span><span style=3D"COLOR:#660">}</span></div></=
code></div><br>
<div>&nbsp;</div>
<div>Explicit static_casting to/from UT are allowed.</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> <=
/span><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">=
=3D=3D(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#66=
0">,</span><span style=3D"COLOR:#000"> T b</span><span style=3D"COLOR:#660"=
>)</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">{</s=
pan><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>&nbsp=
; </span><span style=3D"COLOR:#008">return</span><span style=3D"COLOR:#000"=
> </span><span style=3D"COLOR:#008">static_cast</span><span style=3D"COLOR:=
#660">&lt;</span><span style=3D"COLOR:#000">UT</span><span style=3D"COLOR:#=
660">&gt;(</span><span style=3D"COLOR:#000">a</span><span style=3D"COLOR:#6=
60">)</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">=
=3D=3D</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#008">=
static_cast</span><span style=3D"COLOR:#660">&lt;</span><span style=3D"COLO=
R:#000">UT</span><span style=3D"COLOR:#660">&gt;(</span><span style=3D"COLO=
R:#000">b</span><span style=3D"COLOR:#660">);</span><span style=3D"COLOR:#0=
00"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br></span><span style=3D"COLOR:#660=
">}</span></div></code></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> <=
/span><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">=
!=3D(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660"=
>,</span><span style=3D"COLOR:#000"> T b</span><span style=3D"COLOR:#660">)=
</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">{</spa=
n><span style=3D"COLOR:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=3D"COLOR:#008">return</sp=
an><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">!(</span><=
span style=3D"COLOR:#000">a </span><span style=3D"COLOR:#660">=3D=3D</span>=
<span style=3D"COLOR:#000"> b</span><span style=3D"COLOR:#660">);</span><sp=
an style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br></span=
><span style=3D"COLOR:#660">}</span></div></code></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">constexpr</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000">=
 </span><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> <=
/span><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">=
&lt;=3D(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#6=
60">,</span><span style=3D"COLOR:#000"> T b</span><span style=3D"COLOR:#660=
">)</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">{</=
span><span style=3D"COLOR:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=3D"COLOR:#008">r=
eturn</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">&amp;=
</span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">~</spa=
n><span style=3D"COLOR:#000">b</span><span style=3D"COLOR:#660">)</span><sp=
an style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">=3D=3D</span><sp=
an style=3D"COLOR:#000"> </span><span style=3D"COLOR:#008">static_cast</spa=
n><span style=3D"COLOR:#660">&lt;</span><span style=3D"COLOR:#000">T</span>=
<span style=3D"COLOR:#660">&gt;(</span><span style=3D"COLOR:#066">0</span><=
span style=3D"COLOR:#660">);</span><span style=3D"COLOR:#000"> &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp;<br></span><span style=3D"COLOR:#660">}</span>=
</div></code></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">const</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> </spa=
n><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">&lt;=
(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660">,</=
span><span style=3D"COLOR:#000"> T b</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=3D"COLOR:#008">re=
turn</span><span style=3D"COLOR:#000"> a </span><span style=3D"COLOR:#660">=
&lt;=3D</span><span style=3D"COLOR:#000"> b </span><span style=3D"COLOR:#66=
0">&amp;&amp;</span><span style=3D"COLOR:#000"> a </span><span style=3D"COL=
OR:#660">!=3D</span><span style=3D"COLOR:#000"> b</span><span style=3D"COLO=
R:#660">;</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp;&nbsp;<br></span><span style=3D"COLOR:#660">}</span></div></code>=
</div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">const</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> </spa=
n><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">&gt;=
=3D(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660">=
,</span><span style=3D"COLOR:#000"> T b</span><span style=3D"COLOR:#660">)<=
/span><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">{</span=
><span style=3D"COLOR:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=3D"COLOR=
:#008">return</span><span style=3D"COLOR:#000"> b </span><span style=3D"COL=
OR:#660">&lt;=3D</span><span style=3D"COLOR:#000"> a</span><span style=3D"C=
OLOR:#660">;</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp;<br></span><span style=3D"COLOR:#660">}</span></div></c=
ode></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">const</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#000"> </spa=
n><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#660">&gt;=
(</span><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660">,</=
span><span style=3D"COLOR:#000"> T b</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=3D"CO=
LOR:#008">return</span><span style=3D"COLOR:#000"> b </span><span style=3D"=
COLOR:#660">&lt;</span><span style=3D"COLOR:#000"> a</span><span style=3D"C=
OLOR:#660">;</span><span style=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp;&nbsp;<br></span><span style=3D"COLOR:#660">}</span></d=
iv></code></div><br>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style=3D"BORDER-BOTTOM:#bbb 1px solid;BORDER-LEFT:#bbb 1px solid;BACKG=
ROUND-COLOR:#fafafa;WORD-WRAP:break-word;BORDER-TOP:#bbb 1px solid;BORDER-R=
IGHT:#bbb 1px solid"><code>
<div><span style=3D"COLOR:#008">const</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">inline</span><span style=3D"COLOR:#000"> </s=
pan><span style=3D"COLOR:#008">operator</span><span style=3D"COLOR:#000"> <=
/span><span style=3D"COLOR:#008">bool</span><span style=3D"COLOR:#660">(</s=
pan><span style=3D"COLOR:#000">T a</span><span style=3D"COLOR:#660">)</span=
><span style=3D"COLOR:#000"> </span><span style=3D"COLOR:#660">{</span><spa=
n style=3D"COLOR:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp; </span><span style=
=3D"COLOR:#008">return</span><span style=3D"COLOR:#000"> </span><span style=
=3D"COLOR:#008">static_cast</span><span style=3D"COLOR:#660">&lt;</span><sp=
an style=3D"COLOR:#000">UT</span><span style=3D"COLOR:#660">&gt;(</span><sp=
an style=3D"COLOR:#000">a</span><span style=3D"COLOR:#660">);</span><span s=
tyle=3D"COLOR:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
;<br></span><span style=3D"COLOR:#660">}</span></div></code></div><br>
<div>&nbsp;</div></div></blockquote></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_247_699058019.1422874543392--
------=_Part_246_1668759177.1422874543392--

.


Author: David Krauss <potswa@gmail.com>
Date: Tue, 3 Feb 2015 16:31:12 +0800
Raw View
--Apple-Mail=_0B2A1355-BDA9-4656-9FC3-14AB5E20B399
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9302, at 6:55 PM, adrien courdavault <adrien59ca=
dri@gmail.com> wrote:
>=20
> Hello
>=20
> I agree with the problem list, but I think the solmution here is maybe mo=
re interesting for bit masks with typed enums:
>=20
> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-b=
itfields.html

You can take it a =E2=80=9Cbit=E2=80=9D further and use std::bitset as the =
flag type: http://stackoverflow.com/a/18554839/153285 .

This saves the trouble of manually entering the powers of two, and allows m=
ore than 64 bits. (However, implementations seldom provide efficient small-=
bitset specializations.)

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_0B2A1355-BDA9-4656-9FC3-14AB5E20B399
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9302, at 6:55 PM, adrien courdavault &lt;<a href=3D"mailto:adrien59c=
adri@gmail.com" class=3D"">adrien59cadri@gmail.com</a>&gt; wrote:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=
=3D"">Hello<div class=3D""><br class=3D""></div><div class=3D"">I agree wit=
h the problem list, but I think the solmution here is maybe more interestin=
g for bit masks with typed enums:</div><div class=3D""><br class=3D""></div=
><div class=3D""><a href=3D"https://www.justsoftwaresolutions.co.uk/cpluspl=
us/using-enum-classes-as-bitfields.html" class=3D"">https://www.justsoftwar=
esolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html</a><br clas=
s=3D""></div></div></div></blockquote><div><br class=3D""></div><div>You ca=
n take it a =E2=80=9Cbit=E2=80=9D further and use <font face=3D"Courier" cl=
ass=3D"">std::bitset</font> as the flag type:&nbsp;<a href=3D"http://stacko=
verflow.com/a/18554839/153285" class=3D"">http://stackoverflow.com/a/185548=
39/153285</a> .</div><div><br class=3D""></div><div>This saves the trouble =
of manually entering the powers of two, and allows more than 64 bits. (Howe=
ver, implementations seldom provide efficient small-bitset specializations.=
)</div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_0B2A1355-BDA9-4656-9FC3-14AB5E20B399--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 3 Feb 2015 15:00:25 -0500
Raw View
--001a11c32cf48dc6c7050e348567
Content-Type: text/plain; charset=UTF-8

On Mon, Feb 2, 2015 at 5:55 AM, adrien courdavault <adrien59cadri@gmail.com>
wrote:

> Hello
>
> I agree with the problem list, but I think the solmution here is maybe
> more interesting for bit masks with typed enums:
>
>
> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
>
> which requires only the include of a header in the enum class header and a
> definition for SFINAE to specify if the overloads of bitwise operators
> should be implemented for the type.
>
>
It is unfortunate that the opt-in flag can't just be part of the enum:

#include <type_traits>

enum class Breakfast {
    enable_bitwise_ops = 1,  // give me the ops!
    GreenEggs = 0x1,
    Ham = 0x2
};

template<typename E>
typename std::enable_if<E::enable_bitwise_ops,E>::type
operator|(E lhs,E rhs){
    typedef typename std::underlying_type<E>::type underlying;
    return static_cast<E>(
        static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
}


int main() {
    // your code goes here
    Breakfast b = Breakfast::GreenEggs | Breakfast::Ham;
    return 0;
}

Unfortunately doesn't work. :-(
Or maybe I didn't try hard enough?  Is there something I can put in the
enable-if to detect that enable_bitwise_ops is part of the enum?
(Of course, you could also argue that it isn't the best solution - since it
makes 'enable_bitwise_ops' a Breakfast value.  But it is slightly nicer (to
declare) than specializing a template.)

Tony

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Feb 2, 2015 at 5:55 AM, adrien courdavault <span dir=3D"ltr">&l=
t;<a href=3D"mailto:adrien59cadri@gmail.com" target=3D"_blank">adrien59cadr=
i@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-left:1ex"><div dir=3D"ltr">Hello<div><br></div><div>I agree with the prob=
lem list, but I think the solmution here is maybe more interesting for bit =
masks with typed enums:</div><div><br></div><div><a href=3D"https://www.jus=
tsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html" ta=
rget=3D"_blank">https://www.justsoftwaresolutions.co.uk/cplusplus/using-enu=
m-classes-as-bitfields.html</a><br><br>which requires only the include of a=
 header in the enum class header and a definition for SFINAE to specify if =
the overloads of bitwise operators should be implemented for the type.<br><=
br></div></div></blockquote><div><br></div></div>It is unfortunate that the=
 opt-in flag can&#39;t just be part of the enum:<br><br>#include &lt;type_t=
raits&gt;<br><br>enum class Breakfast {<br>=C2=A0=C2=A0=C2=A0 enable_bitwis=
e_ops =3D 1,=C2=A0 // give me the ops!<br>=C2=A0=C2=A0=C2=A0 GreenEggs =3D =
0x1,<br>=C2=A0=C2=A0=C2=A0 Ham =3D 0x2<br>};<br><br>template&lt;typename E&=
gt;<br>typename std::enable_if&lt;E::enable_bitwise_ops,E&gt;::type<br>oper=
ator|(E lhs,E rhs){<br>=C2=A0=C2=A0=C2=A0 typedef typename std::underlying_=
type&lt;E&gt;::type underlying;<br>=C2=A0=C2=A0=C2=A0 return static_cast&lt=
;E&gt;(<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast&lt;underl=
ying&gt;(lhs) | static_cast&lt;underlying&gt;(rhs));<br>}<br><br><br>int ma=
in() {<br>=C2=A0=C2=A0=C2=A0 // your code goes here<br>=C2=A0=C2=A0=C2=A0 B=
reakfast b =3D Breakfast::GreenEggs | Breakfast::Ham;<br>=C2=A0=C2=A0=C2=A0=
 return 0;<br>}<br><br></div><div class=3D"gmail_extra">Unfortunately doesn=
&#39;t work. :-(<br></div><div class=3D"gmail_extra">Or maybe I didn&#39;t =
try hard enough?=C2=A0 Is there something I can put in the enable-if to det=
ect that enable_bitwise_ops is part of the enum?<br></div><div class=3D"gma=
il_extra">(Of course, you could also argue that it isn&#39;t the best solut=
ion - since it makes &#39;enable_bitwise_ops&#39; a Breakfast value.=C2=A0 =
But it is slightly nicer (to declare) than specializing a template.)<br><br=
></div><div class=3D"gmail_extra">Tony<br><br></div><div class=3D"gmail_ext=
ra"><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c32cf48dc6c7050e348567--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 3 Feb 2015 15:03:48 -0500
Raw View
--001a1135e57ea4586e050e349168
Content-Type: text/plain; charset=UTF-8

On Tue, Feb 3, 2015 at 3:00 PM, Tony V E <tvaneerd@gmail.com> wrote:

>
>
> On Mon, Feb 2, 2015 at 5:55 AM, adrien courdavault <
> adrien59cadri@gmail.com> wrote:
>
>> Hello
>>
>> I agree with the problem list, but I think the solmution here is maybe
>> more interesting for bit masks with typed enums:
>>
>>
>> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
>>
>> which requires only the include of a header in the enum class header and
>> a definition for SFINAE to specify if the overloads of bitwise operators
>> should be implemented for the type.
>>
>>
> It is unfortunate that the opt-in flag can't just be part of the enum:
>
> #include <type_traits>
>
> enum class Breakfast {
>     enable_bitwise_ops = 1,  // give me the ops!
>     GreenEggs = 0x1,
>     Ham = 0x2
> };
>
>
Needed a bool conversion here:


> template<typename E>
> typename std::enable_if<E::enable_bitwise_ops,E>::type
>

typename std::enable_if<bool(E::enable_bitwise_ops),E>::type


> operator|(E lhs,E rhs){
>     typedef typename std::underlying_type<E>::type underlying;
>     return static_cast<E>(
>         static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
> }
>
>
> int main() {
>     // your code goes here
>     Breakfast b = Breakfast::GreenEggs | Breakfast::Ham;
>     return 0;
> }
>
> Unfortunately doesn't work. :-(
> Or maybe I didn't try hard enough?  Is there something I can put in the
> enable-if to detect that enable_bitwise_ops is part of the enum?
> (Of course, you could also argue that it isn't the best solution - since
> it makes 'enable_bitwise_ops' a Breakfast value.  But it is slightly nicer
> (to declare) than specializing a template.)
>
>
Works now. Still questionable.



> Tony
>
>
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Tue, Feb 3, 2015 at 3:00 PM, Tony V E <span dir=3D"ltr">&lt;<a href=
=3D"mailto:tvaneerd@gmail.com" target=3D"_blank">tvaneerd@gmail.com</a>&gt;=
</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div =
class=3D"gmail_extra"><span class=3D""><br><div class=3D"gmail_quote">On Mo=
n, Feb 2, 2015 at 5:55 AM, adrien courdavault <span dir=3D"ltr">&lt;<a href=
=3D"mailto:adrien59cadri@gmail.com" target=3D"_blank">adrien59cadri@gmail.c=
om</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x"><div dir=3D"ltr">Hello<div><br></div><div>I agree with the problem list,=
 but I think the solmution here is maybe more interesting for bit masks wit=
h typed enums:</div><div><br></div><div><a href=3D"https://www.justsoftware=
solutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html" target=3D"_=
blank">https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes=
-as-bitfields.html</a><br><br>which requires only the include of a header i=
n the enum class header and a definition for SFINAE to specify if the overl=
oads of bitwise operators should be implemented for the type.<br><br></div>=
</div></blockquote><div><br></div></div></span>It is unfortunate that the o=
pt-in flag can&#39;t just be part of the enum:<br><br>#include &lt;type_tra=
its&gt;<br><br>enum class Breakfast {<br>=C2=A0=C2=A0=C2=A0 enable_bitwise_=
ops =3D 1,=C2=A0 // give me the ops!<br>=C2=A0=C2=A0=C2=A0 GreenEggs =3D 0x=
1,<br>=C2=A0=C2=A0=C2=A0 Ham =3D 0x2<br>};<br><br></div></div></blockquote>=
<div><br></div><div>Needed a bool conversion here:<br>=C2=A0<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra">templ=
ate&lt;typename E&gt;<br>typename std::enable_if&lt;E::enable_bitwise_ops,E=
&gt;::type<br></div></div></blockquote><div><br></div><div>typename std::en=
able_if&lt;bool(E::enable_bitwise_ops),E&gt;::type<br>=C2=A0<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra">opera=
tor|(E lhs,E rhs){<br>=C2=A0=C2=A0=C2=A0 typedef typename std::underlying_t=
ype&lt;E&gt;::type underlying;<br>=C2=A0=C2=A0=C2=A0 return static_cast&lt;=
E&gt;(<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast&lt;underly=
ing&gt;(lhs) | static_cast&lt;underlying&gt;(rhs));<br>}<br><br><br>int mai=
n() {<br>=C2=A0=C2=A0=C2=A0 // your code goes here<br>=C2=A0=C2=A0=C2=A0 Br=
eakfast b =3D Breakfast::GreenEggs | Breakfast::Ham;<br>=C2=A0=C2=A0=C2=A0 =
return 0;<br>}<br><br></div><div class=3D"gmail_extra">Unfortunately doesn&=
#39;t work. :-(<br></div><div class=3D"gmail_extra">Or maybe I didn&#39;t t=
ry hard enough?=C2=A0 Is there something I can put in the enable-if to dete=
ct that enable_bitwise_ops is part of the enum?<br></div><div class=3D"gmai=
l_extra">(Of course, you could also argue that it isn&#39;t the best soluti=
on - since it makes &#39;enable_bitwise_ops&#39; a Breakfast value.=C2=A0 B=
ut it is slightly nicer (to declare) than specializing a template.)<span cl=
ass=3D"HOEnZb"><font color=3D"#888888"><br><br></font></span></div></div></=
blockquote><div><br>Works now. Still questionable.<br><br>=C2=A0<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><=
span class=3D"HOEnZb"><font color=3D"#888888"></font></span></div><span cla=
ss=3D"HOEnZb"><font color=3D"#888888"><div class=3D"gmail_extra">Tony<br><b=
r></div><div class=3D"gmail_extra"><br></div></font></span></div>
</blockquote></div><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1135e57ea4586e050e349168--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 4 Feb 2015 08:58:50 +0800
Raw View
--Apple-Mail=_74135899-424F-42E8-9A05-DD6C7C7B25EE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9304, at 4:03 AM, Tony V E <tvaneerd@gmail.com> =
wrote:
>=20
> Works now. Still questionable.

If you don=E2=80=99t like explicit/foreign template specialization, ADL is =
another way to implement type-trait lookup.

(This still won=E2=80=99t find the operator functions by ADL unless they=E2=
=80=99re in the same namespace as the enumeration. The traits lookup is ass=
ociated by ADL, though.)

namespace utility {
template< typename >
struct tag {};
}

namespace mystuff {
enum class Breakfast {
    GreenEggs =3D 0x1,
    Ham =3D 0x2
};

constexpr bool has_bitwise_ops( utility::tag< Breakfast > )
    { return true; }
}

namespace bitenum {
constexpr bool has_bitwise_ops( ... ) { return false; }

template< typename E >
std::enable_if_t< has_bitwise_ops( utility::tag< E >{} ),
E > operator | ( E lhs, E rhs ) {
   ...

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_74135899-424F-42E8-9A05-DD6C7C7B25EE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9304, at 4:03 AM, Tony V E &lt;<a href=3D"mailto:tvaneerd@gmail.com"=
 class=3D"">tvaneerd@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-inter=
change-newline"><div class=3D""><span style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant: normal; font-weight: normal;=
 letter-spacing: normal; line-height: normal; orphans: auto; text-align: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; displa=
y: inline !important;" class=3D"">Works now. Still questionable.</span></di=
v></blockquote></div><br class=3D""><div class=3D"">If you don=E2=80=99t li=
ke explicit/foreign template specialization, ADL is another way to implemen=
t type-trait lookup.</div><div class=3D""><br class=3D""></div><div class=
=3D"">(This still won=E2=80=99t find the operator functions by ADL unless t=
hey=E2=80=99re in the same namespace as the enumeration. The traits lookup =
is associated by ADL, though.)</div><div class=3D""><br class=3D""></div><d=
iv class=3D""><font face=3D"Courier" class=3D"">namespace utility {</font><=
/div><div class=3D""><font face=3D"Courier" class=3D"">template&lt; typenam=
e &gt;</font></div><div class=3D""><font face=3D"Courier" class=3D"">struct=
 tag {};</font></div><div class=3D""><font face=3D"Courier" class=3D"">}</f=
ont></div><div class=3D""><font face=3D"Courier" class=3D""><br class=3D"">=
</font></div><div class=3D""><font face=3D"Courier" class=3D"">namespace my=
stuff {</font></div><div class=3D""><font face=3D"Courier" class=3D"">enum =
class Breakfast {<br class=3D"">&nbsp; &nbsp; GreenEggs =3D 0x1,<br class=
=3D"">&nbsp;&nbsp;&nbsp; Ham =3D 0x2<br class=3D"">};</font></div><div clas=
s=3D""><font face=3D"Courier" class=3D""><br class=3D""></font></div><div c=
lass=3D""><font face=3D"Courier" class=3D"">constexpr bool has_bitwise_ops(=
 utility::tag&lt; Breakfast &gt; )</font></div><div class=3D""><font face=
=3D"Courier" class=3D"">&nbsp; &nbsp; { return true; }</font></div><div cla=
ss=3D""><font face=3D"Courier" class=3D"">}</font></div><div class=3D""><fo=
nt face=3D"Courier" class=3D""><br class=3D""></font></div><div class=3D"">=
<font face=3D"Courier" class=3D"">namespace bitenum {</font></div><div clas=
s=3D""><font face=3D"Courier" class=3D"">constexpr bool has_bitwise_ops( ..=
.. ) { return false; }</font></div><div class=3D""><font face=3D"Courier" cl=
ass=3D""><br class=3D""></font></div><div class=3D""><font face=3D"Courier"=
 class=3D"">template&lt; typename E &gt;</font></div><div class=3D""><font =
face=3D"Courier" class=3D"">std::enable_if_t&lt; has_bitwise_ops( utility::=
tag&lt; E &gt;{} ),</font></div><div class=3D""><font face=3D"Courier" clas=
s=3D"">E &gt; operator | ( E lhs, E rhs ) {</font></div><div class=3D""><fo=
nt face=3D"Courier" class=3D"">&nbsp; &nbsp;...</font></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_74135899-424F-42E8-9A05-DD6C7C7B25EE--

.


Author: Myriachan <myriachan@gmail.com>
Date: Tue, 3 Feb 2015 17:21:39 -0800 (PST)
Raw View
------=_Part_209_1110119365.1423012899445
Content-Type: multipart/alternative;
 boundary="----=_Part_210_438242419.1423012899446"

------=_Part_210_438242419.1423012899446
Content-Type: text/plain; charset=UTF-8

On Tuesday, February 3, 2015 at 4:58:59 PM UTC-8, David Krauss wrote:
>
> namespace mystuff {
> enum class Breakfast {
>     GreenEggs = 0x1,
>     Ham = 0x2
> };
>
>
It's a horrible hack, but it's actually possible with macros to automate
the process of determining the next flag in bitfield enums.

#include <cstdio>
#include <cstdint>

#define FLAG_CONCAT2(x, y) x ## y
#define FLAG_CONCAT(x, y) FLAG_CONCAT2(x, y)
#define FLAG(name) \
    FLAG_CONCAT(DUMMY_FLAG_, __LINE__), \
    name = static_cast<decltype(FLAG_CONCAT(DUMMY_FLAG_, __LINE__))>( \
        FLAG_CONCAT(DUMMY_FLAG_, __LINE__) ? \
        ((FLAG_CONCAT(DUMMY_FLAG_, __LINE__) - 1) << 1) : 1)

enum class Meow : std::uint8_t
{
    FLAG(Test0),
    FLAG(Test1),
    FLAG(Test2),
    FLAG(Test3),
    FLAG(Test4),
    FLAG(Test5),
    FLAG(Test6),
    FLAG(Test7),
};

int main()
{
    std::printf("%d %d %d %d %d %d %d %d\n",
        static_cast<int>(Meow::Test0), static_cast<int>(Meow::Test1),
        static_cast<int>(Meow::Test2), static_cast<int>(Meow::Test3),
        static_cast<int>(Meow::Test4), static_cast<int>(Meow::Test5),
        static_cast<int>(Meow::Test6), static_cast<int>(Meow::Test7));
    return 0;
}


C:\Projects\temp\tests>enumflags
1 2 4 8 16 32 64 128

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr">On Tuesday, February 3, 2015 at 4:58:59 PM UTC-8, David Kr=
auss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-=
wrap:break-word"><font face=3D"Courier">namespace mystuff {</font><div><fon=
t face=3D"Courier">enum class Breakfast {<br>&nbsp; &nbsp; GreenEggs =3D 0x=
1,<br>&nbsp;&nbsp;&nbsp; Ham =3D 0x2<br>};</font></div><br></div></blockquo=
te><div><br>It's a horrible hack, but it's actually possible with macros to=
 automate the process of determining the next flag in bitfield enums.<br><b=
r><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&lt;cstdio&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">&lt;cstdint&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">#define</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> FLAG_CONCAT2</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">x</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> y</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> x </span><span style=3D"color: #800;" class=3D"styled-by-prettify">## y=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> FLAG_CONCAT</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">x</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> y</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> FLAG_CONCAT2</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">#define</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> FLAG</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">name</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; &nbsp; FLAG_CONCAT</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">DUMMY_FLAG_</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> __LI=
NE__</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; name </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">FLAG_CONCAT</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">DUMMY_FLAG_</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> __LINE__</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">))&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">\</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nb=
sp; &nbsp; &nbsp; FLAG_CONCAT</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">DUMMY_FLAG_</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> __LINE__</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">?</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">\</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">((</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">FLAG_CONCAT</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">DUMMY_FLAG_</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> __LINE__</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">-</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Meow</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">uint8_t<br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; FLAG</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Test0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; FLAG</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Test1</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>&nbsp; &nbsp; FLAG</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Test2</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">),</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>&nbsp; &nbsp; FLAG</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Test3</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>&nbsp; &nbsp; FLAG</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Test4</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">),</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; &nbsp; FLAG</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">Test5</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; &nbsp; FLAG</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Test6=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; =
FLAG</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Test7</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">p=
rintf</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">"%d %d %d %d %=
d %d %d %d\n"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">static_cast</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&lt;int&gt;</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Meow</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Test0=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">static_cast</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">Test1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Test2</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">stati=
c_cast</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;=
int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Meow</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Test3</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">static_cast</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Meow</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Test4</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">static_cast</span><span style=3D"color: #080;" class=3D"st=
yled-by-prettify">&lt;int&gt;</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Meow</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Test=
5</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;=
 &nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">static_cast</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&lt;int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Me=
ow</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Test6</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Test7</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">=
0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br=
><br><span style=3D"font-family: courier new,monospace;">C:\Projects\temp\t=
ests&gt;enumflags<br>1 2 4 8 16 32 64 128</span><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_210_438242419.1423012899446--
------=_Part_209_1110119365.1423012899445--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 4 Feb 2015 09:26:56 +0800
Raw View
--Apple-Mail=_A815F526-6E43-4C46-B325-E5A40BEE42AA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9304, at 9:21 AM, Myriachan <myriachan@gmail.com=
> wrote:
>=20
> It's a horrible hack, but it's actually possible with macros to automate =
the process of determining the next flag in bitfield enums.

That=E2=80=99s not the problem at hand. We=E2=80=99re talking about generic=
 operator functions.

I did link earlier to a power-of-two avoidance trick, which involves implic=
it conversion from a bit-index enumeration to a bitset class. Such a conver=
sion can be built into generic operators.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_A815F526-6E43-4C46-B325-E5A40BEE42AA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9304, at 9:21 AM, Myriachan &lt;<a href=3D"mailto:myriachan@gmail.co=
m" class=3D"">myriachan@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-in=
terchange-newline"><div class=3D""><span style=3D"font-family: Helvetica; f=
ont-size: 12px; font-style: normal; font-variant: normal; font-weight: norm=
al; letter-spacing: normal; line-height: normal; orphans: auto; text-align:=
 start; text-indent: 0px; text-transform: none; white-space: normal; widows=
: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; dis=
play: inline !important;" class=3D"">It's a horrible hack, but it's actuall=
y possible with macros to automate the process of determining the next flag=
 in bitfield enums.</span><br style=3D"font-family: Helvetica; font-size: 1=
2px; font-style: normal; font-variant: normal; font-weight: normal; letter-=
spacing: normal; line-height: normal; orphans: auto; text-align: start; tex=
t-indent: 0px; text-transform: none; white-space: normal; widows: auto; wor=
d-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""></div></blockqu=
ote></div><br class=3D""><div class=3D"">That=E2=80=99s not the problem at =
hand. We=E2=80=99re talking about generic operator functions.</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">I did link earlier to a power-=
of-two avoidance trick, which involves implicit conversion from a bit-index=
 enumeration to a bitset class. Such a conversion can be built into generic=
 operators.</div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_A815F526-6E43-4C46-B325-E5A40BEE42AA--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Fri, 06 Feb 2015 18:41:40 -0800
Raw View
Tony V E <tvaneerd@gmail.com> writes:

[...]

| template<typename E>
| typename std::enable_if<E::enable_bitwise_ops,E>::type
                          ^^^^^^^^^^^^^^^^^^^^^

Just allow it to be well-behaved enums.

| operator|(E lhs,E rhs){
| =C2=A0=C2=A0=C2=A0 typedef typename std::underlying_type<E>::type underly=
ing;
| =C2=A0=C2=A0=C2=A0 return static_cast<E>(
| =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static_cast<underlying>(lhs) |=
 static_cast<underlying>(rhs));
| }

Interestingly, I have been using this technique in production for
at least half a decade now.  Coupled with this is my general technique of
introducing new, distinction, efficient integer types that enjoye the
same builtin efficiency as existing integer types.  E.g.

     enum class byte : uint8_t { };

I call this sort of scoped enums (that introduce no new enumerators)
"integer classes".  They work very well.  See my recent message to the
EWG reflector and ideas about to simplify construction.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 7 Feb 2015 12:32:50 +0800
Raw View
> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis <gdr@axiomat=
ics.org> wrote:
>=20
> Just allow it to be well-behaved enums.

In a better world, compilers would understand such definitions.

>     enum class byte : uint8_t { };
>=20
> I call this sort of scoped enums (that introduce no new enumerators)
> "integer classes".  They work very well. =20

What do you think of the strong typedefs proposal? Might there be motivatio=
n for its implementation?

> See my recent message to the
> EWG reflector and ideas about to simplify construction.

Perhaps the readers of this public list would appreciate the opportunity to=
 do so, but that list is limited-access.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sat, 7 Feb 2015 00:42:29 -0500
Raw View
--001a11c27f2abc3bf2050e790052
Content-Type: text/plain; charset=UTF-8

On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <gdr@axiomatics.org> wrote:

> Tony V E <tvaneerd@gmail.com> writes:
>
> [...]
>
> | template<typename E>
> | typename std::enable_if<E::enable_bitwise_ops,E>::type
>                           ^^^^^^^^^^^^^^^^^^^^^
>
> Just allow it to be well-behaved enums.
>

I really don't understand what you mean (your terseness often baffles me).
Would you replace it with is_enum<E> or ...?

Tony

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <span dir=3D"ltr">&lt;=
<a href=3D"mailto:gdr@axiomatics.org" target=3D"_blank">gdr@axiomatics.org<=
/a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Tony V E &lt;<a hre=
f=3D"mailto:tvaneerd@gmail.com">tvaneerd@gmail.com</a>&gt; writes:<br>
<br>
[...]<br>
<span class=3D""><br>
| template&lt;typename E&gt;<br>
| typename std::enable_if&lt;E::enable_bitwise_ops,E&gt;::type<br>
</span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 ^^^^^^^^^^^^^^^^^^^^^<br>
<br>
Just allow it to be well-behaved enums.<br></blockquote><div><br></div><div=
>I really don&#39;t understand what you mean (your terseness often baffles =
me).=C2=A0 Would you replace it with is_enum&lt;E&gt; or ...?<br><br></div>=
<div>Tony<br></div></div></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c27f2abc3bf2050e790052--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 09 Feb 2015 12:06:15 -0500
Raw View
On 2015-02-06 23:32, David Krauss wrote:
>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
>>     enum class byte : uint8_t { };
>>
>> I call this sort of scoped enums (that introduce no new enumerators)
>> "integer classes".  They work very well. =20
>=20
> What do you think of the strong typedefs proposal? Might there be motivat=
ion for its implementation?

Getting a bit off-topic, but... I'd like to see strong typedefs. I've
rolled my own in at least one application.

My use case is I have a mesh class with various methods that operate on
various indexed items of the mesh, e.g. vertices, edges and faces. I use
strongly-typed integer classes to differentiate between each type of
index in order to reduce the risk of accidentally conflating them. (It
also allows overloading methods based on the index type, although this
is dubious API and I don't think I'm using it much if at all.)

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Mon, 09 Feb 2015 17:22:35 +0000
Raw View
On 09/02/15 17:06, Matthew Woehlke wrote:
> On 2015-02-06 23:32, David Krauss wrote:
>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
>>>     enum class byte : uint8_t { };
>>>
>>> I call this sort of scoped enums (that introduce no new enumerators)
>>> "integer classes".  They work very well. =20
>>
>> What do you think of the strong typedefs proposal? Might there be motiva=
tion for its implementation?
>=20
> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
> rolled my own in at least one application.

I've rolled my own too in the past. In C++11, I wonder whether we need a
special syntax.

Inherited constructors essentially give us strong typedefs for class
types, and scoped enums do that for integral types.

Do we need strong typedefs for anything else?

Anthony
--=20
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++11 thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 09 Feb 2015 13:49:54 -0500
Raw View
On 2015-02-09 12:22, Anthony Williams wrote:
> On 09/02/15 17:06, Matthew Woehlke wrote:
>> On 2015-02-06 23:32, David Krauss wrote:
>>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
>>>>     enum class byte : uint8_t { };
>>>>
>>>> I call this sort of scoped enums (that introduce no new enumerators)
>>>> "integer classes".  They work very well. =20
>>>
>>> What do you think of the strong typedefs proposal? Might there be motiv=
ation for its implementation?
>>
>> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
>> rolled my own in at least one application.
>=20
> I've rolled my own too in the past. In C++11, I wonder whether we need a
> special syntax.
>=20
> Inherited constructors essentially give us strong typedefs for class
> types, and scoped enums do that for integral types.

Er... how? (Not the classes, the integers...)

If I do this:

  enum class Foo : int {};

I can't seem to do anything useful with this. For example, I can't
brace-initialize it, assign it, pass an integer to a function taking a
Foo in any obvious manner, add to it, etc. I can do all of these with my
class. In particular, I would expect a proper strong typedef to
implement all of the usual integer operations (+,-,*,/,%,++,+=3D,etc.) for
a strongly typed integer.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Mon, 9 Feb 2015 19:29:52 +0000
Raw View
--089e01493f7e5e1dc2050eaccbb1
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 9 Feb 2015 18:50, "Matthew Woehlke" <mw_triad@users.sourceforge.net>
wrote:
>
> On 2015-02-09 12:22, Anthony Williams wrote:
> > On 09/02/15 17:06, Matthew Woehlke wrote:
> >> On 2015-02-06 23:32, David Krauss wrote:
> >>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
> >>>>     enum class byte : uint8_t { };
> >>>>
> >>>> I call this sort of scoped enums (that introduce no new enumerators)
> >>>> "integer classes".  They work very well.
> >>>
> >>> What do you think of the strong typedefs proposal? Might there be
motivation for its implementation?
> >>
> >> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
> >> rolled my own in at least one application.
> >
> > I've rolled my own too in the past. In C++11, I wonder whether we need =
a
> > special syntax.
> >
> > Inherited constructors essentially give us strong typedefs for class
> > types, and scoped enums do that for integral types.
>
> Er... how? (Not the classes, the integers...)
>
> If I do this:
>
>   enum class Foo : int {};
>
> I can't seem to do anything useful with this. For example, I can't
> brace-initialize it, assign it, pass an integer to a function taking a
> Foo in any obvious manner, add to it, etc. I can do all of these with my
> class. In particular, I would expect a proper strong typedef to
> implement all of the usual integer operations (+,-,*,/,%,++,+=3D,etc.) fo=
r
> a strongly typed integer.
>

You can add the operators as has been discussed for the bitmask operators.

Implicit conversions seem wrong for a strong typedef, IMHO. The lack of
such is the chief benefit over a normal typedef.

Initialisation might be an issue, but you could easily do a cast or write a
factory function.

Anthony

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<p dir=3D"ltr"><br>
On 9 Feb 2015 18:50, &quot;Matthew Woehlke&quot; &lt;<a href=3D"mailto:mw_t=
riad@users.sourceforge.net">mw_triad@users.sourceforge.net</a>&gt; wrote:<b=
r>
&gt;<br>
&gt; On 2015-02-09 12:22, Anthony Williams wrote:<br>
&gt; &gt; On 09/02/15 17:06, Matthew Woehlke wrote:<br>
&gt; &gt;&gt; On 2015-02-06 23:32, David Krauss wrote:<br>
&gt; &gt;&gt;&gt;&gt; On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel D=
os Reis wrote:<br>
&gt; &gt;&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0enum class byte : uint8_t { };<br>
&gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;&gt; I call this sort of scoped enums (that introduce no n=
ew enumerators)<br>
&gt; &gt;&gt;&gt;&gt; &quot;integer classes&quot;.=C2=A0 They work very wel=
l.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; What do you think of the strong typedefs proposal? Might =
there be motivation for its implementation?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Getting a bit off-topic, but... I&#39;d like to see strong ty=
pedefs. I&#39;ve<br>
&gt; &gt;&gt; rolled my own in at least one application.<br>
&gt; &gt;<br>
&gt; &gt; I&#39;ve rolled my own too in the past. In C++11, I wonder whethe=
r we need a<br>
&gt; &gt; special syntax.<br>
&gt; &gt;<br>
&gt; &gt; Inherited constructors essentially give us strong typedefs for cl=
ass<br>
&gt; &gt; types, and scoped enums do that for integral types.<br>
&gt;<br>
&gt; Er... how? (Not the classes, the integers...)<br>
&gt;<br>
&gt; If I do this:<br>
&gt;<br>
&gt; =C2=A0 enum class Foo : int {};<br>
&gt;<br>
&gt; I can&#39;t seem to do anything useful with this. For example, I can&#=
39;t<br>
&gt; brace-initialize it, assign it, pass an integer to a function taking a=
<br>
&gt; Foo in any obvious manner, add to it, etc. I can do all of these with =
my<br>
&gt; class. In particular, I would expect a proper strong typedef to<br>
&gt; implement all of the usual integer operations (+,-,*,/,%,++,+=3D,etc.)=
 for<br>
&gt; a strongly typed integer.<br>
&gt;<br></p>
<p dir=3D"ltr">You can add the operators as has been discussed for the bitm=
ask operators.</p>
<p dir=3D"ltr">Implicit conversions seem wrong for a strong typedef, IMHO. =
The lack of such is the chief benefit over a normal typedef.</p>
<p dir=3D"ltr">Initialisation might be an issue, but you could easily do a =
cast or write a factory function.</p>
<p dir=3D"ltr">Anthony</p>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01493f7e5e1dc2050eaccbb1--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 09 Feb 2015 14:43:46 -0500
Raw View
On 2015-02-09 14:29, Anthony Williams wrote:
> On 9 Feb 2015 18:50, "Matthew Woehlke" wrote:
>> On 2015-02-09 12:22, Anthony Williams wrote:
>>> I've rolled my own [strongly typed integers] in the past. In
>>> C++11, I wonder whether we need a special syntax.
>>>
>>> Inherited constructors essentially give us strong typedefs for class
>>> types, and scoped enums do that for integral types.
>>
>> Er... how? (Not the classes, the integers...)
>>
>> If I do this:
>>
>>   enum class Foo : int {};
>>
>> I can't seem to do anything useful with this. For example, I can't
>> brace-initialize it, assign it, pass an integer to a function taking a
>> Foo in any obvious manner, add to it, etc. I can do all of these with my
>> class. In particular, I would expect a proper strong typedef to
>> implement all of the usual integer operations (+,-,*,/,%,++,+=,etc.) for
>> a strongly typed integer.
>
> You can add the operators as has been discussed for the bitmask operators.

....but that's exactly my point. A language level strong typedef need not
have this limitation. If I have to define the operators myself there is
no benefit - and in fact, there are instead drawbacks - to using an enum
to "fake it".

> Implicit conversions seem wrong for a strong typedef, IMHO. The lack of
> such is the chief benefit over a normal typedef.

Yes, but the *only way* to construct such a critter from what I can tell
is with a static cast. That's just ugly. Given a "properly implemented"
strong typedef ('Foo'), I expect these to work:

  void foo(Foo); foo({0});
  auto foo = Foo{0};

I would certainly expect these to work with a language feature. In
addition, I would expect all standard integer operators to Just Work,
without needing to do anything to implement them myself.

IOW, going back to your statement, "I wonder whether we need a special
syntax"... IMHO yes we do. At least for integers. (Oh... and what about
float/double?)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 9 Feb 2015 20:30:15 +0000
Raw View
Floats and doubles, so physical equations are dimensionally correct.

On 2/9/15, Anthony Williams <anthony.ajw@gmail.com> wrote:
> On 09/02/15 17:06, Matthew Woehlke wrote:
>> On 2015-02-06 23:32, David Krauss wrote:
>>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
>>>>     enum class byte : uint8_t { };
>>>>
>>>> I call this sort of scoped enums (that introduce no new enumerators)
>>>> "integer classes".  They work very well.
>>>
>>> What do you think of the strong typedefs proposal? Might there be
>>> motivation for its implementation?
>>
>> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
>> rolled my own in at least one application.
>
> I've rolled my own too in the past. In C++11, I wonder whether we need a
> special syntax.
>
> Inherited constructors essentially give us strong typedefs for class
> types, and scoped enums do that for integral types.
>
> Do we need strong typedefs for anything else?
>
> Anthony
> --
> Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
> just::thread C++11 thread library             http://www.stdthread.co.uk
> Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 9 Feb 2015 20:38:12 +0000
Raw View
So that, e.g. adding a velocity to a time, and assigning to a variable
expecting a mass wouldn't compile.

On 2/9/15, Douglas Boffey <douglas.boffey@gmail.com> wrote:
> Floats and doubles, so physical equations are dimensionally correct.
>
> On 2/9/15, Anthony Williams <anthony.ajw@gmail.com> wrote:
>> On 09/02/15 17:06, Matthew Woehlke wrote:
>>> On 2015-02-06 23:32, David Krauss wrote:
>>>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
>>>>>     enum class byte : uint8_t { };
>>>>>
>>>>> I call this sort of scoped enums (that introduce no new enumerators)
>>>>> "integer classes".  They work very well.
>>>>
>>>> What do you think of the strong typedefs proposal? Might there be
>>>> motivation for its implementation?
>>>
>>> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
>>> rolled my own in at least one application.
>>
>> I've rolled my own too in the past. In C++11, I wonder whether we need a
>> special syntax.
>>
>> Inherited constructors essentially give us strong typedefs for class
>> types, and scoped enums do that for integral types.
>>
>> Do we need strong typedefs for anything else?
>>
>> Anthony
>> --
>> Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
>> just::thread C++11 thread library             http://www.stdthread.co.uk
>> Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
>> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Hyman Rosen <hyman.rosen@gmail.com>
Date: Tue, 17 Feb 2015 14:51:02 -0500
Raw View
--001a1134546cf94ffd050f4e06f5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Strong typedef isn't the same as unit.  If I were to say (taking a page
from Ada)
    typedef new int MyInt;
then I should be able to do
    MyInt x{3};
    x =3D x * x * x;
but if I had
    typedef SI::Time MySec;
    MySec x{3};
then
    x =3D x * x * x;
should not compile.

On Mon, Feb 9, 2015 at 3:38 PM, Douglas Boffey <douglas.boffey@gmail.com>
wrote:

> So that, e.g. adding a velocity to a time, and assigning to a variable
> expecting a mass wouldn't compile.
>
> On 2/9/15, Douglas Boffey <douglas.boffey@gmail.com> wrote:
> > Floats and doubles, so physical equations are dimensionally correct.
> >
> > On 2/9/15, Anthony Williams <anthony.ajw@gmail.com> wrote:
> >> On 09/02/15 17:06, Matthew Woehlke wrote:
> >>> On 2015-02-06 23:32, David Krauss wrote:
> >>>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
> >>>>>     enum class byte : uint8_t { };
> >>>>>
> >>>>> I call this sort of scoped enums (that introduce no new enumerators=
)
> >>>>> "integer classes".  They work very well.
> >>>>
> >>>> What do you think of the strong typedefs proposal? Might there be
> >>>> motivation for its implementation?
> >>>
> >>> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
> >>> rolled my own in at least one application.
> >>
> >> I've rolled my own too in the past. In C++11, I wonder whether we need=
 a
> >> special syntax.
> >>
> >> Inherited constructors essentially give us strong typedefs for class
> >> types, and scoped enums do that for integral types.
> >>
> >> Do we need strong typedefs for anything else?
> >>
> >> Anthony
> >> --
> >> Author of C++ Concurrency in Action
> http://www.stdthread.co.uk/book/
> >> just::thread C++11 thread library
> http://www.stdthread.co.uk
> >> Just Software Solutions Ltd
> http://www.justsoftwaresolutions.co.uk
> >> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 54789=
76
> >>
> >> --
> >>
> >> ---
> >> 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.
> >> Visit this group at
> >> http://groups.google.com/a/isocpp.org/group/std-proposals/.
> >>
> >
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr">Strong typedef isn&#39;t the same as unit.=C2=A0 If I were=
 to say (taking a page from Ada)<div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 typedef new int MyInt;</font><br>then I should be able to do<=
br><font face=3D"monospace, monospace">=C2=A0 =C2=A0 MyInt x{3};<br>=C2=A0 =
=C2=A0 x =3D x * x * x;</font><br>but if I had<br><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 typedef SI::Time MySec;<br>=C2=A0 =C2=A0 MySec x{3=
};</font><br>then<br><font face=3D"monospace, monospace">=C2=A0 =C2=A0 x =
=3D x * x * x;</font><br>should not compile.</div></div><div class=3D"gmail=
_extra"><br><div class=3D"gmail_quote">On Mon, Feb 9, 2015 at 3:38 PM, Doug=
las Boffey <span dir=3D"ltr">&lt;<a href=3D"mailto:douglas.boffey@gmail.com=
" target=3D"_blank">douglas.boffey@gmail.com</a>&gt;</span> wrote:<br><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex">So that, e.g. adding a velocity to a time, and as=
signing to a variable<br>
expecting a mass wouldn&#39;t compile.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
On 2/9/15, Douglas Boffey &lt;<a href=3D"mailto:douglas.boffey@gmail.com">d=
ouglas.boffey@gmail.com</a>&gt; wrote:<br>
&gt; Floats and doubles, so physical equations are dimensionally correct.<b=
r>
&gt;<br>
&gt; On 2/9/15, Anthony Williams &lt;<a href=3D"mailto:anthony.ajw@gmail.co=
m">anthony.ajw@gmail.com</a>&gt; wrote:<br>
&gt;&gt; On 09/02/15 17:06, Matthew Woehlke wrote:<br>
&gt;&gt;&gt; On 2015-02-06 23:32, David Krauss wrote:<br>
&gt;&gt;&gt;&gt;&gt; On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Do=
s Reis wrote:<br>
&gt;&gt;&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0enum class byte : uint8_t { };<br>
&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;&gt; I call this sort of scoped enums (that introduce no ne=
w enumerators)<br>
&gt;&gt;&gt;&gt;&gt; &quot;integer classes&quot;.=C2=A0 They work very well=
..<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; What do you think of the strong typedefs proposal? Might t=
here be<br>
&gt;&gt;&gt;&gt; motivation for its implementation?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Getting a bit off-topic, but... I&#39;d like to see strong typ=
edefs. I&#39;ve<br>
&gt;&gt;&gt; rolled my own in at least one application.<br>
&gt;&gt;<br>
&gt;&gt; I&#39;ve rolled my own too in the past. In C++11, I wonder whether=
 we need a<br>
&gt;&gt; special syntax.<br>
&gt;&gt;<br>
&gt;&gt; Inherited constructors essentially give us strong typedefs for cla=
ss<br>
&gt;&gt; types, and scoped enums do that for integral types.<br>
&gt;&gt;<br>
&gt;&gt; Do we need strong typedefs for anything else?<br>
&gt;&gt;<br>
&gt;&gt; Anthony<br>
&gt;&gt; --<br>
&gt;&gt; Author of C++ Concurrency in Action=C2=A0 =C2=A0 =C2=A0<a href=3D"=
http://www.stdthread.co.uk/book/" target=3D"_blank">http://www.stdthread.co=
..uk/book/</a><br>
&gt;&gt; just::thread C++11 thread library=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0<a href=3D"http://www.stdthread.co.uk" target=3D"_blank">h=
ttp://www.stdthread.co.uk</a><br>
&gt;&gt; Just Software Solutions Ltd=C2=A0 =C2=A0 =C2=A0 =C2=A0<a href=3D"h=
ttp://www.justsoftwaresolutions.co.uk" target=3D"_blank">http://www.justsof=
twaresolutions.co.uk</a><br>
&gt;&gt; 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5=
478976<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt;<br>
&gt;&gt; ---<br>
&gt;&gt; You received this message because you are subscribed to the Google=
 Groups<br>
&gt;&gt; &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
&gt;&gt; To unsubscribe from this group and stop receiving emails from it, =
send an<br>
&gt;&gt; email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org"=
>std-proposals+unsubscribe@isocpp.org</a>.<br>
&gt;&gt; To post to this group, send email to <a href=3D"mailto:std-proposa=
ls@isocpp.org">std-proposals@isocpp.org</a>.<br>
&gt;&gt; Visit this group at<br>
&gt;&gt; <a href=3D"http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/" target=3D"_blank">http://groups.google.com/a/isocpp.org/group/std-prop=
osals/</a>.<br>
&gt;&gt;<br>
&gt;<br>
<br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134546cf94ffd050f4e06f5--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 18 Feb 2015 07:00:40 +0800
Raw View
--Apple-Mail=_DE440A0C-B300-46B1-98DE-9CE9C6DCD402
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9302=E2=80=9318, at 3:51 AM, Hyman Rosen <hyman.rosen@gmail=
..com> wrote:
>=20
> Strong typedef isn't the same as unit.=20

The stated main purpose of strong typedefs is to implement units.

> If I were to say (taking a page from Ada)
>     typedef new int MyInt;
> then I should be able to do
>     MyInt x{3};
>     x =3D x * x * x;
> but if I had
>     typedef SI::Time MySec;
>     MySec x{3};
> then
>     x =3D x * x * x;
> should not compile.

You have to define the behavior of operators over strong typedefs by declar=
ing them, usually with defaulted definitions.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_DE440A0C-B300-46B1-98DE-9CE9C6DCD402
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9318, at 3:51 AM, Hyman Rosen &lt;<a href=3D"mailto:hyman.rosen@gmai=
l.com" class=3D"">hyman.rosen@gmail.com</a>&gt; wrote:</div><br class=3D"Ap=
ple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D"">Strong=
 typedef isn't the same as unit.&nbsp; </div></div></blockquote><div><br cl=
ass=3D""></div><div>The stated main purpose of strong typedefs is to implem=
ent units.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div cl=
ass=3D""><div dir=3D"ltr" class=3D"">If I were to say (taking a page from A=
da)<div class=3D""><font face=3D"monospace, monospace" class=3D"">&nbsp; &n=
bsp; typedef new int MyInt;</font><br class=3D"">then I should be able to d=
o<br class=3D""><font face=3D"monospace, monospace" class=3D"">&nbsp; &nbsp=
; MyInt x{3};<br class=3D"">&nbsp; &nbsp; x =3D x * x * x;</font><br class=
=3D"">but if I had<br class=3D""><font face=3D"monospace, monospace" class=
=3D"">&nbsp; &nbsp; typedef SI::Time MySec;<br class=3D"">&nbsp; &nbsp; MyS=
ec x{3};</font><br class=3D"">then<br class=3D""><font face=3D"monospace, m=
onospace" class=3D"">&nbsp; &nbsp; x =3D x * x * x;</font><br class=3D"">sh=
ould not compile.</div></div></div></blockquote><div><br class=3D""></div><=
div>You have to define the behavior of operators over strong typedefs by de=
claring them, usually with defaulted definitions.</div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_DE440A0C-B300-46B1-98DE-9CE9C6DCD402--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 19 Feb 2015 04:15:44 -0800
Raw View
David Krauss <potswa@gmail.com> writes:

| > On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis <gdr@axiom=
atics.org> wrote:
| >=20
| > Just allow it to be well-behaved enums.
|=20
| In a better world, compilers would understand such definitions.
|=20
| >     enum class byte : uint8_t { };
| >=20
| > I call this sort of scoped enums (that introduce no new enumerators)
| > "integer classes".  They work very well. =20
|=20
| What do you think of the strong typedefs proposal? Might there be
| motivation for its implementation?

Clearly, it is somehow related, but the devil is in the details.
This is something has been proposed several times.  Usually, there are
questions about how to construct values of such type, which conversions
are permitted, which aren't.  The usual discussions and confusion come
from the fact that 'strong typedef' or 'opaque typedefs' tend to mean
different things to different people.

|=20
| > See my recent message to the
| > EWG reflector and ideas about to simplify construction.
|=20
| Perhaps the readers of this public list would appreciate the
| opportunity to do so, but that list is limited-access.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 19 Feb 2015 04:18:52 -0800
Raw View
Matthew Woehlke <mw_triad@users.sourceforge.net> writes:

| On 2015-02-09 12:22, Anthony Williams wrote:
| > On 09/02/15 17:06, Matthew Woehlke wrote:
| >> On 2015-02-06 23:32, David Krauss wrote:
| >>>> On 2015=E2=80=9302=E2=80=9307, at 10:41 AM, Gabriel Dos Reis wrote:
| >>>>     enum class byte : uint8_t { };
| >>>>
| >>>> I call this sort of scoped enums (that introduce no new enumerators)
| >>>> "integer classes".  They work very well. =20
| >>>
| >>> What do you think of the strong typedefs proposal? Might there be
| >>> motivation for its implementation?
| >>
| >> Getting a bit off-topic, but... I'd like to see strong typedefs. I've
| >> rolled my own in at least one application.
| >=20
| > I've rolled my own too in the past. In C++11, I wonder whether we need =
a
| > special syntax.
| >=20
| > Inherited constructors essentially give us strong typedefs for class
| > types, and scoped enums do that for integral types.
|=20
| Er... how? (Not the classes, the integers...)
|=20
| If I do this:
|=20
|   enum class Foo : int {};
|=20
| I can't seem to do anything useful with this.

Actually, you can.

| For example, I can't
| brace-initialize it, assign it, pass an integer to a function taking a
| Foo in any obvious manner, add to it, etc. I can do all of these with my
| class. In particular, I would expect a proper strong typedef to
| implement all of the usual integer operations (+,-,*,/,%,++,+=3D,etc.) fo=
r
| a strongly typed integer.

This is usually where agreements "strong typedefs" stop.  If I do

     enum class SizeType : uint32_t { };

It is not clear I want all usuall arithmetic types to be valid for
SizeType.

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 19 Feb 2015 04:26:13 -0800
Raw View
Tony V E <tvaneerd@gmail.com> writes:

| On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <gdr@axiomatics.org>
| wrote:
|=20
|     Tony V E <tvaneerd@gmail.com> writes:
|    =20
|     [...]
|    =20
|     | template<typename E>
|     | typename std::enable_if<E::enable_bitwise_ops,E>::type
|     =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 ^^^^^^^^^^^^^^^^^^^^^
|    =20
|     Just allow it to be well-behaved enums.
|    =20
|=20
| I really don't understand what you mean (your terseness often baffles
| me).=C2=A0 Would you replace it with is_enum<E> or ...?

Almost: a test that E is a scoped enum.  For example, something like

  #include <type_traits>

  template<typename T>
  using raw =3D std::underlying_type_t<T>;

  template<typename T, bool =3D std::is_enum<T>::value>
  struct wellbehaved_enum_impl : std::false_type { };

  template<typename T>
  struct wellbehaved_enum_impl<T, true>  {
     enum { value =3D not std::is_convertible<T, raw<T>>::value };
  };

  template<typename T>
  struct wellbehaved_enum : wellbehaved_enum_impl<T> { };

  template<typename T>
  using check_type =3D std::enable_if_t<wellbehaved_enum<T>::value, T>;

  template<typename T>
  constexpr check_type<T> operator&(T x, T y) {
     return T(raw<T>(x) & raw<T>(y));
  }

  template<typename T>
  constexpr check_type<T> operator|(T x, T y) {
     return T(raw<T>(x) | raw<T>(y));
  }

  template<typename T>
  inline check_type<T>& operator&=3D(T& x, T y) {
     return x =3D x & y;
  }

  template<typename T>
  inline check_type<T>& operator|=3D(T& x, T y) {
     return x =3D x | y;
  }


  enum class Foo {
     a, b
  };

  int main() {
     auto x =3D Foo::a | Foo::b;
     auto y =3D Foo::a & Foo::b;
  }

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Thu, 19 Feb 2015 13:46:43 +0000
Raw View
Perhaps we need something like:

Foo operator&(Foo, Foo) =3D default;

etc., where Foo is an enum class?

On 2/19/15, Gabriel Dos Reis <gdr@axiomatics.org> wrote:
> Tony V E <tvaneerd@gmail.com> writes:
>
> | On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <gdr@axiomatics.org>
> | wrote:
> |
> |     Tony V E <tvaneerd@gmail.com> writes:
> |
> |     [...]
> |
> |     | template<typename E>
> |     | typename std::enable_if<E::enable_bitwise_ops,E>::type
> |     =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 ^^^^^^^^^^^^^^^^^^^^^
> |
> |     Just allow it to be well-behaved enums.
> |
> |
> | I really don't understand what you mean (your terseness often baffles
> | me).=C2=A0 Would you replace it with is_enum<E> or ...?
>
> Almost: a test that E is a scoped enum.  For example, something like
>
>   #include <type_traits>
>
>   template<typename T>
>   using raw =3D std::underlying_type_t<T>;
>
>   template<typename T, bool =3D std::is_enum<T>::value>
>   struct wellbehaved_enum_impl : std::false_type { };
>
>   template<typename T>
>   struct wellbehaved_enum_impl<T, true>  {
>      enum { value =3D not std::is_convertible<T, raw<T>>::value };
>   };
>
>   template<typename T>
>   struct wellbehaved_enum : wellbehaved_enum_impl<T> { };
>
>   template<typename T>
>   using check_type =3D std::enable_if_t<wellbehaved_enum<T>::value, T>;
>
>   template<typename T>
>   constexpr check_type<T> operator&(T x, T y) {
>      return T(raw<T>(x) & raw<T>(y));
>   }
>
>   template<typename T>
>   constexpr check_type<T> operator|(T x, T y) {
>      return T(raw<T>(x) | raw<T>(y));
>   }
>
>   template<typename T>
>   inline check_type<T>& operator&=3D(T& x, T y) {
>      return x =3D x & y;
>   }
>
>   template<typename T>
>   inline check_type<T>& operator|=3D(T& x, T y) {
>      return x =3D x | y;
>   }
>
>
>   enum class Foo {
>      a, b
>   };
>
>   int main() {
>      auto x =3D Foo::a | Foo::b;
>      auto y =3D Foo::a & Foo::b;
>   }
>
> -- Gaby
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Hyman Rosen <hyman.rosen@gmail.com>
Date: Thu, 19 Feb 2015 16:40:30 -0500
Raw View
--001a11c1257e2dc641050f77ca69
Content-Type: text/plain; charset=UTF-8

I would expect strong typedefs for the arithmetic types to allow all the
normal operations, but not to interconvert with other arithmetic types.
For units, I've always liked the approach used in Barton & Nackman *Scientific
and Engineering C++*:

namespace SimpleSI {
    template <typename ValueType, int Length, int Mass, int Time> struct
Unit {
        ValueType value;
        explicit Unit(ValueType v = ValueType()) : value(v) { }
        Unit operator+(Unit other) const { return Unit(value +
other.value); }
        Unit operator-(Unit other) const { return Unit(value -
other.value); }
    }

    template <typename ValueType> struct Unit<ValueType, 0, 0, 0> {
        ValueType value;
        Unit(ValueType v = ValueType()) : value(v) { }
        operator ValueType() const { return value; }
        Unit operator+(Unit other) const { return Unit(value +
other.value); }
        Unit operator-(Unit other) const { return Unit(value -
other.value); }
    }

    template <typename ValueType, int Length1, int Mass1, int Time1,
                                  int Length2, int Mass2, int Time2>
    Unit<ValueType, Length1 + Length2, Mass1 + Mass2, Time1 + Time2>
    operator*(Unit<ValueType, Length1, Mass1, Time1> a,
              Unit<ValueType, Length2, Mass2, Time2> b) {
        return Unit<ValueType, Length1 + Length2, Mass1 + Mass2, Time1 +
Time2>(a.value * b.value);
    }

    template <typename ValueType, int Length1, int Mass1, int Time1,
                                  int Length2, int Mass2, int Time2>
    Unit<ValueType, Length1 - Length2, Mass1 - Mass2, Time1 - Time2>
    operator/(Unit<ValueType, Length1, Mass1, Time1> a,
              Unit<ValueType, Length2, Mass2, Time2> b) {
        return Unit<ValueType, Length1 - Length2, Mass1 - Mass2, Time1 -
Time2>(a.value / b.value);
    }
}

On Thu, Feb 19, 2015 at 8:46 AM, Douglas Boffey <douglas.boffey@gmail.com>
wrote:

> Perhaps we need something like:
>
> Foo operator&(Foo, Foo) = default;
>
> etc., where Foo is an enum class?
>
> On 2/19/15, Gabriel Dos Reis <gdr@axiomatics.org> wrote:
> > Tony V E <tvaneerd@gmail.com> writes:
> >
> > | On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <gdr@axiomatics.org>
> > | wrote:
> > |
> > |     Tony V E <tvaneerd@gmail.com> writes:
> > |
> > |     [...]
> > |
> > |     | template<typename E>
> > |     | typename std::enable_if<E::enable_bitwise_ops,E>::type
> > |                               ^^^^^^^^^^^^^^^^^^^^^
> > |
> > |     Just allow it to be well-behaved enums.
> > |
> > |
> > | I really don't understand what you mean (your terseness often baffles
> > | me).  Would you replace it with is_enum<E> or ...?
> >
> > Almost: a test that E is a scoped enum.  For example, something like
> >
> >   #include <type_traits>
> >
> >   template<typename T>
> >   using raw = std::underlying_type_t<T>;
> >
> >   template<typename T, bool = std::is_enum<T>::value>
> >   struct wellbehaved_enum_impl : std::false_type { };
> >
> >   template<typename T>
> >   struct wellbehaved_enum_impl<T, true>  {
> >      enum { value = not std::is_convertible<T, raw<T>>::value };
> >   };
> >
> >   template<typename T>
> >   struct wellbehaved_enum : wellbehaved_enum_impl<T> { };
> >
> >   template<typename T>
> >   using check_type = std::enable_if_t<wellbehaved_enum<T>::value, T>;
> >
> >   template<typename T>
> >   constexpr check_type<T> operator&(T x, T y) {
> >      return T(raw<T>(x) & raw<T>(y));
> >   }
> >
> >   template<typename T>
> >   constexpr check_type<T> operator|(T x, T y) {
> >      return T(raw<T>(x) | raw<T>(y));
> >   }
> >
> >   template<typename T>
> >   inline check_type<T>& operator&=(T& x, T y) {
> >      return x = x & y;
> >   }
> >
> >   template<typename T>
> >   inline check_type<T>& operator|=(T& x, T y) {
> >      return x = x | y;
> >   }
> >
> >
> >   enum class Foo {
> >      a, b
> >   };
> >
> >   int main() {
> >      auto x = Foo::a | Foo::b;
> >      auto y = Foo::a & Foo::b;
> >   }
> >
> > -- Gaby
> >
> > --
> >
> > ---
> > 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.
> > Visit this group at
> > http://groups.google.com/a/isocpp.org/group/std-proposals/.
> >
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr">I would expect strong typedefs for the arithmetic types to=
 allow all the normal operations, but not to interconvert with other arithm=
etic types.=C2=A0 For units, I&#39;ve always liked the approach used in Bar=
ton &amp; Nackman <span style=3D"line-height:1.3;color:rgb(17,17,17)"><i st=
yle=3D"font-family:Arial,sans-serif">Scientific and Engineering C++</i><fon=
t face=3D"Arial, sans-serif">:</font><br><br><font face=3D"monospace, monos=
pace">namespace SimpleSI {<br>=C2=A0 =C2=A0 template &lt;typename ValueType=
, int Length, int Mass, int Time&gt; struct Unit {<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 ValueType value;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 explicit Unit(ValueT=
ype v =3D ValueType()) : value(v) { }<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Unit o=
perator+(Unit other) const { return Unit(value + other.value); }</font></sp=
an><br style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-he=
ight:16.8999996185303px"><span style=3D"color:rgb(17,17,17);font-family:mon=
ospace,monospace;line-height:16.8999996185303px">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Unit operator-(Unit other) const { return Unit(value - other.value); }<=
/span><div><span style=3D"color:rgb(17,17,17);font-family:monospace,monospa=
ce;line-height:16.8999996185303px">=C2=A0 =C2=A0 }</span></div><div><span s=
tyle=3D"font-family:monospace,monospace;color:rgb(17,17,17);line-height:1.3=
"><br></span></div><div><span style=3D"font-family:monospace,monospace;colo=
r:rgb(17,17,17);line-height:1.3">=C2=A0 =C2=A0 template &lt;typename ValueT=
ype&gt; struct Unit&lt;ValueType, 0, 0, 0&gt; {</span></div><span style=3D"=
line-height:1.3;color:rgb(17,17,17)"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ValueType value;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 Unit(ValueType v =3D ValueType()) : value(v) { }<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 operator=C2=A0</font></span><span style=3D"color:rgb(17,17,17);font-=
family:monospace,monospace;line-height:16.8999996185303px">ValueType() cons=
t { return value; }</span><span style=3D"line-height:1.3;color:rgb(17,17,17=
)"><font face=3D"monospace, monospace"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Unit=
 operator+(Unit other) const { return Unit(value + other.value); }</font></=
span><br style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-=
height:16.8999996185303px"><span style=3D"color:rgb(17,17,17);font-family:m=
onospace,monospace;line-height:16.8999996185303px">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 Unit operator-(Unit other) const { return Unit(value - other.value); }<=
/span><div><span style=3D"color:rgb(17,17,17);font-family:monospace,monospa=
ce;line-height:16.8999996185303px">=C2=A0 =C2=A0 }</span></div><div><span s=
tyle=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-height:16.=
8999996185303px"><br>=C2=A0 =C2=A0=C2=A0</span><span style=3D"color:rgb(17,=
17,17);font-family:monospace,monospace;line-height:16.8999996185303px">temp=
late &lt;typename ValueType, int Length1, int Mass1, int Time1,</span></div=
><div><span style=3D"color:rgb(17,17,17);font-family:monospace,monospace;li=
ne-height:16.8999996185303px">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0</span><span style=3D"color:rgb(17,17,17);font-family:monospace,monos=
pace;line-height:16.8999996185303px">int Length2, int Mass2, int Time2</spa=
n><span style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-h=
eight:16.8999996185303px">&gt;</span></div><div><span style=3D"color:rgb(17=
,17,17);font-family:monospace,monospace;line-height:16.8999996185303px">=C2=
=A0 =C2=A0 Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:mo=
nospace,monospace;line-height:16.8999996185303px">ValueType, Length1 + Leng=
th2, Mass1 + Mass2, Time1 + Time2&gt;<br>=C2=A0 =C2=A0 operator*(Unit&lt;</=
span><span style=3D"color:rgb(17,17,17);font-family:monospace,monospace;lin=
e-height:16.8999996185303px">ValueType, Length1, Mass1, Time1&gt; a,<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0</span><span style=3D"co=
lor:rgb(17,17,17);font-family:monospace,monospace;line-height:16.8999996185=
303px">Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:monosp=
ace,monospace;line-height:16.8999996185303px">ValueType, Length2, Mass2, Ti=
me2&gt; b) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return=C2=A0</span><span style=
=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-height:16.8999=
996185303px">Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:=
monospace,monospace;line-height:16.8999996185303px">ValueType, Length1 + Le=
ngth2, Mass1 + Mass2, Time1 + Time2&gt;(a.value * b.value);</span></div><di=
v><span style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-h=
eight:16.8999996185303px">=C2=A0 =C2=A0 }</span></div><div><span style=3D"c=
olor:rgb(17,17,17);font-family:monospace,monospace;line-height:16.899999618=
5303px"><br>=C2=A0 =C2=A0=C2=A0</span><span style=3D"color:rgb(17,17,17);fo=
nt-family:monospace,monospace;line-height:16.8999996185303px">template &lt;=
typename ValueType, int Length1, int Mass1, int Time1,</span></div><div><sp=
an style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-height=
:16.8999996185303px">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0</s=
pan><span style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line=
-height:16.8999996185303px">int Length2, int Mass2, int Time2</span><span s=
tyle=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-height:16.=
8999996185303px">&gt;</span></div><div><span style=3D"color:rgb(17,17,17);f=
ont-family:monospace,monospace;line-height:16.8999996185303px">=C2=A0 =C2=
=A0 Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:monospace=
,monospace;line-height:16.8999996185303px">ValueType, Length1 - Length2, Ma=
ss1 - Mass2, Time1 - Time2&gt;<br>=C2=A0 =C2=A0 operator/(Unit&lt;</span><s=
pan style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-heigh=
t:16.8999996185303px">ValueType, Length1, Mass1, Time1&gt; a,<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0</span><span style=3D"color:rgb=
(17,17,17);font-family:monospace,monospace;line-height:16.8999996185303px">=
Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:monospace,mon=
ospace;line-height:16.8999996185303px">ValueType, Length2, Mass2, Time2&gt;=
 b) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return=C2=A0</span><span style=3D"colo=
r:rgb(17,17,17);font-family:monospace,monospace;line-height:16.899999618530=
3px">Unit&lt;</span><span style=3D"color:rgb(17,17,17);font-family:monospac=
e,monospace;line-height:16.8999996185303px">ValueType, Length1 - Length2, M=
ass1 - Mass2, Time1 - Time2&gt;(a.value / b.value);</span></div><div><span =
style=3D"color:rgb(17,17,17);font-family:monospace,monospace;line-height:16=
..8999996185303px">=C2=A0 =C2=A0 }</span></div><div><span style=3D"color:rgb=
(17,17,17);font-family:monospace,monospace;line-height:16.8999996185303px">=
}</span></div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e">On Thu, Feb 19, 2015 at 8:46 AM, Douglas Boffey <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:douglas.boffey@gmail.com" target=3D"_blank">douglas.boffey@=
gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Perhaps =
we need something like:<br>
<br>
Foo operator&amp;(Foo, Foo) =3D default;<br>
<br>
etc., where Foo is an enum class?<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
On 2/19/15, Gabriel Dos Reis &lt;<a href=3D"mailto:gdr@axiomatics.org">gdr@=
axiomatics.org</a>&gt; wrote:<br>
&gt; Tony V E &lt;<a href=3D"mailto:tvaneerd@gmail.com">tvaneerd@gmail.com<=
/a>&gt; writes:<br>
&gt;<br>
&gt; | On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis &lt;<a href=3D"mail=
to:gdr@axiomatics.org">gdr@axiomatics.org</a>&gt;<br>
&gt; | wrote:<br>
&gt; |<br>
&gt; |=C2=A0 =C2=A0 =C2=A0Tony V E &lt;<a href=3D"mailto:tvaneerd@gmail.com=
">tvaneerd@gmail.com</a>&gt; writes:<br>
&gt; |<br>
&gt; |=C2=A0 =C2=A0 =C2=A0[...]<br>
&gt; |<br>
&gt; |=C2=A0 =C2=A0 =C2=A0| template&lt;typename E&gt;<br>
&gt; |=C2=A0 =C2=A0 =C2=A0| typename std::enable_if&lt;E::enable_bitwise_op=
s,E&gt;::type<br>
&gt; |=C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ^^^^^^^^^^^^^^^^^^^^^<br>
&gt; |<br>
&gt; |=C2=A0 =C2=A0 =C2=A0Just allow it to be well-behaved enums.<br>
&gt; |<br>
&gt; |<br>
&gt; | I really don&#39;t understand what you mean (your terseness often ba=
ffles<br>
&gt; | me).=C2=A0 Would you replace it with is_enum&lt;E&gt; or ...?<br>
&gt;<br>
&gt; Almost: a test that E is a scoped enum.=C2=A0 For example, something l=
ike<br>
&gt;<br>
&gt;=C2=A0 =C2=A0#include &lt;type_traits&gt;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0using raw =3D std::underlying_type_t&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T, bool =3D std::is_enum&lt;T&gt;::va=
lue&gt;<br>
&gt;=C2=A0 =C2=A0struct wellbehaved_enum_impl : std::false_type { };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0struct wellbehaved_enum_impl&lt;T, true&gt;=C2=A0 {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 enum { value =3D not std::is_convertible&lt;T, raw=
&lt;T&gt;&gt;::value };<br>
&gt;=C2=A0 =C2=A0};<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0struct wellbehaved_enum : wellbehaved_enum_impl&lt;T&gt; {=
 };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0using check_type =3D std::enable_if_t&lt;wellbehaved_enum&=
lt;T&gt;::value, T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0constexpr check_type&lt;T&gt; operator&amp;(T x, T y) {<br=
>
&gt;=C2=A0 =C2=A0 =C2=A0 return T(raw&lt;T&gt;(x) &amp; raw&lt;T&gt;(y));<b=
r>
&gt;=C2=A0 =C2=A0}<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0constexpr check_type&lt;T&gt; operator|(T x, T y) {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 return T(raw&lt;T&gt;(x) | raw&lt;T&gt;(y));<br>
&gt;=C2=A0 =C2=A0}<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0inline check_type&lt;T&gt;&amp; operator&amp;=3D(T&amp; x,=
 T y) {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 return x =3D x &amp; y;<br>
&gt;=C2=A0 =C2=A0}<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template&lt;typename T&gt;<br>
&gt;=C2=A0 =C2=A0inline check_type&lt;T&gt;&amp; operator|=3D(T&amp; x, T y=
) {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 return x =3D x | y;<br>
&gt;=C2=A0 =C2=A0}<br>
&gt;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0enum class Foo {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 a, b<br>
&gt;=C2=A0 =C2=A0};<br>
&gt;<br>
&gt;=C2=A0 =C2=A0int main() {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 auto x =3D Foo::a | Foo::b;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 auto y =3D Foo::a &amp; Foo::b;<br>
&gt;=C2=A0 =C2=A0}<br>
&gt;<br>
&gt; -- Gaby<br>
&gt;<br>
&gt; --<br>
&gt;<br>
&gt; ---<br>
&gt; You received this message because you are subscribed to the Google Gro=
ups<br>
&gt; &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
&gt; To unsubscribe from this group and stop receiving emails from it, send=
 an<br>
&gt; email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std=
-proposals+unsubscribe@isocpp.org</a>.<br>
&gt; To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
&gt; Visit this group at<br>
&gt; <a href=3D"http://groups.google.com/a/isocpp.org/group/std-proposals/"=
 target=3D"_blank">http://groups.google.com/a/isocpp.org/group/std-proposal=
s/</a>.<br>
&gt;<br>
<br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c1257e2dc641050f77ca69--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Fri, 20 Feb 2015 06:32:45 -0800
Raw View
Douglas Boffey <douglas.boffey@gmail.com> writes:

| Perhaps we need something like:
|
| Foo operator&(Foo, Foo) = default;
|
| etc., where Foo is an enum class?

Possibly.

-- Gaby

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 20 Feb 2015 16:09:10 -0500
Raw View
--089e0116048ec551b4050f8b76db
Content-Type: text/plain; charset=UTF-8

On Thu, Feb 19, 2015 at 7:26 AM, Gabriel Dos Reis <gdr@axiomatics.org>
wrote:

> Tony V E <tvaneerd@gmail.com> writes:
>
> | On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis <gdr@axiomatics.org>
> | wrote:
> |
> |     Tony V E <tvaneerd@gmail.com> writes:
> |
> |     [...]
> |
> |     | template<typename E>
> |     | typename std::enable_if<E::enable_bitwise_ops,E>::type
> |                               ^^^^^^^^^^^^^^^^^^^^^
> |
> |     Just allow it to be well-behaved enums.
> |
> |
> | I really don't understand what you mean (your terseness often baffles
> | me).  Would you replace it with is_enum<E> or ...?
>
> Almost: a test that E is a scoped enum.  For example, something like
>
>   #include <type_traits>
>
>   template<typename T>
>   using raw = std::underlying_type_t<T>;
>
>   template<typename T, bool = std::is_enum<T>::value>
>   struct wellbehaved_enum_impl : std::false_type { };
>
>   template<typename T>
>   struct wellbehaved_enum_impl<T, true>  {
>      enum { value = not std::is_convertible<T, raw<T>>::value };
>   };
>
>   template<typename T>
>   struct wellbehaved_enum : wellbehaved_enum_impl<T> { };
>
>   template<typename T>
>   using check_type = std::enable_if_t<wellbehaved_enum<T>::value, T>;
>
>   template<typename T>
>   constexpr check_type<T> operator&(T x, T y) {
>      return T(raw<T>(x) & raw<T>(y));
>   }
>
>   template<typename T>
>   constexpr check_type<T> operator|(T x, T y) {
>      return T(raw<T>(x) | raw<T>(y));
>   }
>
>   template<typename T>
>   inline check_type<T>& operator&=(T& x, T y) {
>      return x = x & y;
>   }
>
>   template<typename T>
>   inline check_type<T>& operator|=(T& x, T y) {
>      return x = x | y;
>   }
>
>
>   enum class Foo {
>      a, b
>   };
>
>   int main() {
>      auto x = Foo::a | Foo::b;
>      auto y = Foo::a & Foo::b;
>   }
>
> -- Gaby
>
>
OK, thanks for the explanation.  But I don't want all my enums to have
bit-wise operations.  Sometimes - usually I think - enum values are meant
to be mutually exclusive.   So I only want bitwise operations on the ones
that opt-in.  I'd be somewhat OK if in general Foo & Foo returned a
raw<Foo> (to be compatible with C-style enums), but only the ones that
opt-in should convert back to Foo. (Your uses might be different of course.)

Tony

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, Feb 19, 2015 at 7:26 AM, Gabriel Dos Reis <span dir=3D"ltr">&lt=
;<a href=3D"mailto:gdr@axiomatics.org" target=3D"_blank">gdr@axiomatics.org=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><span class=3D"">Tony V E &lt;<a href=3D"mailto:tvaneerd@gmail.com">tvanee=
rd@gmail.com</a>&gt; writes:<br>
<br>
| On Fri, Feb 6, 2015 at 9:41 PM, Gabriel Dos Reis &lt;<a href=3D"mailto:gd=
r@axiomatics.org">gdr@axiomatics.org</a>&gt;<br>
| wrote:<br>
|<br>
|=C2=A0 =C2=A0 =C2=A0Tony V E &lt;<a href=3D"mailto:tvaneerd@gmail.com">tva=
neerd@gmail.com</a>&gt; writes:<br>
|<br>
|=C2=A0 =C2=A0 =C2=A0[...]<br>
|<br>
|=C2=A0 =C2=A0 =C2=A0| template&lt;typename E&gt;<br>
|=C2=A0 =C2=A0 =C2=A0| typename std::enable_if&lt;E::enable_bitwise_ops,E&g=
t;::type<br>
|=C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ^^^^^^^^^^^^^^^^^^^^^<br>
|<br>
|=C2=A0 =C2=A0 =C2=A0Just allow it to be well-behaved enums.<br>
|<br>
|<br>
| I really don&#39;t understand what you mean (your terseness often baffles=
<br>
| me).=C2=A0 Would you replace it with is_enum&lt;E&gt; or ...?<br>
<br>
</span>Almost: a test that E is a scoped enum.=C2=A0 For example, something=
 like<br>
<br>
=C2=A0 #include &lt;type_traits&gt;<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 using raw =3D std::underlying_type_t&lt;T&gt;;<br>
<br>
=C2=A0 template&lt;typename T, bool =3D std::is_enum&lt;T&gt;::value&gt;<br=
>
=C2=A0 struct wellbehaved_enum_impl : std::false_type { };<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 struct wellbehaved_enum_impl&lt;T, true&gt;=C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0enum { value =3D not std::is_convertible&lt;T, raw&lt;T=
&gt;&gt;::value };<br>
=C2=A0 };<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 struct wellbehaved_enum : wellbehaved_enum_impl&lt;T&gt; { };<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 using check_type =3D std::enable_if_t&lt;wellbehaved_enum&lt;T&gt;::=
value, T&gt;;<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 constexpr check_type&lt;T&gt; operator&amp;(T x, T y) {<br>
=C2=A0 =C2=A0 =C2=A0return T(raw&lt;T&gt;(x) &amp; raw&lt;T&gt;(y));<br>
=C2=A0 }<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 constexpr check_type&lt;T&gt; operator|(T x, T y) {<br>
=C2=A0 =C2=A0 =C2=A0return T(raw&lt;T&gt;(x) | raw&lt;T&gt;(y));<br>
=C2=A0 }<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 inline check_type&lt;T&gt;&amp; operator&amp;=3D(T&amp; x, T y) {<br=
>
=C2=A0 =C2=A0 =C2=A0return x =3D x &amp; y;<br>
=C2=A0 }<br>
<br>
=C2=A0 template&lt;typename T&gt;<br>
=C2=A0 inline check_type&lt;T&gt;&amp; operator|=3D(T&amp; x, T y) {<br>
=C2=A0 =C2=A0 =C2=A0return x =3D x | y;<br>
=C2=A0 }<br>
<br>
<br>
=C2=A0 enum class Foo {<br>
=C2=A0 =C2=A0 =C2=A0a, b<br>
=C2=A0 };<br>
<br>
=C2=A0 int main() {<br>
=C2=A0 =C2=A0 =C2=A0auto x =3D Foo::a | Foo::b;<br>
=C2=A0 =C2=A0 =C2=A0auto y =3D Foo::a &amp; Foo::b;<br>
<div class=3D""><div class=3D"h5">=C2=A0 }<br>
<br>
-- Gaby<br>
<br></div></div></blockquote><div><br></div></div>OK, thanks for the explan=
ation.=C2=A0 But I don&#39;t want all my enums to have bit-wise operations.=
=C2=A0 Sometimes - usually I think - enum values are meant to be mutually e=
xclusive.=C2=A0=C2=A0 So I only want bitwise operations on the ones that op=
t-in.=C2=A0 I&#39;d be somewhat OK if in general Foo &amp; Foo returned a r=
aw&lt;Foo&gt; (to be compatible with C-style enums), but only the ones that=
 opt-in should convert back to Foo. (Your uses might be different of course=
..)<br><br></div><div class=3D"gmail_extra">Tony<br><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0116048ec551b4050f8b76db--

.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Sun, 22 Feb 2015 12:21:50 -0800
Raw View
Tony V E <tvaneerd@gmail.com> writes:

[...]

| OK, thanks for the explanation.=C2=A0 But I don't want all my enums to ha=
ve
| bit-wise operations.=C2=A0 Sometimes - usually I think - enum values are
| meant to be mutually exclusive.=C2=A0=C2=A0 So I only want bitwise operat=
ions on
| the ones that opt-in.=C2=A0 I'd be somewhat OK if in general Foo & Foo
| returned a raw<Foo> (to be compatible with C-style enums),

That is what classic non-well behaved enums are for :-)

| but only
| the ones that opt-in should convert back to Foo. (Your uses might be
| different of course.)

std::bitset?

-- Gaby

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.