Topic: enumeration pack and `__enumerator__` template variable


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Thu, 26 Sep 2013 23:41:07 -0700 (PDT)
Raw View
------=_Part_293_25883157.1380264067911
Content-Type: text/plain; charset=ISO-8859-1

The proposed feature includes two minor core language additions that can be
used by library authors to access basic information about enumeration types
during translation.  The current workarounds for doing this involve either
(a) hand-maintaining secondary support entities for enumerations; (b) using
the preprocessor with all the usual macro problems (see boost.preprocessor
applied to enums); or (c) writing a precompiler tool (see Qt moc enum
compilation)

(1) An *enumeration pack* has the following form:

    enumeration-pack:
        enum-name ...

It expands to a list of the enumerators of the named enumeration, in
declared order, and can appear syntactically in the same contexts as a pack
expansion.

(2) The predefined template variable *__enumerator__* is defined as if for
every enumeration E and every enumerator of that enumeration e, a
specialization of an undefined primary template variable of the form:

    template<class E, E e> extern constexpr const char* __enumerator__; //
primary undefined

    template <>
    static constexpr const char* __enumerator__<E,e> = "enumerator-name";

had been provided, where enumerator-name is an implementation-defined
string.

Some of the use cases for library authors of these two primitives are:

Example enum:

    enum foo
    {
        bar,
        baz,
        qux
    };

(A) Use enumerators in an initializer list:

    vector<foo> = { foo... }; // equivalent to = { bar, baz, qux };

(B) Count the number of enumerators:

    template<class E, E... e>
    constexpr size_t __enumerator_count_helper() { return sizeof...(e); }

    template<class E>
    constexpr size_t enumerator_count = __enumeration_count_helper<E,
E...>();

    size_t n = enumerator_count<foo>; // n = 3

(C) Pass enumerators as template arguments

    template<foo... f> void f() { /* ... */ };

    void g() { f<foo...>(); }

(D) Write a to_string function for an enumerator:

    string to_string(foo f)
    {
        static map<foo, string> m = build_map(); // using foo... and
__enumerator__
        return m.at(f);
    }

(E) Iterate over the enumerators:

    for (auto e : { E... })
        do_stuff(e);

It is easy to see how higher level abstractions could be built with this
once enumerators can be iterated and stringified during translation or at
run-time.  Additional facilities could be later added to the standard
library that build upon these.

--

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

------=_Part_293_25883157.1380264067911
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">The proposed feature includes two minor core language addi=
tions that can be used by library authors to access basic information about=
 enumeration types during translation.&nbsp; The current workarounds for do=
ing this involve either (a) hand-maintaining secondary support entities for=
 enumerations; (b) using the preprocessor with all the usual macro problems=
 (see boost.preprocessor applied to enums); or (c) writing a precompiler to=
ol (see Qt moc enum compilation)<br><br>(1) An <i>enumeration pack</i> has =
the following form:<br><br><span style=3D"font-family: courier new,monospac=
e;">&nbsp;&nbsp;&nbsp; enumeration-pack:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; enum-name ...<br></span><br>It expands to a list of the enumera=
tors of the named enumeration, in declared order, and can appear syntactica=
lly in the same contexts as a pack expansion.<br><br>(2) The predefined tem=
plate variable <span style=3D"font-family: courier new,monospace;"><i>__enu=
merator__</i></span> is defined as if for every enumeration E and every enu=
merator of that enumeration e, a specialization of an undefined primary tem=
plate variable of the form:<br><span style=3D"font-family: courier new,mono=
space;"><br>&nbsp;&nbsp;&nbsp; template&lt;class E, E e&gt; extern constexp=
r const char* __enumerator__; // primary undefined<br><br>&nbsp;&nbsp;&nbsp=
; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp; static constexpr const char* __en=
umerator__&lt;E,e&gt; =3D "enumerator-name";<br></span><br>had been provide=
d, where enumerator-name is an implementation-defined string.<br><br>Some o=
f the use cases for library authors of these two primitives are:<br><br>Exa=
mple enum:<br><br><span style=3D"font-family: courier new,monospace;">&nbsp=
;&nbsp;&nbsp; enum foo<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; bar,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baz,<b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; qux<br>&nbsp;&nbsp;&nbsp; };<b=
r></span><br>(A) Use enumerators in an initializer list:<br><br><span style=
=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; vector&lt;foo&g=
t; =3D { foo... }; // equivalent to =3D { bar, baz, qux };<br></span><br>(B=
) Count the number of enumerators:<br><br><span style=3D"font-family: couri=
er new,monospace;">&nbsp;&nbsp;&nbsp; template&lt;class E, E... e&gt;<br>&n=
bsp;&nbsp;&nbsp; constexpr size_t __enumerator_count_helper() { return size=
of...(e); }<br><br>&nbsp;&nbsp;&nbsp; template&lt;class E&gt;<br>&nbsp;&nbs=
p;&nbsp; constexpr size_t enumerator_count =3D __enumeration_count_helper&l=
t;E, E...&gt;();<br><br>&nbsp;&nbsp;&nbsp; size_t n =3D enumerator_count&lt=
;foo&gt;; // n =3D 3<br></span><br>(C) Pass enumerators as template argumen=
ts<br><br><span style=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&=
nbsp; template&lt;foo... f&gt; void f() { /* ... */ };<br><br>&nbsp;&nbsp;&=
nbsp; void g() { f&lt;foo...&gt;(); }<br></span><br>(D) Write a to_string f=
unction for an enumerator:<br><br><span style=3D"font-family: courier new,m=
onospace;">&nbsp;&nbsp;&nbsp; string to_string(foo f)<br>&nbsp;&nbsp;&nbsp;=
 {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static map&lt;foo, string&=
gt; m =3D build_map(); // using foo... and __enumerator__<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; return m.at(f);<br>&nbsp;&nbsp;&nbsp; }<br></s=
pan><br>(E) Iterate over the enumerators:<br><br><span style=3D"font-family=
: courier new,monospace;">&nbsp;&nbsp;&nbsp; for (auto e : { E... })<br>&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_stuff(e);<br></span><br>It is ea=
sy to see how higher level abstractions could be built with this once enume=
rators can be iterated and stringified during translation or at run-time.&n=
bsp; Additional facilities could be later added to the standard library tha=
t build upon these.<br><br></div>

<p></p>

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

------=_Part_293_25883157.1380264067911--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 27 Sep 2013 00:29:50 -0700 (PDT)
Raw View
------=_Part_305_17123134.1380266990383
Content-Type: text/plain; charset=ISO-8859-1



On Friday, September 27, 2013 2:41:07 PM UTC+8, Andrew Tomazos wrote:
>
> The proposed feature includes two minor core language additions that can
> be used by library authors to access basic information about enumeration
> types during translation.  The current workarounds for doing this involve
> either (a) hand-maintaining secondary support entities for enumerations;
> (b) using the preprocessor with all the usual macro problems (see
> boost.preprocessor applied to enums); or (c) writing a precompiler tool
> (see Qt moc enum compilation)
>

Sounds nice. Everyone's always asking for this. Often this "missing
feature" leads people astray to attempt other, more inadvisable kinds of
introspection.

(1) An *enumeration pack* has the following form:
>
>     enumeration-pack:
>         enum-name ...
>
> It expands to a list of the enumerators of the named enumeration, in
> declared order, and can appear syntactically in the same contexts as a pack
> expansion.
>

This avoids ambiguity with other kinds of pack expansions by trading off
flexibility. *Enum-name* is only an identifer, specifically the one used to
declare the enumeration. It cannot be a typedef and cannot include a
nested-name-specifier.

Maybe a less finicky solution would be to let the type of an enumeration
match a non-type parameter pack of the same type. This further overloads
the template argument-parameter matching rules, but not the syntax of the
ellipsis.

enum e { foo, bar, baz };
template< e ... all_values >
struct enum_size { constexpr std::size_t value = sizeof ... alLvalues; };
static_assert ( enum_size< e /* Look ma, no ellipsis! */ >::value == 3, ""
);


> (2) The predefined template variable *__enumerator__* is defined as if
> for every enumeration E and every enumerator of that enumeration e, a
> specialization of an undefined primary template variable of the form:
>
>     template<class E, E e> extern constexpr const char* __enumerator__; //
> primary undefined
>
>     template <>
>     static constexpr const char* __enumerator__<E,e> = "enumerator-name";
>
> had been provided, where enumerator-name is an implementation-defined
> string.
>

Awesome. But why implementation-defined? Let's at least define it for
enumerator names in the basic source character set. Other names can be
conditionally-supported with implementation-defined semantics. It should be
OK for the compiler to flag a wacky name as an error before it goes into a
database as a column name.

Also, it might be cleaner to specify the std:: interface instead of the
implementation-reserved name.

And an extra parameter for character encoding couldn't hurt.

template< typename E, E e, typename c = char /* wchar_t => L"", char32_t =>
U"", unsigned char => u8""? */ >
static constexpr c const * enumerator_name;

Some of the use cases for library authors of these two primitives are:
>
> (B) Count the number of enumerators:
>
>     template<class E, E... e>
>     constexpr size_t __enumerator_count_helper() { return sizeof...(e); }
>
>     template<class E>
>     constexpr size_t enumerator_count = __enumeration_count_helper<E,
> E...>();
>

Woops, can't expand E because it's not an *enum-name*!


> It is easy to see how higher level abstractions could be built with this
> once enumerators can be iterated and stringified during translation or at
> run-time.  Additional facilities could be later added to the standard
> library that build upon these.
>

Like, for example, class_name< class_type > or function_name<
function_type, pointer_to_function > . But, how should the names be formed?
And where is the introspection study group hiding?

--

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

------=_Part_305_17123134.1380266990383
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, September 27, 2013 2:41:07 PM UTC+8, An=
drew Tomazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">The proposed feature includes two minor core language additions that =
can be used by library authors to access basic information about enumeratio=
n types during translation.&nbsp; The current workarounds for doing this in=
volve either (a) hand-maintaining secondary support entities for enumeratio=
ns; (b) using the preprocessor with all the usual macro problems (see boost=
..preprocessor applied to enums); or (c) writing a precompiler tool (see Qt =
moc enum compilation)<br></div></blockquote><div><br>Sounds nice. Everyone'=
s always asking for this. Often this "missing feature" leads people astray =
to attempt other, more inadvisable kinds of introspection.<br><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">(1) An <i>enumer=
ation pack</i> has the following form:<br><br><span style=3D"font-family:co=
urier new,monospace">&nbsp;&nbsp;&nbsp; enumeration-pack:<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; enum-name ...<br></span><br>It expands to a li=
st of the enumerators of the named enumeration, in declared order, and can =
appear syntactically in the same contexts as a pack expansion.<br></div></b=
lockquote><div><br>This avoids ambiguity with other kinds of pack expansion=
s by trading off flexibility. <i>Enum-name</i> is only an identifer, specif=
ically the one used to declare the enumeration. It cannot be a typedef and =
cannot include a nested-name-specifier.<br><br>Maybe a less finicky solutio=
n would be to let the type of an enumeration match a non-type parameter pac=
k of the same type. This further overloads the template argument-parameter =
matching rules, but not the syntax of the ellipsis.<br><br><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> e </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> bar</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> baz =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">template</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> e </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> all_values </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> enum_size </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nstexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">size_t value </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> alLvalues</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">stati=
c_assert</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> enum_size</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> e</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">/* Look ma, no ellipsis! */</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"></span></code> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">value </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">""</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div>&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr">(2) The predefined template variable <span style=3D"=
font-family:courier new,monospace"><i>__enumerator__</i></span> is defined =
as if for every enumeration E and every enumerator of that enumeration e, a=
 specialization of an undefined primary template variable of the form:<br><=
span style=3D"font-family:courier new,monospace"><br>&nbsp;&nbsp;&nbsp; tem=
plate&lt;class E, E e&gt; extern constexpr const char* __enumerator__; // p=
rimary undefined<br><br>&nbsp;&nbsp;&nbsp; template &lt;&gt;<br>&nbsp;&nbsp=
;&nbsp; static constexpr const char* __enumerator__&lt;E,e&gt; =3D "enumera=
tor-name";<br></span><br>had been provided, where enumerator-name is an imp=
lementation-defined string.<br></div></blockquote><div><br>Awesome. But why=
 implementation-defined? Let's at least define it for enumerator names in t=
he basic source character set. Other names can be conditionally-supported w=
ith implementation-defined semantics. It should be OK for the compiler to f=
lag a wacky name as an error before it goes into a database as a column nam=
e.<br><br>Also, it might be cleaner to specify the <span style=3D"font-fami=
ly: courier new,monospace;">std::</span> interface instead of the implement=
ation-reserved name.<br><br>And an extra parameter for character encoding c=
ouldn't hurt.<br><br><div class=3D"prettyprint" style=3D"background-color: =
rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; =
border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div=
 class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">template</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> E</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> E e</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> c </span><span style=3D"color: #660;" class=3D"sty=
led-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"=
>char</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify"><code class=3D=
"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">/* wchar_t =
=3D&gt; L"", char32_t =3D&gt; U"", unsigned char =3D&gt; u8""? */ </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify"></span></code>&gt;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">static</span><spa=
n 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"> c </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> enumerator_name</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr">Some of the use cases for library=
 authors of these two primitives are:<br><br>(B) Count the number of enumer=
ators:<br><br><span style=3D"font-family:courier new,monospace">&nbsp;&nbsp=
;&nbsp; template&lt;class E, E... e&gt;<br>&nbsp;&nbsp;&nbsp; constexpr siz=
e_t __enumerator_count_helper() { return sizeof...(e); }<br><br>&nbsp;&nbsp=
;&nbsp; template&lt;class E&gt;<br>&nbsp;&nbsp;&nbsp; constexpr size_t enum=
erator_count =3D __enumeration_count_helper&lt;E, E...&gt;();<br></span></d=
iv></blockquote><div><br>Woops, can't expand E because it's not an <i>enum-=
name</i>!<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr">It is easy to see how higher level abstractions could be built =
with this once enumerators can be iterated and stringified during translati=
on or at run-time.&nbsp; Additional facilities could be later added to the =
standard library that build upon these.<br></div></blockquote><div><br>Like=
, for example, <span style=3D"font-family: courier new,monospace;">class_na=
me&lt; class_type &gt;</span> or <span style=3D"font-family: courier new,mo=
nospace;">function_name&lt; function_type, pointer_to_function &gt;</span> =
.. But, how should the names be formed? And where is the introspection study=
 group hiding?<br><br></div></div>

<p></p>

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

------=_Part_305_17123134.1380266990383--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Fri, 27 Sep 2013 02:55:01 -0700 (PDT)
Raw View
------=_Part_1_10681980.1380275702074
Content-Type: text/plain; charset=ISO-8859-1

On Friday, September 27, 2013 9:29:50 AM UTC+2, David Krauss wrote:
>
> On Friday, September 27, 2013 2:41:07 PM UTC+8, Andrew Tomazos wrote:
>
(1) An *enumeration pack* has the following form:
>>
>
>>     enumeration-pack:
>>         enum-name ...
>>
>> It expands to a list of the enumerators of the named enumeration, in
>> declared order, and can appear syntactically in the same contexts as a pack
>> expansion.
>>
>
> This avoids ambiguity with other kinds of pack expansions by trading off
> flexibility. *Enum-name* is only an identifer, specifically the one used
> to declare the enumeration. It cannot be a typedef and cannot include a
> nested-name-specifier.
>

Yes, that is a specification error and not my intention.  I actually meant
a type id that denotes an enumeration type.  I am not aware of an
ambiguity, do you see one?


> Maybe a less finicky solution would be to let the type of an enumeration
> match a non-type parameter pack of the same type. This further overloads
> the template argument-parameter matching rules, but not the syntax of the
> ellipsis.
>

I think your solution is easier to implement.  Once the enumerator list is
available, the possibilities are the same, and an easier syntax isn't
important here - so I agree your solution is superior, ambiguity or no.


> (2) The predefined template variable *__enumerator__*
>>
>

It might be cleaner to specify the std:: interface instead of the
> implementation-reserved name.
>

It is modelled after `__func__`, see [dcl.fct.def.general]/8.  I am not
aware of a precedent for a predefined entity being part of the standard
library or namespace `std`.  You can always create a direct alias for it in
the standard library, as per `std::nullptr_t`.  There seems to be a
convention that entities in `std` should never be predefined and always
require inclusion of a relevant header - I am not sure if this is
explicitly stated somewhere.  It seems predefined things have the
`__name__` convention, predefined macros follow this also.

Why implementation-defined? Let's at least define it for enumerator names
> in the basic source character set. Other names can be
> conditionally-supported with implementation-defined semantics. It should be
> OK for the compiler to flag a wacky name as an error before it goes into a
> database as a column name.
>

All identifiers are in the basic source character set, it is impossible for
them not to be.  Characters outside the basic source character set are
logically encoded into universal character names (\uXXXX) during
translation phase 1, and these universal character names in identifiers are
never logically decoded.  If we are to define the representation it should
be as if a string literal token is formed by surrounding the identifier
spelling in doublequotes, and then running the new token through
translation phase 5.  This means the identifier universal character names
will be decoded, and the identifier will be encoded for execution
consistent with an ordinary string literal.

And an extra parameter for character encoding couldn't hurt.
>
> template< typename E, E e, typename c = char /* wchar_t => L"", char32_t
> => U"", unsigned char => u8""? */ >
> static constexpr c const * enumerator_name;
>
>
You forgot `char16_t => u""`

I think this may be unnecessary bloat.  If you want to convert the string
into an encoding other than execution encoding, you can do so at run-time
(or perhaps even at compile-time with C++14 constexpr functions).  At least
if not the execution encoding, then `u8"id"` encoding - as all other
encodings can be built from that - and as UTF-8 is usually both the source
and execution encoding anyway these days it is a good fit as a default.

--

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

------=_Part_1_10681980.1380275702074
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, September 27, 2013 9:29:50 AM UTC+2, David Krau=
ss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>On Friday, Septe=
mber 27, 2013 2:41:07 PM UTC+8, Andrew Tomazos wrote: <br></div></blockquot=
e><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote=
 style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 2=
04); padding-left: 1ex;" class=3D"gmail_quote">(1) An <i>enumeration pack</=
i> has the following form:<br></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><br><span style=3D"font-family:courier new,monospa=
ce">&nbsp;&nbsp;&nbsp; enumeration-pack:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; enum-name ...<br></span><br>It expands to a list of the enumera=
tors of the named enumeration, in declared order, and can appear syntactica=
lly in the same contexts as a pack expansion.<br></div></blockquote><div><b=
r>This avoids ambiguity with other kinds of pack expansions by trading off =
flexibility. <i>Enum-name</i> is only an identifer, specifically the one us=
ed to declare the enumeration. It cannot be a typedef and cannot include a =
nested-name-specifier.<br></div></div></blockquote><div><br>Yes, that is a =
specification error and not my intention.&nbsp; I actually meant a type id =
that denotes an enumeration type.&nbsp; I am not aware of an ambiguity, do =
you see one?<br></div><div>&nbsp;</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div>Maybe a less finicky solution would be to le=
t the type of an enumeration match a non-type parameter pack of the same ty=
pe. This further overloads the template argument-parameter matching rules, =
but not the syntax of the ellipsis.<br></div></div></blockquote><div><br>I =
think your solution is easier to implement.&nbsp; Once the enumerator list =
is available, the possibilities are the same, and an easier syntax isn't im=
portant here - so I agree your solution is superior, ambiguity or no. <br>&=
nbsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">(2) The predefin=
ed template variable <span style=3D"font-family:courier new,monospace"><i>_=
_enumerator__</i></span></div></blockquote></div></blockquote><div dir=3D"l=
tr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid =
rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">&nbsp;</block=
quote><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px soli=
d rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><div>It mig=
ht be cleaner to specify the <span style=3D"font-family:courier new,monospa=
ce">std::</span> interface instead of the implementation-reserved name.<br>=
</div></blockquote></div><div><br>It is modelled after `__func__`, see [dcl=
..fct.def.general]/8.&nbsp; I am not aware of a precedent for a predefined e=
ntity being part of the standard library or namespace `std`.&nbsp; You can =
always create a direct alias for it in the standard library, as per `std::n=
ullptr_t`.&nbsp; There seems to be a convention that entities in `std` shou=
ld never be predefined and always require inclusion of a relevant header - =
I am not sure if this is explicitly stated somewhere.&nbsp; It seems predef=
ined things have the `__name__` convention, predefined macros follow this a=
lso.<br><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1p=
x solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">Why i=
mplementation-defined? Let's at least define it for enumerator
 names in the basic source character set. Other names can be=20
conditionally-supported with implementation-defined semantics. It should
 be OK for the compiler to flag a wacky name as an error before it goes=20
into a database as a column name.<br></blockquote><br>All identifiers are i=
n the basic source character set, it is impossible for them not to be.&nbsp=
; Characters outside the basic source character set are logically encoded i=
nto universal character names (\uXXXX) during translation phase 1, and thes=
e universal character names in identifiers are never logically decoded.&nbs=
p; If we are to define the representation it should be as if a string liter=
al token is formed by surrounding the identifier spelling in doublequotes, =
and then running the new token through translation phase 5.&nbsp; This mean=
s the identifier universal character names will be decoded, and the identif=
ier will be encoded for execution consistent with an ordinary string litera=
l.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div>And an extra parameter for character encoding couldn't hurt.<br><br=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><s=
pan style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">typename</=
span><span style=3D"color:#000"> E</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> E e</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">typename</span=
><span style=3D"color:#000"> c </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">char</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660"><code><span sty=
le=3D"color:#000"> </span><span style=3D"color:#800">/* wchar_t =3D&gt; L""=
, char32_t =3D&gt; U"", unsigned char =3D&gt; u8""? */ </span><span style=
=3D"color:#800"></span></code>&gt;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">static</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> =
c </span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">*</span><span style=3D"color:#000"> enum=
erator_name</span><span style=3D"color:#660">;</span><span style=3D"color:#=
000"><br></span></div></code></div><br></div></div></blockquote><div><br>Yo=
u forgot `char16_t =3D&gt; u""`<br><br>I think this may be unnecessary bloa=
t.&nbsp; If you want to convert the string into an encoding other than exec=
ution encoding, you can do so at run-time (or perhaps even at compile-time =
with C++14 constexpr functions).&nbsp; At least if not the execution encodi=
ng, then `u8"id"` encoding - as all other encodings can be built from that =
- and as UTF-8 is usually both the source and execution encoding anyway the=
se days it is a good fit as a default.<br><br></div></div>

<p></p>

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

------=_Part_1_10681980.1380275702074--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 27 Sep 2013 11:50:48 -0700
Raw View
On quinta-feira, 26 de setembro de 2013 23:41:07, Andrew Tomazos wrote:
> Example enum:
>
>     enum foo
>     {
>         bar,
>         baz,
>         qux
>     };

How about:

 enum foo
 {
  bar,
  barr = bar,
  baz,
  qux,
 };

Following your definition of enumerator pack, the barr value would be present
in the pack expansion. But since it has the same value,

 __enumerator__<foo, bar> == __enumerator<foo, barr>

You may have to add some words on how the compiler is supposed to choose which
one to list ("implementation-defined").

Also note that this compiler solution cannot do name-to-value mapping because
we can never find both "bar" and "barr" strings.

What is __enumerator__<foo, foo(4)> supposed to be? Implementation-defined?
Null pointer?

> (B) Count the number of enumerators:
>     template<class E, E... e>
>     constexpr size_t __enumerator_count_helper() { return sizeof...(e); }
>
>     template<class E>
>     constexpr size_t enumerator_count = __enumeration_count_helper<E,
> E...>();
>
>     size_t n = enumerator_count<foo>; // n = 3

we'd have n == 4. Is that what we want?

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Fri, 27 Sep 2013 13:16:52 -0700 (PDT)
Raw View
------=_Part_465_13026338.1380313012546
Content-Type: text/plain; charset=ISO-8859-1

On Friday, September 27, 2013 8:50:48 PM UTC+2, Thiago Macieira wrote:
>
> On quinta-feira, 26 de setembro de 2013 23:41:07, Andrew Tomazos wrote:
> > Example enum:
> >
> >     enum foo
> >     {
> >         bar,
> >         baz,
> >         qux
> >     };
>
> How about:
>
>         enum foo
>         {
>                 bar,
>                 barr = bar,
>                 baz,
>                 qux,
>         };
>
> Following your definition of enumerator pack, the barr value would be
> present
> in the pack expansion. But since it has the same value,
>
>         __enumerator__<foo, bar> == __enumerator<foo, barr>
>
> You may have to add some words on how the compiler is supposed to choose
> which
> one to list ("implementation-defined").
>
> Also note that this compiler solution cannot do name-to-value mapping
> because
> we can never find both "bar" and "barr" strings.
>

Good point, I think this can be fixed as follows:

The "enumarator-name" string is formed by concatenating `u8"`, the
space-separated identifiers that have an equal value to e in declaration
order, and terminated with `"` - and the token so produced is run through
translation phase 5 to decode universal character names.

So for your example this would be:

  template <> static constexpr const char* __enumerator__<foo,bar> = u8"bar
barr"; // also matches barr
  template <> static constexpr const char* __enumerator__<foo,baz> =
u8"baz";
  template <> static constexpr const char* __enumerator__<foo,qux> =
u8"qux";

This keeps the usual case of non-overlapping enumerators simple, while
still making available all enumerator names, all their values, and all
identifier code points available to library authors to reorganize and
reencode as they desire.


> What is __enumerator__<foo, foo(4)> supposed to be?
> Implementation-defined?
> Null pointer?
>

It won't instantiate because the primary is undefined and there is no such
specialization, so it will fail at compile-time.

> (B) Count the number of enumerators:
> >     template<class E, E... e>
> >     constexpr size_t __enumerator_count_helper() { return sizeof...(e);
> }
> >
> >     template<class E>
> >     constexpr size_t enumerator_count = __enumeration_count_helper<E,
> > E...>();
> >
> >     size_t n = enumerator_count<foo>; // n = 3
>
> we'd have n == 4. Is that what we want?
>

A library author can calculate both values 3 and 4 as desired from the two
provided primitives, so you can have either.

--

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

