Topic: [[simple]] enum
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 28 Jan 2019 00:57:23 +1000
Raw View
--000000000000d4749c058071c736
Content-Type: text/plain; charset="UTF-8"
I've been toying with the following design, and welcome some initial
thoughts...
*Motivation*
Many times when you are modelling something with an enumeration type, you
want the set of values of the type to be exactly the set of enumerators -
and you don't want any of them to be an accidental default (ie you want the
value of all objects of the enumeration type to be explicitly chosen)
C++ enumeration types provide a superset of these requirements, therefore
could be constained to them with an attribute. An enumeration type, so
constrained, would enable the compiler to statically analyze, enforce and
depend upon these constraints (for example in switch statements).
*Informal Specification*
An enumeration type definition marked with the attribute [[simple]]
declares the enumeration type as a *simple* enumeration type.
A simple enumeration type E has the following constaints:
- objects of type E are not default-constructible (must have an initializer
of type E)
- objects of type E are not convertible to their underlying type, and
neither visa-versa
- an object of type E may only hold a value that is equal to (at least) one
of its enumerators.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxGKqxyDtrsT5oW9PsQ%40mail.gmail.com.
--000000000000d4749c058071c736
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I've been toying with the following design, and w=
elcome some initial thoughts...</div><div><b><br></b></div><div><b>Motivati=
on</b></div><div><br></div><div>Many times when you are modelling something=
with an enumeration type, you want the set of values of the type to be exa=
ctly the set of enumerators - and you don't want any of them to be an a=
ccidental default (ie you want the value of all objects of the enumeration =
type to be explicitly chosen)</div><div><br></div><div>C++ enumeration type=
s provide a superset of these requirements, therefore could be constained t=
o them with an attribute.=C2=A0 An enumeration type, so constrained, would =
enable the compiler to statically analyze, enforce and depend upon these co=
nstraints (for example in switch statements).</div><div><br></div><div><b>I=
nformal Specification</b></div><div><br></div>An enumeration type definitio=
n marked with the attribute [[simple]] declares the enumeration type as a <=
i>simple</i> enumeration type.<div><br></div><div>A simple enumeration type=
E has the following constaints:</div><div><br></div><div>- objects of type=
E are not default-constructible (must have an initializer of type E)<br></=
div><div>- objects of type E are not convertible to their underlying type, =
and neither visa-versa<br></div><div>- an object of type E may only hold a =
value that is equal to (at least) one of its enumerators.<br></div><div><br=
></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxG=
KqxyDtrsT5oW9PsQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf=
1viRuGyqdovzMHvdgzacxGKqxyDtrsT5oW9PsQ%40mail.gmail.com</a>.<br />
--000000000000d4749c058071c736--
.
Author: Lawrence Emke <lawrence.emke@gmail.com>
Date: Sun, 27 Jan 2019 10:50:30 -0600
Raw View
--000000000000c3b5bd0580735d28
Content-Type: text/plain; charset="UTF-8"
Yes I agree with your observation. There is a poor design assumption in
the current specification.
the enum was originally designed to implement a set of "options" without a
data type.
Upon implementation they had to specify a data type, so they chose INT. It
was a quick and
dirty implementation. A better choice would have been a new data type e.g.
ENUM. Then
when people started to use this construct, they came up with the idea of
being able to use the same
construct for another purpose, They thought that adding an option for a
non-integer data type
would make it even better.
The problem was seen when inheritance was involved. A function could have
an argument of
a type that is an enum type of object. Another function could have a type
of just "enum".
Now both definitions could have different values for the same label. When
the user called a
function and used the duplicate label which definition of the label should
be used? So they implemented
a rule that every use of an enum label must name of defining type, even if
it was not necessary,
for a particular function, because to enum (non-typed) lists could have the
same label but different
values (due to order of listing in the enum definition).
The real problem is in the "design" specification. Due to evolution, the
enum was allowed
to evolve into two purposes, for the same thing. Bad design. This is just
like the banks
wanting to use SSN for their purpose (which is other than what it was
originally designed).
It was a cheap way for the banks to "reuse" something they already had!!
The legislature (senators and reps), were already to do this for their
friends That would mean
adding an additional dependency or the SSN object. Then who becomes the
owner of this object
the government or the banks? This is the type of design error that is
involved with enum.
The problem really boils down to the use of the INT type as the default
value for untyped
enum objects. The INT type has other attributes other than value. Namely
order and arithmetic.
Programmers have used these attributes, which leads to more problems. It is
like the little old lady
who swallowed the fly.
A solution is to implement untyped enums as an "ID" value which can not be
used like an INT.
It has value, but the only function is to compare values of equal and
unequal. With this
implementation, All untyped enum values could reside in an address space
such that a label
would have only one unique value, even if it appears in two untyped enum
definitions.
The second use of enums with type defined would be an object just like
other local objects.
they would require a class attribute if used from a different enum
definition.
In short there are two different purposes being used by enum. The original
was a simple
list of options. It did not require the user to include a class attribute.
The second purpose
was to provide a list of "constants" (that are valid for a function).
Why should a use of a function have to supply an object qualifier for an
easy remembered
option? Answer: because of using one thing for two purposes.
I would rather have a "options" type specification for the untyped enum,
and a second specification
for a "list of constants".
However, the problem goes deeper. Inheritance causes an additional
complication, when including
multiple objects in a run module. This is not impossible, but it requires
work upon the compiler side.
The quick and dirty solution was just that. But it left the user with the
result of not only having to
remember the label of an enum but also its class name, and include it in a
function call.
On Sun, Jan 27, 2019 at 8:57 AM Andrew Tomazos <andrewtomazos@gmail.com>
wrote:
> I've been toying with the following design, and welcome some initial
> thoughts...
>
> *Motivation*
>
> Many times when you are modelling something with an enumeration type, you
> want the set of values of the type to be exactly the set of enumerators -
> and you don't want any of them to be an accidental default (ie you want the
> value of all objects of the enumeration type to be explicitly chosen)
>
> C++ enumeration types provide a superset of these requirements, therefore
> could be constained to them with an attribute. An enumeration type, so
> constrained, would enable the compiler to statically analyze, enforce and
> depend upon these constraints (for example in switch statements).
>
> *Informal Specification*
>
> An enumeration type definition marked with the attribute [[simple]]
> declares the enumeration type as a *simple* enumeration type.
>
> A simple enumeration type E has the following constaints:
>
> - objects of type E are not default-constructible (must have an
> initializer of type E)
> - objects of type E are not convertible to their underlying type, and
> neither visa-versa
> - an object of type E may only hold a value that is equal to (at least)
> one of its enumerators.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxGKqxyDtrsT5oW9PsQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxGKqxyDtrsT5oW9PsQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO2M9_XO-AX5Pi9uXyka%2BBp3b17zAzw%3DY-M9TE0OBGCxJw%40mail.gmail.com.
--000000000000c3b5bd0580735d28
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Yes I agree with your observation.=C2=A0 There is a poor d=
esign assumption in the current specification.=C2=A0<div>the enum was origi=
nally designed to implement a set of "options" without a data typ=
e.=C2=A0</div><div>Upon implementation they had to specify a data type, so =
they chose INT.=C2=A0 It was a quick and</div><div>dirty implementation. A =
better choice would have been a new data type e.g. ENUM. Then</div><div>whe=
n people started to use this construct, they came up with the idea of being=
able to use the same</div><div>construct for another purpose, They thought=
that adding an option for a non-integer data type</div><div>would make it =
even better.=C2=A0 =C2=A0</div><div><br></div><div>The problem was seen whe=
n inheritance was involved. A function could have an argument of=C2=A0</div=
><div>a type that is an enum type of object.=C2=A0 Another function could h=
ave a type of just "enum".</div><div>Now both definitions could h=
ave different values for the same label. When the user called a</div><div>f=
unction and used the duplicate label which definition of the label should b=
e used? So they implemented</div><div>a rule that every use of an enum labe=
l must name of defining type, even if it was not necessary,</div><div>for a=
particular function, because to enum (non-typed) lists could have the same=
label but different</div><div>values (due to order of listing in the enum =
definition).=C2=A0</div><div><br></div><div>The real problem is in the &quo=
t;design" specification. Due to evolution, the enum was allowed</div><=
div>to evolve into two purposes, for the same thing.=C2=A0 Bad design.=C2=
=A0 This is just like the banks=C2=A0</div><div>wanting to use SSN for thei=
r purpose (which is other than what it was originally designed).</div><div>=
It was a cheap way for the banks to "reuse" something they alread=
y had!!=C2=A0</div><div>The legislature (senators and reps), were already t=
o do this for their friends That would mean</div><div>adding an additional =
dependency or the SSN object. Then who becomes the owner of this object</di=
v><div>the government or the banks?=C2=A0 This is the type of design error =
that is involved with enum.=C2=A0</div><div><br></div><div>The problem real=
ly boils down to the use of the INT type as the default value for untyped</=
div><div>enum objects.=C2=A0 The INT type has other attributes other than v=
alue. Namely order and arithmetic.</div><div>Programmers have used these at=
tributes, which leads to more problems. It is like the little old lady=C2=
=A0</div><div>who swallowed the fly.=C2=A0</div><div><br></div><div>A solut=
ion is to implement untyped enums as an "ID" value which can not =
be used like an INT.</div><div>It has value, but the only function is to co=
mpare values of equal and unequal. With this</div><div>implementation, All =
untyped enum values could reside in an address space such that a label</div=
><div>would have only one unique value, even if it appears in two untyped e=
num definitions.=C2=A0=C2=A0</div><div><br></div><div>The second use of enu=
ms with type defined would be an object just like other local objects.</div=
><div>they would require a class attribute if used from a different enum de=
finition.=C2=A0=C2=A0</div><div><br></div><div>In short there are two diffe=
rent purposes being used by enum. The original was a simple</div><div>list =
of options. It did not require the user to include a class attribute. The s=
econd purpose</div><div>was to provide a list of "constants" (tha=
t are valid for a function).=C2=A0=C2=A0</div><div><br></div><div>Why shoul=
d a use of a function have to supply an object qualifier for an easy rememb=
ered</div><div>option?=C2=A0 Answer: because of using one thing for two pur=
poses.=C2=A0=C2=A0</div><div><br></div><div>I would rather have a "opt=
ions" type specification for the untyped enum, and a second specificat=
ion</div><div>for a "list of constants".</div><div><br></div><div=
>However, the problem goes deeper. Inheritance causes an additional complic=
ation, when including</div><div>multiple objects in a run module.=C2=A0 Thi=
s is not impossible, but it requires work upon the compiler side.</div><div=
>The quick and dirty solution was just that. But it left the user with the =
result of not only having to=C2=A0</div><div>remember the label of an enum =
but also its class name, and include it in a function call.=C2=A0</div></di=
v><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On S=
un, Jan 27, 2019 at 8:57 AM Andrew Tomazos <<a href=3D"mailto:andrewtoma=
zos@gmail.com">andrewtomazos@gmail.com</a>> wrote:<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>I've been t=
oying with the following design, and welcome some initial thoughts...</div>=
<div><b><br></b></div><div><b>Motivation</b></div><div><br></div><div>Many =
times when you are modelling something with an enumeration type, you want t=
he set of values of the type to be exactly the set of enumerators - and you=
don't want any of them to be an accidental default (ie you want the va=
lue of all objects of the enumeration type to be explicitly chosen)</div><d=
iv><br></div><div>C++ enumeration types provide a superset of these require=
ments, therefore could be constained to them with an attribute.=C2=A0 An en=
umeration type, so constrained, would enable the compiler to statically ana=
lyze, enforce and depend upon these constraints (for example in switch stat=
ements).</div><div><br></div><div><b>Informal Specification</b></div><div><=
br></div>An enumeration type definition marked with the attribute [[simple]=
] declares the enumeration type as a <i>simple</i> enumeration type.<div><b=
r></div><div>A simple enumeration type E has the following constaints:</div=
><div><br></div><div>- objects of type E are not default-constructible (mus=
t have an initializer of type E)<br></div><div>- objects of type E are not =
convertible to their underlying type, and neither visa-versa<br></div><div>=
- an object of type E may only hold a value that is equal to (at least) one=
of its enumerators.<br></div><div><br></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxG=
KqxyDtrsT5oW9PsQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAB%2B4KHJr_GAf1viRuGyqdovzMHvdgzacxGKqxyDtrsT5oW9PsQ%40mail.gmail.c=
om</a>.<br>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO2M9_XO-AX5Pi9uXyka%2BBp3b17z=
Azw%3DY-M9TE0OBGCxJw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO2M=
9_XO-AX5Pi9uXyka%2BBp3b17zAzw%3DY-M9TE0OBGCxJw%40mail.gmail.com</a>.<br />
--000000000000c3b5bd0580735d28--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 27 Jan 2019 08:51:39 -0800 (PST)
Raw View
------=_Part_1227_126884055.1548607899967
Content-Type: multipart/alternative;
boundary="----=_Part_1228_995219156.1548607899967"
------=_Part_1228_995219156.1548607899967
Content-Type: text/plain; charset="UTF-8"
Let us call these kinds of enumerations "guarded enumerations".
I think all guarded enumerations should be scoped enumerations. It doesn't
make sense why someone would want an unscoped enumeration that is guarded,
since scoped enumerations already have stronger safety than unscoped ones.
And if the scoping is a problem, then P1099's `using enum` ought to be able
to solve it.
Also, I think a contextual keyword would be a better way to invoke a
guarded enumeration. It feels more like a legit language feature than a
hack, and it would allow us to be a bit more/less draconian in what gets
allowed. Plus, since scoped enumerations have to be named, adding that
restriction makes it grammatically possible to use contextual keywords.
Oh, and it makes it more clear that forward declarations need to be
consistent.
I think that guarded enumerations should not out-right forbid such
conversions. The key thing to me about guarded enumerations is that all
allowed conversions are safe, and therefore, you can know for a fact that
if you have an enumeration object, it has the value of one of its
enumerators.
Conversions to the underlying type can never not be safe, so there's no
reason to forbid them. Conversions *from* the underlying type are a
different matter. Implicit conversions are outright forbidden, but you get
that by using a scoped enumeration. There are two cases of explicit that
need to be considered:
1: Explicit conversion from a constant expression. Here, the compiler can
see the value and know whether or not it matches an enumerator. As such,
explicit conversions from constant expressions should be allowed, but
they're ill-formed if the expression doesn't match an enumerator. Which
also means that if you forward declare one, you still can't construct it.
2: Explicit conversion from a non-constant expression. What we need here is
an explicit "checked conversion" function in the standard library. That is,
`static_cast<guarded_enum>(non_constant_expression);` itself is outright
forbidden, but `checked_enum_cast<guarded_enum>(non_constant_expression);`
would be allowed. It would simply error out if the value is not an
enumerator.
P0709's static exceptions would make for a great error handling mechanism
for such a construct. But because `static_cast` isn't allowed at all, only
the standard library could actually implement `checked_enum_cast` for
guarded enumerations. And implementing that requires building a runtime
table of values for that enumeration, so it isn't free, which is why we
don't allow `static_cast` to do it.
Bikeshedding: The word "simple" suggests having fewer restrictions, that
it's easier to use or something. I say to use "guarded".
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%40isocpp.org.
------=_Part_1228_995219156.1548607899967
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Let us call these kinds of enumerations "guarded=
enumerations".<br></div><div><br></div><div>I think all guarded enume=
rations should be scoped enumerations. It doesn't make sense why someon=
e would want an unscoped enumeration that is guarded, since scoped enumerat=
ions already have stronger safety than unscoped ones. And if the scoping is=
a problem, then P1099's `using enum` ought to be able to solve it.</di=
v><div><br></div><div>Also, I think a contextual keyword would be a better =
way to invoke a guarded enumeration. It feels more like a legit language fe=
ature than a hack, and it would allow us to be a bit more/less draconian in=
what gets allowed. Plus, since scoped enumerations have to be named, addin=
g that restriction makes it grammatically possible to use contextual keywor=
ds.</div><div><br></div>Oh, and it makes it more clear that forward declara=
tions need to be consistent.<br><div><br></div><div>I think that guarded en=
umerations should not out-right forbid such conversions. The key thing to m=
e about guarded enumerations is that all allowed conversions are safe, and =
therefore, you can know for a fact that if you have an enumeration object, =
it has the value of one of its enumerators.<br></div><div><br></div><div>Co=
nversions to the underlying type can never not be safe, so there's no r=
eason to forbid them. Conversions <i>from</i> the underlying type are a dif=
ferent matter. Implicit conversions are outright forbidden, but you get tha=
t by using a scoped enumeration. There are two cases of explicit that need =
to be considered:</div><div><br></div><div>1: Explicit conversion from a co=
nstant expression. Here, the compiler can see the value and know whether or=
not it matches an enumerator. As such, explicit conversions from constant =
expressions should be allowed, but they're ill-formed if the expression=
doesn't match an enumerator. Which also means that if you forward decl=
are one, you still can't construct it.<br></div><div><br></div><div>2: =
Explicit conversion from a non-constant expression. What we need here is an=
explicit "checked conversion" function in the standard library. =
That is, `static_cast<guarded_enum>(non_constant_expression);` itself=
is outright forbidden, but `checked_enum_cast<guarded_enum>(non_cons=
tant_expression);` would be allowed. It would simply error out if the value=
is not an enumerator.</div><div><br></div><div>P0709's static exceptio=
ns would make for a great error handling mechanism for such a construct. Bu=
t because `static_cast` isn't allowed at all, only the standard library=
could actually implement `checked_enum_cast` for guarded enumerations. And=
implementing that requires building a runtime table of values for that enu=
meration, so it isn't free, which is why we don't allow `static_cas=
t` to do it.<br></div><div><br></div><div></div><div>Bikeshedding: The word=
"simple" suggests having fewer restrictions, that it's easie=
r to use or something. I say to use "guarded".<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279=
%40isocpp.org</a>.<br />
------=_Part_1228_995219156.1548607899967--
------=_Part_1227_126884055.1548607899967--
.
Author: Lawrence Emke <lawrence.emke@gmail.com>
Date: Mon, 28 Jan 2019 09:54:56 -0600
Raw View
--000000000000e3fba9058086b461
Content-Type: text/plain; charset="UTF-8"
To achieve a deeper insight into enum concept, lets look at how evolved.
Back in the mid 20th century, scoping spaces were not considered. By default
everything was global in scope within a compile unit.
Then along came libraries. where programmers could reuse someone functions
with out a complete knowledge of the underlying function. The function
required input parameters. There were only two (or three) types of value
spaces
that could be used: number (Boolean a subset of numbers) and strings. The
problem was that the user of the
library function had to know the proper input values to get the correct
results. It was recognized back then that
the GIGO (garbage in garbage out) principle existed. Therefore library
routines had to check their input values
and not blindly operate on invalid input. The situation for the programmer
was that you had to memorize the input
values or look them up every time you wanted to call the library function.
The conversion of the meaning of the
input value to a number was done by the programmer. In comes the ENUM
construct. Now instead of remembering
a number, the programmers could use a more natural label for the input, a
label that was already associated
with the function. This made it easier for the reuse of functions.
The implementation of this ENUM construct was global in score (everything
was). Well how do you implement
such a construct? Well while the "understanding" of the meaning of the
label was tied to the function being
called (that is, in math terms) its domain. to use it the definition had
to be outside of the function that used
it so that the programmer calling the function could access it and produce
a valid call.
In this way the input domain of the function became separate from the
function for which it applied.
The initial implementation had to choose an existing value space. The
simplest was the INT (integer)
space. The person creating the library routine would just list the valid
options. and the user would
use the same list. That was very good at the start. Then more
complications occurred as more and
more libraries were developed. And conflicts between functions that used
the same label would result
in either compiler errors or bad output (incorrect values or error
situations at run time).
How to solve this problem? The simple solution is to require a qualifying
name space to the label.
For the language designers it is a consistent solution with all of the
other constructs of the language.
For the programmer, it now means that they have to remember not only the
name of the label
but the name space value. And the name space value has to be different from
the name space
that contains the function. Why because of the duplicate name rule. Some
programmers
do not like this implementation (I for one). It is just another hoop to
jump through. When I say
to book "open" it has a valid response in its name space. If a doctor say
"open" to a patient,
it has a different result. The word "open" is common to the English
language, but has different
meanings depending to the subject being addressed. The meaning of the word
(i.e. label)
is taken from the input domain of the function being called. We humans do
this type of
ambiguity all of the time.
When I refer to "the old lady who swallowed a fly", I am referring to the
story of a "folk song".
I assume the reader knows the song, and understands the story and its
perspective or teaching.
When the label `static_cast<guarded_enum>(non_constant_expression);` is
used, you expect
the reader to know the underlying name space from which it is taken. In
both cases, we do
not want to include the name space from which the expression is taken. Now
to force the
programmer to include a specific name space qualifier with every function
call seems non-human.
The compiler is suppose to help the programmer write better code with less
effort. Naming
the name space (a different value) than the function seems less appealing.
If you send "open"
to a "door" object it should know what to do. If you send "open" to a
printer object it should know
what to do. The same label produces different results.
The problem is that the "input domain space" of a function is separated
from the function that uses it.
This is required because the definition is implemented as a separate object
within the calling
routines name space. All would be better if the input (parameter) name
space was defined
within the function and have the implied value for that function call.
Externalizing the parameter
name space as an ENUM object causes problems. It is not the label or the
value that is the problem.
It is that the definition because it is independent of the function that is
defining it (giving it value),
can result in incorrect values being use by a function.l It seems a natural
human desire not to be
naming the input domain space when a label is used that is addressed to an
object that defines
the label value. The guarded enums if implemented as a functions input
domain class do not have
to be qualified when calling the function. If I want to create a variable
with a function's input
parameter value, I should name the function and the input name space in the
variable's definition.
Then setting the variables value can be unqualified. Defining an INT and
giving it an ENUM value
of OPEN, leaves the door open for bad input. The term "guarded" should
imply that the ENUM
value is defined as an input value to a specific function. In this way, the
need to require the name
space specification for enum values is eliminated. Maybe the enum
definition should include the
function and parameter attributes so that the programmer does not have to
remember this qualification.
Then in defining a variable to hold an enum value can refer to the enum
construct name.
The situation is further complicated by the fact that over time the labels
in the input domain space
change. Some new ones are added and old ones are deleted. Thankfully
version control seems to be
addressing this issue.
On Sun, Jan 27, 2019 at 10:51 AM Nicol Bolas <jmckesson@gmail.com> wrote:
> Let us call these kinds of enumerations "guarded enumerations".
>
> I think all guarded enumerations should be scoped enumerations. It doesn't
> make sense why someone would want an unscoped enumeration that is guarded,
> since scoped enumerations already have stronger safety than unscoped ones.
> And if the scoping is a problem, then P1099's `using enum` ought to be able
> to solve it.
>
> Also, I think a contextual keyword would be a better way to invoke a
> guarded enumeration. It feels more like a legit language feature than a
> hack, and it would allow us to be a bit more/less draconian in what gets
> allowed. Plus, since scoped enumerations have to be named, adding that
> restriction makes it grammatically possible to use contextual keywords.
>
> Oh, and it makes it more clear that forward declarations need to be
> consistent.
>
> I think that guarded enumerations should not out-right forbid such
> conversions. The key thing to me about guarded enumerations is that all
> allowed conversions are safe, and therefore, you can know for a fact that
> if you have an enumeration object, it has the value of one of its
> enumerators.
>
> Conversions to the underlying type can never not be safe, so there's no
> reason to forbid them. Conversions *from* the underlying type are a
> different matter. Implicit conversions are outright forbidden, but you get
> that by using a scoped enumeration. There are two cases of explicit that
> need to be considered:
>
> 1: Explicit conversion from a constant expression. Here, the compiler can
> see the value and know whether or not it matches an enumerator. As such,
> explicit conversions from constant expressions should be allowed, but
> they're ill-formed if the expression doesn't match an enumerator. Which
> also means that if you forward declare one, you still can't construct it.
>
> 2: Explicit conversion from a non-constant expression. What we need here
> is an explicit "checked conversion" function in the standard library. That
> is, `static_cast<guarded_enum>(non_constant_expression);` itself is
> outright forbidden, but
> `checked_enum_cast<guarded_enum>(non_constant_expression);` would be
> allowed. It would simply error out if the value is not an enumerator.
>
> P0709's static exceptions would make for a great error handling mechanism
> for such a construct. But because `static_cast` isn't allowed at all, only
> the standard library could actually implement `checked_enum_cast` for
> guarded enumerations. And implementing that requires building a runtime
> table of values for that enumeration, so it isn't free, which is why we
> don't allow `static_cast` to do it.
>
> Bikeshedding: The word "simple" suggests having fewer restrictions, that
> it's easier to use or something. I say to use "guarded".
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO23s-8fd-fxJb1HLPaW%3Djy8C2CX9-L37UQe4znn83gx1g%40mail.gmail.com.
--000000000000e3fba9058086b461
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">To achieve a deeper insight into enum concept, lets look a=
t how evolved.=C2=A0<div>Back in the mid 20th century, scoping spaces were =
not considered. By default</div><div>everything was global in scope within =
a compile unit.=C2=A0</div><div><br></div><div>Then along came libraries. w=
here programmers could reuse someone functions with out a complete knowledg=
e of the underlying function.=C2=A0 =C2=A0The function required input param=
eters. There were only two (or three) types of value spaces</div><div>that =
could be used: number (Boolean a subset of numbers) and strings. The proble=
m was that the user of the</div><div>library function had to know the prope=
r input values to get the correct results. It was recognized back then that=
=C2=A0</div><div>the GIGO (garbage in garbage out)=C2=A0 principle existed.=
Therefore library routines had to check their input values</div><div>and n=
ot blindly operate on invalid input.=C2=A0 The situation for the programmer=
was that you had to memorize the input</div><div>values or look them up ev=
ery time you wanted to call the library function.=C2=A0 The conversion of t=
he meaning of the</div><div>input value to a number was done by the program=
mer. In comes the ENUM construct. Now instead of remembering</div><div>a nu=
mber, the programmers could use a more natural label for the input, a label=
that was already associated</div><div>with the function.=C2=A0 This made i=
t easier for the reuse of functions.=C2=A0=C2=A0</div><div><br></div><div>T=
he implementation of this ENUM construct was global in score (everything wa=
s).=C2=A0 Well how do you implement</div><div>such a construct?=C2=A0 Well =
while the "understanding" of the meaning of the label was tied to=
the function being</div><div>called (that is,=C2=A0 in math terms) its dom=
ain. to use it the definition had to be outside of the function that used</=
div><div>it so that the programmer calling the function could access it and=
produce a valid call.=C2=A0=C2=A0</div><div><br></div><div>In this way the=
input domain of the function became separate from the function for which i=
t applied.=C2=A0</div><div>The initial implementation had to choose an exis=
ting value space. The simplest was the INT (integer)</div><div>space. The p=
erson creating the library routine would just list the valid options. and t=
he user would</div><div>use the same list.=C2=A0 That was very good at the =
start. Then more complications occurred as more and</div><div>more librarie=
s were developed. And conflicts between functions that used the same label =
would result</div><div>in either compiler errors or bad output (incorrect v=
alues or error situations at run time).=C2=A0=C2=A0</div><div><br></div><di=
v>How to solve this problem?=C2=A0 The simple solution is to require a qual=
ifying name space to the label.</div><div>For the language designers it is =
a consistent solution with all of the other constructs of the language.</di=
v><div><br></div><div>For the programmer, it now means that they have to re=
member not only the name of the label</div><div>but the name space value. A=
nd the name space value has to be different from the name space</div><div>t=
hat contains the function. Why because of the duplicate name rule.=C2=A0 So=
me programmers=C2=A0</div><div>do not like this implementation (I for one).=
It is just another hoop to jump through.=C2=A0 When I say</div><div>to boo=
k "open" it has a valid response in its name space. If a doctor s=
ay "open" to a patient,</div><div>it has a different result.=C2=
=A0 The word "open" is common to the English language, but has di=
fferent</div><div>meanings depending to the subject being addressed.=C2=A0 =
The meaning of the word (i.e. label)</div><div>is taken from the input doma=
in of the function being called.=C2=A0 We humans do this type of</div><div>=
ambiguity all of the time.=C2=A0</div><div><br></div><div>When I refer to &=
quot;the old lady who swallowed a fly", I am referring to the story of=
a "folk song".</div><div>I assume the reader knows the song, and=
understands the story and its perspective or teaching.</div><div>When the =
label `static_cast<guarded_enum>(non_constant_expression);`=C2=A0 is =
used, you expect</div><div>the reader to know the underlying name space fro=
m which it is taken. In both cases, we do</div><div>not want to include the=
name space from which the expression is taken. Now to force the=C2=A0</div=
><div>programmer to include a specific name space qualifier with every func=
tion call seems non-human.</div><div>The compiler is suppose to help the pr=
ogrammer write better code with less effort. Naming=C2=A0</div><div>the nam=
e space (a different value) than the function seems less appealing. If you =
send "open"</div><div>to a "door" object it should know=
what to do. If you send "open" to a printer object it should kno=
w</div><div>what to do. The same label produces different results.=C2=A0</d=
iv><div><br></div><div>The problem is that the "input domain space&quo=
t; of a function is separated from the function that uses it.</div><div>Thi=
s is required because the definition is implemented as a separate object wi=
thin the calling</div><div>routines name space. All would be better if the =
input (parameter) name space was defined</div><div>within the function and =
have the implied value for that function call. Externalizing the parameter<=
/div><div>name space as an ENUM object causes problems. It is not the label=
or the value that is the problem.</div><div>It is that the definition beca=
use it is independent of the function that is defining it (giving it value)=
,</div><div>can result in incorrect values being use by a function.l It see=
ms a natural human desire not to be</div><div>naming the input domain space=
when a label is used that is addressed to an object that defines</div><div=
>the label value. The guarded enums if implemented as a functions input dom=
ain class do not have</div><div>to be qualified when calling the function.=
=C2=A0 If I want to create a variable with a function's input=C2=A0</di=
v><div>parameter value, I should name the function and the input name space=
in the variable's definition.</div><div>Then setting the variables val=
ue can be unqualified. Defining an INT and giving it an ENUM value</div><di=
v>of OPEN, leaves the door open for bad input. The term "guarded"=
should imply that the ENUM=C2=A0</div><div>value is defined as an input va=
lue to a specific function. In this way, the need to require the name</div>=
<div>space specification for enum values is eliminated. Maybe the enum defi=
nition should include the</div><div>function and parameter attributes so th=
at the programmer does not have to remember this qualification.</div><div>T=
hen in defining a variable to hold an enum value can refer to the enum cons=
truct name.=C2=A0</div><div><br></div><div>The situation is further complic=
ated by the fact that over time the labels in the input domain space</div><=
div>change. Some new ones are added and old ones are deleted. Thankfully ve=
rsion control seems to be</div><div>addressing this issue.=C2=A0=C2=A0</div=
><div>=C2=A0<br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr"=
class=3D"gmail_attr">On Sun, Jan 27, 2019 at 10:51 AM Nicol Bolas <<a h=
ref=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>> wrote:<br></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div=
>Let us call these kinds of enumerations "guarded enumerations".<=
br></div><div><br></div><div>I think all guarded enumerations should be sco=
ped enumerations. It doesn't make sense why someone would want an unsco=
ped enumeration that is guarded, since scoped enumerations already have str=
onger safety than unscoped ones. And if the scoping is a problem, then P109=
9's `using enum` ought to be able to solve it.</div><div><br></div><div=
>Also, I think a contextual keyword would be a better way to invoke a guard=
ed enumeration. It feels more like a legit language feature than a hack, an=
d it would allow us to be a bit more/less draconian in what gets allowed. P=
lus, since scoped enumerations have to be named, adding that restriction ma=
kes it grammatically possible to use contextual keywords.</div><div><br></d=
iv>Oh, and it makes it more clear that forward declarations need to be cons=
istent.<br><div><br></div><div>I think that guarded enumerations should not=
out-right forbid such conversions. The key thing to me about guarded enume=
rations is that all allowed conversions are safe, and therefore, you can kn=
ow for a fact that if you have an enumeration object, it has the value of o=
ne of its enumerators.<br></div><div><br></div><div>Conversions to the unde=
rlying type can never not be safe, so there's no reason to forbid them.=
Conversions <i>from</i> the underlying type are a different matter. Implic=
it conversions are outright forbidden, but you get that by using a scoped e=
numeration. There are two cases of explicit that need to be considered:</di=
v><div><br></div><div>1: Explicit conversion from a constant expression. He=
re, the compiler can see the value and know whether or not it matches an en=
umerator. As such, explicit conversions from constant expressions should be=
allowed, but they're ill-formed if the expression doesn't match an=
enumerator. Which also means that if you forward declare one, you still ca=
n't construct it.<br></div><div><br></div><div>2: Explicit conversion f=
rom a non-constant expression. What we need here is an explicit "check=
ed conversion" function in the standard library. That is, `static_cast=
<guarded_enum>(non_constant_expression);` itself is outright forbidde=
n, but `checked_enum_cast<guarded_enum>(non_constant_expression);` wo=
uld be allowed. It would simply error out if the value is not an enumerator=
..</div><div><br></div><div>P0709's static exceptions would make for a g=
reat error handling mechanism for such a construct. But because `static_cas=
t` isn't allowed at all, only the standard library could actually imple=
ment `checked_enum_cast` for guarded enumerations. And implementing that re=
quires building a runtime table of values for that enumeration, so it isn&#=
39;t free, which is why we don't allow `static_cast` to do it.<br></div=
><div><br></div><div></div><div>Bikeshedding: The word "simple" s=
uggests having fewer restrictions, that it's easier to use or something=
.. I say to use "guarded".<br></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-=
4324-97cd-fe52cbfe2279%40isocpp.org</a>.<br>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO23s-8fd-fxJb1HLPaW%3Djy8C2CX=
9-L37UQe4znn83gx1g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO23s-=
8fd-fxJb1HLPaW%3Djy8C2CX9-L37UQe4znn83gx1g%40mail.gmail.com</a>.<br />
--000000000000e3fba9058086b461--
.
Author: Lawrence Emke <lawrence.emke@gmail.com>
Date: Mon, 28 Jan 2019 10:25:23 -0600
Raw View
--000000000000c8923f0580872181
Content-Type: text/plain; charset="UTF-8"
Rather than changing the ENUM definition, how about a new construct named
FDOM.
for Function domain. It can be considered a "guarded enum" type object.
It can be used for both input and output values from a function.
Its definition includes a unique name, the association to the function
defining and implementing it. It also includes
the argument name to which the function refers, a statement of the name
space from which the values
are taken, and a lists possible label and its associated value. In this
way the user of a
function can code the label directly into a function call without a
qualifier. And if a routine
needs to create a variable with this value it can declare the variable with
the name of the FDOM
definition and set its value to one of the defined labels without a
qualifier.
This would constitute a "guarded" enum type object. And the reference to
the label would be
coded without having to include a FDOM type name. The function would
include the FDOM
definition as part of its header information. The user of the function
would not have to refer to
the FDOM name unless it is creating a variable with one of its valid
values.
On Mon, Jan 28, 2019 at 9:54 AM Lawrence Emke <lawrence.emke@gmail.com>
wrote:
> To achieve a deeper insight into enum concept, lets look at how evolved.
> Back in the mid 20th century, scoping spaces were not considered. By
> default
> everything was global in scope within a compile unit.
>
> Then along came libraries. where programmers could reuse someone functions
> with out a complete knowledge of the underlying function. The function
> required input parameters. There were only two (or three) types of value
> spaces
> that could be used: number (Boolean a subset of numbers) and strings. The
> problem was that the user of the
> library function had to know the proper input values to get the correct
> results. It was recognized back then that
> the GIGO (garbage in garbage out) principle existed. Therefore library
> routines had to check their input values
> and not blindly operate on invalid input. The situation for the
> programmer was that you had to memorize the input
> values or look them up every time you wanted to call the library
> function. The conversion of the meaning of the
> input value to a number was done by the programmer. In comes the ENUM
> construct. Now instead of remembering
> a number, the programmers could use a more natural label for the input, a
> label that was already associated
> with the function. This made it easier for the reuse of functions.
>
> The implementation of this ENUM construct was global in score (everything
> was). Well how do you implement
> such a construct? Well while the "understanding" of the meaning of the
> label was tied to the function being
> called (that is, in math terms) its domain. to use it the definition had
> to be outside of the function that used
> it so that the programmer calling the function could access it and produce
> a valid call.
>
> In this way the input domain of the function became separate from the
> function for which it applied.
> The initial implementation had to choose an existing value space. The
> simplest was the INT (integer)
> space. The person creating the library routine would just list the valid
> options. and the user would
> use the same list. That was very good at the start. Then more
> complications occurred as more and
> more libraries were developed. And conflicts between functions that used
> the same label would result
> in either compiler errors or bad output (incorrect values or error
> situations at run time).
>
> How to solve this problem? The simple solution is to require a qualifying
> name space to the label.
> For the language designers it is a consistent solution with all of the
> other constructs of the language.
>
> For the programmer, it now means that they have to remember not only the
> name of the label
> but the name space value. And the name space value has to be different
> from the name space
> that contains the function. Why because of the duplicate name rule. Some
> programmers
> do not like this implementation (I for one). It is just another hoop to
> jump through. When I say
> to book "open" it has a valid response in its name space. If a doctor say
> "open" to a patient,
> it has a different result. The word "open" is common to the English
> language, but has different
> meanings depending to the subject being addressed. The meaning of the
> word (i.e. label)
> is taken from the input domain of the function being called. We humans do
> this type of
> ambiguity all of the time.
>
> When I refer to "the old lady who swallowed a fly", I am referring to the
> story of a "folk song".
> I assume the reader knows the song, and understands the story and its
> perspective or teaching.
> When the label `static_cast<guarded_enum>(non_constant_expression);` is
> used, you expect
> the reader to know the underlying name space from which it is taken. In
> both cases, we do
> not want to include the name space from which the expression is taken. Now
> to force the
> programmer to include a specific name space qualifier with every function
> call seems non-human.
> The compiler is suppose to help the programmer write better code with less
> effort. Naming
> the name space (a different value) than the function seems less appealing.
> If you send "open"
> to a "door" object it should know what to do. If you send "open" to a
> printer object it should know
> what to do. The same label produces different results.
>
> The problem is that the "input domain space" of a function is separated
> from the function that uses it.
> This is required because the definition is implemented as a separate
> object within the calling
> routines name space. All would be better if the input (parameter) name
> space was defined
> within the function and have the implied value for that function call.
> Externalizing the parameter
> name space as an ENUM object causes problems. It is not the label or the
> value that is the problem.
> It is that the definition because it is independent of the function that
> is defining it (giving it value),
> can result in incorrect values being use by a function.l It seems a
> natural human desire not to be
> naming the input domain space when a label is used that is addressed to an
> object that defines
> the label value. The guarded enums if implemented as a functions input
> domain class do not have
> to be qualified when calling the function. If I want to create a variable
> with a function's input
> parameter value, I should name the function and the input name space in
> the variable's definition.
> Then setting the variables value can be unqualified. Defining an INT and
> giving it an ENUM value
> of OPEN, leaves the door open for bad input. The term "guarded" should
> imply that the ENUM
> value is defined as an input value to a specific function. In this way,
> the need to require the name
> space specification for enum values is eliminated. Maybe the enum
> definition should include the
> function and parameter attributes so that the programmer does not have to
> remember this qualification.
> Then in defining a variable to hold an enum value can refer to the enum
> construct name.
>
> The situation is further complicated by the fact that over time the labels
> in the input domain space
> change. Some new ones are added and old ones are deleted. Thankfully
> version control seems to be
> addressing this issue.
>
>
> On Sun, Jan 27, 2019 at 10:51 AM Nicol Bolas <jmckesson@gmail.com> wrote:
>
>> Let us call these kinds of enumerations "guarded enumerations".
>>
>> I think all guarded enumerations should be scoped enumerations. It
>> doesn't make sense why someone would want an unscoped enumeration that is
>> guarded, since scoped enumerations already have stronger safety than
>> unscoped ones. And if the scoping is a problem, then P1099's `using enum`
>> ought to be able to solve it.
>>
>> Also, I think a contextual keyword would be a better way to invoke a
>> guarded enumeration. It feels more like a legit language feature than a
>> hack, and it would allow us to be a bit more/less draconian in what gets
>> allowed. Plus, since scoped enumerations have to be named, adding that
>> restriction makes it grammatically possible to use contextual keywords.
>>
>> Oh, and it makes it more clear that forward declarations need to be
>> consistent.
>>
>> I think that guarded enumerations should not out-right forbid such
>> conversions. The key thing to me about guarded enumerations is that all
>> allowed conversions are safe, and therefore, you can know for a fact that
>> if you have an enumeration object, it has the value of one of its
>> enumerators.
>>
>> Conversions to the underlying type can never not be safe, so there's no
>> reason to forbid them. Conversions *from* the underlying type are a
>> different matter. Implicit conversions are outright forbidden, but you get
>> that by using a scoped enumeration. There are two cases of explicit that
>> need to be considered:
>>
>> 1: Explicit conversion from a constant expression. Here, the compiler can
>> see the value and know whether or not it matches an enumerator. As such,
>> explicit conversions from constant expressions should be allowed, but
>> they're ill-formed if the expression doesn't match an enumerator. Which
>> also means that if you forward declare one, you still can't construct it.
>>
>> 2: Explicit conversion from a non-constant expression. What we need here
>> is an explicit "checked conversion" function in the standard library. That
>> is, `static_cast<guarded_enum>(non_constant_expression);` itself is
>> outright forbidden, but
>> `checked_enum_cast<guarded_enum>(non_constant_expression);` would be
>> allowed. It would simply error out if the value is not an enumerator.
>>
>> P0709's static exceptions would make for a great error handling mechanism
>> for such a construct. But because `static_cast` isn't allowed at all, only
>> the standard library could actually implement `checked_enum_cast` for
>> guarded enumerations. And implementing that requires building a runtime
>> table of values for that enumeration, so it isn't free, which is why we
>> don't allow `static_cast` to do it.
>>
>> Bikeshedding: The word "simple" suggests having fewer restrictions, that
>> it's easier to use or something. I say to use "guarded".
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO1X5zt94yppdmV36ZcaUrHT1ubGhTv53UbKf9w%2B3yWMww%40mail.gmail.com.
--000000000000c8923f0580872181
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Rather than changing the ENUM definition, how about a new =
construct named FDOM.<div>for Function domain. It can be considered a "=
;guarded enum" type object.=C2=A0</div><div>It can be used for both in=
put and output values from a function.</div><div><br></div><div>Its definit=
ion includes a unique name, the association to the function defining and im=
plementing it. It also includes</div><div>the argument name to which the fu=
nction refers, a statement of the name space from which the values</div><di=
v>are taken, and a lists possible label and its associated value.=C2=A0 In =
this way the user of a=C2=A0</div><div>function can code the label directly=
into a function call without a qualifier. And if a routine</div><div>needs=
to create a variable with this value it can declare the variable with the =
name of the FDOM</div><div>definition and set its value to one of the defin=
ed labels without a qualifier.=C2=A0=C2=A0</div><div><br></div><div>This wo=
uld constitute a "guarded" enum type object. And the reference to=
the label would be</div><div>coded without having to include a FDOM type n=
ame.=C2=A0 The function would include the FDOM</div><div>definition as part=
of its header information.=C2=A0 The user of the function would not have t=
o refer to</div><div>the FDOM name unless it is creating a variable with on=
e of its valid values.=C2=A0</div></div><br><div class=3D"gmail_quote"><div=
dir=3D"ltr" class=3D"gmail_attr">On Mon, Jan 28, 2019 at 9:54 AM Lawrence =
Emke <<a href=3D"mailto:lawrence.emke@gmail.com">lawrence.emke@gmail.com=
</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr">To achieve a deeper insight into enum concept, lets look a=
t how evolved.=C2=A0<div>Back in the mid 20th century, scoping spaces were =
not considered. By default</div><div>everything was global in scope within =
a compile unit.=C2=A0</div><div><br></div><div>Then along came libraries. w=
here programmers could reuse someone functions with out a complete knowledg=
e of the underlying function.=C2=A0 =C2=A0The function required input param=
eters. There were only two (or three) types of value spaces</div><div>that =
could be used: number (Boolean a subset of numbers) and strings. The proble=
m was that the user of the</div><div>library function had to know the prope=
r input values to get the correct results. It was recognized back then that=
=C2=A0</div><div>the GIGO (garbage in garbage out)=C2=A0 principle existed.=
Therefore library routines had to check their input values</div><div>and n=
ot blindly operate on invalid input.=C2=A0 The situation for the programmer=
was that you had to memorize the input</div><div>values or look them up ev=
ery time you wanted to call the library function.=C2=A0 The conversion of t=
he meaning of the</div><div>input value to a number was done by the program=
mer. In comes the ENUM construct. Now instead of remembering</div><div>a nu=
mber, the programmers could use a more natural label for the input, a label=
that was already associated</div><div>with the function.=C2=A0 This made i=
t easier for the reuse of functions.=C2=A0=C2=A0</div><div><br></div><div>T=
he implementation of this ENUM construct was global in score (everything wa=
s).=C2=A0 Well how do you implement</div><div>such a construct?=C2=A0 Well =
while the "understanding" of the meaning of the label was tied to=
the function being</div><div>called (that is,=C2=A0 in math terms) its dom=
ain. to use it the definition had to be outside of the function that used</=
div><div>it so that the programmer calling the function could access it and=
produce a valid call.=C2=A0=C2=A0</div><div><br></div><div>In this way the=
input domain of the function became separate from the function for which i=
t applied.=C2=A0</div><div>The initial implementation had to choose an exis=
ting value space. The simplest was the INT (integer)</div><div>space. The p=
erson creating the library routine would just list the valid options. and t=
he user would</div><div>use the same list.=C2=A0 That was very good at the =
start. Then more complications occurred as more and</div><div>more librarie=
s were developed. And conflicts between functions that used the same label =
would result</div><div>in either compiler errors or bad output (incorrect v=
alues or error situations at run time).=C2=A0=C2=A0</div><div><br></div><di=
v>How to solve this problem?=C2=A0 The simple solution is to require a qual=
ifying name space to the label.</div><div>For the language designers it is =
a consistent solution with all of the other constructs of the language.</di=
v><div><br></div><div>For the programmer, it now means that they have to re=
member not only the name of the label</div><div>but the name space value. A=
nd the name space value has to be different from the name space</div><div>t=
hat contains the function. Why because of the duplicate name rule.=C2=A0 So=
me programmers=C2=A0</div><div>do not like this implementation (I for one).=
It is just another hoop to jump through.=C2=A0 When I say</div><div>to boo=
k "open" it has a valid response in its name space. If a doctor s=
ay "open" to a patient,</div><div>it has a different result.=C2=
=A0 The word "open" is common to the English language, but has di=
fferent</div><div>meanings depending to the subject being addressed.=C2=A0 =
The meaning of the word (i.e. label)</div><div>is taken from the input doma=
in of the function being called.=C2=A0 We humans do this type of</div><div>=
ambiguity all of the time.=C2=A0</div><div><br></div><div>When I refer to &=
quot;the old lady who swallowed a fly", I am referring to the story of=
a "folk song".</div><div>I assume the reader knows the song, and=
understands the story and its perspective or teaching.</div><div>When the =
label `static_cast<guarded_enum>(non_constant_expression);`=C2=A0 is =
used, you expect</div><div>the reader to know the underlying name space fro=
m which it is taken. In both cases, we do</div><div>not want to include the=
name space from which the expression is taken. Now to force the=C2=A0</div=
><div>programmer to include a specific name space qualifier with every func=
tion call seems non-human.</div><div>The compiler is suppose to help the pr=
ogrammer write better code with less effort. Naming=C2=A0</div><div>the nam=
e space (a different value) than the function seems less appealing. If you =
send "open"</div><div>to a "door" object it should know=
what to do. If you send "open" to a printer object it should kno=
w</div><div>what to do. The same label produces different results.=C2=A0</d=
iv><div><br></div><div>The problem is that the "input domain space&quo=
t; of a function is separated from the function that uses it.</div><div>Thi=
s is required because the definition is implemented as a separate object wi=
thin the calling</div><div>routines name space. All would be better if the =
input (parameter) name space was defined</div><div>within the function and =
have the implied value for that function call. Externalizing the parameter<=
/div><div>name space as an ENUM object causes problems. It is not the label=
or the value that is the problem.</div><div>It is that the definition beca=
use it is independent of the function that is defining it (giving it value)=
,</div><div>can result in incorrect values being use by a function.l It see=
ms a natural human desire not to be</div><div>naming the input domain space=
when a label is used that is addressed to an object that defines</div><div=
>the label value. The guarded enums if implemented as a functions input dom=
ain class do not have</div><div>to be qualified when calling the function.=
=C2=A0 If I want to create a variable with a function's input=C2=A0</di=
v><div>parameter value, I should name the function and the input name space=
in the variable's definition.</div><div>Then setting the variables val=
ue can be unqualified. Defining an INT and giving it an ENUM value</div><di=
v>of OPEN, leaves the door open for bad input. The term "guarded"=
should imply that the ENUM=C2=A0</div><div>value is defined as an input va=
lue to a specific function. In this way, the need to require the name</div>=
<div>space specification for enum values is eliminated. Maybe the enum defi=
nition should include the</div><div>function and parameter attributes so th=
at the programmer does not have to remember this qualification.</div><div>T=
hen in defining a variable to hold an enum value can refer to the enum cons=
truct name.=C2=A0</div><div><br></div><div>The situation is further complic=
ated by the fact that over time the labels in the input domain space</div><=
div>change. Some new ones are added and old ones are deleted. Thankfully ve=
rsion control seems to be</div><div>addressing this issue.=C2=A0=C2=A0</div=
><div>=C2=A0<br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr"=
class=3D"gmail-m_-1166841915857271072gmail_attr">On Sun, Jan 27, 2019 at 1=
0:51 AM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com" target=3D"_b=
lank">jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex"><div dir=3D"ltr"><div>Let us call these kinds of e=
numerations "guarded enumerations".<br></div><div><br></div><div>=
I think all guarded enumerations should be scoped enumerations. It doesn=
9;t make sense why someone would want an unscoped enumeration that is guard=
ed, since scoped enumerations already have stronger safety than unscoped on=
es. And if the scoping is a problem, then P1099's `using enum` ought to=
be able to solve it.</div><div><br></div><div>Also, I think a contextual k=
eyword would be a better way to invoke a guarded enumeration. It feels more=
like a legit language feature than a hack, and it would allow us to be a b=
it more/less draconian in what gets allowed. Plus, since scoped enumeration=
s have to be named, adding that restriction makes it grammatically possible=
to use contextual keywords.</div><div><br></div>Oh, and it makes it more c=
lear that forward declarations need to be consistent.<br><div><br></div><di=
v>I think that guarded enumerations should not out-right forbid such conver=
sions. The key thing to me about guarded enumerations is that all allowed c=
onversions are safe, and therefore, you can know for a fact that if you hav=
e an enumeration object, it has the value of one of its enumerators.<br></d=
iv><div><br></div><div>Conversions to the underlying type can never not be =
safe, so there's no reason to forbid them. Conversions <i>from</i> the =
underlying type are a different matter. Implicit conversions are outright f=
orbidden, but you get that by using a scoped enumeration. There are two cas=
es of explicit that need to be considered:</div><div><br></div><div>1: Expl=
icit conversion from a constant expression. Here, the compiler can see the =
value and know whether or not it matches an enumerator. As such, explicit c=
onversions from constant expressions should be allowed, but they're ill=
-formed if the expression doesn't match an enumerator. Which also means=
that if you forward declare one, you still can't construct it.<br></di=
v><div><br></div><div>2: Explicit conversion from a non-constant expression=
.. What we need here is an explicit "checked conversion" function =
in the standard library. That is, `static_cast<guarded_enum>(non_cons=
tant_expression);` itself is outright forbidden, but `checked_enum_cast<=
guarded_enum>(non_constant_expression);` would be allowed. It would simp=
ly error out if the value is not an enumerator.</div><div><br></div><div>P0=
709's static exceptions would make for a great error handling mechanism=
for such a construct. But because `static_cast` isn't allowed at all, =
only the standard library could actually implement `checked_enum_cast` for =
guarded enumerations. And implementing that requires building a runtime tab=
le of values for that enumeration, so it isn't free, which is why we do=
n't allow `static_cast` to do it.<br></div><div><br></div><div></div><d=
iv>Bikeshedding: The word "simple" suggests having fewer restrict=
ions, that it's easier to use or something. I say to use "guarded&=
quot;.<br></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-4324-97cd-fe52cbfe2279%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9d8d3837-a740-=
4324-97cd-fe52cbfe2279%40isocpp.org</a>.<br>
</blockquote></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO1X5zt94yppdmV36ZcaUrHT1ubGhT=
v53UbKf9w%2B3yWMww%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BAqvO1X5z=
t94yppdmV36ZcaUrHT1ubGhTv53UbKf9w%2B3yWMww%40mail.gmail.com</a>.<br />
--000000000000c8923f0580872181--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 28 Jan 2019 11:55:02 -0500
Raw View
On 27/01/2019 09.57, Andrew Tomazos wrote:
> An enumeration type definition marked with the attribute [[simple]]
> declares the enumeration type as a *simple* enumeration type.
>
> A simple enumeration type E has the following constaints:
>
> - objects of type E are not default-constructible (must have an initializer
> of type E)
I've always wished enumerations could have methods, like classes. If
they did, we could write:
enum class Foo
{
Foo() = delete;
};
This would also make it possible to supply a default "ctor" to set the
enum to any value.
> - objects of type E are not convertible to their underlying type, and
> neither visa-versa
This seems... dangerous. IMHO having an escape hatch is good. Preventing
*implicit* conversion is fine, but strongly-typed enumerations already
have that feature.
> - an object of type E may only hold a value that is equal to (at least) one
> of its enumerators.
This feels like something that would be better handled by contracts.
That would give you control over where and how enforcement happens.
The other option, I think, is to wrap the enum in a class and have the
assignment operators verify this. Come to think of it, designing a
template class with these features (using reflection) should be
plausible. Such a class might be a candidate for standardization.
--
Matthew
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20204e61-c4aa-c6d2-16be-2bf251e75fc6%40gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 28 Jan 2019 08:55:32 -0800 (PST)
Raw View
------=_Part_1577_167533981.1548694532697
Content-Type: multipart/alternative;
boundary="----=_Part_1578_2122203260.1548694532697"
------=_Part_1578_2122203260.1548694532697
Content-Type: text/plain; charset="UTF-8"
I'm afraid I don't understand what this analysis has to do with the problem
outlined by the OP. Basically, your post boils down to "we shouldn't have
to specify the enumeration name if it can be derived from the context". OK,
fine, maybe we should do that.
But what the OP is talking about has nothing to do with that. What the OP
wants is to be able to declare an enumeration where there is a stronger
guarantee that any value of that enumeration type will have a valid value
for that enumeration. In more C++ object model terms, what the OP wants is
to make it so that the only legal values for the enumeration are one of the
values of its enumerators.
The OP wants to stop people from casting integers to the enumeration (or at
least, stop it from working if that cast doesn't yield a valid enumerator).
I don't know what that has to do with enumerators as being part of a
function's domain or the other things you discuss.
Also, I take issue with your classification of naming enumerations as being
for the purpose of avoiding name conflicts. That's not why we do it (that's
why we have scoped enums, but named enums happened long before that). We
name enumerations so that we can have strong typing. So that the
enumerators can have a specific type, which can be stored and applied as
needed to things that deal with types.
Enumerations aren't part of a function's domain. They are *values*, and
those values must be able to exist independently of any function
definition. Otherwise, you wouldn't be able to store them in types.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0e2ae043-ccbc-4853-8bf9-0d1644dd4e3a%40isocpp.org.
------=_Part_1578_2122203260.1548694532697
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div></div><div>I'm afraid I don't understand what=
this analysis has to do with the problem outlined by the OP. Basically, yo=
ur post boils down to "we shouldn't have to specify the enumeratio=
n name if it can be derived from the context". OK, fine, maybe we shou=
ld do that.</div><div><br></div><div>But what the OP is talking about has n=
othing to do with that. What the OP wants is to be able to declare an enume=
ration where there is a stronger guarantee that any value of that enumerati=
on type will have a valid value for that enumeration. In more C++ object mo=
del terms, what the OP wants is to make it so that the only legal values fo=
r the enumeration are one of the values of its enumerators.</div><div><br><=
/div><div>The OP wants to stop people from casting integers to the enumerat=
ion (or at least, stop it from working if that cast doesn't yield a val=
id enumerator). I don't know what that has to do with enumerators as be=
ing part of a function's domain or the other things you discuss.</div><=
div><br></div><div>Also, I take issue with your classification of naming en=
umerations as being for the purpose of avoiding name conflicts. That's =
not why we do it (that's why we have scoped enums, but named enums happ=
ened long before that). We name enumerations so that we can have strong typ=
ing. So that the enumerators can have a specific type, which can be stored =
and applied as needed to things that deal with types.</div><div><br></div><=
div>Enumerations aren't part of a function's domain. They are <i>va=
lues</i>, and those values must be able to exist independently of any funct=
ion definition. Otherwise, you wouldn't be able to store them in types.=
<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0e2ae043-ccbc-4853-8bf9-0d1644dd4e3a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0e2ae043-ccbc-4853-8bf9-0d1644dd4e3a=
%40isocpp.org</a>.<br />
------=_Part_1578_2122203260.1548694532697--
------=_Part_1577_167533981.1548694532697--
.
Author: j c <james.a.cooper@gmail.com>
Date: Mon, 28 Jan 2019 17:59:55 +0000
Raw View
--0000000000006d787305808872f4
Content-Type: text/plain; charset="UTF-8"
On Mon, Jan 28, 2019 at 4:55 PM Nicol Bolas <jmckesson@gmail.com> wrote:
> I'm afraid I don't understand what this analysis has to do with the
> problem outlined by the OP. Basically, your post boils down to "we
> shouldn't have to specify the enumeration name if it can be derived from
> the context". OK, fine, maybe we should do that.
>
> But what the OP is talking about has nothing to do with that. What the OP
> wants is to be able to declare an enumeration where there is a stronger
> guarantee that any value of that enumeration type will have a valid value
> for that enumeration. In more C++ object model terms, what the OP wants is
> to make it so that the only legal values for the enumeration are one of the
> values of its enumerators.
>
> The OP wants to stop people from casting integers to the enumeration (or
> at least, stop it from working if that cast doesn't yield a valid
> enumerator). I don't know what that has to do with enumerators as being
> part of a function's domain or the other things you discuss.
>
>
How would this work with enums that represent bits in a value? Combinations
of the bits could be valid yet not necessarily be listed in the enum
definition itself.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCC7b-fvXm-azbnR%3DQ0-Ba1UCRV6P81k6Z9GQMPSwzKs9w%40mail.gmail.com.
--0000000000006d787305808872f4
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr"><br></div><br><div class=3D"gmail_quote">=
<div dir=3D"ltr" class=3D"gmail_attr">On Mon, Jan 28, 2019 at 4:55 PM Nicol=
Bolas <<a href=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&g=
t; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div d=
ir=3D"ltr"><div></div><div>I'm afraid I don't understand what this =
analysis has to do with the problem outlined by the OP. Basically, your pos=
t boils down to "we shouldn't have to specify the enumeration name=
if it can be derived from the context". OK, fine, maybe we should do =
that.</div><div><br></div><div>But what the OP is talking about has nothing=
to do with that. What the OP wants is to be able to declare an enumeration=
where there is a stronger guarantee that any value of that enumeration typ=
e will have a valid value for that enumeration. In more C++ object model te=
rms, what the OP wants is to make it so that the only legal values for the =
enumeration are one of the values of its enumerators.</div><div><br></div><=
div>The OP wants to stop people from casting integers to the enumeration (o=
r at least, stop it from working if that cast doesn't yield a valid enu=
merator). I don't know what that has to do with enumerators as being pa=
rt of a function's domain or the other things you discuss.</div><br></d=
iv></blockquote><div><br></div><div>How would this work with enums that rep=
resent bits in a value? Combinations of the bits could be valid yet not nec=
essarily be listed in the enum definition itself. <br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFQaeCC7b-fvXm-azbnR%3DQ0-Ba1UCRV6P8=
1k6Z9GQMPSwzKs9w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCC7b-fvXm=
-azbnR%3DQ0-Ba1UCRV6P81k6Z9GQMPSwzKs9w%40mail.gmail.com</a>.<br />
--0000000000006d787305808872f4--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Tue, 29 Jan 2019 04:21:09 +1000
Raw View
--00000000000078f3b4058088be0c
Content-Type: text/plain; charset="UTF-8"
On Tue, Jan 29, 2019 at 4:00 AM j c <james.a.cooper@gmail.com> wrote:
> On Mon, Jan 28, 2019 at 4:55 PM Nicol Bolas <jmckesson@gmail.com> wrote:
>
>> I'm afraid I don't understand what this analysis has to do with the
>> problem outlined by the OP. Basically, your post boils down to "we
>> shouldn't have to specify the enumeration name if it can be derived from
>> the context". OK, fine, maybe we should do that.
>>
>> But what the OP is talking about has nothing to do with that. What the OP
>> wants is to be able to declare an enumeration where there is a stronger
>> guarantee that any value of that enumeration type will have a valid value
>> for that enumeration. In more C++ object model terms, what the OP wants is
>> to make it so that the only legal values for the enumeration are one of the
>> values of its enumerators.
>>
>> The OP wants to stop people from casting integers to the enumeration (or
>> at least, stop it from working if that cast doesn't yield a valid
>> enumerator). I don't know what that has to do with enumerators as being
>> part of a function's domain or the other things you discuss.
>>
>>
> How would this work with enums that represent bits in a value?
> Combinations of the bits could be valid yet not necessarily be listed in
> the enum definition itself.
>
It, intentionally, wouldn't work with that use case (bitmasks). If that is
how you are using a particular enumeration type, you wouldn't declare the
enumeration type as [[simple]].
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHKhMGXyH6YXrWAG5v41L%2BGYNAtWe-%2BB%2Bhp0eo53%2BNToQA%40mail.gmail.com.
--00000000000078f3b4058088be0c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">On Tue, Jan 29, 2019 at 4:00 AM j c <<=
a href=3D"mailto:james.a.cooper@gmail.com">james.a.cooper@gmail.com</a>>=
wrote:<br></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr">On Mon, Jan 28, 2019 a=
t 4:55 PM Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com" target=3D"=
_blank">jmckesson@gmail.com</a>> wrote:<br></div><div class=3D"gmail_quo=
te"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div=
></div><div>I'm afraid I don't understand what this analysis has to=
do with the problem outlined by the OP. Basically, your post boils down to=
"we shouldn't have to specify the enumeration name if it can be d=
erived from the context". OK, fine, maybe we should do that.</div><div=
><br></div><div>But what the OP is talking about has nothing to do with tha=
t. What the OP wants is to be able to declare an enumeration where there is=
a stronger guarantee that any value of that enumeration type will have a v=
alid value for that enumeration. In more C++ object model terms, what the O=
P wants is to make it so that the only legal values for the enumeration are=
one of the values of its enumerators.</div><div><br></div><div>The OP want=
s to stop people from casting integers to the enumeration (or at least, sto=
p it from working if that cast doesn't yield a valid enumerator). I don=
't know what that has to do with enumerators as being part of a functio=
n's domain or the other things you discuss.</div><br></div></blockquote=
><div><br></div><div>How would this work with enums that represent bits in =
a value? Combinations of the bits could be valid yet not necessarily be lis=
ted in the enum definition itself.=C2=A0</div></div></div></blockquote><div=
><br></div><div>It, intentionally, wouldn't work with that use case (bi=
tmasks).=C2=A0 If that is how you are using a particular enumeration type, =
you wouldn't declare the enumeration type as [[simple]].</div><div><br>=
</div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHKhMGXyH6YXrWAG5v41L%2BGYNAtW=
e-%2BB%2Bhp0eo53%2BNToQA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4=
KHKhMGXyH6YXrWAG5v41L%2BGYNAtWe-%2BB%2Bhp0eo53%2BNToQA%40mail.gmail.com</a>=
..<br />
--00000000000078f3b4058088be0c--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 29 Jan 2019 11:46:07 -0800 (PST)
Raw View
------=_Part_2274_1696248537.1548791167907
Content-Type: multipart/alternative;
boundary="----=_Part_2275_798958509.1548791167907"
------=_Part_2275_798958509.1548791167907
Content-Type: text/plain; charset="UTF-8"
On Sunday, January 27, 2019 at 8:57:38 AM UTC-6, Andrew Tomazos wrote:
>
> *Informal Specification*
>
> An enumeration type definition marked with the attribute [[simple]]
> declares the enumeration type as a *simple* enumeration type.
>
> A simple enumeration type E has the following constaints:
>
> - objects of type E are not default-constructible (must have an
> initializer of type E)
> - objects of type E are not convertible to their underlying type, and
> neither visa-versa
> - an object of type E may only hold a value that is equal to (at least)
> one of its enumerators.
>
>
Sounds like a variant
struct A { };
struct B { };
struct C { };
using E = variant<A,B,C>;
That satisfies all of your requirements.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/23347641-b39f-4a76-ac34-abc56f97e7c9%40isocpp.org.
------=_Part_2275_798958509.1548791167907
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, January 27, 2019 at 8:57:38 AM UTC-6, Andrew To=
mazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><b>Informal Specification</b><br></div><div><br></div>An enumeration ty=
pe definition marked with the attribute [[simple]] declares the enumeration=
type as a <i>simple</i> enumeration type.<div><br></div><div>A simple enum=
eration type E has the following constaints:</div><div><br></div><div>- obj=
ects of type E are not default-constructible (must have an initializer of t=
ype E)<br></div><div>- objects of type E are not convertible to their under=
lying type, and neither visa-versa<br></div><div>- an object of type E may =
only hold a value that is equal to (at least) one of its enumerators.<br></=
div><div><br></div></div></blockquote><div><br></div><div>Sounds like a var=
iant</div><div><br></div><div><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; overflow-wrap: break-word;"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><font color=3D"#660066"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> A </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
B </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> C </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> E </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"> variant</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">A</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">B</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">C</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
;;</span></font></div></code></div><br>That satisfies all of your requireme=
nts.=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/23347641-b39f-4a76-ac34-abc56f97e7c9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/23347641-b39f-4a76-ac34-abc56f97e7c9=
%40isocpp.org</a>.<br />
------=_Part_2275_798958509.1548791167907--
------=_Part_2274_1696248537.1548791167907--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 29 Jan 2019 21:48:22 +0200
Raw View
On Tue, 29 Jan 2019 at 21:46, Barry Revzin <barry.revzin@gmail.com> wrote:
>
> On Sunday, January 27, 2019 at 8:57:38 AM UTC-6, Andrew Tomazos wrote:
>>
>> Informal Specification
>>
>> An enumeration type definition marked with the attribute [[simple]] declares the enumeration type as a simple enumeration type.
>>
>> A simple enumeration type E has the following constaints:
>>
>> - objects of type E are not default-constructible (must have an initializer of type E)
>> - objects of type E are not convertible to their underlying type, and neither visa-versa
>> - an object of type E may only hold a value that is equal to (at least) one of its enumerators.
>>
>
> Sounds like a variant
>
> struct A { };
> struct B { };
> struct C { };
> using E = variant<A,B,C>;
>
> That satisfies all of your requirements.
Except that it's default-constructible.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbyT_qWUQ5v53D1rxrGf9zvFfQH2yUfVFBLo9tKpTno8A%40mail.gmail.com.
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Wed, 30 Jan 2019 16:41:44 -0800 (PST)
Raw View
------=_Part_2960_595639832.1548895304325
Content-Type: multipart/alternative;
boundary="----=_Part_2961_2144390526.1548895304325"
------=_Part_2961_2144390526.1548895304325
Content-Type: text/plain; charset="UTF-8"
On Tuesday, January 29, 2019 at 1:48:35 PM UTC-6, Ville Voutilainen wrote:
>
> On Tue, 29 Jan 2019 at 21:46, Barry Revzin <barry....@gmail.com
> <javascript:>> wrote:
> >
> > On Sunday, January 27, 2019 at 8:57:38 AM UTC-6, Andrew Tomazos wrote:
> >>
> >> Informal Specification
> >>
> >> An enumeration type definition marked with the attribute [[simple]]
> declares the enumeration type as a simple enumeration type.
> >>
> >> A simple enumeration type E has the following constaints:
> >>
> >> - objects of type E are not default-constructible (must have an
> initializer of type E)
> >> - objects of type E are not convertible to their underlying type, and
> neither visa-versa
> >> - an object of type E may only hold a value that is equal to (at least)
> one of its enumerators.
> >>
> >
> > Sounds like a variant
> >
> > struct A { };
> > struct B { };
> > struct C { };
> > using E = variant<A,B,C>;
> >
> > That satisfies all of your requirements.
>
> Except that it's default-constructible.
>
I am just going to keep sending this reply on repeat until Google finally
lets me through....
Yes, you're right. Also OP didn't want implicit construction. But yeah, you
can tweak a variant to allow that. This probably isn't 100% either, but I
think it's sufficiently in the right direction:
template <typename... Ts>
struct simple_enum : variant<Ts...>
{
template <typename U> requires (Same<U,Ts> || ...)
constexpr explicit simple_enum(U u) : variant<Ts...>(u) { }
simple_enum(simple_enum const&) = default;
simple_enum& operator=(simple_enum const&) = default;
};
using E = simple_enum<A, B, C>;
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cf73dd2c-bb16-4f55-a01e-f020f1d1793d%40isocpp.org.
------=_Part_2961_2144390526.1548895304325
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, January 29, 2019 at 1:48:35 PM UTC-6, =
Ville Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Tue=
, 29 Jan 2019 at 21:46, Barry Revzin <<a href=3D"javascript:" target=3D"=
_blank" gdf-obfuscated-mailto=3D"f772uERhFwAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D=
'javascript:';return true;">barry....@gmail.com</a>> wrote:
<br>>
<br>> On Sunday, January 27, 2019 at 8:57:38 AM UTC-6, Andrew Tomazos wr=
ote:
<br>>>
<br>>> Informal Specification
<br>>>
<br>>> An enumeration type definition marked with the attribute [[sim=
ple]] declares the enumeration type as a simple enumeration type.
<br>>>
<br>>> A simple enumeration type E has the following constaints:
<br>>>
<br>>> - objects of type E are not default-constructible (must have a=
n initializer of type E)
<br>>> - objects of type E are not convertible to their underlying ty=
pe, and neither visa-versa
<br>>> - an object of type E may only hold a value that is equal to (=
at least) one of its enumerators.
<br>>>
<br>>
<br>> Sounds like a variant
<br>>
<br>> struct A { };
<br>> struct B { };
<br>> struct C { };
<br>> using E =3D variant<A,B,C>;
<br>>
<br>> That satisfies all of your requirements.
<br>
<br>Except that it's default-constructible.
<br></blockquote><div><br></div><div>I am just going to keep sending this r=
eply on repeat until Google finally lets me through....</div><div><br></div=
><div>Yes, you're right. Also OP didn't want implicit construction.=
But yeah, you can tweak a variant to allow that. This probably isn't 1=
00% either, but I think it's sufficiently in the right direction:</div>=
<div><br></div><div><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; overflow-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><font color=3D"#660066"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Ts</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> simple_enum </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> variant</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Ts</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">...></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> requir=
es </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Same</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">U</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Ts</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: #660;" class=3D"styled-by-prettify">...)</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">explicit</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> simple_enum</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">U u</span><span style=3D"col=
or: #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"style=
d-by-prettify"> variant</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Ts</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
...>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">u</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n 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"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br><br>=C2=A0 =C2=A0 simple_enum</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">simple_enum </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&)</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">default</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
=C2=A0 </span></font><span style=3D"color: rgb(0, 0, 0);"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">simple_enum</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: #008;" =
class=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">=3D(</span></span><span style=3D"color: rgb(0, 0=
, 0);"><span style=3D"color: #000;" class=3D"styled-by-prettify">simple_enu=
m </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&)</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">;</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">using</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> E </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> simp=
le_enum</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">A</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> B</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><font color=3D"#000000"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">>;</span></font></div></c=
ode></div><br>=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cf73dd2c-bb16-4f55-a01e-f020f1d1793d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cf73dd2c-bb16-4f55-a01e-f020f1d1793d=
%40isocpp.org</a>.<br />
------=_Part_2961_2144390526.1548895304325--
------=_Part_2960_595639832.1548895304325--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 31 Jan 2019 07:01:01 -0800 (PST)
Raw View
------=_Part_3181_395227351.1548946861113
Content-Type: multipart/alternative;
boundary="----=_Part_3182_1973445714.1548946861113"
------=_Part_3182_1973445714.1548946861113
Content-Type: text/plain; charset="UTF-8"
While that works to forbid default constructibility, it doesn't really
change the fact that it is still very much unlike an enumeration, even a
limited one as described by the OP.
`A` is a type, not an enumerator. And while you can create a value of type
`A`, that value will not be of type `E`. It will be convertible to `E`, but
it won't actually be an `E`. By contrast, enumerators are always typed to
their enumeration.
You cannot compare a value of type `A` with a value of type `B`, not unless
you go through a lot of trouble to add <=> and == operators for all
combinations of the enumerators to each type. By contrast, even these
so-called "simple" enumerations still retain comparability between
enumerators, even though they cannot be converted to integers.
A far more reasonable implementation for this would be something of this
sort:
template<typename enumeration>
class guarded_enum_def
{
public:
guarded_enum_def() = delete;
auto operator<=>(guarded_enum_def const &) = default;
private:
underlying_type val_;
guarded_enum_def(underlying_type val) : val_(val) {}
friend class enumeration;
};
struct my_enum
{
static inline constexpr guarded_enum_def<my_enum> enumerator1 = {0};
static inline constexpr guarded_enum_def<my_enum> enumerator2 = {2};
static inline constexpr guarded_enum_def<my_enum> enumerator3 = {8};
static inline constexpr guarded_enum_def<my_enum> enumerator4 = {10};
};
But even that is over-complicated, making it difficult for the reader to
understand what is going on. The giant bundle of repeated syntax (`static
inline constexpr guarded_enum_def<my_enum>`) creates a lot of noise in the
numeration definition. And `my_enum` is purely for scoping; the enumerators
themselves are of the `guarded_enum_def<my_enum>` type.
It's a functional solution, but it's not a good one.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353%40isocpp.org.
------=_Part_3182_1973445714.1548946861113
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">While that works to forbid default constructibility, it do=
esn't really change the fact that it is still very much unlike an enume=
ration, even a limited one as described by the OP.<br><br>`A` is a type, no=
t an enumerator. And while you can create a value of type `A`, that value w=
ill not be of type `E`. It will be convertible to `E`, but it won't act=
ually be an `E`. By contrast, enumerators are always typed to their enumera=
tion.<br><br>You cannot compare a value of type `A` with a value of type `B=
`, not unless you go through a lot of trouble to add <=3D> and =3D=3D=
operators for all combinations of the enumerators to each type. By contras=
t, even these so-called "simple" enumerations still retain compar=
ability between enumerators, even though they cannot be converted to intege=
rs.<br><br>A far more reasonable implementation for this would be something=
of this sort:<br><br><div style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; ov=
erflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> enumeration</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> guarded_en=
um_def<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">public</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 guarded_enum_def<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">delete</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br>=C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">operator</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify"><=3D>(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">guarded_enum_def </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">const</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"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">default</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">private</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 underlying_type val_</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 guarded_enum_def</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">underlying_type val</span><s=
pan 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"> val_</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">val</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</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><br>=C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">friend</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> enumeration</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 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">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> my_enum<br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">static</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">inline</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> guarded_en=
um_def</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><=
my_enum></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> enumerator1 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n 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"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">static</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">inline</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> guarded_enum_def</span><span style=3D"color: #080;" class=3D=
"styled-by-prettify"><my_enum></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> enumerator2 </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">inline</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> guarded_enum_def</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><my_enum></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> enumerator3 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #066;"=
class=3D"styled-by-prettify">8</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">static</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>inline</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> guarded_enum=
_def</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><my=
_enum></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
enumerator4 </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #066;" class=3D"styled-by-prettify">10</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 style=3D"color: #660;"=
class=3D"styled-by-prettify">};</span></div></code></div><br>But even that=
is over-complicated, making it difficult for the reader to understand what=
is going on. The giant bundle of repeated syntax (`static inline constexpr=
guarded_enum_def<my_enum>`) creates a lot of noise in the numeration=
definition. And `my_enum` is purely for scoping; the enumerators themselve=
s are of the `guarded_enum_def<my_enum>` type.<br><br>It's a func=
tional solution, but it's not a good one.</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353=
%40isocpp.org</a>.<br />
------=_Part_3182_1973445714.1548946861113--
------=_Part_3181_395227351.1548946861113--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Fri, 1 Feb 2019 01:39:05 +1000
Raw View
--0000000000008b32ec0580c2d4b9
Content-Type: text/plain; charset="UTF-8"
tooling and switch statements
On Fri, Feb 1, 2019 at 1:01 AM Nicol Bolas <jmckesson@gmail.com> wrote:
> While that works to forbid default constructibility, it doesn't really
> change the fact that it is still very much unlike an enumeration, even a
> limited one as described by the OP.
>
> `A` is a type, not an enumerator. And while you can create a value of type
> `A`, that value will not be of type `E`. It will be convertible to `E`, but
> it won't actually be an `E`. By contrast, enumerators are always typed to
> their enumeration.
>
> You cannot compare a value of type `A` with a value of type `B`, not
> unless you go through a lot of trouble to add <=> and == operators for all
> combinations of the enumerators to each type. By contrast, even these
> so-called "simple" enumerations still retain comparability between
> enumerators, even though they cannot be converted to integers.
>
> A far more reasonable implementation for this would be something of this
> sort:
>
> template<typename enumeration>
> class guarded_enum_def
> {
> public:
> guarded_enum_def() = delete;
>
> auto operator<=>(guarded_enum_def const &) = default;
>
> private:
> underlying_type val_;
> guarded_enum_def(underlying_type val) : val_(val) {}
>
> friend class enumeration;
> };
>
> struct my_enum
> {
> static inline constexpr guarded_enum_def<my_enum> enumerator1 = {0};
> static inline constexpr guarded_enum_def<my_enum> enumerator2 = {2};
> static inline constexpr guarded_enum_def<my_enum> enumerator3 = {8};
> static inline constexpr guarded_enum_def<my_enum> enumerator4 = {10};
> };
>
> But even that is over-complicated, making it difficult for the reader to
> understand what is going on. The giant bundle of repeated syntax (`static
> inline constexpr guarded_enum_def<my_enum>`) creates a lot of noise in the
> numeration definition. And `my_enum` is purely for scoping; the enumerators
> themselves are of the `guarded_enum_def<my_enum>` type.
>
> It's a functional solution, but it's not a good one.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHLm0M3Jph83T-QfVDcEDXwV2h0DSiDX1o4E6qVVN5rjPQ%40mail.gmail.com.
--0000000000008b32ec0580c2d4b9
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">tooling and switch statements</div><br><div class=3D"gmail=
_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Fri, Feb 1, 2019 at 1:01 A=
M Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.co=
m</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div dir=3D"ltr">While that works to forbid default constructibility, it d=
oesn't really change the fact that it is still very much unlike an enum=
eration, even a limited one as described by the OP.<br><br>`A` is a type, n=
ot an enumerator. And while you can create a value of type `A`, that value =
will not be of type `E`. It will be convertible to `E`, but it won't ac=
tually be an `E`. By contrast, enumerators are always typed to their enumer=
ation.<br><br>You cannot compare a value of type `A` with a value of type `=
B`, not unless you go through a lot of trouble to add <=3D> and =3D=
=3D operators for all combinations of the enumerators to each type. By cont=
rast, even these so-called "simple" enumerations still retain com=
parability between enumerators, even though they cannot be converted to int=
egers.<br><br>A far more reasonable implementation for this would be someth=
ing of this sort:<br><br><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px" class=3D"g=
mail-m_3947044010483965891prettyprint"><code class=3D"gmail-m_3947044010483=
965891prettyprint"><div class=3D"gmail-m_3947044010483965891subprettyprint"=
><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891sty=
led-by-prettify">template</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify"><</span><span style=
=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prett=
ify">typename</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_39470=
44010483965891styled-by-prettify"> enumeration</span><span style=3D"color:r=
gb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">>=
</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_394704401048396589=
1styled-by-prettify"><br></span><span style=3D"color:rgb(0,0,136)" class=3D=
"gmail-m_3947044010483965891styled-by-prettify">class</span><span style=3D"=
color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> =
guarded_enum_def<br></span><span style=3D"color:rgb(102,102,0)" class=3D"gm=
ail-m_3947044010483965891styled-by-prettify">{</span><span style=3D"color:r=
gb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"><br></sp=
an><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891s=
tyled-by-prettify">public</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify">:</span><span style=3D"c=
olor:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"><b=
r>=C2=A0 guarded_enum_def</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify">()</span><span style=3D"=
color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> =
</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_39470440104839=
65891styled-by-prettify">=3D</span><span style=3D"color:rgb(0,0,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify"> </span><span style=3D"c=
olor:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">=
delete</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_39470440=
10483965891styled-by-prettify">;</span><span style=3D"color:rgb(0,0,0)" cla=
ss=3D"gmail-m_3947044010483965891styled-by-prettify"><br><br>=C2=A0 </span>=
<span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styl=
ed-by-prettify">auto</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-=
m_3947044010483965891styled-by-prettify"> </span><span style=3D"color:rgb(0=
,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">operator</=
span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044010483965=
891styled-by-prettify"><=3D>(</span><span style=3D"color:rgb(0,0,0)" =
class=3D"gmail-m_3947044010483965891styled-by-prettify">guarded_enum_def </=
span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_394704401048396589=
1styled-by-prettify">const</span><span style=3D"color:rgb(0,0,0)" class=3D"=
gmail-m_3947044010483965891styled-by-prettify"> </span><span style=3D"color=
:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">&a=
mp;)</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_39470440104839=
65891styled-by-prettify"> </span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify">=3D</span><span style=3D=
"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">=
</span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_394704401048396=
5891styled-by-prettify">default</span><span style=3D"color:rgb(102,102,0)" =
class=3D"gmail-m_3947044010483965891styled-by-prettify">;</span><span style=
=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettif=
y"><br><br></span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_39470=
44010483965891styled-by-prettify">private</span><span style=3D"color:rgb(10=
2,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">:</span><=
span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-=
by-prettify"><br>=C2=A0 underlying_type val_</span><span style=3D"color:rgb=
(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">;</spa=
n><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styl=
ed-by-prettify"><br>=C2=A0 guarded_enum_def</span><span style=3D"color:rgb(=
102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">(</span=
><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891style=
d-by-prettify">underlying_type val</span><span style=3D"color:rgb(102,102,0=
)" class=3D"gmail-m_3947044010483965891styled-by-prettify">)</span><span st=
yle=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-pret=
tify"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044=
010483965891styled-by-prettify">:</span><span style=3D"color:rgb(0,0,0)" cl=
ass=3D"gmail-m_3947044010483965891styled-by-prettify"> val_</span><span sty=
le=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-p=
rettify">(</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_39470440=
10483965891styled-by-prettify">val</span><span style=3D"color:rgb(102,102,0=
)" class=3D"gmail-m_3947044010483965891styled-by-prettify">)</span><span st=
yle=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-pret=
tify"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044=
010483965891styled-by-prettify">{}</span><span style=3D"color:rgb(0,0,0)" c=
lass=3D"gmail-m_3947044010483965891styled-by-prettify"><br><br>=C2=A0 </spa=
n><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891st=
yled-by-prettify">friend</span><span style=3D"color:rgb(0,0,0)" class=3D"gm=
ail-m_3947044010483965891styled-by-prettify"> </span><span style=3D"color:r=
gb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">class<=
/span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891=
styled-by-prettify"> enumeration</span><span style=3D"color:rgb(102,102,0)"=
class=3D"gmail-m_3947044010483965891styled-by-prettify">;</span><span styl=
e=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-pretti=
fy"><br></span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_394704=
4010483965891styled-by-prettify">};</span><span style=3D"color:rgb(0,0,0)" =
class=3D"gmail-m_3947044010483965891styled-by-prettify"><br><br></span><spa=
n style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-b=
y-prettify">struct</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_=
3947044010483965891styled-by-prettify"> my_enum<br></span><span style=3D"co=
lor:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"=
>{</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965=
891styled-by-prettify"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)"=
class=3D"gmail-m_3947044010483965891styled-by-prettify">static</span><span=
style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-p=
rettify"> </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_394704=
4010483965891styled-by-prettify">inline</span><span style=3D"color:rgb(0,0,=
0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> </span><span s=
tyle=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-p=
rettify">constexpr</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_=
3947044010483965891styled-by-prettify"> guarded_enum_def</span><span style=
=3D"color:rgb(0,136,0)" class=3D"gmail-m_3947044010483965891styled-by-prett=
ify"><my_enum></span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-=
m_3947044010483965891styled-by-prettify"> enumerator1 </span><span style=3D=
"color:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-pretti=
fy">=3D</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_39470440104=
83965891styled-by-prettify"> </span><span style=3D"color:rgb(102,102,0)" cl=
ass=3D"gmail-m_3947044010483965891styled-by-prettify">{</span><span style=
=3D"color:rgb(0,102,102)" class=3D"gmail-m_3947044010483965891styled-by-pre=
ttify">0</span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_394704=
4010483965891styled-by-prettify">};</span><span style=3D"color:rgb(0,0,0)" =
class=3D"gmail-m_3947044010483965891styled-by-prettify"><br>=C2=A0 </span><=
span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891style=
d-by-prettify">static</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail=
-m_3947044010483965891styled-by-prettify"> </span><span style=3D"color:rgb(=
0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">inline</s=
pan><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891st=
yled-by-prettify"> </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail=
-m_3947044010483965891styled-by-prettify">constexpr</span><span style=3D"co=
lor:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> gu=
arded_enum_def</span><span style=3D"color:rgb(0,136,0)" class=3D"gmail-m_39=
47044010483965891styled-by-prettify"><my_enum></span><span style=3D"c=
olor:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> e=
numerator2 </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_394=
7044010483965891styled-by-prettify">=3D</span><span style=3D"color:rgb(0,0,=
0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> </span><span s=
tyle=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by=
-prettify">{</span><span style=3D"color:rgb(0,102,102)" class=3D"gmail-m_39=
47044010483965891styled-by-prettify">2</span><span style=3D"color:rgb(102,1=
02,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">};</span><sp=
an style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by=
-prettify"><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)" class=3D"gm=
ail-m_3947044010483965891styled-by-prettify">static</span><span style=3D"co=
lor:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"> </=
span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_394704401048396589=
1styled-by-prettify">inline</span><span style=3D"color:rgb(0,0,0)" class=3D=
"gmail-m_3947044010483965891styled-by-prettify"> </span><span style=3D"colo=
r:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">con=
stexpr</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_394704401048=
3965891styled-by-prettify"> guarded_enum_def</span><span style=3D"color:rgb=
(0,136,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"><my_e=
num></span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_39470440104=
83965891styled-by-prettify"> enumerator3 </span><span style=3D"color:rgb(10=
2,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">=3D</span=
><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891style=
d-by-prettify"> </span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-=
m_3947044010483965891styled-by-prettify">{</span><span style=3D"color:rgb(0=
,102,102)" class=3D"gmail-m_3947044010483965891styled-by-prettify">8</span>=
<span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_3947044010483965891st=
yled-by-prettify">};</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-=
m_3947044010483965891styled-by-prettify"><br>=C2=A0 </span><span style=3D"c=
olor:rgb(0,0,136)" class=3D"gmail-m_3947044010483965891styled-by-prettify">=
static</span><span style=3D"color:rgb(0,0,0)" class=3D"gmail-m_394704401048=
3965891styled-by-prettify"> </span><span style=3D"color:rgb(0,0,136)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify">inline</span><span style=
=3D"color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettif=
y"> </span><span style=3D"color:rgb(0,0,136)" class=3D"gmail-m_394704401048=
3965891styled-by-prettify">constexpr</span><span style=3D"color:rgb(0,0,0)"=
class=3D"gmail-m_3947044010483965891styled-by-prettify"> guarded_enum_def<=
/span><span style=3D"color:rgb(0,136,0)" class=3D"gmail-m_39470440104839658=
91styled-by-prettify"><my_enum></span><span style=3D"color:rgb(0,0,0)=
" class=3D"gmail-m_3947044010483965891styled-by-prettify"> enumerator4 </sp=
an><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_394704401048396589=
1styled-by-prettify">=3D</span><span style=3D"color:rgb(0,0,0)" class=3D"gm=
ail-m_3947044010483965891styled-by-prettify"> </span><span style=3D"color:r=
gb(102,102,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify">{</s=
pan><span style=3D"color:rgb(0,102,102)" class=3D"gmail-m_39470440104839658=
91styled-by-prettify">10</span><span style=3D"color:rgb(102,102,0)" class=
=3D"gmail-m_3947044010483965891styled-by-prettify">};</span><span style=3D"=
color:rgb(0,0,0)" class=3D"gmail-m_3947044010483965891styled-by-prettify"><=
br></span><span style=3D"color:rgb(102,102,0)" class=3D"gmail-m_39470440104=
83965891styled-by-prettify">};</span></div></code></div><br>But even that i=
s over-complicated, making it difficult for the reader to understand what i=
s going on. The giant bundle of repeated syntax (`static inline constexpr g=
uarded_enum_def<my_enum>`) creates a lot of noise in the numeration d=
efinition. And `my_enum` is purely for scoping; the enumerators themselves =
are of the `guarded_enum_def<my_enum>` type.<br><br>It's a functi=
onal solution, but it's not a good one.</div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-43db-a371-90fb02750353%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b69ebae5-a93a-=
43db-a371-90fb02750353%40isocpp.org</a>.<br>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHLm0M3Jph83T-QfVDcEDXwV2h0DSi=
DX1o4E6qVVN5rjPQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAB%2B4KHLm0M3J=
ph83T-QfVDcEDXwV2h0DSiDX1o4E6qVVN5rjPQ%40mail.gmail.com</a>.<br />
--0000000000008b32ec0580c2d4b9--
.