------=_Part_465_13026338.1380313012546
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, September 27, 2013 8:50:48 PM UTC+2, Thiago Mac=
ieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On quinta-feira, 2=
6 de setembro de 2013 23:41:07, Andrew Tomazos wrote:
<br>&gt; Example enum:
<br>&gt;=20
<br>&gt; &nbsp; &nbsp; enum foo
<br>&gt; &nbsp; &nbsp; {
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; bar,
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; baz,
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; qux
<br>&gt; &nbsp; &nbsp; };
<br>
<br>How about:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum foo
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;bar,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;barr =3D bar,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;baz,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;qux,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
<br>
<br>Following your definition of enumerator pack, the barr value would be p=
resent=20
<br>in the pack expansion. But since it has the same value,
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__enumerator__&lt;foo, =
bar&gt; =3D=3D __enumerator&lt;foo, barr&gt;
<br>
<br>You may have to add some words on how the compiler is supposed to choos=
e which=20
<br>one to list ("implementation-defined").
<br>
<br>Also note that this compiler solution cannot do name-to-value mapping b=
ecause=20
<br>we can never find both "bar" and "barr" strings.
<br></blockquote><div><br>Good point, I think this can be fixed as follows:=
<br><br>The "enumarator-name" string is formed by concatenating `u8"`, the =
space-separated identifiers that have an equal value to e in declaration or=
der, and terminated with `"` - and the token so produced is run through tra=
nslation phase 5 to decode universal character names.<br><br>So for your ex=
ample this would be:<br><br><span style=3D"font-family:courier new,monospac=
e">&nbsp; template &lt;&gt; static constexpr const char* __enumerator__&lt;=
foo,bar&gt; =3D u8"bar barr"; // also matches barr<br></span><span style=3D=
"font-family:courier new,monospace">&nbsp; template &lt;&gt; static constex=
pr const char* __enumerator__&lt;foo,baz&gt; =3D u8"baz";<br></span><span s=
tyle=3D"font-family:courier new,monospace">&nbsp; template &lt;&gt; static =
constexpr const char* __enumerator__&lt;foo,qux&gt; =3D u8"qux";<br></span>=
<br>This keeps the usual case of non-overlapping enumerators simple, while =
still making available all enumerator names, all their values, and all iden=
tifier code points available to library authors to reorganize and reencode =
as they desire.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>What is __enumerator__&lt;foo, foo(4)&gt; supposed to be? Implementation-d=
efined?=20
<br>Null pointer?
<br></blockquote><div>&nbsp;<br>It won't instantiate because the primary is=
 undefined and there is no such specialization, so it will fail at compile-=
time.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; (B) Co=
unt the number of enumerators:
<br>&gt; &nbsp; &nbsp; template&lt;class E, E... e&gt;
<br>&gt; &nbsp; &nbsp; constexpr size_t __enumerator_count_helper() { retur=
n sizeof...(e); }
<br>&gt; &nbsp; &nbsp;=20
<br>&gt; &nbsp; &nbsp; template&lt;class E&gt;
<br>&gt; &nbsp; &nbsp; constexpr size_t enumerator_count =3D __enumeration_=
count_helper&lt;E,
<br>&gt; E...&gt;();
<br>&gt;=20
<br>&gt; &nbsp; &nbsp; size_t n =3D enumerator_count&lt;foo&gt;; // n =3D 3
<br>
<br>we'd have n =3D=3D 4. Is that what we want?
<br></blockquote><div><br>A library author can calculate both values 3 and =
4 as desired from the two provided primitives, so you can have either.<br><=
br></div></div>

<p></p>

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

------=_Part_465_13026338.1380313012546--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 27 Sep 2013 14:59:57 -0700
Raw View
--nextPart2349756.SQQNimgqBK
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On sexta-feira, 27 de setembro de 2013 13:16:52, Andrew Tomazos wrote:
>   template <> static constexpr const char* __enumerator__<foo,bar> = u8"bar
> barr"; // also matches barr
>   template <> static constexpr const char* __enumerator__<foo,baz> =
> u8"baz";
>   template <> static constexpr const char* __enumerator__<foo,qux> =
> u8"qux";

How about:

  template <> static constexpr const char* __enumerator__<foo,bar> =
 u8"bar\0barr\0";
  template <> static constexpr const char* __enumerator__<foo,baz> =
 u8"baz\0";
  template <> static constexpr const char* __enumerator__<foo,qux> =
 u8"qux\0";

This way, we have NUL-terminated names and no memory allocation is required
for placing the names in a list. The end of the list can be found by the
presence of a double NUL. It also allows for the code doing value-to-string to
ignore the extra names.

PS: it should be const char xxx[] or you need to add an extra const.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--nextPart2349756.SQQNimgqBK
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBSRf/dM/XwBW70U1gRArtZAJoC4eaXGX03z383zovbOtCQ+90xUwCfWxmP
ZSYaBzkgTk8cLFlFO0WEGC4=
=kgxd
-----END PGP SIGNATURE-----

--nextPart2349756.SQQNimgqBK--


.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 27 Sep 2013 15:31:14 -0700
Raw View
On sexta-feira, 27 de setembro de 2013 14:59:57, Thiago Macieira wrote:
> PS: it should be const char xxx[] or you need to add an extra const.

Oops, never mind this. The constexpr takes care of making the pointer const
too. I'm just used to looking for the "const" after the *.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sat, 28 Sep 2013 13:10:30 -0700 (PDT)
Raw View
------=_Part_212_32473281.1380399030373
Content-Type: text/plain; charset=ISO-8859-1

This sounds like an interesting approach, but I'm not so sure if it is free
of possible parsing ambiguities and if its degree of flexibility is quite
enough for all use cases, e.g. efficient implementation of flag sets or
arrays indexed by an enum.

The last few months I have thought about this problem and implemented a
clang compiler extension allowing the reflection of enumeration types,
among other things. For simplicities sake, the changes to the compiler
consist only of the introduction of a few compiler intrinsics that expand
into a constexpr during evaluation, similar to how type traits are already
implemented. These are:
    __enum_value_count(<enum-type>)  --> size_t
    __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
    __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const char
[]

Of course, something like this should not be the standardized public
interface, as these intrinsics are probably too awkward to use for the
average programmer and too large a deviation from current practice. But
using the new C++14 addition "Compile-time integer sequences" (N3658), this
can easily be brought into a much nicer form which could fullfill the role
of a public API:

    template<class E, class IdxSeq>
    struct enum_data_t;

    // requires a correct index sequence pack to expand the values:
    template<class E, size_t... Idx>
    struct enum_data_t<E, std::index_sequence<Idx...>> {
        static constexpr size_t count = __enum_value_count(E);
        static constexpr E values[] = { __enum_value(E, Idx)... };
        static constexpr char const *names[] = { __enum_value_name(E,
Idx)... };
    };

    // always use the correct index sequence for the given enum
    template<class E>
    using enum_data = enum_data_t<E, std::make_index_sequence<
__enum_value_count(E) >>;

    // for odr-use:
    template<typename E, size_t... Idx>
    constexpr E enum_data_t<E, std::index_sequence<Idx...>>::values[];
    template<typename E, size_t... Idx>
    constexpr char const * enum_data_t<E,
std::index_sequence<Idx...>>::names[];

    // usage:
    enum class E1 { first = 99, second = first };
    using E1D = enum_data<E1>;
    for (int i=0; i<E1D::count; i++)
        std::cout << E1D::names[i] << " = " << (int)E1D::values[i] <<
std::endl;

With the new constexpr relaxations coming in C++14 this could even be
enough for all compile-time purposes. Otherwise, the individual intrinsics
could also be exposed similar to existing type traits:

    template<class E, size_t Idx>
    struct enumerator_value {
        static constexpr E value = __enum_value(E, Idx);
    };

I have also experimented a lot with more advanced functionality that could
be provided on this basis. Among these is the pretty tricky (considering
all edge cases) lookup-by-value to access the enumerator name/index. That
in turn can function as a base for more interesting enum use cases like
flag sets, enum arrays, I/O via iostream etc.

Is there interest in my implementation? I could make it available via
github. I would hope it might be of interest to anyone wanting to
experiment with possible prospective std lib interfaces.

Does anyone know anything further about SG7, the reflection study group?
The forum on here seems to be empty, and not a lot of proposals have been
put forth for quite a while now. I would be very interested in a discussion
about concrete, low-hanging-fruit reflection aspects that could hopefully
be ready for the C++17 timeline.

--

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

------=_Part_212_32473281.1380399030373
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This sounds like an interesting approach, but I'm not so s=
ure if it is free of possible parsing ambiguities and if its degree of flex=
ibility is quite enough for all use cases, e.g. efficient implementation of=
 flag sets or arrays indexed by an enum.<br><br>The last few months I have =
thought about this problem and implemented a clang compiler extension allow=
ing the reflection of enumeration types, among other things. For simpliciti=
es sake, the changes to the compiler consist only of the introduction of a =
few compiler intrinsics that expand into a constexpr during evaluation, sim=
ilar to how type traits are already implemented. These are:<br>&nbsp;&nbsp;=
&nbsp; __enum_value_count(&lt;enum-type&gt;)&nbsp; --&gt; size_t<br>&nbsp;&=
nbsp;&nbsp; __enum_value(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; =
--&gt;&nbsp; &lt;enum-type&gt;<br>&nbsp;&nbsp;&nbsp; __enum_value_name(&lt;=
enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp; UTF8 const char =
[]<br><br>Of course, something like this should not be the standardized pub=
lic interface, as these intrinsics are probably too awkward to use for the =
average programmer and too large a deviation from current practice. But usi=
ng the new C++14 addition "Compile-time integer sequences" (N3658), this ca=
n easily be brought into a much nicer form which could fullfill the role of=
 a public API:<br><br>&nbsp;&nbsp;&nbsp; template&lt;class E, class IdxSeq&=
gt;<br>&nbsp;&nbsp;&nbsp; struct enum_data_t;<br><br>&nbsp;&nbsp;&nbsp; // =
requires a correct index sequence pack to expand the values:<br>&nbsp;&nbsp=
;&nbsp; template&lt;class E, size_t... Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct=
 enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt; {<br>&nbsp;&nbsp;&=
nbsp; &nbsp;&nbsp;&nbsp; static constexpr size_t count =3D __enum_value_cou=
nt(E);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E values[]=
 =3D { __enum_value(E, Idx)... };<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
static constexpr char const *names[] =3D { __enum_value_name(E, Idx)... };<=
br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; // always use the correc=
t index sequence for the given enum<br>&nbsp;&nbsp;&nbsp; template&lt;class=
 E&gt;<br>&nbsp;&nbsp;&nbsp; using enum_data =3D enum_data_t&lt;E, std::mak=
e_index_sequence&lt; __enum_value_count(E) &gt;&gt;;<br><br>&nbsp;&nbsp;&nb=
sp; // for odr-use:<br>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t...=
 Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr E enum_data_t&lt;E, std::index_se=
quence&lt;Idx...&gt;&gt;::values[];<br>&nbsp;&nbsp;&nbsp; template&lt;typen=
ame E, size_t... Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr char const * enum=
_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt;::names[];<br><br>&nbsp;=
&nbsp;&nbsp; // usage:<br>&nbsp;&nbsp;&nbsp; enum class E1 { first =3D 99, =
second =3D first };<br>&nbsp;&nbsp;&nbsp; using E1D =3D enum_data&lt;E1&gt;=
;<br>&nbsp;&nbsp;&nbsp; for (int i=3D0; i&lt;E1D::count; i++)<br>&nbsp;&nbs=
p;&nbsp; &nbsp;&nbsp;&nbsp; std::cout &lt;&lt; E1D::names[i] &lt;&lt; " =3D=
 " &lt;&lt; (int)E1D::values[i] &lt;&lt; std::endl;<br><br>With the new con=
stexpr relaxations coming in C++14 this could even be enough for all compil=
e-time purposes. Otherwise, the individual intrinsics could also be exposed=
 similar to existing type traits:<br><br>&nbsp;&nbsp;&nbsp; template&lt;cla=
ss E, size_t Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enumerator_value {<br>&nb=
sp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E value =3D __enum_valu=
e(E, Idx);<br>&nbsp;&nbsp;&nbsp; };<br><br>I have also experimented a lot w=
ith more advanced functionality that could be provided on this basis. Among=
 these is the pretty tricky (considering all edge cases) lookup-by-value to=
 access the enumerator name/index. That in turn can function as a base for =
more interesting enum use cases like flag sets, enum arrays, I/O via iostre=
am etc.<br><br>Is there interest in my implementation? I could make it avai=
lable via github. I would hope it might be of interest to anyone wanting to=
 experiment with possible prospective std lib interfaces.<br><br>Does anyon=
e know anything further about SG7, the reflection study group? The forum on=
 here seems to be empty, and not a lot of proposals have been put forth for=
 quite a while now. I would be very interested in a discussion about concre=
te, low-hanging-fruit reflection aspects that could hopefully be ready for =
the C++17 timeline.<br></div>

<p></p>

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

------=_Part_212_32473281.1380399030373--

.


Author: inkwizytoryankes@gmail.com
Date: Sat, 28 Sep 2013 17:05:50 -0700 (PDT)
Raw View
------=_Part_1303_17362017.1380413150968
Content-Type: text/plain; charset=ISO-8859-1

This look better than original proposition, mainly because its library
extension, it could be even fake in current C++ using some macro magic.
Now only thing that that will this lack is some way for switch statement
support, because you cant add new cases when enum change size.

On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>
> This sounds like an interesting approach, but I'm not so sure if it is
> free of possible parsing ambiguities and if its degree of flexibility is
> quite enough for all use cases, e.g. efficient implementation of flag sets
> or arrays indexed by an enum.
>
> The last few months I have thought about this problem and implemented a
> clang compiler extension allowing the reflection of enumeration types,
> among other things. For simplicities sake, the changes to the compiler
> consist only of the introduction of a few compiler intrinsics that expand
> into a constexpr during evaluation, similar to how type traits are already
> implemented. These are:
>     __enum_value_count(<enum-type>)  --> size_t
>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
> char []
>
> Of course, something like this should not be the standardized public
> interface, as these intrinsics are probably too awkward to use for the
> average programmer and too large a deviation from current practice. But
> using the new C++14 addition "Compile-time integer sequences" (N3658), this
> can easily be brought into a much nicer form which could fullfill the role
> of a public API:
>
>     template<class E, class IdxSeq>
>     struct enum_data_t;
>
>     // requires a correct index sequence pack to expand the values:
>     template<class E, size_t... Idx>
>     struct enum_data_t<E, std::index_sequence<Idx...>> {
>         static constexpr size_t count = __enum_value_count(E);
>         static constexpr E values[] = { __enum_value(E, Idx)... };
>         static constexpr char const *names[] = { __enum_value_name(E,
> Idx)... };
>     };
>
>     // always use the correct index sequence for the given enum
>     template<class E>
>     using enum_data = enum_data_t<E, std::make_index_sequence<
> __enum_value_count(E) >>;
>
>     // for odr-use:
>     template<typename E, size_t... Idx>
>     constexpr E enum_data_t<E, std::index_sequence<Idx...>>::values[];
>     template<typename E, size_t... Idx>
>     constexpr char const * enum_data_t<E,
> std::index_sequence<Idx...>>::names[];
>
>     // usage:
>     enum class E1 { first = 99, second = first };
>     using E1D = enum_data<E1>;
>     for (int i=0; i<E1D::count; i++)
>         std::cout << E1D::names[i] << " = " << (int)E1D::values[i] <<
> std::endl;
>
> With the new constexpr relaxations coming in C++14 this could even be
> enough for all compile-time purposes. Otherwise, the individual intrinsics
> could also be exposed similar to existing type traits:
>
>     template<class E, size_t Idx>
>     struct enumerator_value {
>         static constexpr E value = __enum_value(E, Idx);
>     };
>
> I have also experimented a lot with more advanced functionality that could
> be provided on this basis. Among these is the pretty tricky (considering
> all edge cases) lookup-by-value to access the enumerator name/index. That
> in turn can function as a base for more interesting enum use cases like
> flag sets, enum arrays, I/O via iostream etc.
>
> Is there interest in my implementation? I could make it available via
> github. I would hope it might be of interest to anyone wanting to
> experiment with possible prospective std lib interfaces.
>
> Does anyone know anything further about SG7, the reflection study group?
> The forum on here seems to be empty, and not a lot of proposals have been
> put forth for quite a while now. I would be very interested in a discussion
> about concrete, low-hanging-fruit reflection aspects that could hopefully
> be ready for the C++17 timeline.
>

--

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

------=_Part_1303_17362017.1380413150968
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This look better than original proposition, mainly because=
 its library extension, it could be even fake in current C++ using some mac=
ro magic.<br>Now only thing that that will this lack is some way for switch=
 statement support, because you cant add new cases when enum change size.<b=
r><br>On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">This sou=
nds like an interesting approach, but I'm not so sure if it is free of poss=
ible parsing ambiguities and if its degree of flexibility is quite enough f=
or all use cases, e.g. efficient implementation of flag sets or arrays inde=
xed by an enum.<br><br>The last few months I have thought about this proble=
m and implemented a clang compiler extension allowing the reflection of enu=
meration types, among other things. For simplicities sake, the changes to t=
he compiler consist only of the introduction of a few compiler intrinsics t=
hat expand into a constexpr during evaluation, similar to how type traits a=
re already implemented. These are:<br>&nbsp;&nbsp;&nbsp; __enum_value_count=
(&lt;enum-type&gt;<wbr>)&nbsp; --&gt; size_t<br>&nbsp;&nbsp;&nbsp; __enum_v=
alue(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp; &lt;enu=
m-type&gt;<br>&nbsp;&nbsp;&nbsp; __enum_value_name(&lt;enum-type&gt;, &lt;i=
ndex-constexpr&gt;)&nbsp; --&gt;&nbsp; UTF8 const char []<br><br>Of course,=
 something like this should not be the standardized public interface, as th=
ese intrinsics are probably too awkward to use for the average programmer a=
nd too large a deviation from current practice. But using the new C++14 add=
ition "Compile-time integer sequences" (N3658), this can easily be brought =
into a much nicer form which could fullfill the role of a public API:<br><b=
r>&nbsp;&nbsp;&nbsp; template&lt;class E, class IdxSeq&gt;<br>&nbsp;&nbsp;&=
nbsp; struct enum_data_t;<br><br>&nbsp;&nbsp;&nbsp; // requires a correct i=
ndex sequence pack to expand the values:<br>&nbsp;&nbsp;&nbsp; template&lt;=
class E, size_t... Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enum_data_t&lt;E, s=
td::index_sequence&lt;Idx...&gt;&gt; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&n=
bsp; static constexpr size_t count =3D __enum_value_count(E);<br>&nbsp;&nbs=
p;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E values[] =3D { __enum_value(=
E, Idx)... };<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr cha=
r const *names[] =3D { __enum_value_name(E, Idx)... };<br>&nbsp;&nbsp;&nbsp=
; };<br><br>&nbsp;&nbsp;&nbsp; // always use the correct index sequence for=
 the given enum<br>&nbsp;&nbsp;&nbsp; template&lt;class E&gt;<br>&nbsp;&nbs=
p;&nbsp; using enum_data =3D enum_data_t&lt;E, std::make_index_sequence&lt;=
 __enum_value_count(E) &gt;&gt;;<br><br>&nbsp;&nbsp;&nbsp; // for odr-use:<=
br>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t... Idx&gt; <br>&nbsp;&=
nbsp;&nbsp; constexpr E enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;=
&gt;::<wbr>values[];<br>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t..=
.. Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr char const * enum_data_t&lt;E, s=
td::index_sequence&lt;Idx...&gt;&gt;::<wbr>names[];<br><br>&nbsp;&nbsp;&nbs=
p; // usage:<br>&nbsp;&nbsp;&nbsp; enum class E1 { first =3D 99, second =3D=
 first };<br>&nbsp;&nbsp;&nbsp; using E1D =3D enum_data&lt;E1&gt;;<br>&nbsp=
;&nbsp;&nbsp; for (int i=3D0; i&lt;E1D::count; i++)<br>&nbsp;&nbsp;&nbsp; &=
nbsp;&nbsp;&nbsp; std::cout &lt;&lt; E1D::names[i] &lt;&lt; " =3D " &lt;&lt=
; (int)E1D::values[i] &lt;&lt; std::endl;<br><br>With the new constexpr rel=
axations coming in C++14 this could even be enough for all compile-time pur=
poses. Otherwise, the individual intrinsics could also be exposed similar t=
o existing type traits:<br><br>&nbsp;&nbsp;&nbsp; template&lt;class E, size=
_t Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enumerator_value {<br>&nbsp;&nbsp;&=
nbsp; &nbsp;&nbsp;&nbsp; static constexpr E value =3D __enum_value(E, Idx);=
<br>&nbsp;&nbsp;&nbsp; };<br><br>I have also experimented a lot with more a=
dvanced functionality that could be provided on this basis. Among these is =
the pretty tricky (considering all edge cases) lookup-by-value to access th=
e enumerator name/index. That in turn can function as a base for more inter=
esting enum use cases like flag sets, enum arrays, I/O via iostream etc.<br=
><br>Is there interest in my implementation? I could make it available via =
github. I would hope it might be of interest to anyone wanting to experimen=
t with possible prospective std lib interfaces.<br><br>Does anyone know any=
thing further about SG7, the reflection study group? The forum on here seem=
s to be empty, and not a lot of proposals have been put forth for quite a w=
hile now. I would be very interested in a discussion about concrete, low-ha=
nging-fruit reflection aspects that could hopefully be ready for the C++17 =
timeline.<br></div></blockquote></div>

<p></p>

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

------=_Part_1303_17362017.1380413150968--

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 28 Sep 2013 17:20:46 -0700 (PDT)
Raw View
------=_Part_1426_746227.1380414046560
Content-Type: text/plain; charset=ISO-8859-1



On Friday, September 27, 2013 5:55:01 PM UTC+8, Andrew Tomazos wrote:
>
> On Friday, September 27, 2013 9:29:50 AM UTC+2, David Krauss wrote:
>>
>> On Friday, September 27, 2013 2:41:07 PM UTC+8, Andrew Tomazos wrote:
>>
> (1) An *enumeration pack* has the following form:
>>>
>>
>>>     enumeration-pack:
>>>         enum-name ...
>>>
>>> It expands to a list of the enumerators of the named enumeration, in
>>> declared order, and can appear syntactically in the same contexts as a pack
>>> expansion.
>>>
>>
>> This avoids ambiguity with other kinds of pack expansions by trading off
>> flexibility. *Enum-name* is only an identifer, specifically the one used
>> to declare the enumeration. It cannot be a typedef and cannot include a
>> nested-name-specifier.
>>
>
> Yes, that is a specification error and not my intention.  I actually meant
> a type id that denotes an enumeration type.  I am not aware of an
> ambiguity, do you see one?
>

Bah. I saw one before but didn't post it. Now I don't see it any more. You
would need an enumeration type and an unexpanded pack name on equal
footing. But both would need to be the immediate operand of the ellipsis
and not inside a subexpression. Maybe I had an incorrect example.


> Maybe a less finicky solution would be to let the type of an enumeration
>> match a non-type parameter pack of the same type. This further overloads
>> the template argument-parameter matching rules, but not the syntax of the
>> ellipsis.
>>
>
> I think your solution is easier to implement.  Once the enumerator list is
> available, the possibilities are the same, and an easier syntax isn't
> important here - so I agree your solution is superior, ambiguity or no.
>

Cool. Also it's more consistent because other pack expansion contexts do
allow subexpressions, and this feature would be different from the
"general" case. But not so for parameter matching.


> (2) The predefined template variable *__enumerator__*
>>>
>>
>
> It might be cleaner to specify the std:: interface instead of the
>> implementation-reserved name.
>>
>
> It is modelled after `__func__`, see [dcl.fct.def.general]/8.  I am not
> aware of a precedent for a predefined entity being part of the standard
> library or namespace `std`.  You can always create a direct alias for it in
> the standard library, as per `std::nullptr_t`.  There seems to be a
> convention that entities in `std` should never be predefined and always
> require inclusion of a relevant header - I am not sure if this is
> explicitly stated somewhere.  It seems predefined things have the
> `__name__` convention, predefined macros follow this also.
>

Results from typeid() are the closest analogy. It's not a template, but it
probably would be if redone today, and the user must include <type_info>for it to work.

__func__ is special because it has local scope. Also, it's compatible with
C. A quick survey shows the only underscore-"escaped" predefined identifier
not inherited from C is __cplusplus, but the C standard explicitly requires
that not be defined. And __func__ is the only non-preprocessor entity.


> Why implementation-defined? Let's at least define it for enumerator names
>> in the basic source character set. Other names can be
>> conditionally-supported with implementation-defined semantics. It should be
>> OK for the compiler to flag a wacky name as an error before it goes into a
>> database as a column name.
>>
>
> All identifiers are in the basic source character set, it is impossible
> for them not to be.  Characters outside the basic source character set are
> logically encoded into universal character names (\uXXXX) during
> translation phase 1, and these universal character names in identifiers are
> never logically decoded.
>

Yes, outputting UCNs would be a defect. But they are decoded if
preprocessor-stringized.


>   If we are to define the representation it should be as if a string
> literal token is formed by surrounding the identifier spelling in
> doublequotes, and then running the new token through translation phase 5.
> This means the identifier universal character names will be decoded, and
> the identifier will be encoded for execution consistent with an ordinary
> string literal.
>

This is what usually happens when using the stringize operator. Anyway,
easier just to specify that UCNs are conditionally-supported and
implementation-defined.

Do you agree that specifying the result makes sense, as long as there are
no UCNs?


> And an extra parameter for character encoding couldn't hurt.
>>
>> template< typename E, E e, typename c = char /* wchar_t => L"", char32_t
>> => U"", unsigned char => u8""? */ >
>> static constexpr c const * enumerator_name;
>>
>>
> You forgot `char16_t => u""`
>

I just ran out of horizontal space. And unsigned char => u8 is intended to
be a speculation, because u8"" does generate an array of unsigned char
(although it probably should).

I think this may be unnecessary bloat.  If you want to convert the string
> into an encoding other than execution encoding, you can do so at run-time
> (or perhaps even at compile-time with C++14 constexpr functions).  At least
> if not the execution encoding, then `u8"id"` encoding - as all other
> encodings can be built from that - and as UTF-8 is usually both the source
> and execution encoding anyway these days it is a good fit as a default.
>

The feature will see heavy use in serialization, so it should be able to
reliably produce strings in certain formats, or flag errors if the
conversion may be invalid. For example, if memory serves, Oracle databases
use UTF-16 (surrogate pairs) encoded in UTF-8. Many folks just don't want
non-ASCII characters in their file formats. Specifying file formats and
database schemas will probably be one of the most common uses. It would be
a positive compiler feature to flag non-ASCII characters upon request, so
it would be better if compliance didn't require translating the entire
execution character set.

Compile-time encoding translation will certainly happen, but until that
occurs, I think conditional, implementation-defined support is a good
compromise.

--

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

------=_Part_1426_746227.1380414046560
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, September 27, 2013 5:55:01 PM UTC+8, An=
drew Tomazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">On Friday, September 27, 2013 9:29:50 AM UTC+2, David Krauss wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div>On Friday, September 27, 2013 2:=
41:07 PM UTC+8, Andrew Tomazos wrote: <br></div></blockquote><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><blockquote style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" clas=
s=3D"gmail_quote">(1) An <i>enumeration pack</i> has the following form:<br=
></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>=
<span style=3D"font-family:courier new,monospace">&nbsp;&nbsp;&nbsp; enumer=
ation-pack:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum-name ...<br>=
</span><br>It expands to a list of the enumerators of the named enumeration=
, in declared order, and can appear syntactically in the same contexts as a=
 pack expansion.<br></div></blockquote><div><br>This avoids ambiguity with =
other kinds of pack expansions by trading off flexibility. <i>Enum-name</i>=
 is only an identifer, specifically the one used to declare the enumeration=
.. It cannot be a typedef and cannot include a nested-name-specifier.<br></d=
iv></div></blockquote><div><br>Yes, that is a specification error and not m=
y intention.&nbsp; I actually meant a type id that denotes an enumeration t=
ype.&nbsp; I am not aware of an ambiguity, do you see one?<br></div></div><=
/blockquote><div><br>Bah. I saw one before but didn't post it. Now I don't =
see it any more. You would need an enumeration type and an unexpanded pack =
name on equal footing. But both would need to be the immediate operand of t=
he ellipsis and not inside a subexpression. Maybe I had an incorrect exampl=
e.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>Maybe a less finicky solution would be to let the type of an enumeration=
 match a non-type parameter pack of the same type. This further overloads t=
he template argument-parameter matching rules, but not the syntax of the el=
lipsis.<br></div></div></blockquote><div><br>I think your solution is easie=
r to implement.&nbsp; Once the enumerator list is available, the possibilit=
ies are the same, and an easier syntax isn't important here - so I agree yo=
ur solution is superior, ambiguity or no. <br></div></div></blockquote><div=
><br>Cool. Also it's more consistent because other pack expansion contexts =
do allow subexpressions, and this feature would be different from the "gene=
ral" case. But not so for parameter matching.<br>&nbsp;</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">(2) The predefined template variable <span style=3D"font-family=
:courier new,monospace"><i>__enumerator__</i></span></div></blockquote></di=
v></blockquote><div dir=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_=
quote">&nbsp;</blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"=
><div>It might be cleaner to specify the <span style=3D"font-family:courier=
 new,monospace">std::</span> interface instead of the implementation-reserv=
ed name.<br></div></blockquote></div><div><br>It is modelled after `__func_=
_`, see [dcl.fct.def.general]/8.&nbsp; I am not aware of a precedent for a =
predefined entity being part of the standard library or namespace `std`.&nb=
sp; You can always create a direct alias for it in the standard library, as=
 per `std::nullptr_t`.&nbsp; There seems to be a convention that entities i=
n `std` should never be predefined and always require inclusion of a releva=
nt header - I am not sure if this is explicitly stated somewhere.&nbsp; It =
seems predefined things have the `__name__` convention, predefined macros f=
ollow this also.<br></div></div></blockquote><div><br>Results from <span st=
yle=3D"font-family: courier new,monospace;">typeid()</span> are the closest=
 analogy. It's not a template, but it probably would be if redone today, an=
d the user must include <span style=3D"font-family: courier new,monospace;"=
>&lt;type_info&gt;</span> for it to work.<br><br><span style=3D"font-family=
: courier new,monospace;">__func__</span> is special because it has local s=
cope. Also, it's compatible with C. A quick survey shows the only underscor=
e-"escaped" predefined identifier not inherited from C is <span style=3D"fo=
nt-family: courier new,monospace;">__cplusplus</span>, but the C standard e=
xplicitly requires that not be defined. And <span style=3D"font-family: cou=
rier new,monospace;">__func__</span> is the only non-preprocessor entity.<b=
r>&nbsp; <br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1=
px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><blo=
ckquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204,=
 204, 204); padding-left: 1ex;" class=3D"gmail_quote">Why implementation-de=
fined? Let's at least define it for enumerator names in the basic source ch=
aracter set. Other names can be conditionally-supported with implementation=
-defined semantics. It should be OK for the compiler to flag a wacky name a=
s an error before it goes into a database as a column name.<br></blockquote=
></blockquote></div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-=
left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quot=
e"><br>All identifiers are in the basic source character set, it is impossi=
ble for them not to be. &nbsp;Characters outside the basic source character=
 set are logically encoded into universal character names (\uXXXX) during t=
ranslation phase 1, and these universal character names in identifiers are =
never logically decoded.<br></blockquote><div><br>Yes, outputting UCNs woul=
d be a defect. But they are decoded if preprocessor-stringized.<br>&nbsp;</=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>&nbs=
p; If we are to define the representation it should be as if a string liter=
al token is formed by surrounding the identifier spelling in doublequotes, =
and then running the new token through translation phase 5.&nbsp; This mean=
s the identifier universal character names will be decoded, and the identif=
ier will be encoded for execution consistent with an ordinary string litera=
l.<br></div></div></blockquote><div><br>This is what usually happens when u=
sing the stringize operator. Anyway, easier just to specify that UCNs are c=
onditionally-supported and implementation-defined.<br><br>Do you agree that=
 specifying the result makes sense, as long as there are no UCNs?<br>&nbsp;=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>And an extra paramet=
er for character encoding couldn't hurt.<br><br><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">typename</span><span style=3D"color:#0=
00"> E</span><span style=3D"color:#660">,</span><span style=3D"color:#000">=
 E e</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">typename</span><span style=3D"color:#000">=
 c </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">char</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660"><code><span style=3D"color:#000"> </span><s=
pan style=3D"color:#800">/* wchar_t =3D&gt; L"", char32_t =3D&gt; U"", unsi=
gned char =3D&gt; u8""? */ </span><span style=3D"color:#800"></span></code>=
&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008"=
>static</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>constexpr</span><span style=3D"color:#000"> c </span><span style=3D"color:=
#008">const</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">*</span><span style=3D"color:#000"> enumerator_name</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code>=
</div><br></div></div></blockquote><div><br>You forgot `char16_t =3D&gt; u"=
"`<br></div></div></blockquote><div><br>I just ran out of horizontal space.=
 And unsigned char =3D&gt; u8 is intended to be a speculation, because u8""=
 does generate an array of unsigned char (although it probably should).<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v>I think this may be unnecessary bloat.&nbsp; If you want to convert the s=
tring into an encoding other than execution encoding, you can do so at run-=
time (or perhaps even at compile-time with C++14 constexpr functions).&nbsp=
; At least if not the execution encoding, then `u8"id"` encoding - as all o=
ther encodings can be built from that - and as UTF-8 is usually both the so=
urce and execution encoding anyway these days it is a good fit as a default=
..<br></div></div></blockquote><div><br>The feature will see heavy use in se=
rialization, so it should be able to reliably produce strings in certain fo=
rmats, or flag errors if the conversion may be invalid. For example, if mem=
ory serves, Oracle databases use UTF-16 (surrogate pairs) encoded in UTF-8.=
 Many folks just don't want non-ASCII characters in their file formats. Spe=
cifying file formats and database schemas will probably be one of the most =
common uses. It would be a positive compiler feature to flag non-ASCII char=
acters=20
upon request, so it would be better if compliance didn't require translatin=
g the=20
entire execution character set.<br><br>Compile-time encoding translation wi=
ll certainly happen, but until that occurs, I think conditional, implementa=
tion-defined support is a good compromise.<br><br></div></div>

<p></p>

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

------=_Part_1426_746227.1380414046560--

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 28 Sep 2013 17:36:57 -0700 (PDT)
Raw View
------=_Part_1397_26222118.1380415017771
Content-Type: text/plain; charset=ISO-8859-1



On Saturday, September 28, 2013 2:50:48 AM UTC+8, Thiago Macieira wrote:
>
> How about:
>
>         enum foo
>         {
>                 bar,
>                 barr = bar,
>                 baz,
>                 qux,
>         };
>
> Following your definition of enumerator pack, the barr value would be
> present
> in the pack expansion. But since it has the same value,
>
>         __enumerator__<foo, bar> == __enumerator<foo, barr>
>
> You may have to add some words on how the compiler is supposed to choose
> which
> one to list ("implementation-defined").
>

Personally I'd expect either ill-formed or UB. The facility should be
useful for making file formats and getting some assurance about
correctness. It should be deterministic and portable.

An attribute for enumerators that are "meta" so old-fashioned e::count or
whatever can still be used, without disturbing the reflection, would be a
good idea one way or another. (But attributes are out of favor,
particularly where they could determine correctness, and I don't know what
else could do this besides a completely new kind of specifier.)

--

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

------=_Part_1397_26222118.1380415017771
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, September 28, 2013 2:50:48 AM UTC+8, =
Thiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">How abou=
t:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum foo
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;bar,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;barr =3D bar,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;baz,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;qux,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
<br>
<br>Following your definition of enumerator pack, the barr value would be p=
resent=20
<br>in the pack expansion. But since it has the same value,
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__enumerator__&lt;foo, =
bar&gt; =3D=3D __enumerator&lt;foo, barr&gt;
<br>
<br>You may have to add some words on how the compiler is supposed to choos=
e which=20
<br>one to list ("implementation-defined").
<br></blockquote><div><br>Personally I'd expect either ill-formed or UB. Th=
e facility should be useful for making file formats and getting some assura=
nce about correctness. It should be deterministic and portable.<br><br>An a=
ttribute for enumerators that are "meta" so old-fashioned <span style=3D"fo=
nt-family: courier new,monospace;">e::count</span> or whatever can still be=
 used, without disturbing the reflection, would be a good idea one way or a=
nother. (But attributes are out of favor, particularly where they could det=
ermine correctness, and I don't know what else could do this besides a comp=
letely new kind of specifier.)<br><br></div></div>

<p></p>

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

------=_Part_1397_26222118.1380415017771--

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 28 Sep 2013 17:39:38 -0700 (PDT)
Raw View
------=_Part_1383_21614773.1380415178146
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Sunday, September 29, 2013 8:36:57 AM UTC+8, David Krauss wrote:
>
> An attribute for enumerators that are "meta" so old-fashioned e::count or=
=20
> whatever can still be used, without disturbing the reflection, would be a=
=20
> good idea one way or another. (But attributes are out of favor,=20
> particularly where they could determine correctness, and I don't know wha=
t=20
> else could do this besides a completely new kind of specifier.)
>

=85 oh, enumerators don't even have attributes in the current grammar. But=
=20
that's a minor thing.

--=20

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

------=_Part_1383_21614773.1380415178146
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, September 29, 2013 8:36:57 AM UTC+8, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">An attribute for enumerators that are "meta" so old-fashioned <span sty=
le=3D"font-family:courier new,monospace">e::count</span> or whatever can st=
ill be used, without disturbing the reflection, would be a good idea one wa=
y or another. (But attributes are out of favor, particularly where they cou=
ld determine correctness, and I don't know what else could do this besides =
a completely new kind of specifier.)<br></div></blockquote><div><br>=85 oh,=
 enumerators don't even have attributes in the current grammar. But that's =
a minor thing.<br><br></div></div>

<p></p>

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

------=_Part_1383_21614773.1380415178146--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sat, 28 Sep 2013 20:09:46 -0700 (PDT)
Raw View
------=_Part_455_29006727.1380424187032
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>
> This sounds like an interesting approach, but I'm not so sure if it is
> free of possible parsing ambiguities
>

While that may be the case for the original proposal (not that I am aware
of a specific ambiguity), with David Krauss's suggested adjustment there
clearly are no ambiguities:

That is: A non-type parameter pack of enum type E, will match by a type
argument of enum type E, semantically expanding to the enumerator list of
the enumeration:

    enum E { a, b, c };

    template<E...> f();

    f<E>(); // expands to f<a,b,c>();

The important thing is to provide the enumerator list during translation to
library authors.

and if its degree of flexibility is quite enough for all use cases, e.g.
> efficient implementation of flag sets or arrays indexed by an enum.
>

The intention of the two primitives is to make it possible for you to
implement all of these things as library features.   Once you have the
enumerator list as a pack I believe during translation you should be able
to create "flag sets" or "arrays indexed by an enum" or whatever other
fruit you may want.  You will have statically all the information available
about the enumerators and their values.

For example I would claim (or at least intend that) the entire library and
API you specified could be implemented during translation with generic
programming based on the two primitives.

It would be helpful if you could provide an example of a library feature
you want where this is not the case.

--

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

------=_Part_455_29006727.1380424187032
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christi=
an Kaeser wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">This sounds like an interesting approach, but I'm not so sure if it is f=
ree of possible parsing ambiguities</div></blockquote><div><br>While that m=
ay be the case for the original proposal (not that I am aware of a specific=
 ambiguity), with David Krauss's suggested adjustment there clearly are no =
ambiguities:<br><br>That is: A non-type parameter pack of enum type E, will=
 match by a type argument of enum type E, semantically expanding to the enu=
merator list of the enumeration:<br><span style=3D"font-family: courier new=
,monospace;"><br>&nbsp;&nbsp;&nbsp; enum E { a, b, c };<br><br>&nbsp;&nbsp;=
&nbsp; template&lt;E...&gt; f();<br><br>&nbsp;&nbsp;&nbsp; f&lt;E&gt;(); //=
 expands to f&lt;a,b,c&gt;();<br><br></span>The important thing is to provi=
de the enumerator list during translation to library authors.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">and if its de=
gree of flexibility is quite enough for all use cases, e.g. efficient imple=
mentation of flag sets or arrays indexed by an enum.<br></div></blockquote>=
<div><br>The intention of the two primitives is to make it possible for you=
 to implement all of these things as library features. &nbsp; Once you have=
 the enumerator list as a pack I believe during translation you should be a=
ble to create "flag sets" or "arrays indexed by an enum" or whatever other =
fruit you may want.&nbsp; You will have statically all the information avai=
lable about the enumerators and their values.<br><br>For example I would cl=
aim (or at least intend that) the entire library and API you specified coul=
d be implemented during translation with generic programming based on the t=
wo primitives.<br><br>It would be helpful if you could provide an example o=
f a library feature you want where this is not the case.<br><br></div></div=
>

<p></p>

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

------=_Part_455_29006727.1380424187032--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sat, 28 Sep 2013 21:10:03 -0700 (PDT)
Raw View
------=_Part_1016_448726.1380427803340
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sunday, September 29, 2013 2:20:46 AM UTC+2, David Krauss wrote:
>
> Yes, outputting UCNs would be a defect. But they are decoded if=20
> preprocessor-stringized.
>

That is because when you stringize an identifier during preprocessing=20
(translation phase 4) it becomes a string literal, and UCNs are decoded in=
=20
string literals (but not identifiers) during translation phase 5.
=20

>    If we are to define the representation it should be as if a string=20
> literal token is formed by surrounding the identifier spelling in=20
> doublequotes, and then running the new token through translation phase 5.=
 =20
> This means the identifier universal character names will be decoded, and=
=20
> the identifier will be encoded for execution consistent with an ordinary=
=20
> string literal.
>
> This is what usually happens when using the stringize operator. Anyway,=
=20
> easier just to specify that UCNs are conditionally-supported and=20
> implementation-defined.
>
> Do you agree that specifying the result makes sense, as long as there are=
=20
> no UCNs?
>

I am now happy with specifying exactly the format (not making it=20
implementation-defined) including UCNs (note that UCNs are not=20
conditionally-supported in identifiers, they are a hard requirement)

The updated text would be as per Thiago Macieira's suggestion:

The predefined template variable *__enumerator__* is defined as if for=20
every enumeration E and every unique enumerator value v of that=20
enumeration, a specialization of an undefined primary template variable:

    template <>
    constexpr const char* __enumerator__<E,v> =3D u8"enumerator-name";

had been provided, where enumerator-name is formed by concatenating the=20
identifier of each enumerator e with value v, in declaration order, each=20
terminated with \0.  [Note: Any universal-character-names in the=20
identifiers are decoded. end Note]

[Example:

    enum Efoo
    {
        bar =3D 42,
        baz =3D 43,
        qux =3D 44,
        e=CF=80 =3D 42,
        f\u03C0 =3D 42,
    };

 As if:

    template <class E, E> extern constexpr const char* __enumerator__; //=
=20
undefined

    template <> constexpr const char* __enumerator__<E,foo(42)> =3D=20
u8"bar\0e\u03C0\0f\u03C0\0";
    template <> constexpr const char* __enumerator__<E,foo(43)> =3D u8"baz\=
0";
    template <> constexpr const char* __enumerator__<E,foo(44)> =3D u8"qux\=
0";

end Example]

As pointed out by Thiago:

    std::string s =3D __enumerator__<E, e>;

will give you the UTF-8 encoded name of the first declared enumerator of=20
the same value of e.  In the typical non-overlapping case, this will be e=
=20
and what you expect.  The design still makes available all the code points=
=20
(as UTF-8 completely encodes all universal characters) of all the=20
enumerator identifiers, so a library author can transform and transcode=20
this information into whatever structure they want.

--=20

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

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

<div dir=3D"ltr">On Sunday, September 29, 2013 2:20:46 AM UTC+2, David Krau=
ss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Yes,=
 outputting UCNs would be a defect. But they are decoded if preprocessor-st=
ringized.<br><div></div></div></blockquote><div><br>That is because when yo=
u stringize an identifier during preprocessing (translation phase 4) it bec=
omes a string literal, and UCNs are decoded in string literals (but not ide=
ntifiers) during translation phase 5.<br>&nbsp;</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>&nbsp;&nbsp; If we are to defi=
ne the representation it should be as if a string literal token is formed b=
y surrounding the identifier spelling in doublequotes, and then running the=
 new token through translation phase 5.&nbsp; This means the identifier uni=
versal character names will be decoded, and the identifier will be encoded =
for execution consistent with an ordinary string literal.<br></div><div><br=
>This is what usually happens when using the stringize operator. Anyway, ea=
sier just to specify that UCNs are conditionally-supported and implementati=
on-defined.<br><br>Do you agree that specifying the result makes sense, as =
long as there are no UCNs?<br></div></div></blockquote><div><br>I am now ha=
ppy with specifying exactly the format (not making it implementation-define=
d) including UCNs (note that UCNs are not conditionally-supported in identi=
fiers, they are a hard requirement)<br><br>The updated text would be as per=
 Thiago Macieira's suggestion:<br><br>The predefined template variable <spa=
n style=3D"font-family:courier new,monospace"><i>__enumerator__</i></span>
 is defined as if for every enumeration E and every unique enumerator value=
 v of that=20
enumeration, a specialization of an undefined primary template=20
variable:<br><span style=3D"font-family:courier new,monospace"><br>&nbsp;&n=
bsp;&nbsp; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp; constexpr const char* __=
enumerator__&lt;E,v&gt; =3D u8"enumerator-name";<br></span><br>had been pro=
vided, where enumerator-name is formed by concatenating the identifier of e=
ach enumerator e with value v, in declaration order, each terminated with \=
0.&nbsp; [Note: Any universal-character-names in the identifiers are decode=
d. end Note]<br><br>[Example:<br><br>&nbsp;&nbsp;&nbsp; enum Efoo<br>&nbsp;=
&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar =3D 42,<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baz =3D 43,<br>&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp; qux =3D 44,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; e=CF=80 =3D 42,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f\u=
03C0 =3D 42,<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;As if:<br><br>&nbsp;&nbs=
p;&nbsp; template &lt;class E, E&gt; extern constexpr const char* __enumera=
tor__; // undefined<br><br>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:co=
urier new,monospace">template &lt;&gt; constexpr const char* __enumerator__=
&lt;E,foo(42)&gt; =3D u8"bar\0e\u03C0\0f\u03C0\0";</span><br>&nbsp;&nbsp;&n=
bsp; <span style=3D"font-family:courier new,monospace">template &lt;&gt; co=
nstexpr const char* __enumerator__&lt;E,foo(43)&gt; =3D u8"baz\0";</span><b=
r>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:courier new,monospace">temp=
late &lt;&gt; constexpr const char* __enumerator__&lt;E,foo(44)&gt; =3D u8"=
qux\0";<br></span><br>end Example]<br><br>As pointed out by Thiago:<br><br>=
&nbsp;&nbsp;&nbsp; std::string s =3D __enumerator__&lt;E, e&gt;;<br><br>wil=
l give you the UTF-8 encoded name of the first declared enumerator of the s=
ame value of e.&nbsp; In the typical non-overlapping case, this will be e a=
nd what you expect.&nbsp; The design still makes available all the code poi=
nts (as UTF-8 completely encodes all universal characters) of all the enume=
rator identifiers, so a library author can transform and transcode this inf=
ormation into whatever structure they want.<br><br></div></div>

<p></p>

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

------=_Part_1016_448726.1380427803340--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sat, 28 Sep 2013 21:13:10 -0700 (PDT)
Raw View
------=_Part_1268_15344318.1380427990503
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Sunday, September 29, 2013 6:10:03 AM UTC+2, Andrew Tomazos wrote:
>
> On Sunday, September 29, 2013 2:20:46 AM UTC+2, David Krauss wrote:
>>
>> Yes, outputting UCNs would be a defect. But they are decoded if=20
>> preprocessor-stringized.
>>
>
> That is because when you stringize an identifier during preprocessing=20
> (translation phase 4) it becomes a string literal, and UCNs are decoded i=
n=20
> string literals (but not identifiers) during translation phase 5.
> =20
>
>>    If we are to define the representation it should be as if a string=20
>> literal token is formed by surrounding the identifier spelling in=20
>> doublequotes, and then running the new token through translation phase 5=
.. =20
>> This means the identifier universal character names will be decoded, and=
=20
>> the identifier will be encoded for execution consistent with an ordinary=
=20
>> string literal.
>>
>> This is what usually happens when using the stringize operator. Anyway,=
=20
>> easier just to specify that UCNs are conditionally-supported and=20
>> implementation-defined.
>>
>> Do you agree that specifying the result makes sense, as long as there ar=
e=20
>> no UCNs?
>>
>
> I am now happy with specifying exactly the format (not making it=20
> implementation-defined) including UCNs (note that UCNs are not=20
> conditionally-supported in identifiers, they are a hard requirement)
>
> The updated text would be as per Thiago Macieira's suggestion:
>
> The predefined template variable *__enumerator__* is defined as if for=20
> every enumeration E and every unique enumerator value v of that=20
> enumeration, a specialization of an undefined primary template variable:
>
>     template <>
>     constexpr const char* __enumerator__<E,v> =3D u8"enumerator-name";
>
> had been provided, where enumerator-name is formed by concatenating the=
=20
> identifier of each enumerator e with value v, in declaration order, each=
=20
> terminated with \0.  [Note: Any universal-character-names in the=20
> identifiers are decoded. end Note]
>
> [Example:
>
>     enum Efoo
>     {
>         bar =3D 42,
>         baz =3D 43,
>         qux =3D 44,
>         e=CF=80 =3D 42,
>         f\u03C0 =3D 42,
>     };
>
>  As if:
>
>     template <class E, E> extern constexpr const char* __enumerator__; //=
=20
> undefined
>
>     template <> constexpr const char* __enumerator__<E,foo(42)> =3D=20
> u8"bar\0e\u03C0\0f\u03C0\0";
>     template <> constexpr const char* __enumerator__<E,foo(43)> =3D=20
> u8"baz\0";
>     template <> constexpr const char* __enumerator__<E,foo(44)> =3D=20
> u8"qux\0";
>
> end Example]
>
>
Typo: s/E/Efoo/

    template <> constexpr const char* __enumerator__<Efoo,foo(42)> =3D=20
u8"bar\0e\u03C0\0f\u03C0\0";
    template <> constexpr const char* __enumerator__<Efoo,foo(43)> =3D=20
u8"baz\0";
    template <> constexpr const char* __enumerator__<Efoo,foo(44)> =3D=20
u8"qux\0";
=20

--=20

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

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

<div dir=3D"ltr"><br><br>On Sunday, September 29, 2013 6:10:03 AM UTC+2, An=
drew Tomazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">On Sunday, September 29, 2013 2:20:46 AM UTC+2, David Krauss wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Yes, outputting UCNs=
 would be a defect. But they are decoded if preprocessor-stringized.<br><di=
v></div></div></blockquote><div><br>That is because when you stringize an i=
dentifier during preprocessing (translation phase 4) it becomes a string li=
teral, and UCNs are decoded in string literals (but not identifiers) during=
 translation phase 5.<br>&nbsp;</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>&nbsp;&nbsp; If we are to define the representation=
 it should be as if a string literal token is formed by surrounding the ide=
ntifier spelling in doublequotes, and then running the new token through tr=
anslation phase 5.&nbsp; This means the identifier universal character name=
s will be decoded, and the identifier will be encoded for execution consist=
ent with an ordinary string literal.<br></div><div><br>This is what usually=
 happens when using the stringize operator. Anyway, easier just to specify =
that UCNs are conditionally-supported and implementation-defined.<br><br>Do=
 you agree that specifying the result makes sense, as long as there are no =
UCNs?<br></div></div></blockquote><div><br>I am now happy with specifying e=
xactly the format (not making it implementation-defined) including UCNs (no=
te that UCNs are not conditionally-supported in identifiers, they are a har=
d requirement)<br><br>The updated text would be as per Thiago Macieira's su=
ggestion:<br><br>The predefined template variable <span style=3D"font-famil=
y:courier new,monospace"><i>__enumerator__</i></span>
 is defined as if for every enumeration E and every unique enumerator value=
 v of that=20
enumeration, a specialization of an undefined primary template=20
variable:<br><span style=3D"font-family:courier new,monospace"><br>&nbsp;&n=
bsp;&nbsp; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp; constexpr const char* __=
enumerator__&lt;E,v&gt; =3D u8"enumerator-name";<br></span><br>had been pro=
vided, where enumerator-name is formed by concatenating the identifier of e=
ach enumerator e with value v, in declaration order, each terminated with \=
0.&nbsp; [Note: Any universal-character-names in the identifiers are decode=
d. end Note]<br><br>[Example:<br><br>&nbsp;&nbsp;&nbsp; enum Efoo<br>&nbsp;=
&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar =3D 42,<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baz =3D 43,<br>&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp; qux =3D 44,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; e=CF=80 =3D 42,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f\u=
03C0 =3D 42,<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;As if:<br><br>&nbsp;&nbs=
p;&nbsp; template &lt;class E, E&gt; extern constexpr const char* __enumera=
tor__; // undefined<br><br>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:co=
urier new,monospace">template &lt;&gt; constexpr const char* __enumerator__=
&lt;E,foo(42)&gt; =3D u8"bar\0e\u03C0\0f\u03C0\0";</span><br>&nbsp;&nbsp;&n=
bsp; <span style=3D"font-family:courier new,monospace">template &lt;&gt; co=
nstexpr const char* __enumerator__&lt;E,foo(43)&gt; =3D u8"baz\0";</span><b=
r>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:courier new,monospace">temp=
late &lt;&gt; constexpr const char* __enumerator__&lt;E,foo(44)&gt; =3D u8"=
qux\0";<br></span><br>end Example]<br><br></div></div></blockquote><div><br=
>Typo: s/E/Efoo/<br><br>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:couri=
er new,monospace">template &lt;&gt; constexpr const char* __enumerator__&lt=
;Efoo,foo(42)&gt; =3D u8"bar\0e\u03C0\0f\u03C0\0";</span><br>&nbsp;&nbsp;&n=
bsp; <span style=3D"font-family:courier new,monospace">template &lt;&gt; co=
nstexpr const char* __enumerator__&lt;Efoo,foo(43)&gt; =3D u8"baz\0";</span=
><br>&nbsp;&nbsp;&nbsp; <span style=3D"font-family:courier new,monospace">t=
emplate &lt;&gt; constexpr const char* __enumerator__&lt;Efoo,foo(44)&gt; =
=3D u8"qux\0";<br></span>&nbsp;</div></div>

<p></p>

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

------=_Part_1268_15344318.1380427990503--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sat, 28 Sep 2013 22:58:18 -0700 (PDT)
Raw View
------=_Part_1401_260895.1380434298715
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>
> The last few months I have thought about this problem and implemented a
> clang compiler extension allowing the reflection of enumeration types,
> among other things. For simplicities sake, the changes to the compiler
> consist only of the introduction of a few compiler intrinsics that expand
> into a constexpr during evaluation, similar to how type traits are already
> implemented. These are:
>     __enum_value_count(<enum-type>)  --> size_t
>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
> char []
>

The idea of indexing the enumerators by declaration position is perhaps
superior for the second primitive __enumerator__, to concatenating all
enumerators of equal value.

Perhaps a better specification for __enumerator__ is:

The predefined template variable *__enumerator__* is defined as if for
every enumeration E and every enumerator e, a specialization of an
undefined primary template variable:

    template <class E, std::size_t>
    extern constexpr const char* __enumerator__; //undefined

    template <>
    constexpr const char* __enumerator__<E,i> = u8"enumerator-name";

is provided where enumerator-name is the identifier of e, and i is the
(zero-based) index position of e in declaration order. [Note: Any
universal-character-names in the identifier are decoded. end Note]

Your other two instrinsics can be deduced trivially from the enumerator
pack primitive.

I disagree that we shouldn't standardize these two primitives as a first
step.  It is something we could do quickly, implement easily - and answers
an urgent and pressing need of all enumeration users right now.  Later on
standard library features could be added that build upon these primitives,
either as a stand-alone enumeration type traits library as you suggest, or
as part of an overarching language-wide reflection library - but there is
zero risk in standardizing these two underlying primitives now as a first
step.

--

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

------=_Part_1401_260895.1380434298715
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christi=
an Kaeser wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">The last few months I have thought about this problem and implemented a =
clang compiler extension allowing the reflection of enumeration types, amon=
g other things. For simplicities sake, the changes to the compiler consist =
only of the introduction of a few compiler intrinsics that expand into a co=
nstexpr during evaluation, similar to how type traits are already implement=
ed. These are:<br>&nbsp;&nbsp;&nbsp; __enum_value_count(&lt;enum-type&gt;<w=
br>)&nbsp; --&gt; size_t<br>&nbsp;&nbsp;&nbsp; __enum_value(&lt;enum-type&g=
t;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp; &lt;enum-type&gt;<br>&nbsp;=
&nbsp;&nbsp; __enum_value_name(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&=
nbsp; --&gt;&nbsp; UTF8 const char []<br></div></blockquote><div><br>The id=
ea of indexing the enumerators by declaration position is perhaps superior =
for the second primitive __enumerator__, to concatenating all enumerators o=
f equal value.<br><br>Perhaps a better specification for __enumerator__ is:=
<br><br>The predefined template variable <span style=3D"font-family:courier=
 new,monospace"><i>__enumerator__</i></span>
 is defined as if for every enumeration E and every enumerator e, a special=
ization of an undefined primary template=20
variable:<br><span style=3D"font-family:courier new,monospace"><br>&nbsp;&n=
bsp;&nbsp; template &lt;class E, std::size_t&gt;<br>&nbsp;&nbsp;&nbsp; exte=
rn constexpr const char* __enumerator__; //undefined<br><br>&nbsp;&nbsp;&nb=
sp; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp; constexpr const char* __enumera=
tor__&lt;E,i&gt; =3D u8"enumerator-name";</span><br><br>is provided where e=
numerator-name is the identifier of e, and i is the (zero-based) index posi=
tion of e in declaration order. [Note: Any universal-character-names in the=
 identifier are decoded. end Note]<br><br>Your other two instrinsics can be=
 deduced trivially from the enumerator pack primitive.<br><br>I disagree th=
at we shouldn't standardize these two primitives as a first step.&nbsp; It =
is something we could do quickly, implement easily - and answers an urgent =
and pressing need of all enumeration users right now.&nbsp; Later on standa=
rd library features could be added that build upon these primitives, either=
 as a stand-alone enumeration type traits library as you suggest, or as par=
t of an overarching language-wide reflection library - but there is zero ri=
sk in standardizing these two underlying primitives now as a first step.<br=
><br></div></div>

<p></p>

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

------=_Part_1401_260895.1380434298715--

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sun, 29 Sep 2013 04:19:23 -0700 (PDT)
Raw View
------=_Part_1330_22577839.1380453563331
Content-Type: text/plain; charset=ISO-8859-1

Thanks, I agree that especially for reflection library solutions are
preferable to language extensions, simply because of the specification work
new language rules require, and the (understandably) large committee
scrutiny/resistance they would have to face.
I think very good reasons should to be brought forth as to why a
libary-only change would not be good enough.

Concerning your comment, for what specific purpose do you want enum switch
statement support in this scenario? I agree that it would be one solution
for run-time enum-value -> enumerator-name lookup. But in my current
implementation, I designed several lookup functors (taking an enum-value,
returning something like an enumerator-index) for this purpose, that use
various algorithms for the lookup. These could be automatically selected
based on certain enum type properties. That would employ more or less the
techniques of a compiler optimized switch statement, and therefore should
deliver comparable performance. Allowing templated generation of switch
cases has been debated on here before I think, but I fear that this might
be hard to realize.

On Sunday, 29 September 2013 02:05:50 UTC+2, inkwizyt...@gmail.com wrote:
>
> This look better than original proposition, mainly because its library
> extension, it could be even fake in current C++ using some macro magic.
> Now only thing that that will this lack is some way for switch statement
> support, because you cant add new cases when enum change size.
>
> On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>>
>> This sounds like an interesting approach, but I'm not so sure if it is
>> free of possible parsing ambiguities and if its degree of flexibility is
>> quite enough for all use cases, e.g. efficient implementation of flag sets
>> or arrays indexed by an enum.
>>
>> The last few months I have thought about this problem and implemented a
>> clang compiler extension allowing the reflection of enumeration types,
>> among other things. For simplicities sake, the changes to the compiler
>> consist only of the introduction of a few compiler intrinsics that expand
>> into a constexpr during evaluation, similar to how type traits are already
>> implemented. These are:
>>     __enum_value_count(<enum-type>)  --> size_t
>>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
>> char []
>>
>> Of course, something like this should not be the standardized public
>> interface, as these intrinsics are probably too awkward to use for the
>> average programmer and too large a deviation from current practice. But
>> using the new C++14 addition "Compile-time integer sequences" (N3658), this
>> can easily be brought into a much nicer form which could fullfill the role
>> of a public API:
>>
>>     template<class E, class IdxSeq>
>>     struct enum_data_t;
>>
>>     // requires a correct index sequence pack to expand the values:
>>     template<class E, size_t... Idx>
>>     struct enum_data_t<E, std::index_sequence<Idx...>> {
>>         static constexpr size_t count = __enum_value_count(E);
>>         static constexpr E values[] = { __enum_value(E, Idx)... };
>>         static constexpr char const *names[] = { __enum_value_name(E,
>> Idx)... };
>>     };
>>
>>     // always use the correct index sequence for the given enum
>>     template<class E>
>>     using enum_data = enum_data_t<E, std::make_index_sequence<
>> __enum_value_count(E) >>;
>>
>>     // for odr-use:
>>     template<typename E, size_t... Idx>
>>     constexpr E enum_data_t<E, std::index_sequence<Idx...>>::values[];
>>     template<typename E, size_t... Idx>
>>     constexpr char const * enum_data_t<E,
>> std::index_sequence<Idx...>>::names[];
>>
>>     // usage:
>>     enum class E1 { first = 99, second = first };
>>     using E1D = enum_data<E1>;
>>     for (int i=0; i<E1D::count; i++)
>>         std::cout << E1D::names[i] << " = " << (int)E1D::values[i] <<
>> std::endl;
>>
>> With the new constexpr relaxations coming in C++14 this could even be
>> enough for all compile-time purposes. Otherwise, the individual intrinsics
>> could also be exposed similar to existing type traits:
>>
>>     template<class E, size_t Idx>
>>     struct enumerator_value {
>>         static constexpr E value = __enum_value(E, Idx);
>>     };
>>
>> I have also experimented a lot with more advanced functionality that
>> could be provided on this basis. Among these is the pretty tricky
>> (considering all edge cases) lookup-by-value to access the enumerator
>> name/index. That in turn can function as a base for more interesting enum
>> use cases like flag sets, enum arrays, I/O via iostream etc.
>>
>> Is there interest in my implementation? I could make it available via
>> github. I would hope it might be of interest to anyone wanting to
>> experiment with possible prospective std lib interfaces.
>>
>> Does anyone know anything further about SG7, the reflection study group?
>> The forum on here seems to be empty, and not a lot of proposals have been
>> put forth for quite a while now. I would be very interested in a discussion
>> about concrete, low-hanging-fruit reflection aspects that could hopefully
>> be ready for the C++17 timeline.
>>
>

--

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

------=_Part_1330_22577839.1380453563331
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thanks, I agree that especially for reflection library sol=
utions are preferable to language extensions, simply because of the specifi=
cation work new language rules require, and the (understandably) large comm=
ittee scrutiny/resistance they would have to face. <br>I think very good re=
asons should to be brought forth as to why a libary-only change would not b=
e good enough.<br><br>Concerning your comment, for what specific purpose do=
 you want enum switch statement support in this scenario? I agree that it w=
ould be one solution for run-time enum-value -&gt; enumerator-name lookup. =
But in my current implementation, I designed several lookup functors (takin=
g an enum-value, returning something like an enumerator-index) for this pur=
pose, that use various algorithms for the lookup. These could be automatica=
lly selected based on certain enum type properties. That would employ more =
or less the techniques of a compiler optimized switch statement, and theref=
ore should deliver comparable performance. Allowing templated generation of=
 switch cases has been debated on here before I think, but I fear that this=
 might be hard to realize.<br><br>On Sunday, 29 September 2013 02:05:50 UTC=
+2, inkwizyt...@gmail.com  wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">This look better than original proposition, mainly beca=
use its library extension, it could be even fake in current C++ using some =
macro magic.<br>Now only thing that that will this lack is some way for swi=
tch statement support, because you cant add new cases when enum change size=
..<br><br>On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaese=
r wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">This sound=
s like an interesting approach, but I'm not so sure if it is free of possib=
le parsing ambiguities and if its degree of flexibility is quite enough for=
 all use cases, e.g. efficient implementation of flag sets or arrays indexe=
d by an enum.<br><br>The last few months I have thought about this problem =
and implemented a clang compiler extension allowing the reflection of enume=
ration types, among other things. For simplicities sake, the changes to the=
 compiler consist only of the introduction of a few compiler intrinsics tha=
t expand into a constexpr during evaluation, similar to how type traits are=
 already implemented. These are:<br>&nbsp;&nbsp;&nbsp; __enum_value_count(&=
lt;enum-type&gt;<wbr>)&nbsp; --&gt; size_t<br>&nbsp;&nbsp;&nbsp; __enum_val=
ue(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp; &lt;enum-=
type&gt;<br>&nbsp;&nbsp;&nbsp; __enum_value_name(&lt;enum-type&gt;, &lt;ind=
ex-constexpr&gt;)&nbsp; --&gt;&nbsp; UTF8 const char []<br><br>Of course, s=
omething like this should not be the standardized public interface, as thes=
e intrinsics are probably too awkward to use for the average programmer and=
 too large a deviation from current practice. But using the new C++14 addit=
ion "Compile-time integer sequences" (N3658), this can easily be brought in=
to a much nicer form which could fullfill the role of a public API:<br><br>=
&nbsp;&nbsp;&nbsp; template&lt;class E, class IdxSeq&gt;<br>&nbsp;&nbsp;&nb=
sp; struct enum_data_t;<br><br>&nbsp;&nbsp;&nbsp; // requires a correct ind=
ex sequence pack to expand the values:<br>&nbsp;&nbsp;&nbsp; template&lt;cl=
ass E, size_t... Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enum_data_t&lt;E, std=
::index_sequence&lt;Idx...&gt;&gt; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbs=
p; static constexpr size_t count =3D __enum_value_count(E);<br>&nbsp;&nbsp;=
&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E values[] =3D { __enum_value(E,=
 Idx)... };<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr char =
const *names[] =3D { __enum_value_name(E, Idx)... };<br>&nbsp;&nbsp;&nbsp; =
};<br><br>&nbsp;&nbsp;&nbsp; // always use the correct index sequence for t=
he given enum<br>&nbsp;&nbsp;&nbsp; template&lt;class E&gt;<br>&nbsp;&nbsp;=
&nbsp; using enum_data =3D enum_data_t&lt;E, std::make_index_sequence&lt; _=
_enum_value_count(E) &gt;&gt;;<br><br>&nbsp;&nbsp;&nbsp; // for odr-use:<br=
>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t... Idx&gt; <br>&nbsp;&nb=
sp;&nbsp; constexpr E enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&g=
t;::<wbr>values[];<br>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t... =
Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr char const * enum_data_t&lt;E, std=
::index_sequence&lt;Idx...&gt;&gt;::<wbr>names[];<br><br>&nbsp;&nbsp;&nbsp;=
 // usage:<br>&nbsp;&nbsp;&nbsp; enum class E1 { first =3D 99, second =3D f=
irst };<br>&nbsp;&nbsp;&nbsp; using E1D =3D enum_data&lt;E1&gt;;<br>&nbsp;&=
nbsp;&nbsp; for (int i=3D0; i&lt;E1D::count; i++)<br>&nbsp;&nbsp;&nbsp; &nb=
sp;&nbsp;&nbsp; std::cout &lt;&lt; E1D::names[i] &lt;&lt; " =3D " &lt;&lt; =
(int)E1D::values[i] &lt;&lt; std::endl;<br><br>With the new constexpr relax=
ations coming in C++14 this could even be enough for all compile-time purpo=
ses. Otherwise, the individual intrinsics could also be exposed similar to =
existing type traits:<br><br>&nbsp;&nbsp;&nbsp; template&lt;class E, size_t=
 Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enumerator_value {<br>&nbsp;&nbsp;&nb=
sp; &nbsp;&nbsp;&nbsp; static constexpr E value =3D __enum_value(E, Idx);<b=
r>&nbsp;&nbsp;&nbsp; };<br><br>I have also experimented a lot with more adv=
anced functionality that could be provided on this basis. Among these is th=
e pretty tricky (considering all edge cases) lookup-by-value to access the =
enumerator name/index. That in turn can function as a base for more interes=
ting enum use cases like flag sets, enum arrays, I/O via iostream etc.<br><=
br>Is there interest in my implementation? I could make it available via gi=
thub. I would hope it might be of interest to anyone wanting to experiment =
with possible prospective std lib interfaces.<br><br>Does anyone know anyth=
ing further about SG7, the reflection study group? The forum on here seems =
to be empty, and not a lot of proposals have been put forth for quite a whi=
le now. I would be very interested in a discussion about concrete, low-hang=
ing-fruit reflection aspects that could hopefully be ready for the C++17 ti=
meline.<br></div></blockquote></div></blockquote></div>

<p></p>

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

------=_Part_1330_22577839.1380453563331--

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sun, 29 Sep 2013 04:28:32 -0700 (PDT)
Raw View
------=_Part_91_1055363.1380454112189
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, 29 September 2013 05:09:46 UTC+2, Andrew Tomazos wrote:

> While that may be the case for the original proposal (not that I am aware
> of a specific ambiguity), with David Krauss's suggested adjustment there
> clearly are no ambiguities:
>
> That is: A non-type parameter pack of enum type E, will match by a type
> argument of enum type E, semantically expanding to the enumerator list of
> the enumeration:
>
>     enum E { a, b, c };
>
>     template<E...> f();
>
>     f<E>(); // expands to f<a,b,c>();
>
>
You are correct, I first thought the original proposition was "enum types
are implicitly parameter packs", which of course would create lots of
problems. If really only "enum-name ..." would be allowed (e.g. the
ellipsis has to follow the type-name directly), I would find the
similarities/differences this (very) special case would have to regular
parameter packs quite problematic/limiting/hard to teach.

As for David Krauss's proposal, this seems interesting, but again (like
nearly any language change) is bound to have a lot of problematic corner
cases. Take this example:

    template<class T, T... Ts>
    void problematic() { std::cout << "1"; }

    template<class T, class U>
    void problematic() { std::cout << "2"; }

Currently, there is no ambiguity when called this way:

    enum Enum {};
    problematic<Enum, Enum>();

But what would happen with the new proposed way of implicit expansion?

Even without this specific problem, I find such an implicit conversion
(from a type into a value-parameter-list) very surprising and therefore
problematic. In my opinion, such a big, "magical" feature needs to be way
more explicit. Why not expose such functionality only through the standard
library? This way all the trouble of a core language change is also avoided.



> The important thing is to provide the enumerator list during translation
> to library authors.
>
> and if its degree of flexibility is quite enough for all use cases, e.g.
>> efficient implementation of flag sets or arrays indexed by an enum.
>>
>
> The intention of the two primitives is to make it possible for you to
> implement all of these things as library features.   Once you have the
> enumerator list as a pack I believe during translation you should be able
> to create "flag sets" or "arrays indexed by an enum" or whatever other
> fruit you may want.  You will have statically all the information available
> about the enumerators and their values.
>

I understand that and have exactly the same goal as you, to see some form
of enum reflection in the standard. The question of how to get there is of
course the big one.


>
> For example I would claim (or at least intend that) the entire library and
> API you specified could be implemented during translation with generic
> programming based on the two primitives.
>
> It would be helpful if you could provide an example of a library feature
> you want where this is not the case.
>
>
The example "enum_data" interface I presented could not be reproduced with
these two primitives in the general case. In my original post I think I
forgot to clarify how my interface works exactly (as mentioned, already
implemented in clang). Given an enum type:
    enum E1 {
        e0,
        e1 = 10,
        elast = e0
    };

Then given my "enum_data" definition from before the following would hold:
    enum_data<E1>::count == 3 == __enum_value_count(E1)  //
__enumerator_count might be a better name..
    enum_data<E1>::values == [ 0, 10, 0 ]
    enum_data<E1>::names == [ "e0", "e1", "elast" ]

This is a very low level view of an enumeration, as it keeps the complete
ordering even of duplicate values in the enum definition. This could not be
reconstructed with your/David Krauss's approach, as a "enum_data" filled
with your primitives would look like this:
    enum_data<E1>::count == 2
    enum_data<E1>::values == [ 0, 10 ]
    enum_data<E1>::names == [ "e0\0elast\0", "e1\0" ] // or similar?

I mainly chose my way for implementation as it was trivial to do in clang
(clang already keeps all defined enumerators in this order) and because I
wanted to expose as much information as possible for experimenting.

One application I could think of where my interface might be desirable
would be a graphical/console interface where the user can select the value
for an enum out of a list of all options. Here, the original enumerator
order might be nice to have. Of course, I myself am not totally convinced
that this is really an important scenario.


--

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

------=_Part_91_1055363.1380454112189
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, 29 September 2013 05:09:46 UTC+2, Andre=
w Tomazos  wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>While that may be the case for the original proposal (not tha=
t I am aware of a specific ambiguity), with David Krauss's suggested adjust=
ment there clearly are no ambiguities:<br><br>That is: A non-type parameter=
 pack of enum type E, will match by a type argument of enum type E, semanti=
cally expanding to the enumerator list of the enumeration:<br><span style=
=3D"font-family:courier new,monospace"><br>&nbsp;&nbsp;&nbsp; enum E { a, b=
, c };<br><br>&nbsp;&nbsp;&nbsp; template&lt;E...&gt; f();<br><br>&nbsp;&nb=
sp;&nbsp; f&lt;E&gt;(); // expands to f&lt;a,b,c&gt;();<br><br></span></div=
></div></blockquote><div><br>You are correct, I first thought the original =
proposition was "enum types are implicitly parameter packs", which of cours=
e would create lots of problems. If really only "enum-name ..." would be al=
lowed (e.g. the ellipsis has to follow the type-name directly), I would fin=
d the similarities/differences this (very) special case would have to regul=
ar parameter packs quite problematic/limiting/hard to teach.<br><br>As for =
David Krauss's proposal, this seems interesting, but again (like nearly any=
 language change) is bound to have a lot of problematic corner cases. Take =
this example:<br><br>&nbsp;&nbsp;&nbsp; template&lt;class T, T... Ts&gt;<br=
>&nbsp;&nbsp;&nbsp; void problematic() { std::cout &lt;&lt; "1"; }<br><br>&=
nbsp;&nbsp;&nbsp; template&lt;class T, class U&gt;<br>&nbsp;&nbsp;&nbsp; vo=
id problematic() { std::cout &lt;&lt; "2"; }<br><br>Currently, there is no =
ambiguity when called this way:<br><br>&nbsp;&nbsp;&nbsp; enum Enum {};<br>=
&nbsp;&nbsp;&nbsp; problematic&lt;Enum, Enum&gt;();<br><br>But what would h=
appen with the new proposed way of implicit expansion?<br><br>Even without =
this specific problem, I find such an implicit conversion (from a type into=
 a value-parameter-list) very surprising and therefore problematic. In my o=
pinion, such a big, "magical" feature needs to be way more explicit. Why no=
t expose such functionality only through the standard library? This way all=
 the trouble of a core language change is also avoided.<br><br>&nbsp;</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><span st=
yle=3D"font-family:courier new,monospace"></span>The important thing is to =
provide the enumerator list during translation to library authors.<br><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">and if its de=
gree of flexibility is quite enough for all use cases, e.g. efficient imple=
mentation of flag sets or arrays indexed by an enum.<br></div></blockquote>=
<div><br>The intention of the two primitives is to make it possible for you=
 to implement all of these things as library features. &nbsp; Once you have=
 the enumerator list as a pack I believe during translation you should be a=
ble to create "flag sets" or "arrays indexed by an enum" or whatever other =
fruit you may want.&nbsp; You will have statically all the information avai=
lable about the enumerators and their values.<br></div></div></blockquote><=
div><br>I understand that and have exactly the same goal as you, to see som=
e form of enum reflection in the standard. The question of how to get there=
 is of course the big one.<br>&nbsp;</div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div><br>For example I would claim (or at leas=
t intend that) the entire library and API you specified could be implemente=
d during translation with generic programming based on the two primitives.<=
br><br>It would be helpful if you could provide an example of a library fea=
ture you want where this is not the case.<br><br></div></div></blockquote><=
div><br>The example "enum_data" interface I presented could not be reproduc=
ed with these two primitives in the general case. In my original post I thi=
nk I forgot to clarify how my interface works exactly (as mentioned, alread=
y implemented in clang). Given an enum type:<br>&nbsp;&nbsp;&nbsp; enum E1 =
{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e0,<br>&nbsp;&nbsp;&nbsp; &nbsp;=
&nbsp;&nbsp; e1 =3D 10,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; elast =3D =
e0<br>&nbsp;&nbsp;&nbsp; };<br><br>Then given my "enum_data" definition fro=
m before the following would hold:<br>&nbsp;&nbsp;&nbsp; enum_data&lt;E1&gt=
;::count =3D=3D 3 =3D=3D __enum_value_count(E1)&nbsp; // __enumerator_count=
 might be a better name..<br>&nbsp;&nbsp;&nbsp; enum_data&lt;E1&gt;::values=
 =3D=3D [ 0, 10, 0 ]<br>&nbsp;&nbsp;&nbsp; enum_data&lt;E1&gt;::names =3D=
=3D [ "e0", "e1", "elast" ]<br><br>This is a very low level view of an enum=
eration, as it keeps the complete ordering even of duplicate values in the =
enum definition. This could not be reconstructed with your/David Krauss's a=
pproach, as a "enum_data" filled with your primitives would look like this:=
<br>&nbsp;&nbsp;&nbsp; enum_data&lt;E1&gt;::count =3D=3D 2<br>&nbsp;&nbsp;&=
nbsp; enum_data&lt;E1&gt;::values =3D=3D [ 0, 10 ]<br>&nbsp;&nbsp;&nbsp; en=
um_data&lt;E1&gt;::names =3D=3D [ "e0\0elast\0", "e1\0" ] // or similar?<br=
><br>I mainly chose my way for implementation as it was trivial to do in cl=
ang (clang already keeps all defined enumerators in this order) and because=
 I wanted to expose as much information as possible for experimenting.<br><=
br>One application I could think of where my interface might be desirable w=
ould be a graphical/console interface where the user can select the value f=
or an enum out of a list of all options. Here, the original enumerator orde=
r might be nice to have. Of course, I myself am not totally convinced that =
this is really an important scenario.<br>&nbsp;</div></div>

<p></p>

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

------=_Part_91_1055363.1380454112189--

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sun, 29 Sep 2013 04:36:34 -0700 (PDT)
Raw View
------=_Part_1391_27460266.1380454594298
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, 29 September 2013 07:58:18 UTC+2, Andrew Tomazos wrote:
>
> On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>>
>> The last few months I have thought about this problem and implemented a
>> clang compiler extension allowing the reflection of enumeration types,
>> among other things. For simplicities sake, the changes to the compiler
>> consist only of the introduction of a few compiler intrinsics that expand
>> into a constexpr during evaluation, similar to how type traits are already
>> implemented. These are:
>>     __enum_value_count(<enum-type>)  --> size_t
>>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
>> char []
>>
>
> The idea of indexing the enumerators by declaration position is perhaps
> superior for the second primitive __enumerator__, to concatenating all
> enumerators of equal value.
>
> Perhaps a better specification for __enumerator__ is:
>
> The predefined template variable *__enumerator__* is defined as if for
> every enumeration E and every enumerator e, a specialization of an
> undefined primary template variable:
>
>     template <class E, std::size_t>
>     extern constexpr const char* __enumerator__; //undefined
>
>     template <>
>     constexpr const char* __enumerator__<E,i> = u8"enumerator-name";
>
> is provided where enumerator-name is the identifier of e, and i is the
> (zero-based) index position of e in declaration order. [Note: Any
> universal-character-names in the identifier are decoded. end Note]
>
> Your other two instrinsics can be deduced trivially from the enumerator
> pack primitive.
>
>
Wait, maybe there has been a misunderstanding here. I am not suggesting to
standardize my __enum... intrinsics, they are purely an implementation
detail very similar to how e.g. the standard library class std::is_enum is
implemented via the __is_enum intrinsic in GCC/clang. I am suggesting to
standardize some kind of thin library wrapper around such a functionality.

As I have described, I am convinced that - especially for enum reflection -
core language changes are not necessary, as library extensions can fully
handle this (just like type traits are also implement as library
extensions).



> I disagree that we shouldn't standardize these two primitives as a first
> step.  It is something we could do quickly, implement easily - and answers
> an urgent and pressing need of all enumeration users right now.  Later on
> standard library features could be added that build upon these primitives,
> either as a stand-alone enumeration type traits library as you suggest, or
> as part of an overarching language-wide reflection library - but there is
> zero risk in standardizing these two underlying primitives now as a first
> step.
>
>
I am not saying we should wait for very high level reflection library
features. I just think that a "nicer" (e.g. more in terms with previous
language style) form has to be found, otherwise I can't imagine committee
acceptance of such a proposal.

Taking your new suggestion for __enumerator__, these would be my proposals
for a library interface. All could be part of a new std::meta namespace, or
simply std.

1) template variable like you suggested, but why not simply call it
"enumerator_name" (and keep it in array form instead of decaying into a
pointer):

    template<typename E, size_t Idx>
    constexpr decltype(auto) enumerator_name = /* see definition, in my
implementation simply __enum_value_name(E, Idx) */;

2) classic type trait like struct - this has the advantage of precedent in
the library, instead of a new style:

    template<typename E, size_t Idx>
    struct enumerator_name {
        // member could be called "c_str" or "value" or "name" or ...
        static constexpr decltype(auto) c_str = /*__enum_value_name(E,
Idx)*/;
    };

3) something like my previous "enum_data" suggestion:

    template<typename E>
    struct enumerator_data {
        static constexpr size_t count = /*__enum_value_count(E)*/;
        static constexpr E values[] = /*{ __enum_value(E, Idx)... }*/;
        static constexpr char const *names[] = /*{ __enum_value_name(E,
Idx)... }*/;
    };


Of course, thinking/discussing about concrete more advanced use cases
building on these(or similar) interfaces would probably be a good idea,
simply as motivational cases for a proposal paper and to gather some
practical experience.

--

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

------=_Part_1391_27460266.1380454594298
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, 29 September 2013 07:58:18 UTC+2, Andre=
w Tomazos  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">The last few mo=
nths I have thought about this problem and implemented a clang compiler ext=
ension allowing the reflection of enumeration types, among other things. Fo=
r simplicities sake, the changes to the compiler consist only of the introd=
uction of a few compiler intrinsics that expand into a constexpr during eva=
luation, similar to how type traits are already implemented. These are:<br>=
&nbsp;&nbsp;&nbsp; __enum_value_count(&lt;enum-type&gt;<wbr>)&nbsp; --&gt; =
size_t<br>&nbsp;&nbsp;&nbsp; __enum_value(&lt;enum-type&gt;, &lt;index-cons=
texpr&gt;)&nbsp; --&gt;&nbsp; &lt;enum-type&gt;<br>&nbsp;&nbsp;&nbsp; __enu=
m_value_name(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp;=
 UTF8 const char []<br></div></blockquote><div><br>The idea of indexing the=
 enumerators by declaration position is perhaps superior for the second pri=
mitive __enumerator__, to concatenating all enumerators of equal value.<br>=
<br>Perhaps a better specification for __enumerator__ is:<br><br>The predef=
ined template variable <span style=3D"font-family:courier new,monospace"><i=
>__enumerator__</i></span>
 is defined as if for every enumeration E and every enumerator e, a special=
ization of an undefined primary template=20
variable:<br><span style=3D"font-family:courier new,monospace"><br>&nbsp;&n=
bsp;&nbsp; template &lt;class E, std::size_t&gt;<br>&nbsp;&nbsp;&nbsp; exte=
rn constexpr const char* __enumerator__; //undefined<br><br>&nbsp;&nbsp;&nb=
sp; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp; constexpr const char* __enumera=
tor__&lt;E,i&gt; =3D u8"enumerator-name";</span><br><br>is provided where e=
numerator-name is the identifier of e, and i is the (zero-based) index posi=
tion of e in declaration order. [Note: Any universal-character-names in the=
 identifier are decoded. end Note]<br><br>Your other two instrinsics can be=
 deduced trivially from the enumerator pack primitive.<br><br></div></div><=
/blockquote><div><br>Wait, maybe there has been a misunderstanding here. I =
am not suggesting to standardize my __enum... intrinsics, they are purely a=
n implementation detail very similar to how e.g. the standard library class=
 std::is_enum is implemented via the __is_enum intrinsic in GCC/clang. I am=
 suggesting to standardize some kind of thin library wrapper around such a =
functionality.<br><br>As I have described, I am convinced that - especially=
 for enum reflection - core language changes are not necessary, as library =
extensions can fully handle this (just like type traits are also implement =
as library extensions).<br><br>&nbsp;</div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr"><div>I disagree that we shouldn't standardize=
 these two primitives as a first step.&nbsp; It is something we could do qu=
ickly, implement easily - and answers an urgent and pressing need of all en=
umeration users right now.&nbsp; Later on standard library features could b=
e added that build upon these primitives, either as a stand-alone enumerati=
on type traits library as you suggest, or as part of an overarching languag=
e-wide reflection library - but there is zero risk in standardizing these t=
wo underlying primitives now as a first step.<br><br></div></div></blockquo=
te><div><br>I am not saying we should wait for very high level reflection l=
ibrary features. I just think that a "nicer" (e.g. more in terms with previ=
ous language style) form has to be found, otherwise I can't imagine committ=
ee acceptance of such a proposal.<br><br>Taking your new suggestion for __e=
numerator__, these would be my proposals for a library interface. All could=
 be part of a new std::meta namespace, or simply std.<br><br>1) template va=
riable like you suggested, but why not simply call it "enumerator_name" (an=
d keep it in array form instead of decaying into a pointer):<br><br>&nbsp;&=
nbsp; &nbsp;template&lt;typename E, size_t Idx&gt;<br>&nbsp;&nbsp; &nbsp;co=
nstexpr decltype(auto) enumerator_name =3D /* see definition, in my impleme=
ntation simply __enum_value_name(E, Idx) */;<br><br>2) classic type trait l=
ike struct - this has the advantage of precedent in the library, instead of=
 a new style:<br><br>&nbsp;&nbsp; &nbsp;template&lt;typename E, size_t Idx&=
gt;<br>&nbsp;&nbsp; &nbsp;struct enumerator_name {<br>&nbsp;&nbsp; &nbsp;&n=
bsp;&nbsp; &nbsp;// member could be called "c_str" or "value" or "name" or =
....<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;static constexpr decltype(auto=
) c_str =3D /*__enum_value_name(E, Idx)*/;<br>&nbsp;&nbsp; &nbsp;};<br><br>=
3) something like my previous "enum_data" suggestion:<br><br>&nbsp;&nbsp; &=
nbsp;template&lt;typename E&gt;<br>&nbsp;&nbsp; &nbsp;struct enumerator_dat=
a {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;static constexpr size_t count =
=3D /*__enum_value_count(E)*/;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;sta=
tic constexpr E values[] =3D /*{ __enum_value(E, Idx)... }*/;<br>&nbsp;&nbs=
p; &nbsp;&nbsp;&nbsp; &nbsp;static constexpr char const *names[] =3D /*{ __=
enum_value_name(E, Idx)... }*/;<br>&nbsp;&nbsp; &nbsp;};<br><br><br>Of cour=
se, thinking/discussing about concrete more advanced use cases building on =
these(or similar) interfaces would probably be a good idea, simply as motiv=
ational cases for a proposal paper and to gather some practical experience.=
<br></div></div>

<p></p>

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

------=_Part_1391_27460266.1380454594298--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 29 Sep 2013 07:10:49 -0700 (PDT)
Raw View
------=_Part_65_6933073.1380463849792
Content-Type: text/plain; charset=ISO-8859-1

Sometimes you want chose program action based on enum value. Right now you
can do it creating switch statement that will chose correct action, but
this is error prone because if someone add new enum value your code will
break (depending on if that value should have special handling). With
templates from your proposition is possible to handle that situation:
template<typename Enum, int pos>
void switch_(Enum e)
{
    if(enum_data<E1>::values[pos] == e)
        Action<enum_data<E1>::values[pos]>::func();
    else
        switch_<Enum, pos + 1>(e);
}
but as you can see it require some additional boilerplate code to work and
have similar performance as hand written switch (O(log n) or O(1) in some
cases). Additional problems is multiple function calls that need be removed
by compiler, this will slow down debug builds because they usually dont
have optimization.

One possible solution I have is introduce new version of `for` that will
"iterate" on compiling time (resolving `switch` is only one use case of
this):
template<typename... T>
void func()
{
    for...(Ti : T)// Ti is element from pack T equal [A, B, C]
    {
        Ti::func();
    }
    //this will generate code similar to:
    //
    //    A::func();
    //    B::func();
    //    C::func();
    //
}

template<int... I>
int switch_(int i)
{
    switch(i)
    {
        for...(ii : I) //I is pack of [1, 3, 2]
        {
            case ii: return Type<ii>::value;
        }
        //this will generate code similar to:
        //
        //    case 1: return Type<1>::value;
        //    case 3: return Type<3>::value;
        //    case 2: return Type<2>::value;
        //
    }
}
template<Enum... E>
void switch2_(Enum e)
{
    switch(e)
    {
        for...(ee : E) //E is pack of [Enum::a1, Enum::a2, Enum::a3]
        {
            case ee:
                A<ee>();
                A2<ee>();
                break;
        }
        default:
            break;

        //this will create code similar to:
        //
        //   case Enum::a1: A<Enum::a1>(); A2<Enum::a1>(); break;
        //   case Enum::a2: A<Enum::a2>(); A2<Enum::a2>(); break;
        //   case Enum::a3: A<Enum::a3>(); A2<Enum::a3>(); break;
        //   default: break;
        //
    }
}
But this is separate proposition to "enumeration pack". And even change
core language more than Andrew Tomazos proposition.
Funny thing, I like more your proposition but Andrew ones have more* *synergies
with my `for`:
void func(Enum e)
{
    switch(e)
    {
        for...(ee : Enum...) //create pack of [Enum::a1, Enum::a2,
Enum::a3, Enum::a4]
        {
            case ee: /*do somthing*/ break;
        }
    }
}




On Sunday, September 29, 2013 1:19:23 PM UTC+2, Christian Kaeser wrote:
>
> Thanks, I agree that especially for reflection library solutions are
> preferable to language extensions, simply because of the specification work
> new language rules require, and the (understandably) large committee
> scrutiny/resistance they would have to face.
> I think very good reasons should to be brought forth as to why a
> libary-only change would not be good enough.
>
> Concerning your comment, for what specific purpose do you want enum switch
> statement support in this scenario? I agree that it would be one solution
> for run-time enum-value -> enumerator-name lookup. But in my current
> implementation, I designed several lookup functors (taking an enum-value,
> returning something like an enumerator-index) for this purpose, that use
> various algorithms for the lookup. These could be automatically selected
> based on certain enum type properties. That would employ more or less the
> techniques of a compiler optimized switch statement, and therefore should
> deliver comparable performance. Allowing templated generation of switch
> cases has been debated on here before I think, but I fear that this might
> be hard to realize.
>
> On Sunday, 29 September 2013 02:05:50 UTC+2, inkwizyt...@gmail.com wrote:
>>
>> This look better than original proposition, mainly because its library
>> extension, it could be even fake in current C++ using some macro magic.
>> Now only thing that that will this lack is some way for switch statement
>> support, because you cant add new cases when enum change size.
>>
>> On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:
>>>
>>> This sounds like an interesting approach, but I'm not so sure if it is
>>> free of possible parsing ambiguities and if its degree of flexibility is
>>> quite enough for all use cases, e.g. efficient implementation of flag sets
>>> or arrays indexed by an enum.
>>>
>>> The last few months I have thought about this problem and implemented a
>>> clang compiler extension allowing the reflection of enumeration types,
>>> among other things. For simplicities sake, the changes to the compiler
>>> consist only of the introduction of a few compiler intrinsics that expand
>>> into a constexpr during evaluation, similar to how type traits are already
>>> implemented. These are:
>>>     __enum_value_count(<enum-type>)  --> size_t
>>>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>>>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
>>> char []
>>>
>>> Of course, something like this should not be the standardized public
>>> interface, as these intrinsics are probably too awkward to use for the
>>> average programmer and too large a deviation from current practice. But
>>> using the new C++14 addition "Compile-time integer sequences" (N3658), this
>>> can easily be brought into a much nicer form which could fullfill the role
>>> of a public API:
>>>
>>>     template<class E, class IdxSeq>
>>>     struct enum_data_t;
>>>
>>>     // requires a correct index sequence pack to expand the values:
>>>     template<class E, size_t... Idx>
>>>     struct enum_data_t<E, std::index_sequence<Idx...>> {
>>>         static constexpr size_t count = __enum_value_count(E);
>>>         static constexpr E values[] = { __enum_value(E, Idx)... };
>>>         static constexpr char const *names[] = { __enum_value_name(E,
>>> Idx)... };
>>>     };
>>>
>>>     // always use the correct index sequence for the given enum
>>>     template<class E>
>>>     using enum_data = enum_data_t<E, std::make_index_sequence<
>>> __enum_value_count(E) >>;
>>>
>>>     // for odr-use:
>>>     template<typename E, size_t... Idx>
>>>     constexpr E enum_data_t<E, std::index_sequence<Idx...>>::values[];
>>>     template<typename E, size_t... Idx>
>>>     constexpr char const * enum_data_t<E,
>>> std::index_sequence<Idx...>>::names[];
>>>
>>>     // usage:
>>>     enum class E1 { first = 99, second = first };
>>>     using E1D = enum_data<E1>;
>>>     for (int i=0; i<E1D::count; i++)
>>>         std::cout << E1D::names[i] << " = " << (int)E1D::values[i] <<
>>> std::endl;
>>>
>>> With the new constexpr relaxations coming in C++14 this could even be
>>> enough for all compile-time purposes. Otherwise, the individual intrinsics
>>> could also be exposed similar to existing type traits:
>>>
>>>     template<class E, size_t Idx>
>>>     struct enumerator_value {
>>>         static constexpr E value = __enum_value(E, Idx);
>>>     };
>>>
>>> I have also experimented a lot with more advanced functionality that
>>> could be provided on this basis. Among these is the pretty tricky
>>> (considering all edge cases) lookup-by-value to access the enumerator
>>> name/index. That in turn can function as a base for more interesting enum
>>> use cases like flag sets, enum arrays, I/O via iostream etc.
>>>
>>> Is there interest in my implementation? I could make it available via
>>> github. I would hope it might be of interest to anyone wanting to
>>> experiment with possible prospective std lib interfaces.
>>>
>>> Does anyone know anything further about SG7, the reflection study group?
>>> The forum on here seems to be empty, and not a lot of proposals have been
>>> put forth for quite a while now. I would be very interested in a discussion
>>> about concrete, low-hanging-fruit reflection aspects that could hopefully
>>> be ready for the C++17 timeline.
>>>
>>

--

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

------=_Part_65_6933073.1380463849792
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sometimes you want chose program action based on enum valu=
e. Right now you can do it creating switch statement that will chose correc=
t action, but this is error prone because if someone add new enum value you=
r code will break (depending on if that value should have special handling)=
.. With templates from your proposition is possible to handle that situation=
:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templat=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Enum</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> pos</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> switc=
h_</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">Enum</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> e</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>&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0=
, 255);"><span class=3D"styled-by-prettify">if</span></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">enum_data</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">E1</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;::</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">values</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">pos</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> e</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Action</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">enum_data</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">E1</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">values</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">[</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">pos</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"></span></code>&gt;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">::func();<br>&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0=
, 0, 255);">else</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switc=
h_&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><cod=
e class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"></span><span style=3D"color: #606;" class=3D"styled-by-prettify">Enu=
m</span><span style=3D"color: #660;" class=3D"styled-by-prettify">, </span>=
</code></span><span style=3D"color: #000;" class=3D"styled-by-prettify"><co=
de class=3D"prettyprint"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">pos</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify"> + 1</span></code></span></code>&gt;(e);<br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div>but as =
you can see it require some additional boilerplate code to work and have si=
milar performance as hand written switch (O(log n) or O(1) in some cases). =
Additional problems is multiple function calls that need be removed by comp=
iler, this will slow down debug builds because they usually dont have optim=
ization.<br><br>One possible solution I have is introduce new version of `f=
or` that will "iterate" on compiling time (resolving `switch` is only one u=
se case of this):<br><div class=3D"prettyprint" style=3D"background-color: =
rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; =
border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div=
 class=3D"subprettyprint"><code class=3D"prettyprint"><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">typename...</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(153, 0, 255=
);"><span class=3D"styled-by-prettify">T</span></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span></code><span style=3D"color: rgb(=
0, 0, 255);">void </span>func()<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"c=
olor: rgb(0, 0, 255);">for</span>...(<span style=3D"color: rgb(153, 0, 255)=
;">Ti </span>: <span style=3D"color: rgb(153, 0, 255);">T</span>)<span styl=
e=3D"color: rgb(102, 102, 102);">// Ti is element from pack <code class=3D"=
prettyprint">T equal </code>[A, B, C]</span><br>&nbsp;&nbsp;&nbsp; {<br>&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(153, 0, 2=
55);">Ti</span>::func();<br>&nbsp;&nbsp;&nbsp; }<span style=3D"color: rgb(1=
02, 102, 102);"><br>&nbsp;&nbsp;&nbsp; //this will generate code similar to=
:<br>&nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; A::fu=
nc();<br>&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; B::func();<br>&nbsp;&nbsp;=
&nbsp; //&nbsp;&nbsp;&nbsp; C::func();<br>&nbsp;&nbsp;&nbsp; //</span><br>}=
<br><br><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;<span style=3D"color: rg=
b(0, 0, 255);">int</span></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> I</span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><span style=
=3D"color: rgb(0, 0, 255);">int </span>switch_(<span style=3D"color: rgb(0,=
 0, 255);">int </span>i)<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"color: r=
gb(0, 0, 255);">switch</span>(i)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0, 0, 255);">for</spa=
n>...(ii : I) <span style=3D"color: rgb(102, 102, 102);">//I is pack of [1,=
 3, 2]</span><br></span></code></code><code class=3D"prettyprint"><code cla=
ss=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pr=
ettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br></span></code></code></code></spa=
n></code></code><code class=3D"prettyprint"><code class=3D"prettyprint"><co=
de class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
</span></code></code></code><span style=3D"color: rgb(0, 0, 255);">case </s=
pan><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"=
prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">ii</=
span></code></code></code>: <span style=3D"color: rgb(0, 0, 255);">return <=
/span><span style=3D"color: rgb(153, 0, 255);">Type</span>&lt;ii&gt;::value=
;<br><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><co=
de class=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</s=
pan></code></code></code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span styl=
e=3D"color: rgb(102, 102, 102);">&nbsp; //this will generate code </span></=
span></code></code></code></span></code></code><span style=3D"color: rgb(10=
2, 102, 102);"><code class=3D"prettyprint"><code class=3D"prettyprint"><spa=
n class=3D"styled-by-prettify"><code class=3D"prettyprint"><code class=3D"p=
rettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify">=
<code class=3D"prettyprint">similar </code>to:<br>&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;=
&nbsp;&nbsp; case 1: return </span></code></code></code></span></code></cod=
e><code class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"st=
yled-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><=
code class=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=
=3D"prettyprint">Type&lt;1&gt;</code>::value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; </span></code></code></code></span></=
code></code><code class=3D"prettyprint"><code class=3D"prettyprint"><span c=
lass=3D"styled-by-prettify"><code class=3D"prettyprint"><code class=3D"pret=
typrint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify"><co=
de class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyp=
rint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><code =
class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-=
prettify">case 3: return </span></code></code></code></span></code></code><=
/code></span></code></code></code></span></code></code><code class=3D"prett=
yprint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify"><cod=
e class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettypr=
int"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><code c=
lass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-p=
rettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code clas=
s=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><code class=3D"prettyprint"><span class=
=3D"styled-by-prettify"><code class=3D"prettyprint"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><span class=3D"styled-by-prettify"><code c=
lass=3D"prettyprint">Type&lt;3&gt;</code></span></code></code></code></span=
></code></code></code>::value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
; //&nbsp;&nbsp;&nbsp; </span></code></code></code></span></code></code></c=
ode></span></code></code></code></span></code></code><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify"><code =
class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyprin=
t"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><code cla=
ss=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pre=
ttify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify">case 2: return </span><=
/code></code></code></span></code></code></code></span></code></code></code=
></span></code></code><code class=3D"prettyprint"><code class=3D"prettyprin=
t"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><code cla=
ss=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pre=
ttify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D=
"styled-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint=
"><code class=3D"prettyprint"><span class=3D"styled-by-prettify"><code clas=
s=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyprint"><=
span class=3D"styled-by-prettify"><code class=3D"prettyprint">Type&lt;2&gt;=
</code></span></code></code></code></span></code></code></code>::value;</sp=
an></code></code></code></span></code></code></code><br>&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; //</span></code></code></code></span></code></code>=
</span><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<code class=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><br></co=
de></span></code></code></code>&nbsp;&nbsp;&nbsp; }<br>}</span></code></cod=
e><br><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
template</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;<span style=3D"color: rgb(153, 0, 255);">Enum</span></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">...</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> E</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"></span></code></code></code><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br><span style=3D"color: rgb(0=
, 0, 255);">void </span>switch2_(</span></code></code></code><code class=3D=
"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyprint"><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span style=3D"color: rgb(153, 0, 255);"><span class=3D"st=
yled-by-prettify">Enum</span></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify"><span style=3D"color: rgb(153, 0, 255);"> </span>e</span=
></code></code></code></code>)</span></code></code></code><br>{<code class=
=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyprint"><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;&nbsp;&nb=
sp; <span style=3D"color: rgb(0, 0, 255);">switch</span>(e)<br>&nbsp;&nbsp;=
&nbsp; {</span></code></code></code><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
<span style=3D"color: rgb(0, 0, 255);">for</span>...(ee : E) <span style=3D=
"color: rgb(102, 102, 102);">//E is pack of [</span></span></code></code></=
code><span style=3D"color: rgb(102, 102, 102);"><code class=3D"prettyprint"=
><code class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"sty=
led-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><c=
ode class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled=
-by-prettify"></span></code></code></code><code class=3D"prettyprint"><code=
 class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pr=
ettify">Enum</span><span class=3D"styled-by-prettify">::</span></code></cod=
e></code></code></span></code></code></code></code>a1, </span></code></code=
></code><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint=
"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pr=
ettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><=
code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prett=
yprint"><span class=3D"styled-by-prettify">Enum</span><span class=3D"styled=
-by-prettify">::</span></code></code></code></code></span></code></code></c=
ode></code></span></code></code></code></code>a2, </span></code></code></co=
de><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"p=
rettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pret=
typrint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><co=
de class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyp=
rint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><code =
class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyprin=
t"><span class=3D"styled-by-prettify">Enum</span><span class=3D"styled-by-p=
rettify">::</span></code></code></code></code></span></code></code></code><=
/code></span></code></code></code></code>a3]</span></code></code></code></s=
pan><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0=
, 0, 255);">case </span>ee:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(15=
3, 0, 255);">A</span>&lt;ee&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code class=3D"pretty=
print"><span style=3D"color: rgb(153, 0, 255);">A2</span>&lt;ee&gt;();</cod=
e><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0, 0, 255);">break</span>;<=
br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0, 0, 255);">default</span>:<b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span =
style=3D"color: rgb(0, 0, 255);">break</span>;<br><br>&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(102, 102, 102);">//this wil=
l create code similar to:<code class=3D"prettyprint"><br>&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /=
/ &nbsp; case <code class=3D"prettyprint"><code class=3D"prettyprint"><code=
 class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prett=
ify">Enum</span><span class=3D"styled-by-prettify">::</span></code></code><=
/code></code></span></code></code></code></code>a1: A&lt;</span></code></co=
de></code></code><code class=3D"prettyprint"><code class=3D"prettyprint"><c=
ode class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled=
-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code=
 class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prett=
ify">Enum</span><span class=3D"styled-by-prettify">::</span></code></code><=
/code></code></span></code></code></code></code>a1</span></code></code></co=
de></code>&gt;(); A2&lt;</span></code></code></code></code><code class=3D"p=
rettyprint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code c=
lass=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"pret=
typrint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code clas=
s=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><span class=3D"styled-by-prettify">Enum</span><span class=3D"=
styled-by-prettify">::</span></code></code></code></code></span></code></co=
de></code></code>a1</span></code></code></code></code>&gt;(); break;</span>=
</code></code></code></code></code><code class=3D"prettyprint"><br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; case <code class=3D"prettyprin=
t"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"p=
rettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pret=
typrint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><co=
de class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prettyp=
rint"><span class=3D"styled-by-prettify">Enum</span><span class=3D"styled-b=
y-prettify">::</span></code></code></code></code></span></code></code></cod=
e></code>a2: A&lt;</span></code></code></code></code><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint=
"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pr=
ettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint"><=
code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"prett=
yprint"><span class=3D"styled-by-prettify">Enum</span><span class=3D"styled=
-by-prettify">::</span></code></code></code></code></span></code></code></c=
ode></code>a2</span></code></code></code></code>&gt;(); A2&lt;</span></code=
></code></code></code><code class=3D"prettyprint"><code class=3D"prettyprin=
t"><code class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"s=
tyled-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint">=
<code class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styl=
ed-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><co=
de class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-=
by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code =
class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-=
prettify">Enum</span><span class=3D"styled-by-prettify">::</span></code></c=
ode></code></code></span></code></code></code></code>a2</span></code></code=
></code></code>&gt;(); break;</span></code></code></code></code></code><cod=
e class=3D"prettyprint"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &=
nbsp; case <code class=3D"prettyprint"><code class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prett=
ify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify=
">Enum</span><span class=3D"styled-by-prettify">::</span></code></code></co=
de></code></span></code></code></code></code>a3: A&lt;</span></code></code>=
</code></code><code class=3D"prettyprint"><code class=3D"prettyprint"><code=
 class=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prett=
ify"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><code class=3D"prettyprint"><span class=3D"styled-by-prettify=
">Enum</span><span class=3D"styled-by-prettify">::</span></code></code></co=
de></code></span></code></code></code></code>a3</span></code></code></code>=
</code>&gt;(); A2&lt;</span></code></code></code></code><code class=3D"pret=
typrint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code clas=
s=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyp=
rint"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D=
"prettyprint"><span class=3D"styled-by-prettify"><code class=3D"prettyprint=
"><code class=3D"prettyprint"><code class=3D"prettyprint"><code class=3D"pr=
ettyprint"><span class=3D"styled-by-prettify">Enum</span><span class=3D"sty=
led-by-prettify">::</span></code></code></code></code></span></code></code>=
</code></code>a3</span></code></code></code></code>&gt;(); break;</span></c=
ode></code></code></code></code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp; //&nbsp;&nbsp; default: break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; //</span><br>&nbsp;&nbsp;&nbsp; }<br>}<br></div></code></div>But this=
 is separate proposition to "enumeration pack". And even change core langua=
ge more than Andrew Tomazos proposition.<br>Funny thing, I like more your p=
roposition but Andrew ones have more<em> </em>synergies with my `for`:<br><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wor=
d-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: rgb(0, 0, 0);"><span class=3D"styled-by-prettify"=
><span style=3D"color: rgb(0, 0, 255);">void </span>func(<span style=3D"col=
or: rgb(153, 0, 255);">Enum </span>e)<br>{<br>&nbsp;&nbsp;&nbsp; <span styl=
e=3D"color: rgb(0, 0, 255);">switch</span>(e)<br>&nbsp;&nbsp;&nbsp; {<br>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color: rgb(0, 0, 25=
5);">for</span>...(ee : <span style=3D"color: rgb(153, 0, 255);">Enum</span=
>...)<span style=3D"color: rgb(102, 102, 102);"> //create pack of [Enum::a1=
, Enum::a2, Enum::a3, Enum::a4]</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp; <span style=3D"color: rgb(0, 0, 255);">case </span>ee: <span style=
=3D"color: rgb(102, 102, 102);">/*do somthing*/</span> <span style=3D"color=
: rgb(0, 0, 255);">break</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</span></span><span style=3D"color: #660;=
" class=3D"styled-by-prettify"></span></div></code></div><br><br><br><br>On=
 Sunday, September 29, 2013 1:19:23 PM UTC+2, Christian Kaeser wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Thanks, I agree tha=
t especially for reflection library solutions are preferable to language ex=
tensions, simply because of the specification work new language rules requi=
re, and the (understandably) large committee scrutiny/resistance they would=
 have to face. <br>I think very good reasons should to be brought forth as =
to why a libary-only change would not be good enough.<br><br>Concerning you=
r comment, for what specific purpose do you want enum switch statement supp=
ort in this scenario? I agree that it would be one solution for run-time en=
um-value -&gt; enumerator-name lookup. But in my current implementation, I =
designed several lookup functors (taking an enum-value, returning something=
 like an enumerator-index) for this purpose, that use various algorithms fo=
r the lookup. These could be automatically selected based on certain enum t=
ype properties. That would employ more or less the techniques of a compiler=
 optimized switch statement, and therefore should deliver comparable perfor=
mance. Allowing templated generation of switch cases has been debated on he=
re before I think, but I fear that this might be hard to realize.<br><br>On=
 Sunday, 29 September 2013 02:05:50 UTC+2, <a>inkwizyt...@gmail.com</a>  wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">This look bett=
er than original proposition, mainly because its library extension, it coul=
d be even fake in current C++ using some macro magic.<br>Now only thing tha=
t that will this lack is some way for switch statement support, because you=
 cant add new cases when enum change size.<br><br>On Saturday, September 28=
, 2013 10:10:30 PM UTC+2, Christian Kaeser wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">This sounds like an interesting approach, bu=
t I'm not so sure if it is free of possible parsing ambiguities and if its =
degree of flexibility is quite enough for all use cases, e.g. efficient imp=
lementation of flag sets or arrays indexed by an enum.<br><br>The last few =
months I have thought about this problem and implemented a clang compiler e=
xtension allowing the reflection of enumeration types, among other things. =
For simplicities sake, the changes to the compiler consist only of the intr=
oduction of a few compiler intrinsics that expand into a constexpr during e=
valuation, similar to how type traits are already implemented. These are:<b=
r>&nbsp;&nbsp;&nbsp; __enum_value_count(&lt;enum-type&gt;<wbr>)&nbsp; --&gt=
; size_t<br>&nbsp;&nbsp;&nbsp; __enum_value(&lt;enum-type&gt;, &lt;index-co=
nstexpr&gt;)&nbsp; --&gt;&nbsp; &lt;enum-type&gt;<br>&nbsp;&nbsp;&nbsp; __e=
num_value_name(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbs=
p; UTF8 const char []<br><br>Of course, something like this should not be t=
he standardized public interface, as these intrinsics are probably too awkw=
ard to use for the average programmer and too large a deviation from curren=
t practice. But using the new C++14 addition "Compile-time integer sequence=
s" (N3658), this can easily be brought into a much nicer form which could f=
ullfill the role of a public API:<br><br>&nbsp;&nbsp;&nbsp; template&lt;cla=
ss E, class IdxSeq&gt;<br>&nbsp;&nbsp;&nbsp; struct enum_data_t;<br><br>&nb=
sp;&nbsp;&nbsp; // requires a correct index sequence pack to expand the val=
ues:<br>&nbsp;&nbsp;&nbsp; template&lt;class E, size_t... Idx&gt;<br>&nbsp;=
&nbsp;&nbsp; struct enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt;=
 {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr size_t count =
=3D __enum_value_count(E);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static =
constexpr E values[] =3D { __enum_value(E, Idx)... };<br>&nbsp;&nbsp;&nbsp;=
 &nbsp;&nbsp;&nbsp; static constexpr char const *names[] =3D { __enum_value=
_name(E, Idx)... };<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; // a=
lways use the correct index sequence for the given enum<br>&nbsp;&nbsp;&nbs=
p; template&lt;class E&gt;<br>&nbsp;&nbsp;&nbsp; using enum_data =3D enum_d=
ata_t&lt;E, std::make_index_sequence&lt; __enum_value_count(E) &gt;&gt;;<br=
><br>&nbsp;&nbsp;&nbsp; // for odr-use:<br>&nbsp;&nbsp;&nbsp; template&lt;t=
ypename E, size_t... Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr E enum_data_t=
&lt;E, std::index_sequence&lt;Idx...&gt;&gt;::<wbr>values[];<br>&nbsp;&nbsp=
;&nbsp; template&lt;typename E, size_t... Idx&gt; <br>&nbsp;&nbsp;&nbsp; co=
nstexpr char const * enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt=
;::<wbr>names[];<br><br>&nbsp;&nbsp;&nbsp; // usage:<br>&nbsp;&nbsp;&nbsp; =
enum class E1 { first =3D 99, second =3D first };<br>&nbsp;&nbsp;&nbsp; usi=
ng E1D =3D enum_data&lt;E1&gt;;<br>&nbsp;&nbsp;&nbsp; for (int i=3D0; i&lt;=
E1D::count; i++)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; std::cout &lt;&lt=
; E1D::names[i] &lt;&lt; " =3D " &lt;&lt; (int)E1D::values[i] &lt;&lt; std:=
:endl;<br><br>With the new constexpr relaxations coming in C++14 this could=
 even be enough for all compile-time purposes. Otherwise, the individual in=
trinsics could also be exposed similar to existing type traits:<br><br>&nbs=
p;&nbsp;&nbsp; template&lt;class E, size_t Idx&gt;<br>&nbsp;&nbsp;&nbsp; st=
ruct enumerator_value {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static con=
stexpr E value =3D __enum_value(E, Idx);<br>&nbsp;&nbsp;&nbsp; };<br><br>I =
have also experimented a lot with more advanced functionality that could be=
 provided on this basis. Among these is the pretty tricky (considering all =
edge cases) lookup-by-value to access the enumerator name/index. That in tu=
rn can function as a base for more interesting enum use cases like flag set=
s, enum arrays, I/O via iostream etc.<br><br>Is there interest in my implem=
entation? I could make it available via github. I would hope it might be of=
 interest to anyone wanting to experiment with possible prospective std lib=
 interfaces.<br><br>Does anyone know anything further about SG7, the reflec=
tion study group? The forum on here seems to be empty, and not a lot of pro=
posals have been put forth for quite a while now. I would be very intereste=
d in a discussion about concrete, low-hanging-fruit reflection aspects that=
 could hopefully be ready for the C++17 timeline.<br></div></blockquote></d=
iv></blockquote></div></blockquote></div>

<p></p>

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

------=_Part_65_6933073.1380463849792--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sun, 29 Sep 2013 07:33:30 -0700 (PDT)
Raw View
------=_Part_206_30969415.1380465210700
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sunday, September 29, 2013 1:36:34 PM UTC+2, Christian Kaeser wrote:
>
>
>     template<typename E>
>     struct enumerator_data {
>
=20
Whether it is called a language or library feature or the specific names I=
=20
don't find particularly interesting.  It's clear we need compiler support=
=20
to implement it, so I was thinking that starting with the core language=20
primitives/instrinsics would be a good first step - but if it has a better=
=20
chance called a library feature that is fine too.  My fear of calling it a=
=20
library was that people would try to pile on advanced use cases and=20
bloat/delay what would-be a simple, obvious and straightforward addition -=
=20
but I guess we can avoid that.

It's clear that the enumeration_data struct could be formed by the two=20
primitives, and in the other direction, I think the two primitives could be=
=20
formed with such an enumerator_data struct by expanding the indexes to=20
(0,1,2...,count-1) and then mapping them statically to values[i] and=20
names[i], all of which are constant expressions, so actually it is the same=
=20
information and the struct is isomorphic to the two primitives.  So the=20
enumerator_data struct is fine with me, and I agree aesthetically it is=20
better than the primitives too.  So fine, let's do that.

I'll make the following cosmetic adjustments (motivation `std::type_info`,=
=20
`std::vector::size`):

    namespace std
    {
        template<typename E>
        struct enumerator_info {
            static constexpr size_t size;
            static constexpr E values[];
            static constexpr const char* names[];
        };
    }

So for an enumeration:

    enum Efoo
    {
        bar =3D 42,
        baz =3D 43,
        qux =3D 44,
        e=CF=80 =3D 42,
        f\u03C0 =3D 42,
    };

The automatically-generated specialization is therefore:

    template<>
    struct std::enumerator_info<Efoo>
    {
        static constexpr size_t size =3D 5;
        static constexpr Efoo values[] =3D {bar, baz, qux, e=CF=80, f\u03C0=
};
        static constexpr const char* names[] =3D
            { u8"bar", u8"baz", u8"qux", u8"e\u03C0", u8"f\u03C0" };
    };

It's important that if we write a program and define an enumeration E, but=
=20
do not use std::enumerator_info<E>, then std::enumerator_info<E> should not=
=20
show up anywhere or cost anything.  With the two original primitives this=
=20
is pretty clear, obvious with the pack and implied as per `__func__` with=
=20
the predefined variable `__enumerator__`.  I am not aware of a library=20
feature with this property, or how this can be specified (or if it is=20
necessary to specify this property).

Basically I want to say that for each enumeration E a specialization of an=
=20
incomplete primary template:

    template<typename>
    struct std::enumerator_info;

is provided for std::enumerator_info<E> only if std::enumerator_info<E> is=
=20
"used" (odr-used?).  Is there a precedent for such a construction?  A=20
per-user-defined-type specialization with in the standard library that=20
could be used as a prototype for wording?

Would it help in this regard, or make any difference if it was specified as=
=20
constexpr functions instead:

    namespace std
    {
        template<typename E>
        struct enumerator_info {
            static constexpr size_t size();
            static constexpr E values(size_t index);
            static constexpr const char* names(size_t index);
        };
    }


I'm not sure.

--=20

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

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

<div dir=3D"ltr">On Sunday, September 29, 2013 1:36:34 PM UTC+2, Christian =
Kaeser wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<br><div>&nbsp;&nbsp;&nbsp; template&lt;typename E&gt;<br>&nbsp;&nbsp; &nbs=
p;struct enumerator_data {<br></div></div></blockquote><div>&nbsp;</div><di=
v dir=3D"ltr"><div>Whether it is called a language or library feature or th=
e specific names I don't find particularly interesting.&nbsp; It's clear we=
 need compiler support to implement it, so I was thinking that starting wit=
h the core language primitives/instrinsics would be a good first step - but=
 if it has a better chance called a library feature that is fine too.&nbsp;=
 My fear of calling it a library was that people would try to pile on advan=
ced use cases and bloat/delay what would-be a simple, obvious and straightf=
orward addition - but I guess we can avoid that.<br><br>It's clear that the=
 enumeration_data struct could be formed by the two primitives, and in the =
other direction, I think the two primitives could be formed with such an en=
umerator_data struct by expanding the indexes to (0,1,2...,count-1) and the=
n mapping them statically to values[i] and names[i], all of which are const=
ant expressions, so actually it is the same information and the struct is i=
somorphic to the two primitives.&nbsp; So the enumerator_data struct is fin=
e with me, and I agree aesthetically it is better than the primitives too.&=
nbsp; So fine, let's do that.<br><br>I'll make the following cosmetic adjus=
tments (motivation `std::type_info`, `std::vector::size`):<br><br><span sty=
le=3D"font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; namespace std=
<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; template&lt;ty=
pename E&gt;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; struct enumerator_inf=
o {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static cons=
texpr size_t size;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp; static constexpr E values[];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp; static constexpr const char* names[];<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; }<br><br>So f=
or an enumeration:<br></span><br><span style=3D"font-family: courier new,mo=
nospace;">&nbsp;&nbsp;&nbsp; enum Efoo<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bar =3D 42,<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; baz =3D 43,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
qux =3D 44,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e=CF=80 =3D 42,<b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f\u03C0 =3D 42,<br>&nbsp;&nbsp=
;&nbsp; };<br></span><br>The automatically-generated specialization is ther=
efore:<br><br><span style=3D"font-family: courier new,monospace;">&nbsp; &n=
bsp; template&lt;&gt;<br>&nbsp;&nbsp;&nbsp; struct std::enumerator_info&lt;=
Efoo&gt;<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; s=
tatic constexpr size_t size =3D 5;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;=
 static constexpr Efoo values[] =3D {bar, baz, qux, </span><span style=3D"f=
ont-family: courier new,monospace;"><span style=3D"font-family: courier new=
,monospace;">e=CF=80, </span></span><span style=3D"font-family: courier new=
,monospace;"><span style=3D"font-family: courier new,monospace;"><span styl=
e=3D"font-family: courier new,monospace;">f\u03C0};<br></span></span>&nbsp;=
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr const char* names[] =3D<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { u8"ba=
r", u8"baz", u8"qux", u8"e\u03C0", u8"f\u03C0" };<br>&nbsp;&nbsp;&nbsp; };<=
br></span><br>It's important that if we write a program and define an enume=
ration E, but do not use std::enumerator_info&lt;E&gt;, then std::enumerato=
r_info&lt;E&gt; should not show up anywhere or cost anything.&nbsp; With th=
e two original primitives this is pretty clear, obvious with the pack and i=
mplied as per `__func__` with the predefined variable `__enumerator__`.&nbs=
p; I am not aware of a library feature with this property, or how this can =
be specified (or if it is necessary to specify this property).<br><br>Basic=
ally I want to say that for each enumeration E a specialization of an incom=
plete primary template:<br><br><span style=3D"font-family: courier new,mono=
space;">&nbsp; &nbsp; template&lt;typename&gt;<br>&nbsp;&nbsp;&nbsp; struct=
 std::enumerator_info;<br><span style=3D"font-family: arial,sans-serif;"><b=
r>is provided for std::enumerator_info&lt;E&gt; only if std::enumerator_inf=
o&lt;E&gt; is "used" (odr-used?).&nbsp; Is there a precedent for such a con=
struction?&nbsp; A per-user-defined-type specialization with in the standar=
d library that could be used as a prototype for wording?<br><br>Would it he=
lp in this regard, or make any difference if it was specified as constexpr =
functions instead:<br></span></span><br><span style=3D"font-family: courier=
 new,monospace;">&nbsp;&nbsp;&nbsp; namespace std<br>&nbsp;&nbsp;&nbsp; {<b=
r>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; template&lt;typename E&gt;<br>&nbsp;&nbs=
p; &nbsp;&nbsp;&nbsp;&nbsp; struct enumerator_info {<br>&nbsp;&nbsp; &nbsp;=
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr size_t size();<br>&n=
bsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static constexp=
r E values(size_t index);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp; static constexpr const char* names(size_t index);<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; }<br><br></sp=
an><br><span style=3D"font-family: courier new,monospace;"><span style=3D"f=
ont-family: courier new,monospace;"><span style=3D"font-family: arial,sans-=
serif;">I'm not sure.<br><br></span></span></span></div></div></div>

<p></p>

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

------=_Part_206_30969415.1380465210700--

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sun, 29 Sep 2013 09:16:43 -0700 (PDT)
Raw View
------=_Part_213_21343080.1380471403567
Content-Type: text/plain; charset=ISO-8859-1

On Sunday, 29 September 2013 16:10:49 UTC+2, inkwizyt...@gmail.com wrote:
>
> Sometimes you want chose program action based on enum value. Right now you
> can do it creating switch statement that will chose correct action, but
> this is error prone because if someone add new enum value your code will
> break (depending on if that value should have special handling). With
> templates from your proposition is possible to handle that situation:
> template<typename Enum, int pos>
> void switch_(Enum e)
> {
>     if(enum_data<E1>::values[pos] == e)
>         Action<enum_data<E1>::values[pos]>::func();
>     else
>         switch_<Enum, pos + 1>(e);
> }
> but as you can see it require some additional boilerplate code to work and
> have similar performance as hand written switch (O(log n) or O(1) in some
> cases). Additional problems is multiple function calls that need be removed
> by compiler, this will slow down debug builds because they usually dont
> have optimization.
>
> One possible solution I have is introduce new version of `for` that will
> "iterate" on compiling time (resolving `switch` is only one use case of
> this):
> template<typename... T>
> void func()
> {
>     for...(Ti : T)// Ti is element from pack T equal [A, B, C]
>     {
>         Ti::func();
>     }
>     //this will generate code similar to:
>     //
>     //    A::func();
>     //    B::func();
>     //    C::func();
>     //
> }
>
> template<int... I>
> int switch_(int i)
> {
>     switch(i)
>     {
>         for...(ii : I) //I is pack of [1, 3, 2]
>         {
>             case ii: return Type<ii>::value;
>         }
>         //this will generate code similar to:
>         //
>         //    case 1: return Type<1>::value;
>         //    case 3: return Type<3>::value;
>         //    case 2: return Type<2>::value;
>         //
>     }
> }
> template<Enum... E>
> void switch2_(Enum e)
> {
>     switch(e)
>     {
>         for...(ee : E) //E is pack of [Enum::a1, Enum::a2, Enum::a3]
>         {
>             case ee:
>                 A<ee>();
>                 A2<ee>();
>                 break;
>         }
>         default:
>             break;
>
>         //this will create code similar to:
>         //
>         //   case Enum::a1: A<Enum::a1>(); A2<Enum::a1>(); break;
>         //   case Enum::a2: A<Enum::a2>(); A2<Enum::a2>(); break;
>         //   case Enum::a3: A<Enum::a3>(); A2<Enum::a3>(); break;
>         //   default: break;
>         //
>     }
> }
> But this is separate proposition to "enumeration pack". And even change
> core language more than Andrew Tomazos proposition.
> Funny thing, I like more your proposition but Andrew ones have more* *synergies
> with my `for`:
> void func(Enum e)
> {
>     switch(e)
>     {
>         for...(ee : Enum...) //create pack of [Enum::a1, Enum::a2,
> Enum::a3, Enum::a4]
>         {
>             case ee: /*do somthing*/ break;
>         }
>     }
> }
>
>
>
>
> On Sunday, September 29, 2013 1:19:23 PM UTC+2, Christian Kaeser wrote:
>>
>> Thanks, I agree that especially for reflection library solutions are
>> preferable to language extensions, simply because of the specification work
>> new language rules require, and the (understandably) large committee
>> scrutiny/resistance they would have to face.
>> I think very good reasons should to be brought forth as to why a
>> libary-only change would not be good enough.
>>
>> Concerning your comment, for what specific purpose do you want enum
>> switch statement support in this scenario? I agree that it would be one
>> solution for run-time enum-value -> enumerator-name lookup. But in my
>> current implementation, I designed several lookup functors (taking an
>> enum-value, returning something like an enumerator-index) for this purpose,
>> that use various algorithms for the lookup. These could be automatically
>> selected based on certain enum type properties. That would employ more or
>> less the techniques of a compiler optimized switch statement, and therefore
>> should deliver comparable performance. Allowing templated generation of
>> switch cases has been debated on here before I think, but I fear that this
>> might be hard to realize.
>>
>> On Sunday, 29 September 2013 02:05:50 UTC+2, inkwizyt...@gmail.com wrote:
>>>
>>> This look better than original proposition, mainly because its library
>>> extension, it could be even fake in current C++ using some macro magic.
>>> Now only thing that that will this lack is some way for switch statement
>>> support, because you cant add new cases when enum change size.
>>>
>>> On Saturday, September 28, 2013 10:10:30 PM UTC+2, Christian Kaeser
>>> wrote:
>>>>
>>>> This sounds like an interesting approach, but I'm not so sure if it is
>>>> free of possible parsing ambiguities and if its degree of flexibility is
>>>> quite enough for all use cases, e.g. efficient implementation of flag sets
>>>> or arrays indexed by an enum.
>>>>
>>>> The last few months I have thought about this problem and implemented a
>>>> clang compiler extension allowing the reflection of enumeration types,
>>>> among other things. For simplicities sake, the changes to the compiler
>>>> consist only of the introduction of a few compiler intrinsics that expand
>>>> into a constexpr during evaluation, similar to how type traits are already
>>>> implemented. These are:
>>>>     __enum_value_count(<enum-type>)  --> size_t
>>>>     __enum_value(<enum-type>, <index-constexpr>)  -->  <enum-type>
>>>>     __enum_value_name(<enum-type>, <index-constexpr>)  -->  UTF8 const
>>>> char []
>>>>
>>>> Of course, something like this should not be the standardized public
>>>> interface, as these intrinsics are probably too awkward to use for the
>>>> average programmer and too large a deviation from current practice. But
>>>> using the new C++14 addition "Compile-time integer sequences" (N3658), this
>>>> can easily be brought into a much nicer form which could fullfill the role
>>>> of a public API:
>>>>
>>>>     template<class E, class IdxSeq>
>>>>     struct enum_data_t;
>>>>
>>>>     // requires a correct index sequence pack to expand the values:
>>>>     template<class E, size_t... Idx>
>>>>     struct enum_data_t<E, std::index_sequence<Idx...>> {
>>>>         static constexpr size_t count = __enum_value_count(E);
>>>>         static constexpr E values[] = { __enum_value(E, Idx)... };
>>>>         static constexpr char const *names[] = { __enum_value_name(E,
>>>> Idx)... };
>>>>     };
>>>>
>>>>     // always use the correct index sequence for the given enum
>>>>     template<class E>
>>>>     using enum_data = enum_data_t<E, std::make_index_sequence<
>>>> __enum_value_count(E) >>;
>>>>
>>>>     // for odr-use:
>>>>     template<typename E, size_t... Idx>
>>>>     constexpr E enum_data_t<E, std::index_sequence<Idx...>>::values[];
>>>>     template<typename E, size_t... Idx>
>>>>     constexpr char const * enum_data_t<E,
>>>> std::index_sequence<Idx...>>::names[];
>>>>
>>>>     // usage:
>>>>     enum class E1 { first = 99, second = first };
>>>>     using E1D = enum_data<E1>;
>>>>     for (int i=0; i<E1D::count; i++)
>>>>         std::cout << E1D::names[i] << " = " << (int)E1D::values[i] <<
>>>> std::endl;
>>>>
>>>> With the new constexpr relaxations coming in C++14 this could even be
>>>> enough for all compile-time purposes. Otherwise, the individual intrinsics
>>>> could also be exposed similar to existing type traits:
>>>>
>>>>     template<class E, size_t Idx>
>>>>     struct enumerator_value {
>>>>         static constexpr E value = __enum_value(E, Idx);
>>>>     };
>>>>
>>>> I have also experimented a lot with more advanced functionality that
>>>> could be provided on this basis. Among these is the pretty tricky
>>>> (considering all edge cases) lookup-by-value to access the enumerator
>>>> name/index. That in turn can function as a base for more interesting enum
>>>> use cases like flag sets, enum arrays, I/O via iostream etc.
>>>>
>>>> Is there interest in my implementation? I could make it available via
>>>> github. I would hope it might be of interest to anyone wanting to
>>>> experiment with possible prospective std lib interfaces.
>>>>
>>>> Does anyone know anything further about SG7, the reflection study
>>>> group? The forum on here seems to be empty, and not a lot of proposals have
>>>> been put forth for quite a while now. I would be very interested in a
>>>> discussion about concrete, low-hanging-fruit reflection aspects that could
>>>> hopefully be ready for the C++17 timeline.
>>>>
>>>

Okay I see, you want an compile time error if Action is not specialized for
a newly added enum value? Clang by default issues a warning if any
enumeration values are missed in a switch statement, do you think more
security is necessary?

I really like your for/switch proposal, as indeed this seems like an
interesting feature for generic algorithms.
But is it really necessary to add something like the "for..." construct?
Couldn't maybe the parameter pack expansion rules be simply expanded to
allow something like this:

template<typename E, E... Es>
void algo(E e) {
    switch(e) {
    { case Es : Action<Es>(); A2<Es>(); break; }...
    case some_other_case: SomeAction(); break;
        default: break;
    }
}

I am not deeply familiar with parameter pack details, but I am not quite
clear why such statement unpacking is not allowed. But having this work,
combined with something like N3728 would in my opinion be a great benefit
of generic programming in C++.

Btw, creating a pack of enum values from one of my proposed interfaces
should be doable (although filtering duplicate values will be very hard
with current TMP):

    template<class E, E... Vs>
    struct type_value_list {};

    template<class E, class IdxSeq>
    struct pack_enum_values_t;

    template<class E, size_t... Idx>
    struct pack_enum_values_t<E, std::index_sequence<Idx...>> {
        using typelist = type_value_list<E, std::meta::enumerator_value<E,
Idx>::value...>;
    };

    template<class E>
    using enum_value_pack = typename pack_enum_values_t<E,
std::make_index_sequence< std::meta::enumerator_count<E>::value
>>::typelist;



--

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

------=_Part_213_21343080.1380471403567
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, 29 September 2013 16:10:49 UTC+2, inkwizyt...@g=
mail.com  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">Sometimes you want chose program action based on enum value. Right now y=
ou can do it creating switch statement that will chose correct action, but =
this is error prone because if someone add new enum value your code will br=
eak (depending on if that value should have special handling). With templat=
es from your proposition is possible to handle that situation:<br><div styl=
e=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border=
-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#008">typename</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#606">Enum</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#000"> pos</span><span style=3D"color:#660">&gt;</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#008">void</span><span s=
tyle=3D"color:#000"> switch_</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#606">Enum</span><span style=3D"color:#000"> e</span><span =
style=3D"color:#660">)</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </s=
pan><span style=3D"color:rgb(0,0,255)"><span>if</span></span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">enum_data</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#000">E1</span><span style=
=3D"color:#660">&gt;::</span><span style=3D"color:#000">values</span><span =
style=3D"color:#660">[</span><span style=3D"color:#000">pos</span><span sty=
le=3D"color:#660">]</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">=3D=3D</span><span style=3D"color:#000"> e</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp;=
 &nbsp; </span><span style=3D"color:#606">Action</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#660"><code><span style=3D"color:#00=
0">enum_data</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#000">E1</span><span style=3D"color:#660">&gt;::</span><span style=3D"co=
lor:#000">values</span><span style=3D"color:#660">[</span><span style=3D"co=
lor:#000">p<wbr>os</span><span style=3D"color:#660">]</span><span style=3D"=
color:#000"></span></code>&gt;</span><span style=3D"color:#000">::func();<b=
r>&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">else</span><br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch_&lt;</span><span style=3D"col=
or:#000"><code><span style=3D"color:#000"></span><span style=3D"color:#606"=
>Enum</span><span style=3D"color:#660">, </span></code></span><span style=
=3D"color:#000"><code><span style=3D"color:#660"><code><span style=3D"color=
:#000">pos</span><span style=3D"color:#660"> + 1</span></code></span></code=
>&gt;(e);<br></span><span style=3D"color:#660">}</span><span style=3D"color=
:#000"><br></span></div></code></div>but as you can see it require some add=
itional boilerplate code to work and have similar performance as hand writt=
en switch (O(log n) or O(1) in some cases). Additional problems is multiple=
 function calls that need be removed by compiler, this will slow down debug=
 builds because they usually dont have optimization.<br><br>One possible so=
lution I have is introduce new version of `for` that will "iterate" on comp=
iling time (resolving `switch` is only one use case of this):<br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px;word-wrap:break-word"><code><div><code><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">typename...</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:rgb(153,0,255)"><span>T</span></span><span style=3D=
"color:#660">&gt;</span><span style=3D"color:#000"><br></span></code><span =
style=3D"color:rgb(0,0,255)">void </span>func()<br>{<br>&nbsp;&nbsp;&nbsp; =
<span style=3D"color:rgb(0,0,255)">for</span>...(<span style=3D"color:rgb(1=
53,0,255)">Ti </span>: <span style=3D"color:rgb(153,0,255)">T</span>)<span =
style=3D"color:rgb(102,102,102)">// Ti is element from pack <code>T equal <=
/code>[A, B, C]</span><br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(153,0,255)">Ti</span>::func();<b=
r>&nbsp;&nbsp;&nbsp; }<span style=3D"color:rgb(102,102,102)"><br>&nbsp;&nbs=
p;&nbsp; //this will generate code similar to:<br>&nbsp;&nbsp;&nbsp; //<br>=
&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; A::func();<br>&nbsp;&nbsp;&nbsp; //=
&nbsp;&nbsp;&nbsp; B::func();<br>&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; C:=
:func();<br>&nbsp;&nbsp;&nbsp; //</span><br>}<br><br><code><code><span styl=
e=3D"color:#008">template</span><span style=3D"color:#660">&lt;<span style=
=3D"color:rgb(0,0,255)">int</span></span><span style=3D"color:#008">...</sp=
an><span style=3D"color:#000"> I</span><span style=3D"color:#606"></span><s=
pan style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br><span st=
yle=3D"color:rgb(0,0,255)">int </span>switch_(<span style=3D"color:rgb(0,0,=
255)">int </span>i)<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0=
,255)">switch</span>(i)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">for</span>...(ii : I)=
 <span style=3D"color:rgb(102,102,102)">//I is pack of [1, 3, 2]</span><br>=
</span></code></code><code><code><span style=3D"color:#000"><code><code><co=
de><span style=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<=
br></span></code></code></code></span></code></code><code><code><code><span=
 style=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp; </span></code></code></code><span style=3D"color:rgb(0,0,255)=
">case </span><code><code><code><span style=3D"color:#000">ii</span></code>=
</code></code>: <span style=3D"color:rgb(0,0,255)">return </span><span styl=
e=3D"color:rgb(153,0,255)">Type</span>&lt;ii&gt;::value;<br><code><code><sp=
an style=3D"color:#000"><code><code><code><span style=3D"color:#000"><code>=
<code><code><span style=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp; }</span></code></code></code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;<span style=3D"color:rgb(102,102,102)">&nbsp; //this will generate code </=
span></span></code></code></code></span></code></code><span style=3D"color:=
rgb(102,102,102)"><code><code><span><code><code><code><span><code>similar <=
/code>to:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; case 1: return </span></=
code></code></code></span></code></code><code><code><span><code><code><code=
><span><code>Type&lt;1&gt;</code>::value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; </span></code></code></code></span></code=
></code><code><code><span><code><code><code><span><code><code><code><span><=
code><code><code><span>case 3: return </span></code></code></code></span></=
code></code></code></span></code></code></code></span></code></code><code><=
code><span><code><code><code><span><code><code><code><span><code><code><cod=
e><span><code><code><code><span><code><code><code><span><code>Type&lt;3&gt;=
</code></span></code></code></code></span></code></code></code>::value;<br>=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; </span></co=
de></code></code></span></code></code></code></span></code></code></code></=
span></code></code><code><code><span><code><code><code><span><code><code><c=
ode><span><code><code><code><span>case 2: return </span></code></code></cod=
e></span></code></code></code></span></code></code></code></span></code></c=
ode><code><code><span><code><code><code><span><code><code><code><span><code=
><code><code><span><code><code><code><span><code><code><code><span><code>Ty=
pe&lt;2&gt;</code></span></code></code></code></span></code></code></code>:=
:value;</span></code></code></code></span></code></code></code><br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span></code></code></code></span></c=
ode></code></span><code><code><span style=3D"color:#000"><code><code><code>=
<span style=3D"color:#000"><code><br></code></span></code></code></code>&nb=
sp;&nbsp;&nbsp; }<br>}</span></code></code><br><code><code><code><span styl=
e=3D"color:#008">template</span><span style=3D"color:#660">&lt;<span style=
=3D"color:rgb(153,0,255)">Enum</span></span><span style=3D"color:#008">...<=
/span><span style=3D"color:#000"> E</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"></span></code></code></code><code><code><co=
de><span style=3D"color:#000"><br><span style=3D"color:rgb(0,0,255)">void <=
/span>switch2_(</span></code></code></code><code><code><code><span style=3D=
"color:#000"><code><code><code><code><span style=3D"color:rgb(153,0,255)"><=
span>Enum</span></span><span style=3D"color:#008"><span style=3D"color:rgb(=
153,0,255)"> </span>e</span></code></code></code></code>)</span></code></co=
de></code><br>{<code><code><code><span style=3D"color:#000"><br>&nbsp;&nbsp=
;&nbsp; <span style=3D"color:rgb(0,0,255)">switch</span>(e)<br>&nbsp;&nbsp;=
&nbsp; {</span></code></code></code><code><code><code><span style=3D"color:=
#000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:r=
gb(0,0,255)">for</span>...(ee : E) <span style=3D"color:rgb(102,102,102)">/=
/E is pack of [</span></span></code></code></code><span style=3D"color:rgb(=
102,102,102)"><code><code><code><span><code><code><code><code><span></span>=
</code></code></code><code><code><code><span><code><code><code><code><span>=
Enum</span><span>::</span></code></code></code></code></span></code></code>=
</code></code>a1, </span></code></code></code><code><code><code><span><code=
><code><code><code><span><code><code><code><code><span><code><code><code><c=
ode><span>Enum</span><span>::</span></code></code></code></code></span></co=
de></code></code></code></span></code></code></code></code>a2, </span></cod=
e></code></code><code><code><code><span><code><code><code><code><span><code=
><code><code><code><span><code><code><code><code><span>Enum</span><span>::<=
/span></code></code></code></code></span></code></code></code></code></span=
></code></code></code></code>a3]</span></code></code></code></span><br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">case=
 </span>ee:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(153,0,255)">A</span=
>&lt;ee&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code><span style=3D"color:rgb(153,0,255)=
">A2</span>&lt;ee&gt;();</code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb=
(0,0,255)">break</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,25=
5)">default</span>:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">break</span>;<br><br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(102,102,102=
)">//this will create code similar to:<code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; =
case <code><code><code><code><span><code><code><code><code><span><code><cod=
e><code><code><span>Enum</span><span>::</span></code></code></code></code><=
/span></code></code></code></code>a1: A&lt;</span></code></code></code></co=
de><code><code><code><code><span><code><code><code><code><span><code><code>=
<code><code><span><code><code><code><code><span>Enum</span><span>::</span><=
/code></code></code></code></span></code></code></code></code>a1</span></co=
de></code></code></code>&gt;(); A2&lt;</span></code></code></code></code><c=
ode><code><code><code><span><code><code><code><code><span><code><code><code=
><code><span><code><code><code><code><span>Enum</span><span>::</span></code=
></code></code></code></span></code></code></code></code>a1</span></code></=
code></code></code>&gt;(); break;</span></code></code></code></code></code>=
<code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; case <code><=
code><code><code><span><code><code><code><code><span><code><code><code><cod=
e><span>Enum</span><span>::</span></code></code></code></code></span></code=
></code></code></code>a2: A&lt;</span></code></code></code></code><code><co=
de><code><code><span><code><code><code><code><span><code><code><code><code>=
<span><code><code><code><code><span>Enum</span><span>::</span></code></code=
></code></code></span></code></code></code></code>a2</span></code></code></=
code></code>&gt;(); A2&lt;</span></code></code></code></code><code><code><c=
ode><code><span><code><code><code><code><span><code><code><code><code><span=
><code><code><code><code><span>Enum</span><span>::</span></code></code></co=
de></code></span></code></code></code></code>a2</span></code></code></code>=
</code>&gt;(); break;</span></code></code></code></code></code><code><br>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; case <code><code><code><=
code><span><code><code><code><code><span><code><code><code><code><span>Enum=
</span><span>::</span></code></code></code></code></span></code></code></co=
de></code>a3: A&lt;</span></code></code></code></code><code><code><code><co=
de><span><code><code><code><code><span><code><code><code><code><span><code>=
<code><code><code><span>Enum</span><span>::</span></code></code></code></co=
de></span></code></code></code></code>a3</span></code></code></code></code>=
&gt;(); A2&lt;</span></code></code></code></code><code><code><code><code><s=
pan><code><code><code><code><span><code><code><code><code><span><code><code=
><code><code><span>Enum</span><span>::</span></code></code></code></code></=
span></code></code></code></code>a3</span></code></code></code></code>&gt;(=
); break;</span></code></code></code></code></code><br>&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; default: break;<br>&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp; //</span><br>&nbsp;&nbsp;&nbsp; }<br>}<br></div></=
code></div>But this is separate proposition to "enumeration pack". And even=
 change core language more than Andrew Tomazos proposition.<br>Funny thing,=
 I like more your proposition but Andrew ones have more<i> </i>synergies wi=
th my `for`:<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word=
"><code><div><span style=3D"color:rgb(0,0,0)"><span><span style=3D"color:rg=
b(0,0,255)">void </span>func(<span style=3D"color:rgb(153,0,255)">Enum </sp=
an>e)<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">switch<=
/span>(e)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp; <span style=3D"color:rgb(0,0,255)">for</span>...(ee : <span style=3D"c=
olor:rgb(153,0,255)">Enum</span>...)<span style=3D"color:rgb(102,102,102)">=
 //create pack of [Enum::a1, Enum::a2, Enum::a3, Enum::a4]</span><br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">case <=
/span>ee: <span style=3D"color:rgb(102,102,102)">/*do somthing*/</span> <sp=
an style=3D"color:rgb(0,0,255)">break</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</span></span><span style=3D=
"color:#660"></span></div></code></div><br><br><br><br>On Sunday, September=
 29, 2013 1:19:23 PM UTC+2, Christian Kaeser wrote:<blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr">Thanks, I agree that especially for reflec=
tion library solutions are preferable to language extensions, simply becaus=
e of the specification work new language rules require, and the (understand=
ably) large committee scrutiny/resistance they would have to face. <br>I th=
ink very good reasons should to be brought forth as to why a libary-only ch=
ange would not be good enough.<br><br>Concerning your comment, for what spe=
cific purpose do you want enum switch statement support in this scenario? I=
 agree that it would be one solution for run-time enum-value -&gt; enumerat=
or-name lookup. But in my current implementation, I designed several lookup=
 functors (taking an enum-value, returning something like an enumerator-ind=
ex) for this purpose, that use various algorithms for the lookup. These cou=
ld be automatically selected based on certain enum type properties. That wo=
uld employ more or less the techniques of a compiler optimized switch state=
ment, and therefore should deliver comparable performance. Allowing templat=
ed generation of switch cases has been debated on here before I think, but =
I fear that this might be hard to realize.<br><br>On Sunday, 29 September 2=
013 02:05:50 UTC+2, <a>inkwizyt...@gmail.com</a>  wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">This look better than original prop=
osition, mainly because its library extension, it could be even fake in cur=
rent C++ using some macro magic.<br>Now only thing that that will this lack=
 is some way for switch statement support, because you cant add new cases w=
hen enum change size.<br><br>On Saturday, September 28, 2013 10:10:30 PM UT=
C+2, Christian Kaeser wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">This sounds like an interesting approach, but I'm not so sure if =
it is free of possible parsing ambiguities and if its degree of flexibility=
 is quite enough for all use cases, e.g. efficient implementation of flag s=
ets or arrays indexed by an enum.<br><br>The last few months I have thought=
 about this problem and implemented a clang compiler extension allowing the=
 reflection of enumeration types, among other things. For simplicities sake=
, the changes to the compiler consist only of the introduction of a few com=
piler intrinsics that expand into a constexpr during evaluation, similar to=
 how type traits are already implemented. These are:<br>&nbsp;&nbsp;&nbsp; =
__enum_value_count(&lt;enum-type&gt;<wbr>)&nbsp; --&gt; size_t<br>&nbsp;&nb=
sp;&nbsp; __enum_value(&lt;enum-type&gt;, &lt;index-constexpr&gt;)&nbsp; --=
&gt;&nbsp; &lt;enum-type&gt;<br>&nbsp;&nbsp;&nbsp; __enum_value_name(&lt;en=
um-type&gt;, &lt;index-constexpr&gt;)&nbsp; --&gt;&nbsp; UTF8 const char []=
<br><br>Of course, something like this should not be the standardized publi=
c interface, as these intrinsics are probably too awkward to use for the av=
erage programmer and too large a deviation from current practice. But using=
 the new C++14 addition "Compile-time integer sequences" (N3658), this can =
easily be brought into a much nicer form which could fullfill the role of a=
 public API:<br><br>&nbsp;&nbsp;&nbsp; template&lt;class E, class IdxSeq&gt=
;<br>&nbsp;&nbsp;&nbsp; struct enum_data_t;<br><br>&nbsp;&nbsp;&nbsp; // re=
quires a correct index sequence pack to expand the values:<br>&nbsp;&nbsp;&=
nbsp; template&lt;class E, size_t... Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct e=
num_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt; {<br>&nbsp;&nbsp;&nb=
sp; &nbsp;&nbsp;&nbsp; static constexpr size_t count =3D __enum_value_count=
(E);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E values[] =
=3D { __enum_value(E, Idx)... };<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s=
tatic constexpr char const *names[] =3D { __enum_value_name(E, Idx)... };<b=
r>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; // always use the correct=
 index sequence for the given enum<br>&nbsp;&nbsp;&nbsp; template&lt;class =
E&gt;<br>&nbsp;&nbsp;&nbsp; using enum_data =3D enum_data_t&lt;E, std::make=
_index_sequence&lt; __enum_value_count(E) &gt;&gt;;<br><br>&nbsp;&nbsp;&nbs=
p; // for odr-use:<br>&nbsp;&nbsp;&nbsp; template&lt;typename E, size_t... =
Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr E enum_data_t&lt;E, std::index_seq=
uence&lt;Idx...&gt;&gt;::<wbr>values[];<br>&nbsp;&nbsp;&nbsp; template&lt;t=
ypename E, size_t... Idx&gt; <br>&nbsp;&nbsp;&nbsp; constexpr char const * =
enum_data_t&lt;E, std::index_sequence&lt;Idx...&gt;&gt;::<wbr>names[];<br><=
br>&nbsp;&nbsp;&nbsp; // usage:<br>&nbsp;&nbsp;&nbsp; enum class E1 { first=
 =3D 99, second =3D first };<br>&nbsp;&nbsp;&nbsp; using E1D =3D enum_data&=
lt;E1&gt;;<br>&nbsp;&nbsp;&nbsp; for (int i=3D0; i&lt;E1D::count; i++)<br>&=
nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; std::cout &lt;&lt; E1D::names[i] &lt;&=
lt; " =3D " &lt;&lt; (int)E1D::values[i] &lt;&lt; std::endl;<br><br>With th=
e new constexpr relaxations coming in C++14 this could even be enough for a=
ll compile-time purposes. Otherwise, the individual intrinsics could also b=
e exposed similar to existing type traits:<br><br>&nbsp;&nbsp;&nbsp; templa=
te&lt;class E, size_t Idx&gt;<br>&nbsp;&nbsp;&nbsp; struct enumerator_value=
 {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static constexpr E value =3D __=
enum_value(E, Idx);<br>&nbsp;&nbsp;&nbsp; };<br><br>I have also experimente=
d a lot with more advanced functionality that could be provided on this bas=
is. Among these is the pretty tricky (considering all edge cases) lookup-by=
-value to access the enumerator name/index. That in turn can function as a =
base for more interesting enum use cases like flag sets, enum arrays, I/O v=
ia iostream etc.<br><br>Is there interest in my implementation? I could mak=
e it available via github. I would hope it might be of interest to anyone w=
anting to experiment with possible prospective std lib interfaces.<br><br>D=
oes anyone know anything further about SG7, the reflection study group? The=
 forum on here seems to be empty, and not a lot of proposals have been put =
forth for quite a while now. I would be very interested in a discussion abo=
ut concrete, low-hanging-fruit reflection aspects that could hopefully be r=
eady for the C++17 timeline.<br></div></blockquote></div></blockquote></div=
></blockquote></div></blockquote><div>&nbsp;</div><div>&nbsp;<br>Okay I see=
, you want an compile time error if Action is not specialized for a newly a=
dded enum value? Clang by default issues a warning if any enumeration value=
s are missed in a switch statement, do you think more security is necessary=
?<br><br>I really like your for/switch proposal, as indeed this seems like =
an interesting feature for generic algorithms.<br>But is it really necessar=
y to add something like the "for..." construct? Couldn't maybe the paramete=
r pack expansion rules be simply expanded to allow something like this:<br>=
<br>template&lt;typename E, E... Es&gt;<br>void algo(E e) {<br>&nbsp;&nbsp;=
 &nbsp;switch(e) {<br>&nbsp;&nbsp; &nbsp;{ case Es : Action&lt;Es&gt;(); A2=
&lt;Es&gt;(); break; }...<br>&nbsp;&nbsp; &nbsp;case some_other_case: SomeA=
ction(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: brea=
k;<br>&nbsp;&nbsp; &nbsp;}<br>}<br><br>I am not deeply familiar with parame=
ter pack details, but I am not quite clear why such statement unpacking is =
not allowed. But having this work, combined with something like N3728 would=
 in my opinion be a great benefit of generic programming in C++.<br><br>Btw=
, creating a pack of enum values from one of my proposed interfaces should =
be doable (although filtering duplicate values will be very hard with curre=
nt TMP):<br><br>&nbsp;&nbsp; &nbsp;template&lt;class E, E... Vs&gt;<br>&nbs=
p;&nbsp; &nbsp;struct type_value_list {};<br><br>&nbsp;&nbsp; &nbsp;templat=
e&lt;class E, class IdxSeq&gt;<br>&nbsp;&nbsp; &nbsp;struct pack_enum_value=
s_t;<br><br>&nbsp;&nbsp; &nbsp;template&lt;class E, size_t... Idx&gt;<br>&n=
bsp;&nbsp; &nbsp;struct pack_enum_values_t&lt;E, std::index_sequence&lt;Idx=
....&gt;&gt; {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;using typelist =3D t=
ype_value_list&lt;E, std::meta::enumerator_value&lt;E, Idx&gt;::value...&gt=
;;<br>&nbsp;&nbsp; &nbsp;};<br><br>&nbsp;&nbsp; &nbsp;template&lt;class E&g=
t;<br>&nbsp;&nbsp; &nbsp;using enum_value_pack =3D typename pack_enum_value=
s_t&lt;E, std::make_index_sequence&lt; std::meta::enumerator_count&lt;E&gt;=
::value &gt;&gt;::typelist;<br><br></div><div>&nbsp;</div></div>

<p></p>

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

------=_Part_213_21343080.1380471403567--

.


Author: Christian Kaeser <christiankaeser87@googlemail.com>
Date: Sun, 29 Sep 2013 09:19:56 -0700 (PDT)
Raw View
------=_Part_59_23105422.1380471596134
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Sunday, 29 September 2013 16:33:30 UTC+2, Andrew Tomazos wrote:
>
> On Sunday, September 29, 2013 1:36:34 PM UTC+2, Christian Kaeser wrote:
>>
>>
>>     template<typename E>
>>     struct enumerator_data {
>>
> =20
> Whether it is called a language or library feature or the specific names =
I=20
> don't find particularly interesting.  It's clear we need compiler support=
=20
> to implement it, so I was thinking that starting with the core language=
=20
> primitives/instrinsics would be a good first step - but if it has a bette=
r=20
> chance called a library feature that is fine too.  My fear of calling it =
a=20
> library was that people would try to pile on advanced use cases and=20
> bloat/delay what would-be a simple, obvious and straightforward addition =
-=20
> but I guess we can avoid that.
>
> It's clear that the enumeration_data struct could be formed by the two=20
> primitives, and in the other direction, I think the two primitives could =
be=20
> formed with such an enumerator_data struct by expanding the indexes to=20
> (0,1,2...,count-1) and then mapping them statically to values[i] and=20
> names[i], all of which are constant expressions, so actually it is the sa=
me=20
> information and the struct is isomorphic to the two primitives.  So the=
=20
> enumerator_data struct is fine with me, and I agree aesthetically it is=
=20
> better than the primitives too.  So fine, let's do that.
>
> I'll make the following cosmetic adjustments (motivation `std::type_info`=
,=20
> `std::vector::size`):
>
>     namespace std
>     {
>         template<typename E>
>         struct enumerator_info {
>             static constexpr size_t size;
>             static constexpr E values[];
>             static constexpr const char* names[];
>         };
>     }
>
> So for an enumeration:
>
>     enum Efoo
>     {
>         bar =3D 42,
>         baz =3D 43,
>         qux =3D 44,
>         e=CF=80 =3D 42,
>         f\u03C0 =3D 42,
>     };
>
> The automatically-generated specialization is therefore:
>
>     template<>
>     struct std::enumerator_info<Efoo>
>     {
>         static constexpr size_t size =3D 5;
>         static constexpr Efoo values[] =3D {bar, baz, qux, e=CF=80, f\u03=
C0};
>         static constexpr const char* names[] =3D
>             { u8"bar", u8"baz", u8"qux", u8"e\u03C0", u8"f\u03C0" };
>     };
>
>
This std::enumerator_info definition sounds good to me.

=20

> It's important that if we write a program and define an enumeration E, bu=
t=20
> do not use std::enumerator_info<E>, then std::enumerator_info<E> should n=
ot=20
> show up anywhere or cost anything.  With the two original primitives this=
=20
> is pretty clear, obvious with the pack and implied as per `__func__` with=
=20
> the predefined variable `__enumerator__`.  I am not aware of a library=20
> feature with this property, or how this can be specified (or if it is=20
> necessary to specify this property).
>
> Basically I want to say that for each enumeration E a specialization of a=
n=20
> incomplete primary template:
>
>     template<typename>
>     struct std::enumerator_info;
>
> is provided for std::enumerator_info<E> only if std::enumerator_info<E> i=
s=20
> "used" (odr-used?).  Is there a precedent for such a construction?  A=20
> per-user-defined-type specialization with in the standard library that=20
> could be used as a prototype for wording?
>
> Would it help in this regard, or make any difference if it was specified=
=20
> as constexpr functions instead:
>
>     namespace std
>     {
>         template<typename E>
>         struct enumerator_info {
>             static constexpr size_t size();
>             static constexpr E values(size_t index);
>             static constexpr const char* names(size_t index);
>         };
>     }
>
>
> I'm not sure.
>
>
That should not be a problem. Standard template rules will take care that=
=20
only template specializations that are actually referenced will be=20
compiled. The same with linkage, only if a static variable is referenced is=
=20
it actually linked. This is at least how it behaves in my implementation.
For the wording for this, I suspect it should be similar to the type traits=
=20
classes? These do only have one constexpr integer value, and therefore=20
probably do not have a outside-of-class definition that would be required=
=20
for the arrays. But otherwise it should be quite similar. But I think some=
=20
of the experts on here, especially someone specialized on standardese like=
=20
Daniel Kr=C3=BCgler could probably clarify this.

--=20

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

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

<div dir=3D"ltr"><br><br>On Sunday, 29 September 2013 16:33:30 UTC+2, Andre=
w Tomazos  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">On Sunday, September 29, 2013 1:36:34 PM UTC+2, Christian Kaeser wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div>&nbsp;&nb=
sp;&nbsp; template&lt;typename E&gt;<br>&nbsp;&nbsp; &nbsp;struct enumerato=
r_data {<br></div></div></blockquote><div>&nbsp;</div><div dir=3D"ltr"><div=
>Whether it is called a language or library feature or the specific names I=
 don't find particularly interesting.&nbsp; It's clear we need compiler sup=
port to implement it, so I was thinking that starting with the core languag=
e primitives/instrinsics would be a good first step - but if it has a bette=
r chance called a library feature that is fine too.&nbsp; My fear of callin=
g it a library was that people would try to pile on advanced use cases and =
bloat/delay what would-be a simple, obvious and straightforward addition - =
but I guess we can avoid that.<br><br>It's clear that the enumeration_data =
struct could be formed by the two primitives, and in the other direction, I=
 think the two primitives could be formed with such an enumerator_data stru=
ct by expanding the indexes to (0,1,2...,count-1) and then mapping them sta=
tically to values[i] and names[i], all of which are constant expressions, s=
o actually it is the same information and the struct is isomorphic to the t=
wo primitives.&nbsp; So the enumerator_data struct is fine with me, and I a=
gree aesthetically it is better than the primitives too.&nbsp; So fine, let=
's do that.<br><br>I'll make the following cosmetic adjustments (motivation=
 `std::type_info`, `std::vector::size`):<br><br><span style=3D"font-family:=
courier new,monospace">&nbsp;&nbsp;&nbsp; namespace std<br>&nbsp;&nbsp;&nbs=
p; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; template&lt;typename E&gt;<br>&nbs=
p;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; struct enumerator_info {<br>&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr size_t size;<b=
r>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static cons=
texpr E values[];<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; static constexpr const char* names[];<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; }<br><br>So for an enumeration:<b=
r></span><br><span style=3D"font-family:courier new,monospace">&nbsp;&nbsp;=
&nbsp; enum Efoo<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; bar =3D 42,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baz =
=3D 43,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; qux =3D 44,<br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e=CF=80 =3D 42,<br>&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; f\u03C0 =3D 42,<br>&nbsp;&nbsp;&nbsp; };<br></span>=
<br>The automatically-generated specialization is therefore:<br><br><span s=
tyle=3D"font-family:courier new,monospace">&nbsp; &nbsp; template&lt;&gt;<b=
r>&nbsp;&nbsp;&nbsp; struct std::enumerator_info&lt;Efoo&gt;<br>&nbsp;&nbsp=
;&nbsp; {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr size_t =
size =3D 5;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr Efoo =
values[] =3D {bar, baz, qux, </span><span style=3D"font-family:courier new,=
monospace"><span style=3D"font-family:courier new,monospace">e=CF=80, </spa=
n></span><span style=3D"font-family:courier new,monospace"><span style=3D"f=
ont-family:courier new,monospace"><span style=3D"font-family:courier new,mo=
nospace">f\u03C0};<br></span></span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; s=
tatic constexpr const char* names[] =3D<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { u8"bar", u8"baz", u8"qux", u8"e\u03C0"=
, u8"f\u03C0" };<br>&nbsp;&nbsp;&nbsp; };<br></span><br></div></div></div><=
/blockquote><div><br>This std::enumerator_info definition sounds good to me=
..<br><br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div dir=3D"ltr"><div>It's important that if we write a program an=
d define an enumeration E, but do not use std::enumerator_info&lt;E&gt;, th=
en std::enumerator_info&lt;E&gt; should not show up anywhere or cost anythi=
ng.&nbsp; With the two original primitives this is pretty clear, obvious wi=
th the pack and implied as per `__func__` with the predefined variable `__e=
numerator__`.&nbsp; I am not aware of a library feature with this property,=
 or how this can be specified (or if it is necessary to specify this proper=
ty).<br><br>Basically I want to say that for each enumeration E a specializ=
ation of an incomplete primary template:<br><br><span style=3D"font-family:=
courier new,monospace">&nbsp; &nbsp; template&lt;typename&gt;<br>&nbsp;&nbs=
p;&nbsp; struct std::enumerator_info;<br><span style=3D"font-family:arial,s=
ans-serif"><br>is provided for std::enumerator_info&lt;E&gt; only if std::e=
numerator_info&lt;E&gt; is "used" (odr-used?).&nbsp; Is there a precedent f=
or such a construction?&nbsp; A per-user-defined-type specialization with i=
n the standard library that could be used as a prototype for wording?<br><b=
r>Would it help in this regard, or make any difference if it was specified =
as constexpr functions instead:<br></span></span><br><span style=3D"font-fa=
mily:courier new,monospace">&nbsp;&nbsp;&nbsp; namespace std<br>&nbsp;&nbsp=
;&nbsp; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; template&lt;typename E&gt;<br=
>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; struct enumerator_info {<br>&nbsp;&n=
bsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; static constexpr size_t si=
ze();<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stat=
ic constexpr E values(size_t index);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp; static constexpr const char* names(size_t index)=
;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; }<=
br><br></span><br><span style=3D"font-family:courier new,monospace"><span s=
tyle=3D"font-family:courier new,monospace"><span style=3D"font-family:arial=
,sans-serif">I'm not sure.<br><br></span></span></span></div></div></div></=
blockquote><div><br>That should not be a problem. Standard template rules w=
ill take care that only template specializations that are actually referenc=
ed will be compiled. The same with linkage, only if a static variable is re=
ferenced is it actually linked. This is at least how it behaves in my imple=
mentation.<br>For the wording for this, I suspect it should be similar to t=
he type traits classes? These do only have one constexpr integer value, and=
 therefore probably do not have a outside-of-class definition that would be=
 required for the arrays. But otherwise it should be quite similar. But I t=
hink some of the experts on here, especially someone specialized on standar=
dese like Daniel Kr=C3=BCgler could probably clarify this.</div></div>

<p></p>

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

------=_Part_59_23105422.1380471596134--

.


Author: inkwizytoryankes@gmail.com
Date: Mon, 30 Sep 2013 14:44:42 -0700 (PDT)
Raw View
------=_Part_621_3569397.1380577482505
Content-Type: text/plain; charset=ISO-8859-1

More that security concerns, I simply dont want rewrite all switches every
time I add new enum value. And this is only side effect :)
Main goal of this was simplify `switch` based on `int`. It could be used by
variadic types or interpretors
(add `goto` to beginning and you can implements turning machine using one
`switch` without any function calls).
Without something like this is impossible to maintain such code manually.

I have once similar idea of syntax like:
{
    //some code
}...

But I didnt like it. Its harder to spot and dont allow nesting.
with explicit `for...` is lot of harder to ignore it even if you dont
understood it.
Next thing is nesting. Without my `for...` you cant made "cross join" of
two packs:
//T and K are parametr pack
{
    T a;//K shouldnt be expanded there too?
    {
       K c;
    }...
}...
In my case its simple:
for...(Ti : T)
{
    Ti a;
    for...(Ki : K)
    {
        Ki c;
    }
}
or if you want expand `T` and `K` and some syntax sugar for getting pack
position:

for...(Ti, Ki, I : T, K, int)
{
    std::tuple<Ti, Ki> a;
    for(int i = 0; i < I; ++i) //I is index of Ti in T and Ki in K, its run
form 0 to size...(Ti)
        print("1");
    print("\n");
}

I think you could replace `int` with some enum that have same number of
elements as this packs.


And about your `enum_type` interface. Yes I could get everything I want
form it. Only problem is that you cant do it directly and must use helper
function (similar to that you show).
This isnt big problem or cost compare to functionality it give.

On Sunday, September 29, 2013 6:16:43 PM UTC+2, Christian Kaeser wrote:
>
> On Sunday, 29 September 2013 16:10:49 UTC+2, inkwizyt...@gmail.com wrote:
>>
>> Sometimes you want chose program action based on enum value. Right now
>> you can do it creating switch statement that will chose correct action, but
>> this is error prone because if someone add new enum value your code will
>> break (depending on if that value should have special handling). With
>> templates from your proposition is possible to handle that situation:
>> template<typename Enum, int pos>
>> void switch_(Enum e)
>> {
>>     if(enum_data<E1>::values[pos] == e)
>>         Action<enum_data<E1>::values[pos]>::func();
>>     else
>>         switch_<Enum, pos + 1>(e);
>> }
>> but as you can see it require some additional boilerplate code to work
>> and have similar performance as hand written switch (O(log n) or O(1) in
>> some cases). Additional problems is multiple function calls that need be
>> removed by compiler, this will slow down debug builds because they usually
>> dont have optimization.
>>
>> One possible solution I have is introduce new version of `for` that will
>> "iterate" on compiling time (resolving `switch` is only one use case of
>> this):
>> template<typename... T>
>> void func()
>> {
>>     for...(Ti : T)// Ti is element from pack T equal [A, B, C]
>>     {
>>         Ti::func();
>>     }
>>     //this will generate code similar to:
>>     //
>>     //    A::func();
>>     //    B::func();
>>     //    C::func();
>>     //
>> }
>>
>> template<int... I>
>> int switch_(int i)
>> {
>>     switch(i)
>>     {
>>         for...(ii : I) //I is pack of [1, 3, 2]
>>         {
>>             case ii: return Type<ii>::value;
>>         }
>>         //this will generate code similar to:
>>         //
>>         //    case 1: return Type<1>::value;
>>         //    case 3: return Type<3>::value;
>>         //    case 2: return Type<2>::value;
>>         //
>>     }
>> }
>> template<Enum... E>
>> void switch2_(Enum e)
>> {
>>     switch(e)
>>     {
>>         for...(ee : E) //E is pack of [Enum::a1, Enum::a2, Enum::a3]
>>         {
>>             case ee:
>>                 A<ee>();
>>                 A2<ee>();
>>                 break;
>>         }
>>         default:
>>             break;
>>
>>         //this will create code similar to:
>>         //
>>         //   case Enum::a1: A<Enum::a1>(); A2<Enum::a1>(); break;
>>         //   case Enum::a2: A<Enum::a2>(); A2<Enum::a2>(); break;
>>         //   case Enum::a3: A<Enum::a3>(); A2<Enum::a3>(); break;
>>         //   default: break;
>>         //
>>     }
>> }
>> But this is separate proposition to "enumeration pack". And even change
>> core language more than Andrew Tomazos proposition.
>> Funny thing, I like more your proposition but Andrew ones have more* *synergies
>> with my `for`:
>> void func(Enum e)
>> {
>>     switch(e)
>>     {
>>         for...(ee : Enum...) //create pack of [Enum::a1, Enum::a2,
>> Enum::a3, Enum::a4]
>>         {
>>             case ee: /*do somthing*/ break;
>>         }
>>     }
>> }
>>
>
> Okay I see, you want an compile time error if Action is not specialized
> for a newly added enum value? Clang by default issues a warning if any
> enumeration values are missed in a switch statement, do you think more
> security is necessary?
>
> I really like your for/switch proposal, as indeed this seems like an
> interesting feature for generic algorithms.
> But is it really necessary to add something like the "for..." construct?
> Couldn't maybe the parameter pack expansion rules be simply expanded to
> allow something like this:
>
> template<typename E, E... Es>
> void algo(E e) {
>     switch(e) {
>     { case Es : Action<Es>(); A2<Es>(); break; }...
>     case some_other_case: SomeAction(); break;
>         default: break;
>     }
> }
>
> I am not deeply familiar with parameter pack details, but I am not quite
> clear why such statement unpacking is not allowed. But having this work,
> combined with something like N3728 would in my opinion be a great benefit
> of generic programming in C++.
>
> Btw, creating a pack of enum values from one of my proposed interfaces
> should be doable (although filtering duplicate values will be very hard
> with current TMP):
>
>     template<class E, E... Vs>
>     struct type_value_list {};
>
>     template<class E, class IdxSeq>
>     struct pack_enum_values_t;
>
>     template<class E, size_t... Idx>
>     struct pack_enum_values_t<E, std::index_sequence<Idx...>> {
>         using typelist = type_value_list<E, std::meta::enumerator_value<E,
> Idx>::value...>;
>     };
>
>     template<class E>
>     using enum_value_pack = typename pack_enum_values_t<E,
> std::make_index_sequence< std::meta::enumerator_count<E>::value
> >>::typelist;
>
>
>

--

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

------=_Part_621_3569397.1380577482505
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">More that security concerns, I simply dont want rewrite al=
l switches every time I add new enum value. And this is only side effect :)=
<br>Main goal of this was simplify `switch` based on `int`. It could be use=
d by variadic types or interpretors<br>(add `goto` to beginning and you can=
 implements turning machine using one `switch` without any function calls).=
<br>Without something like this is impossible to maintain such code manuall=
y.<br><br>I have once similar idea of syntax like:<br><div class=3D"prettyp=
rint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187,=
 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">//some code</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">}...</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span></div></code></div><br>But I didnt=
 like it. Its harder to spot and dont allow nesting.<br>with explicit `for.=
...` is lot of harder to ignore it even if you dont understood it.<br>Next t=
hing is nesting. Without my `for...` you cant made "cross join" of two pack=
s:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">//T an=
d K are parametr pack</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp; T a</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
K shouldnt be expanded there too?</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp;K c</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}...</span><span style=3D"co=
lor: #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></span></div></code></div>In my case its s=
imple:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">fo=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...(</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Ti</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: #0=
00;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"sty=
led-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>&nbsp; &nbsp; </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Ti</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbs=
p; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">...(</span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Ki</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"> K</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Ki</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div>or if you want expand `T` and `K` and some syntax sug=
ar for getting pack position: <br><br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">for</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">...(</span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Ti</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #606;" class=3D"styled-by-prettify">Ki</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> I </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> K</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">Ti</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">K=
i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</spa=
n><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;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> I</span><span style=3D"co=
lor: #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"styl=
ed-by-prettify">i</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">//I is inde=
x of Ti in T and Ki in K, its run form 0 to size...(Ti)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">print<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">"1"</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">print</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
80;" class=3D"styled-by-prettify">"\n"</span><span style=3D"color: #660;" c=
lass=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-prett=
ify"><br></span></div></code></div><br>I think you could replace `int` with=
 some enum that have same number of elements as this packs.<br><br><br>And =
about your `enum_type` interface. Yes I could get everything I want form it=
.. Only problem is that you cant do it directly and must use helper function=
 (similar to that you show).<br>This isnt big problem or cost compare to fu=
nctionality it give.<br><br>On Sunday, September 29, 2013 6:16:43 PM UTC+2,=
 Christian Kaeser wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Sunday, 29 September 2013 16:10:49 UTC+2, <a>inkwizyt...@gmai=
l.com</a>  wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">S=
ometimes you want chose program action based on enum value. Right now you c=
an do it creating switch statement that will chose correct action, but this=
 is error prone because if someone add new enum value your code will break =
(depending on if that value should have special handling). With templates f=
rom your proposition is possible to handle that situation:<br><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"c=
olor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#606">Enum</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">int</span><span style=3D=
"color:#000"> pos</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">void</span><span styl=
e=3D"color:#000"> switch_</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#606">Enum</span><span style=3D"color:#000"> e</span><span sty=
le=3D"color:#660">)</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </span=
><span style=3D"color:rgb(0,0,255)"><span>if</span></span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">enum_data</span><span style=3D=
"color:#660">&lt;</span><span style=3D"color:#000">E1</span><span style=3D"=
color:#660">&gt;::</span><span style=3D"color:#000">values</span><span styl=
e=3D"color:#660">[</span><span style=3D"color:#000">pos</span><span style=
=3D"color:#660">]</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">=3D=3D</span><span style=3D"color:#000"> e</span><span style=3D"=
color:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nb=
sp; </span><span style=3D"color:#606">Action</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#660"><code><span style=3D"color:#000">e=
num_data</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
000">E1</span><span style=3D"color:#660">&gt;::</span><span style=3D"color:=
#000">values</span><span style=3D"color:#660">[</span><span style=3D"color:=
#000">p<wbr>os</span><span style=3D"color:#660">]</span><span style=3D"colo=
r:#000"></span></code>&gt;</span><span style=3D"color:#000">::func();<br>&n=
bsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">else</span><br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch_&lt;</span><span style=3D"color:#=
000"><code><span style=3D"color:#000"></span><span style=3D"color:#606">Enu=
m</span><span style=3D"color:#660">, </span></code></span><span style=3D"co=
lor:#000"><code><span style=3D"color:#660"><code><span style=3D"color:#000"=
>pos</span><span style=3D"color:#660"> + 1</span></code></span></code>&gt;(=
e);<br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"=
><br></span></div></code></div>but as you can see it require some additiona=
l boilerplate code to work and have similar performance as hand written swi=
tch (O(log n) or O(1) in some cases). Additional problems is multiple funct=
ion calls that need be removed by compiler, this will slow down debug build=
s because they usually dont have optimization.<br><br>One possible solution=
 I have is introduce new version of `for` that will "iterate" on compiling =
time (resolving `switch` is only one use case of this):<br><div style=3D"ba=
ckground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:=
solid;border-width:1px;word-wrap:break-word"><code><div><code><span style=
=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#008">typename...</span><span style=3D"color:#000"> </span><=
span style=3D"color:rgb(153,0,255)"><span>T</span></span><span style=3D"col=
or:#660">&gt;</span><span style=3D"color:#000"><br></span></code><span styl=
e=3D"color:rgb(0,0,255)">void </span>func()<br>{<br>&nbsp;&nbsp;&nbsp; <spa=
n style=3D"color:rgb(0,0,255)">for</span>...(<span style=3D"color:rgb(153,0=
,255)">Ti </span>: <span style=3D"color:rgb(153,0,255)">T</span>)<span styl=
e=3D"color:rgb(102,102,102)">// Ti is element from pack <code>T equal </cod=
e>[A, B, C]</span><br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp; <span style=3D"color:rgb(153,0,255)">Ti</span>::func();<br>&n=
bsp;&nbsp;&nbsp; }<span style=3D"color:rgb(102,102,102)"><br>&nbsp;&nbsp;&n=
bsp; //this will generate code similar to:<br>&nbsp;&nbsp;&nbsp; //<br>&nbs=
p;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; A::func();<br>&nbsp;&nbsp;&nbsp; //&nbs=
p;&nbsp;&nbsp; B::func();<br>&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; C::fun=
c();<br>&nbsp;&nbsp;&nbsp; //</span><br>}<br><br><code><code><span style=3D=
"color:#008">template</span><span style=3D"color:#660">&lt;<span style=3D"c=
olor:rgb(0,0,255)">int</span></span><span style=3D"color:#008">...</span><s=
pan style=3D"color:#000"> I</span><span style=3D"color:#606"></span><span s=
tyle=3D"color:#660">&gt;</span><span style=3D"color:#000"><br><span style=
=3D"color:rgb(0,0,255)">int </span>switch_(<span style=3D"color:rgb(0,0,255=
)">int </span>i)<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,25=
5)">switch</span>(i)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">for</span>...(ii : I) <s=
pan style=3D"color:rgb(102,102,102)">//I is pack of [1, 3, 2]</span><br></s=
pan></code></code><code><code><span style=3D"color:#000"><code><code><code>=
<span style=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>=
</span></code></code></code></span></code></code><code><code><code><span st=
yle=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; </span></code></code></code><span style=3D"color:rgb(0,0,255)">c=
ase </span><code><code><code><span style=3D"color:#000">ii</span></code></c=
ode></code>: <span style=3D"color:rgb(0,0,255)">return </span><span style=
=3D"color:rgb(153,0,255)">Type</span>&lt;ii&gt;::value;<br><code><code><spa=
n style=3D"color:#000"><code><code><code><span style=3D"color:#000"><code><=
code><code><span style=3D"color:#000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; }</span></code></code></code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
<span style=3D"color:rgb(102,102,102)">&nbsp; //this will generate code </s=
pan></span></code></code></code></span></code></code><span style=3D"color:r=
gb(102,102,102)"><code><code><span><code><code><code><span><code>similar </=
code>to:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; case 1: return </span></c=
ode></code></code></span></code></code><code><code><span><code><code><code>=
<span><code>Type&lt;1&gt;</code>::value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; </span></code></code></code></span></code>=
</code><code><code><span><code><code><code><span><code><code><code><span><c=
ode><code><code><span>case 3: return </span></code></code></code></span></c=
ode></code></code></span></code></code></code></span></code></code><code><c=
ode><span><code><code><code><span><code><code><code><span><code><code><code=
><span><code><code><code><span><code><code><code><span><code>Type&lt;3&gt;<=
/code></span></code></code></code></span></code></code></code>::value;<br>&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp; </span></cod=
e></code></code></span></code></code></code></span></code></code></code></s=
pan></code></code><code><code><span><code><code><code><span><code><code><co=
de><span><code><code><code><span>case 2: return </span></code></code></code=
></span></code></code></code></span></code></code></code></span></code></co=
de><code><code><span><code><code><code><span><code><code><code><span><code>=
<code><code><span><code><code><code><span><code><code><code><span><code>Typ=
e&lt;2&gt;</code></span></code></code></code></span></code></code></code>::=
value;</span></code></code></code></span></code></code></code><br>&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span></code></code></code></span></co=
de></code></span><code><code><span style=3D"color:#000"><code><code><code><=
span style=3D"color:#000"><code><br></code></span></code></code></code>&nbs=
p;&nbsp;&nbsp; }<br>}</span></code></code><br><code><code><code><span style=
=3D"color:#008">template</span><span style=3D"color:#660">&lt;<span style=
=3D"color:rgb(153,0,255)">Enum</span></span><span style=3D"color:#008">...<=
/span><span style=3D"color:#000"> E</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"></span></code></code></code><code><code><co=
de><span style=3D"color:#000"><br><span style=3D"color:rgb(0,0,255)">void <=
/span>switch2_(</span></code></code></code><code><code><code><span style=3D=
"color:#000"><code><code><code><code><span style=3D"color:rgb(153,0,255)"><=
span>Enum</span></span><span style=3D"color:#008"><span style=3D"color:rgb(=
153,0,255)"> </span>e</span></code></code></code></code>)</span></code></co=
de></code><br>{<code><code><code><span style=3D"color:#000"><br>&nbsp;&nbsp=
;&nbsp; <span style=3D"color:rgb(0,0,255)">switch</span>(e)<br>&nbsp;&nbsp;=
&nbsp; {</span></code></code></code><code><code><code><span style=3D"color:=
#000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:r=
gb(0,0,255)">for</span>...(ee : E) <span style=3D"color:rgb(102,102,102)">/=
/E is pack of [</span></span></code></code></code><span style=3D"color:rgb(=
102,102,102)"><code><code><code><span><code><code><code><code><span></span>=
</code></code></code><code><code><code><span><code><code><code><code><span>=
Enum</span><span>::</span></code></code></code></code></span></code></code>=
</code></code>a1, </span></code></code></code><code><code><code><span><code=
><code><code><code><span><code><code><code><code><span><code><code><code><c=
ode><span>Enum</span><span>::</span></code></code></code></code></span></co=
de></code></code></code></span></code></code></code></code>a2, </span></cod=
e></code></code><code><code><code><span><code><code><code><code><span><code=
><code><code><code><span><code><code><code><code><span>Enum</span><span>::<=
/span></code></code></code></code></span></code></code></code></code></span=
></code></code></code></code>a3]</span></code></code></code></span><br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">case=
 </span>ee:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(153,0,255)">A</span=
>&lt;ee&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code><span style=3D"color:rgb(153,0,255)=
">A2</span>&lt;ee&gt;();</code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb=
(0,0,255)">break</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,25=
5)">default</span>:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">break</span>;<br><br>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(102,102,102=
)">//this will create code similar to:<code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp; //<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; =
case <code><code><code><code><span><code><code><code><code><span><code><cod=
e><code><code><span>Enum</span><span>::</span></code></code></code></code><=
/span></code></code></code></code>a1: A&lt;</span></code></code></code></co=
de><code><code><code><code><span><code><code><code><code><span><code><code>=
<code><code><span><code><code><code><code><span>Enum</span><span>::</span><=
/code></code></code></code></span></code></code></code></code>a1</span></co=
de></code></code></code>&gt;(); A2&lt;</span></code></code></code></code><c=
ode><code><code><code><span><code><code><code><code><span><code><code><code=
><code><span><code><code><code><code><span>Enum</span><span>::</span></code=
></code></code></code></span></code></code></code></code>a1</span></code></=
code></code></code>&gt;(); break;</span></code></code></code></code></code>=
<code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; case <code><=
code><code><code><span><code><code><code><code><span><code><code><code><cod=
e><span>Enum</span><span>::</span></code></code></code></code></span></code=
></code></code></code>a2: A&lt;</span></code></code></code></code><code><co=
de><code><code><span><code><code><code><code><span><code><code><code><code>=
<span><code><code><code><code><span>Enum</span><span>::</span></code></code=
></code></code></span></code></code></code></code>a2</span></code></code></=
code></code>&gt;(); A2&lt;</span></code></code></code></code><code><code><c=
ode><code><span><code><code><code><code><span><code><code><code><code><span=
><code><code><code><code><span>Enum</span><span>::</span></code></code></co=
de></code></span></code></code></code></code>a2</span></code></code></code>=
</code>&gt;(); break;</span></code></code></code></code></code><code><br>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // &nbsp; case <code><code><code><=
code><span><code><code><code><code><span><code><code><code><code><span>Enum=
</span><span>::</span></code></code></code></code></span></code></code></co=
de></code>a3: A&lt;</span></code></code></code></code><code><code><code><co=
de><span><code><code><code><code><span><code><code><code><code><span><code>=
<code><code><code><span>Enum</span><span>::</span></code></code></code></co=
de></span></code></code></code></code>a3</span></code></code></code></code>=
&gt;(); A2&lt;</span></code></code></code></code><code><code><code><code><s=
pan><code><code><code><code><span><code><code><code><code><span><code><code=
><code><code><span>Enum</span><span>::</span></code></code></code></code></=
span></code></code></code></code>a3</span></code></code></code></code>&gt;(=
); break;</span></code></code></code></code></code><br>&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; default: break;<br>&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp; //</span><br>&nbsp;&nbsp;&nbsp; }<br>}<br></div></=
code></div>But this is separate proposition to "enumeration pack". And even=
 change core language more than Andrew Tomazos proposition.<br>Funny thing,=
 I like more your proposition but Andrew ones have more<i> </i>synergies wi=
th my `for`:<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word=
"><code><div><span style=3D"color:rgb(0,0,0)"><span><span style=3D"color:rg=
b(0,0,255)">void </span>func(<span style=3D"color:rgb(153,0,255)">Enum </sp=
an>e)<br>{<br>&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">switch<=
/span>(e)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp; <span style=3D"color:rgb(0,0,255)">for</span>...(ee : <span style=3D"c=
olor:rgb(153,0,255)">Enum</span>...)<span style=3D"color:rgb(102,102,102)">=
 //create pack of [Enum::a1, Enum::a2, Enum::a3, Enum::a4]</span><br>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=3D"color:rgb(0,0,255)">case <=
/span>ee: <span style=3D"color:rgb(102,102,102)">/*do somthing*/</span> <sp=
an style=3D"color:rgb(0,0,255)">break</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</span></span><span style=3D=
"color:#660"></span></div></code></div></div></blockquote><div>&nbsp;<br>Ok=
ay I see, you want an compile time error if Action is not specialized for a=
 newly added enum value? Clang by default issues a warning if any enumerati=
on values are missed in a switch statement, do you think more security is n=
ecessary?<br><br>I really like your for/switch proposal, as indeed this see=
ms like an interesting feature for generic algorithms.<br>But is it really =
necessary to add something like the "for..." construct? Couldn't maybe the =
parameter pack expansion rules be simply expanded to allow something like t=
his:<br><br>template&lt;typename E, E... Es&gt;<br>void algo(E e) {<br>&nbs=
p;&nbsp; &nbsp;switch(e) {<br>&nbsp;&nbsp; &nbsp;{ case Es : Action&lt;Es&g=
t;(); A2&lt;Es&gt;(); break; }...<br>&nbsp;&nbsp; &nbsp;case some_other_cas=
e: SomeAction(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defau=
lt: break;<br>&nbsp;&nbsp; &nbsp;}<br>}<br><br>I am not deeply familiar wit=
h parameter pack details, but I am not quite clear why such statement unpac=
king is not allowed. But having this work, combined with something like N37=
28 would in my opinion be a great benefit of generic programming in C++.<br=
><br>Btw, creating a pack of enum values from one of my proposed interfaces=
 should be doable (although filtering duplicate values will be very hard wi=
th current TMP):<br><br>&nbsp;&nbsp; &nbsp;template&lt;class E, E... Vs&gt;=
<br>&nbsp;&nbsp; &nbsp;struct type_value_list {};<br><br>&nbsp;&nbsp; &nbsp=
;template&lt;class E, class IdxSeq&gt;<br>&nbsp;&nbsp; &nbsp;struct pack_en=
um_values_t;<br><br>&nbsp;&nbsp; &nbsp;template&lt;class E, size_t... Idx&g=
t;<br>&nbsp;&nbsp; &nbsp;struct pack_enum_values_t&lt;E, std::index_sequenc=
e&lt;Idx...&gt;&gt; {<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;using typeli=
st =3D type_value_list&lt;E, std::meta::enumerator_value&lt;E, Idx&gt;::val=
ue...&gt;;<br>&nbsp;&nbsp; &nbsp;};<br><br>&nbsp;&nbsp; &nbsp;template&lt;c=
lass E&gt;<br>&nbsp;&nbsp; &nbsp;using enum_value_pack =3D typename pack_en=
um_values_t&lt;E, std::make_index_sequence&lt; std::meta::enumerator_count&=
lt;E&gt;<wbr>::value &gt;&gt;::typelist;<br><br></div><div>&nbsp;</div></di=
v></blockquote></div>

<p></p>

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

------=_Part_621_3569397.1380577482505--

.