Topic: statement folding on variadic templates


Author: Greg Marr <gregmmarr@gmail.com>
Date: Wed, 8 Jun 2016 08:11:21 -0700 (PDT)
Raw View
------=_Part_649_1412130046.1465398681382
Content-Type: multipart/alternative;
 boundary="----=_Part_650_1948991266.1465398681383"

------=_Part_650_1948991266.1465398681383
Content-Type: text/plain; charset=UTF-8

On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vidyuk wrote:
>
> Expression folding on a variadic template parameters pack are great and
> allows to write internal function stuff inside a function instead of
> writing some recursive template code which is required to be moved outside
> of the function. But when one want to repeat some statement for every
> element of a parameter pack recursive templates or abusing of coma operator
> folding are stil the only options. After facing this issue several times I
> start to realize that it would be great to have the following extension to
> the C++11 range-for syntax:
>

Have you seen Sean Parent's for_each_argument?

template <class F, class... Args>
void for_each_argument(F f, Args&&... args) {
 [](...){}((f(std::forward<Args>(args)), 0)...);
}



There was even a CppCon 2015 talk about it

https://www.youtube.com/watch?v=2l83JlqkzBk

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0aa49f06-08b0-433a-a897-720140eb7097%40isocpp.org.

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

<div dir=3D"ltr">On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vi=
dyuk 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">Ex=
pression folding on a variadic template parameters pack are great and allow=
s to write internal function stuff inside a function instead of writing som=
e recursive template code which is required to be moved outside of the func=
tion. But when one want to repeat some statement for every element of a par=
ameter pack recursive templates or abusing of coma operator folding are sti=
l the only options. After facing this issue several times I start to realiz=
e that it would be great to have the following extension to the C++11 range=
-for syntax:<br></div></blockquote><div><br></div><div>Have you seen Sean P=
arent&#39;s for_each_argument?</div><div><br></div><div class=3D"prettyprin=
t" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; ba=
ckground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">class</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> for_each_argum=
ent</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">F f</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&amp;&amp;...</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> args</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=
](...){}((</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">forward</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">args</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)),</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify=
">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div></cod=
e></div><div><br><font color=3D"#595959" face=3D"Consolas, Courier New, Luc=
ida Console, monospace"><span style=3D"font-size: 12px; white-space: pre;">=
<br></span></font></div><div><font color=3D"#595959" face=3D"arial, sans-se=
rif"><span style=3D"font-size: 12px; white-space: pre;">There was even a Cp=
pCon 2015 talk about it </span></font></div><div><font color=3D"#595959" fa=
ce=3D"arial, sans-serif"><span style=3D"font-size: 12px; white-space: pre;"=
><br></span></font></div><div><font color=3D"#595959" face=3D"arial, sans-s=
erif"><span style=3D"font-size: 12px; white-space: pre;">https://www.youtub=
e.com/watch?v=3D2l83JlqkzBk</span><br></font></div><div><font color=3D"#595=
959" face=3D"arial, sans-serif"><span style=3D"font-size: 12px; white-space=
: pre;"><br></span></font></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0aa49f06-08b0-433a-a897-720140eb7097%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0aa49f06-08b0-433a-a897-720140eb7097=
%40isocpp.org</a>.<br />

------=_Part_650_1948991266.1465398681383--

------=_Part_649_1412130046.1465398681382--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Wed, 8 Jun 2016 11:03:32 -0700 (PDT)
Raw View
------=_Part_1710_1167150558.1465409012569
Content-Type: multipart/alternative;
 boundary="----=_Part_1711_1224358494.1465409012569"

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

Foreach from the presentation you've posted allows to repeat overloaded=20
function or functor with multiple operator() for each argument from a pack=
=20
by abusing coma operator. In C++17 it's even simplier since you don't need=
=20
intermediate garbage initializer_list. You can perform expression folding=
=20
directly and it terribly great (tried it with gcc 6.1).

This kind of folding is the simpliest one. I use it a lot but always feel=
=20
myself sad using such kind of haks. In the example I've shown "if (cond)=20
return foo(arg_from_pack);" statement is folded which can't be done by=20
abusing coma opertor and requires recursive templates. One more thing on=20
the syntax i propose: It allows to solve those kind of tasks without hacks=
=20
or boilerplate code. It uses simple to write and understand construction=20
(simple for human and for compiler).

Sergey Vidyuk

=D1=81=D1=80=D0=B5=D0=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 21=
:11:21 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=
=D0=BB=D1=8C Greg Marr =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vidyuk wrote:
>>
>> Expression folding on a variadic template parameters pack are great and=
=20
>> allows to write internal function stuff inside a function instead of=20
>> writing some recursive template code which is required to be moved outsi=
de=20
>> of the function. But when one want to repeat some statement for every=20
>> element of a parameter pack recursive templates or abusing of coma opera=
tor=20
>> folding are stil the only options. After facing this issue several times=
 I=20
>> start to realize that it would be great to have the following extension =
to=20
>> the C++11 range-for syntax:
>>
>
> Have you seen Sean Parent's for_each_argument?
>
> template <class F, class... Args>
> void for_each_argument(F f, Args&&... args) {
>  [](...){}((f(std::forward<Args>(args)), 0)...);
> }
>
>
>
> There was even a CppCon 2015 talk about it=20
>
> https://www.youtube.com/watch?v=3D2l83JlqkzBk
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9c9cb032-a950-476b-823c-28643ef305d8%40isocpp.or=
g.

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

<div dir=3D"ltr">Foreach from the presentation you&#39;ve posted allows to =
repeat overloaded function or functor with multiple operator() for each arg=
ument from a pack by abusing coma operator. In C++17 it&#39;s even simplier=
 since you don&#39;t need intermediate garbage initializer_list. You can pe=
rform expression folding directly and it terribly great (tried it with gcc =
6.1).<br><br>This kind of folding is the simpliest one. I use it a lot but =
always feel myself sad using such kind of haks. In the example I&#39;ve sho=
wn &quot;if (cond) return foo(arg_from_pack);&quot; statement is folded whi=
ch can&#39;t be done by abusing coma opertor and requires recursive templat=
es. One more thing on the syntax i propose: It allows to solve those kind o=
f tasks without hacks or boilerplate code. It uses simple to write and unde=
rstand construction (simple for human and for compiler).<br><br>Sergey Vidy=
uk<br><br>=D1=81=D1=80=D0=B5=D0=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =
=D0=B3., 21:11:21 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=
=82=D0=B5=D0=BB=D1=8C Greg Marr =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=
<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">On Wednesday,=
 June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vidyuk 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">Expression folding on a variadic te=
mplate parameters pack are great and allows to write internal function stuf=
f inside a function instead of writing some recursive template code which i=
s required to be moved outside of the function. But when one want to repeat=
 some statement for every element of a parameter pack recursive templates o=
r abusing of coma operator folding are stil the only options. After facing =
this issue several times I start to realize that it would be great to have =
the following extension to the C++11 range-for syntax:<br></div></blockquot=
e><div><br></div><div>Have you seen Sean Parent&#39;s for_each_argument?</d=
iv><div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap=
:break-word;background-color:rgb(250,250,250)"><code><div><span style=3D"co=
lor:#008">template</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> F</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#660">...</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#606">Args</span><span style=3D"color:#660">&gt;</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#008">void</span><span style=3D"co=
lor:#000"> for_each_argument</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">F f</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#606">Args</span><span styl=
e=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> args</span=
><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0</span>=
<span style=3D"color:#660">[](...){}((</span><span style=3D"color:#000">f</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Arg<wb=
r>s</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000"=
>args</span><span style=3D"color:#660">)),</span><span style=3D"color:#000"=
> </span><span style=3D"color:#066">0</span><span style=3D"color:#660">)...=
);</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br><br></span></div></code></div><div><b=
r><font color=3D"#595959" face=3D"Consolas, Courier New, Lucida Console, mo=
nospace"><span style=3D"font-size:12px;white-space:pre"><br></span></font><=
/div><div><font color=3D"#595959" face=3D"arial, sans-serif"><span style=3D=
"font-size:12px;white-space:pre">There was even a CppCon 2015 talk about it=
 </span></font></div><div><font color=3D"#595959" face=3D"arial, sans-serif=
"><span style=3D"font-size:12px;white-space:pre"><br></span></font></div><d=
iv><font color=3D"#595959" face=3D"arial, sans-serif"><span style=3D"font-s=
ize:12px;white-space:pre"><a href=3D"https://www.youtube.com/watch?v=3D2l83=
JlqkzBk" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39=
;https://www.youtube.com/watch?v\x3d2l83JlqkzBk&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://www.youtube.com/watch?v\x3d2l83JlqkzBk&#39;;re=
turn true;">https://www.youtube.com/watch?<wbr>v=3D2l83JlqkzBk</a></span><b=
r></font></div><div><font color=3D"#595959" face=3D"arial, sans-serif"><spa=
n style=3D"font-size:12px;white-space:pre"><br></span></font></div></div></=
blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9c9cb032-a950-476b-823c-28643ef305d8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9c9cb032-a950-476b-823c-28643ef305d8=
%40isocpp.org</a>.<br />

------=_Part_1711_1224358494.1465409012569--

------=_Part_1710_1167150558.1465409012569--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Thu, 9 Jun 2016 04:53:51 -0700 (PDT)
Raw View
------=_Part_682_394776987.1465473231403
Content-Type: multipart/alternative;
 boundary="----=_Part_683_254538336.1465473231403"

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

On Wednesday, 8 June 2016 19:03:33 UTC+1, Sergey Vidyuk wrote:
>
> =D1=81=D1=80=D0=B5=D0=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., =
21:11:21 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=
=D0=BB=D1=8C Greg Marr =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vidyuk wrote:
>>>
>>> Expression folding on a variadic template parameters pack are great and=
=20
>>> allows to write internal function stuff inside a function instead of=20
>>> writing some recursive template code which is required to be moved outs=
ide=20
>>> of the function. But when one want to repeat some statement for every=
=20
>>> element of a parameter pack recursive templates or abusing of coma oper=
ator=20
>>> folding are stil the only options. After facing this issue several time=
s I=20
>>> start to realize that it would be great to have the following extension=
 to=20
>>> the C++11 range-for syntax:
>>>
>>
>> Have you seen Sean Parent's for_each_argument?
>>
>> template <class F, class... Args>
>> void for_each_argument(F f, Args&&... args) {
>>  [](...){}((f(std::forward<Args>(args)), 0)...);
>> }
>>
>>
Well, sure it's possible to emulate variadic for using existing=20
language/library features, but a new language feature (built-in control=20
flow construct) is more readable and integrates better; most of the same=20
arguments for if constexpr (p0128r1) hold here as well.

I'm not sure about the motivating example, though; it seems to me that in=
=20
that case what you really want is a switch statement:

template<typename Func, typename... A>
auto invoke(Func&& f, A&&... a) const {
    switch constexpr (type_idx_) {
        case... indexof(V): return std::invoke(std::forward<Func>(f),=20
static_cast<V*>(data_), std::forward<A>(a)...);
    }
    throw std::logic_error("should never happen");
}

Do you have any other examples with stronger motivation e.g. where each=20
iteration has a side effect, or where you conditionally break/return=20
depending on something more complex than a switch-style predicate?

Aside from that, the syntax doesn't look to me to be distinctive enough;=20
just having the for-range-initializer end in an ellipsis could be confused=
=20
with e.g. a fold. (Yes, folds are parenthesized, but it's easy to overlook=
=20
that.) Bikeshedding a bit, but I'd follow the "if constexpr" path and spell=
=20
it "for constexpr". Perhaps we could end up with a full family of constexpr=
=20
control flow statements.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f014c520-9de6-488a-8c0f-1193bd43c0d0%40isocpp.or=
g.

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

<div dir=3D"ltr">On Wednesday, 8 June 2016 19:03:33 UTC+1, Sergey Vidyuk  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">=D1=81=
=D1=80=D0=B5=D0=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 21:11:21=
 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=
=D1=8C Greg Marr =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr">On Wednesday, June 8, 2016 at 10:=
14:50 AM UTC-4, Sergey Vidyuk 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">Expression folding on a variadic template parameters pack=
 are great and allows to write internal function stuff inside a function in=
stead of writing some recursive template code which is required to be moved=
 outside of the function. But when one want to repeat some statement for ev=
ery element of a parameter pack recursive templates or abusing of coma oper=
ator folding are stil the only options. After facing this issue several tim=
es I start to realize that it would be great to have the following extensio=
n to the C++11 range-for syntax:<br></div></blockquote><div><br></div><div>=
Have you seen Sean Parent&#39;s for_each_argument?</div><div><br></div><div=
 style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;background=
-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">template</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span=
><span style=3D"color:#008">class</span><span style=3D"color:#000"> F</span=
><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">class</span><span style=3D"color:#660">...</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Args</span><span=
 style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">void</span><span style=3D"color:#000"> for_each_argu=
ment</span><span style=3D"color:#660">(</span><span style=3D"color:#000">F =
f</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#606">Args</span><span style=3D"color:#660">&amp;&a=
mp;...</span><span style=3D"color:#000"> args</span><span style=3D"color:#6=
60">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"><br>=C2=A0</span><span style=3D"color:#66=
0">[](...){}((</span><span style=3D"color:#000">f</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">std</span><span style=3D"color:#=
660">::</span><span style=3D"color:#000">forward</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#606">Arg<wbr>s</span><span style=3D=
"color:#660">&gt;(</span><span style=3D"color:#000">args</span><span style=
=3D"color:#660">)),</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">0</span><span style=3D"color:#660">)...);</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"c=
olor:#000"><br><br></span></div></code></div></div></blockquote></div></blo=
ckquote><div><br></div><div>Well, sure it&#39;s possible to emulate variadi=
c for using existing language/library features, but a new language feature =
(built-in control flow construct) is more readable and integrates better; m=
ost of the same arguments for if constexpr (p0128r1) hold here as well.</di=
v><div><br></div><div>I&#39;m not sure about the motivating example, though=
; it seems to me that in that case what you really want is a switch stateme=
nt:</div><div><br></div>    <div class=3D"prettyprint" style=3D"border: 1px=
 solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250=
, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an 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=
: #606;" class=3D"styled-by-prettify">Func</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">typename</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> A</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> invoke</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Func</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> A</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&amp;&amp;...</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a</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">const</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">switch</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">type_idx_</span><span style=3D"color: #660;" class=3D"st=
yled-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>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">case</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> indexof</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">V</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">):</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">invoke</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forw=
ard</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span style=3D"color: #606;" class=3D"styled-by-prettify">Func</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"c=
olor: #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">static_cast</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">V</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">*&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">data_</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">forward</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">A</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #00=
0;" 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>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">throw</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">logic_error</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
">&quot;should never happen&quot;</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-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><div><br></div><div>Do you have any other ex=
amples with stronger motivation e.g. where each iteration has a side effect=
, or where you conditionally break/return depending on something more compl=
ex than a switch-style predicate?</div><div><br></div><div>Aside from that,=
 the syntax doesn&#39;t look to me to be distinctive enough; just having th=
e for-range-initializer end in an ellipsis could be confused with e.g. a fo=
ld. (Yes, folds are parenthesized, but it&#39;s easy to overlook that.) Bik=
eshedding a bit, but I&#39;d follow the &quot;if constexpr&quot; path and s=
pell it &quot;for constexpr&quot;. Perhaps we could end up with a full fami=
ly of constexpr control flow statements.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f014c520-9de6-488a-8c0f-1193bd43c0d0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f014c520-9de6-488a-8c0f-1193bd43c0d0=
%40isocpp.org</a>.<br />

------=_Part_683_254538336.1465473231403--

------=_Part_682_394776987.1465473231403--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 9 Jun 2016 12:06:10 -0700 (PDT)
Raw View
------=_Part_1472_884747112.1465499170876
Content-Type: multipart/alternative;
 boundary="----=_Part_1473_448844899.1465499170877"

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

On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vidyuk wrote:
>
> Expression folding on a variadic template parameters pack are great and=
=20
> allows to write internal function stuff inside a function instead of=20
> writing some recursive template code which is required to be moved outsid=
e=20
> of the function. But when one want to repeat some statement for every=20
> element of a parameter pack recursive templates or abusing of coma operat=
or=20
> folding are stil the only options.
>

FWIW, I *don't* think that today's option, "abuse of comma operator=20
folding", is very bad. It would be *nice* to have a fold-expression-esque=
=20
(fold-statement?) syntax for folding over semicolons; but I have no=20
concrete idea of what that would look like.
=20

> After facing this issue several times I start to realize that it would be=
=20
> great to have the following extension to the C++11 range-for syntax:
>
> template<typename... L> void foo() {
>     for (typename T: L...) {
>         // do the stuff
>     }
> }
>
> template<typename... A> void foo(A&& a) {
>     for (const auto& arg: a...) {
>         // do the stuff
>     }
> }
>
> In both cases the loop is unrolled in compile time and it's body is=20
> instantiate for each exact type in the same way as a body of template=20
> function. Each instantiation of a body has it's own scope and there are n=
o=20
> outter scope polution posibility. Standard loop operators break and=20
> continue should also be allowed for both cases and work in the same way a=
s=20
> in any runtime C++ loop.
>

My kneejerk reaction was that for (typename T */*...*/*) is a non-starter,=
=20
because you're proposing to have it mean something very different from for=
=20
(int I */*...*/*).
Plus, you'll have troublesome grammar issues if the user tries to use the=
=20
new syntax to replace a repeated statement where the repeated statement=20
contains a "break" or "continue".
However, on further reflection, I think that I might just be approaching=20
the problem from the wrong angle =E2=80=94 I've been thinking of it as "a w=
ay to=20
textually replace sizeof...(P) repeats of the same statement with a single=
=20
statement" (i.e. a variant of folding), whereas I think you're thinking of=
=20
it as "a way to control-flow over compile-time entities" (i.e. a variant of=
=20
if-constexpr).  I actually think your syntax is reasonable with a very=20
small tweak, and here's why:

There is currently a very well-received-in-Jacksonville proposal (P0292R1=
=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html>) to=
=20
add "if constexpr" to the language.
If integer indexing into packs were proposed and accepted, then the obvious=
=20
syntax for looping over a pack at compile-time would be

    for constexpr (size_t i=3D0; i < sizeof...(Ts); ++i) {  // new syntax=
=20
("for constexpr")
        using T =3D Ts...[i];  // new syntax (pack indexing)
        f<T>();
    }

or (arguably; anyway I'm not convinced that it's a horrible idea) that=20
could be reduced to just

    for constexpr (typename T : Ts...) {  // new syntax ("for constexpr")
        f<T>();
    }

The remaining problem is that I'm not sure the "obvious" syntax (above)=20
actually makes any sense. We want to be able to ++i, but at the same time=
=20
use f<i>(). Perhaps i should magically be constexpr in the body of the=20
loop, but non-constexpr in the header of the loop?
I've emailed Jens Maurer separately to ask what the semantics of if=20
constexpr are supposed to be in similar cases, and will report back on the=
=20
results if he doesn't post here first. :)

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f11d3266-3407-4c00-a578-5d07beeb1071%40isocpp.or=
g.

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

<div dir=3D"ltr">On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vid=
yuk 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">Exp=
ression folding on a variadic template parameters pack are great and allows=
 to write internal function stuff inside a function instead of writing some=
 recursive template code which is required to be moved outside of the funct=
ion. But when one want to repeat some statement for every element of a para=
meter pack recursive templates or abusing of coma operator folding are stil=
 the only options.</div></blockquote><div><br></div><div>FWIW, I <i>don&#39=
;t</i> think that today&#39;s option, &quot;abuse of comma operator folding=
&quot;, is very bad. It would be <i>nice</i> to have a fold-expression-esqu=
e (fold-statement?) syntax for folding over semicolons; but I have no concr=
ete idea of what that would look like.</div><div>=C2=A0</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"> After facing this issue se=
veral times I start to realize that it would be great to have the following=
 extension to the C++11 range-for syntax:<br><br><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">te=
mplate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#00=
8">typename</span><span style=3D"color:#660">...</span><span style=3D"color=
:#000"> L</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">void</span><span style=3D"color:#0=
00"> foo</span><span style=3D"color:#660">()</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#660"></span><span style=3D"col=
or:#000"></span><span style=3D"color:#008">for</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
typename</span><span style=3D"color:#000"> T</span><span style=3D"color:#66=
0">:</span><span style=3D"color:#000"> L</span><span style=3D"color:#660">.=
...)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color:#800">// do the stuff</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#660"></span><span style=3D"color:=
#660">}</span><span style=3D"color:#000"><br></span><br><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:#660">...</span><s=
pan style=3D"color:#000"> A</span><span style=3D"color:#660">&gt;</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">void</span><span=
 style=3D"color:#000"> foo</span><span style=3D"color:#660">(A&amp;&amp; a)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#660"></span><=
span style=3D"color:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">f=
or</span><span style=3D"color:#000"> </span><span style=3D"color:#660">(con=
st auto</span><span style=3D"color:#008"></span><span style=3D"color:#000">=
&amp; arg</span><span style=3D"color:#660">:</span><span style=3D"color:#00=
0"> a</span><span style=3D"color:#660">...)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#800">// do the st=
uff</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#000"></span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br></span></code></div></code></div><br>In both cases the loop i=
s unrolled in compile time and it&#39;s body is instantiate for each exact =
type in the same way as a body of template function. Each instantiation of =
a body has it&#39;s own scope and there are no outter scope polution posibi=
lity. Standard loop operators break and continue should also be allowed for=
 both cases and work in the same way as in any runtime C++ loop.<br></div><=
/blockquote><div><br></div><div>My kneejerk reaction was that <font face=3D=
"courier new, monospace">for (typename T <i>/*...*/</i>)</font> is a non-st=
arter, because you&#39;re proposing to have it mean something very differen=
t from <font face=3D"courier new, monospace">for (int I <i>/*...*/</i>)</fo=
nt>.</div><div>Plus, you&#39;ll have troublesome grammar issues if the user=
 tries to use the new syntax to replace a repeated statement where the repe=
ated statement contains a &quot;break&quot; or &quot;continue&quot;.</div><=
div>However, on further reflection, I think that I might just be approachin=
g the problem from the wrong angle =E2=80=94 I&#39;ve been thinking of it a=
s &quot;a way to textually replace sizeof...(P) repeats of the same stateme=
nt with a single statement&quot; (i.e. a variant of folding), whereas I thi=
nk you&#39;re thinking of it as &quot;a way to control-flow over compile-ti=
me entities&quot; (i.e. a variant of if-constexpr). =C2=A0I actually think =
your syntax is reasonable with a very small tweak, and here&#39;s why:</div=
><div><br></div><div>There is currently a very well-received-in-Jacksonvill=
e proposal (<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2=
016/p0292r1.html">P0292R1</a>) to add &quot;if constexpr&quot; to the langu=
age.</div><div>If integer indexing into packs were proposed and accepted, t=
hen the obvious syntax for looping over a pack at compile-time would be</di=
v><div><br></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 f=
or constexpr (size_t i=3D0; i &lt; sizeof...(Ts); ++i) { =C2=A0// new synta=
x (&quot;for constexpr&quot;)</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0// new sy=
ntax (pack indexing)</font></div><div><font face=3D"courier new, monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();</font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 =C2=A0 }</font></div><div><br></div><div>or (=
arguably; anyway I&#39;m not convinced that it&#39;s a horrible idea) that =
could be reduced to just</div><div><br></div><div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 for constexpr (typename T : Ts...) { =C2=A0=
// new syntax (&quot;for constexpr&quot;)</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();<br></font><=
/div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div=
></div><div><br></div><div>The remaining problem is that I&#39;m not sure t=
he &quot;obvious&quot; syntax (above) actually makes any sense. We want to =
be able to <font face=3D"courier new, monospace">++i</font>, but at the sam=
e time use <font face=3D"courier new, monospace">f&lt;i&gt;()</font>. Perha=
ps <font face=3D"courier new, monospace">i</font> should magically be const=
expr in the body of the loop, but non-constexpr in the header of the loop?<=
/div><div>I&#39;ve emailed Jens Maurer separately to ask what the semantics=
 of <font face=3D"courier new, monospace">if constexpr</font> are supposed =
to be in similar cases, and will report back on the results if he doesn&#39=
;t post here first. :)</div><div><br></div><div>=E2=80=93Arthur<br></div></=
div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f11d3266-3407-4c00-a578-5d07beeb1071%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f11d3266-3407-4c00-a578-5d07beeb1071=
%40isocpp.org</a>.<br />

------=_Part_1473_448844899.1465499170877--

------=_Part_1472_884747112.1465499170876--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 9 Jun 2016 13:13:45 -0700
Raw View
--001a11478cfa36dba00534de0fc3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thu, Jun 9, 2016 at 12:06 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vidyuk wrote:
>>
>> Expression folding on a variadic template parameters pack are great and
>> allows to write internal function stuff inside a function instead of
>> writing some recursive template code which is required to be moved outsi=
de
>> of the function. But when one want to repeat some statement for every
>> element of a parameter pack recursive templates or abusing of coma opera=
tor
>> folding are stil the only options.
>>
>
> FWIW, I *don't* think that today's option, "abuse of comma operator
> folding", is very bad. It would be *nice* to have a fold-expression-esque
> (fold-statement?) syntax for folding over semicolons; but I have no
> concrete idea of what that would look like.
>

I think last time this came up the reasonable options were:

expr_stmt() ... ;   // #1: problem: what does "if (blah) expr_stmt() ...;"
mean?
expr_stmt(), ... ;  // #2: make outermost parens in comma fold optional in
this context
( expr_stmt(), ... ) ; // #3: status quo, a little verbose

Supporting #2 seems very reasonable to me. In fact, we could make the
parens in a fold-expression optional for any full-expression:

  std::cout << ... << pack;
  pack_of_references =3D ... =3D 0;

  if (pack_of_bools && ...)

There are other cases where we could allow it, but we need to be a bit
careful:

  f(a + ... + b) // maybe ok?
  f(a, ... , b) // ill-formed

The rules we originally picked for fold-expressions were deliberately very
conservative; relaxing them is probably a good idea.

After facing this issue several times I start to realize that it would be
>> great to have the following extension to the C++11 range-for syntax:
>>
>> template<typename... L> void foo() {
>>     for (typename T: L...) {
>>         // do the stuff
>>     }
>> }
>>
>> template<typename... A> void foo(A&& a) {
>>     for (const auto& arg: a...) {
>>         // do the stuff
>>     }
>> }
>>
>> In both cases the loop is unrolled in compile time and it's body is
>> instantiate for each exact type in the same way as a body of template
>> function. Each instantiation of a body has it's own scope and there are =
no
>> outter scope polution posibility. Standard loop operators break and
>> continue should also be allowed for both cases and work in the same way =
as
>> in any runtime C++ loop.
>>
>
> My kneejerk reaction was that for (typename T */*...*/*) is a
> non-starter, because you're proposing to have it mean something very
> different from for (int I */*...*/*).
> Plus, you'll have troublesome grammar issues if the user tries to use the
> new syntax to replace a repeated statement where the repeated statement
> contains a "break" or "continue".
> However, on further reflection, I think that I might just be approaching
> the problem from the wrong angle =E2=80=94 I've been thinking of it as "a=
 way to
> textually replace sizeof...(P) repeats of the same statement with a singl=
e
> statement" (i.e. a variant of folding), whereas I think you're thinking o=
f
> it as "a way to control-flow over compile-time entities" (i.e. a variant =
of
> if-constexpr).  I actually think your syntax is reasonable with a very
> small tweak, and here's why:
>
> There is currently a very well-received-in-Jacksonville proposal (P0292R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html>)
> to add "if constexpr" to the language.
> If integer indexing into packs were proposed and accepted, then the
> obvious syntax for looping over a pack at compile-time would be
>
>     for constexpr (size_t i=3D0; i < sizeof...(Ts); ++i) {  // new syntax
> ("for constexpr")
>         using T =3D Ts...[i];  // new syntax (pack indexing)
>         f<T>();
>     }
>
> or (arguably; anyway I'm not convinced that it's a horrible idea) that
> could be reduced to just
>
>     for constexpr (typename T : Ts...) {  // new syntax ("for constexpr")
>         f<T>();
>     }
>
> The remaining problem is that I'm not sure the "obvious" syntax (above)
> actually makes any sense. We want to be able to ++i, but at the same time
> use f<i>(). Perhaps i should magically be constexpr in the body of the
> loop, but non-constexpr in the header of the loop?
> I've emailed Jens Maurer separately to ask what the semantics of if
> constexpr are supposed to be in similar cases, and will report back on
> the results if he doesn't post here first. :)
>
> =E2=80=93Arthur
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f11d3266-340=
7-4c00-a578-5d07beeb1071%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f11d3266-34=
07-4c00-a578-5d07beeb1071%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOfiQq%3DhhVBJAQ3Ekeo6mkWxPasnURXOW6r8zNo8oOk93=
ptbAQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jun 9, 2016 at 12:06 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@g=
mail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><span class=3D"">On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, S=
ergey Vidyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>Expression folding on a variadic template parameters pack are great and al=
lows to write internal function stuff inside a function instead of writing =
some recursive template code which is required to be moved outside of the f=
unction. But when one want to repeat some statement for every element of a =
parameter pack recursive templates or abusing of coma operator folding are =
stil the only options.</div></blockquote><div><br></div></span><div>FWIW, I=
 <i>don&#39;t</i> think that today&#39;s option, &quot;abuse of comma opera=
tor folding&quot;, is very bad. It would be <i>nice</i> to have a fold-expr=
ession-esque (fold-statement?) syntax for folding over semicolons; but I ha=
ve no concrete idea of what that would look like.</div></div></blockquote><=
div><br></div><div>I think last time this came up the reasonable options we=
re:</div><div><br></div><div>expr_stmt() ... ; =C2=A0 // #1: problem: what =
does &quot;if (blah) expr_stmt() ...;&quot; mean?</div><div>expr_stmt(), ..=
.. ; =C2=A0// #2: make outermost parens in comma fold optional in this conte=
xt</div><div>( expr_stmt(), ... ) ; // #3: status quo, a little verbose</di=
v><div><br></div><div>Supporting #2 seems very reasonable to me. In fact, w=
e could make the parens in a fold-expression optional for any full-expressi=
on:</div><div><br></div><div>=C2=A0 std::cout &lt;&lt; ... &lt;&lt; pack;</=
div><div>=C2=A0 pack_of_references =3D ... =3D 0;</div><div><br></div><div>=
=C2=A0 if (pack_of_bools &amp;&amp; ...)</div><div><br></div><div>There are=
 other cases where we could allow it, but we need to be a bit careful:</div=
><div><br></div><div>=C2=A0 f(a + ... + b) // maybe ok?</div><div>=C2=A0 f(=
a, ... , b) // ill-formed</div><div><br></div><div>The rules we originally =
picked for fold-expressions were deliberately very conservative; relaxing t=
hem is probably a good idea.</div><div><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><span class=3D""><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"> After facing this issue several times I start to real=
ize that it would be great to have the following extension to the C++11 ran=
ge-for syntax:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:brea=
k-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 sty=
le=3D"color:#660">...</span><span style=3D"color:#000"> L</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><span styl=
e=3D"color:#660">()</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:#660"></span><span style=3D"color:#000"></span><span sty=
le=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> T</span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> L</span><span style=3D"color:#660">...)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#800=
">// do the stuff</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#660"></span><span style=3D"color:#660">}</span><span s=
tyle=3D"color:#000"><br></span><br><code><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#660">...</span><span style=3D"color:#000=
"> A</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">void</span><span style=3D"color:#000"> =
foo</span><span style=3D"color:#660">(A&amp;&amp; a)</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#660"></span><span style=3D"color:#00=
0">=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">(const auto</span><span sty=
le=3D"color:#008"></span><span style=3D"color:#000">&amp; arg</span><span s=
tyle=3D"color:#660">:</span><span style=3D"color:#000"> a</span><span style=
=3D"color:#660">...)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 </span><span style=3D"color:#800">// do the stuff</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#000"></span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></co=
de></div></code></div><br>In both cases the loop is unrolled in compile tim=
e and it&#39;s body is instantiate for each exact type in the same way as a=
 body of template function. Each instantiation of a body has it&#39;s own s=
cope and there are no outter scope polution posibility. Standard loop opera=
tors break and continue should also be allowed for both cases and work in t=
he same way as in any runtime C++ loop.<br></div></blockquote><div><br></di=
v></span><div>My kneejerk reaction was that <font face=3D"courier new, mono=
space">for (typename T <i>/*...*/</i>)</font> is a non-starter, because you=
&#39;re proposing to have it mean something very different from <font face=
=3D"courier new, monospace">for (int I <i>/*...*/</i>)</font>.</div><div>Pl=
us, you&#39;ll have troublesome grammar issues if the user tries to use the=
 new syntax to replace a repeated statement where the repeated statement co=
ntains a &quot;break&quot; or &quot;continue&quot;.</div><div>However, on f=
urther reflection, I think that I might just be approaching the problem fro=
m the wrong angle =E2=80=94 I&#39;ve been thinking of it as &quot;a way to =
textually replace sizeof...(P) repeats of the same statement with a single =
statement&quot; (i.e. a variant of folding), whereas I think you&#39;re thi=
nking of it as &quot;a way to control-flow over compile-time entities&quot;=
 (i.e. a variant of if-constexpr).=C2=A0 I actually think your syntax is re=
asonable with a very small tweak, and here&#39;s why:</div><div><br></div><=
div>There is currently a very well-received-in-Jacksonville proposal (<a hr=
ef=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html"=
 target=3D"_blank">P0292R1</a>) to add &quot;if constexpr&quot; to the lang=
uage.</div><div>If integer indexing into packs were proposed and accepted, =
then the obvious syntax for looping over a pack at compile-time would be</d=
iv><div><br></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
for constexpr (size_t i=3D0; i &lt; sizeof...(Ts); ++i) { =C2=A0// new synt=
ax (&quot;for constexpr&quot;)</font></div><div><font face=3D"courier new, =
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0// new s=
yntax (pack indexing)</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 }</font></div><div><br></div><div>or =
(arguably; anyway I&#39;m not convinced that it&#39;s a horrible idea) that=
 could be reduced to just</div><div><br></div><div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 for constexpr (typename T : Ts...) { =C2=
=A0// new syntax (&quot;for constexpr&quot;)</font></div><div><font face=3D=
"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();<br></fon=
t></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></=
div></div><div><br></div><div>The remaining problem is that I&#39;m not sur=
e the &quot;obvious&quot; syntax (above) actually makes any sense. We want =
to be able to <font face=3D"courier new, monospace">++i</font>, but at the =
same time use <font face=3D"courier new, monospace">f&lt;i&gt;()</font>. Pe=
rhaps <font face=3D"courier new, monospace">i</font> should magically be co=
nstexpr in the body of the loop, but non-constexpr in the header of the loo=
p?</div><div>I&#39;ve emailed Jens Maurer separately to ask what the semant=
ics of <font face=3D"courier new, monospace">if constexpr</font> are suppos=
ed to be in similar cases, and will report back on the results if he doesn&=
#39;t post here first. :)</div><div><br></div><div>=E2=80=93Arthur<br></div=
></div><span class=3D"">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f11d3266-3407-4c00-a578-5d07beeb1071%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f11d3266-3407-=
4c00-a578-5d07beeb1071%40isocpp.org</a>.<br>
</blockquote></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3DhhVBJAQ3Ekeo6mkWxPasnURXOW6=
r8zNo8oOk93ptbAQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3DhhVBJ=
AQ3Ekeo6mkWxPasnURXOW6r8zNo8oOk93ptbAQ%40mail.gmail.com</a>.<br />

--001a11478cfa36dba00534de0fc3--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Thu, 9 Jun 2016 13:52:14 -0700
Raw View
--001a11355fc4d4b1040534de9816
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thu, Jun 9, 2016 at 1:13 PM, Richard Smith <richard@metafoo.co.uk> wrote=
:
> On Thu, Jun 9, 2016 at 12:06 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.co=
m
> wrote:
>>
>> FWIW, I don't think that today's option, "abuse of comma operator
>> folding", is very bad. It would be nice to have a fold-expression-esque
>> (fold-statement?) syntax for folding over semicolons; but I have no
concrete
>> idea of what that would look like.
>
> I think last time this came up the reasonable options were:
>
> expr_stmt() ... ;   // #1: problem: what does "if (blah) expr_stmt() ...;=
"
> mean?
> expr_stmt(), ... ;  // #2: make outermost parens in comma fold optional i=
n
> this context
> ( expr_stmt(), ... ) ; // #3: status quo, a little verbose

I don't care about any of the above options, because they're all isomorphic
to #3, which we have today (well, in C++17 we will).  When I say
"fold-statement" and "folding over semicolons", I mean folding that expands
to things that *aren't* expr-stmts.

    template<typename... Ts>
    void f() {
        ( if (is_same_v<int, Ts>) return; )...;
        puts("None of my parameters are int.");
    }

Admittedly that's a toy example (I could just use if (any_of(...))
instead), and I don't have any non-toy examples of my own. I think Sergey's
"variant_ptr::invoke" example is a good example of the problem, in that I'm
having a lot of trouble refactoring it into anything that works equally
well in C++17.


> The rules we originally picked for fold-expressions were deliberately ver=
y
> conservative; relaxing them is probably a good idea.

Agreed FWIW, but I think not useful for Sergey's use-case.

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0K%2B_d_h1eby%2BnFE0wmdK%2B3%2BB%3DzFOG5nL=
p1H15jRTo0Jgg%40mail.gmail.com.

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

<div dir=3D"ltr">On Thu, Jun 9, 2016 at 1:13 PM, Richard Smith &lt;<a href=
=3D"mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>&gt; wrote:<br>&=
gt; On Thu, Jun 9, 2016 at 12:06 PM, Arthur O&#39;Dwyer &lt;<a href=3D"mail=
to:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>&gt;=C2=A0wrote:=
<br>&gt;&gt;<br>&gt;&gt; FWIW, I don&#39;t think that today&#39;s option, &=
quot;abuse of comma operator<br>&gt;&gt; folding&quot;, is very bad. It wou=
ld be nice to have a fold-expression-esque<br>&gt;&gt; (fold-statement?) sy=
ntax for folding over semicolons; but I have no concrete<br>&gt;&gt; idea o=
f what that would look like.<br>&gt;<br>&gt; I think last time this came up=
 the reasonable options were:<br>&gt;<br>&gt; expr_stmt() ... ; =C2=A0 // #=
1: problem: what does &quot;if (blah) expr_stmt() ...;&quot;<br>&gt; mean?<=
br>&gt; expr_stmt(), ... ; =C2=A0// #2: make outermost parens in comma fold=
 optional in<br>&gt; this context<br>&gt; ( expr_stmt(), ... ) ; // #3: sta=
tus quo, a little verbose<br><br><div>I don&#39;t care about any of the abo=
ve options, because they&#39;re all isomorphic to #3, which we have today (=
well, in C++17 we will).=C2=A0 When I say &quot;fold-statement&quot; and &q=
uot;folding over semicolons&quot;, I mean folding that expands to things th=
at <i>aren&#39;t</i> expr-stmts.</div><div><br></div><div>=C2=A0 =C2=A0 tem=
plate&lt;typename... Ts&gt;</div><div>=C2=A0 =C2=A0 void f() {</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ( if (is_same_v&lt;int, Ts&gt;) return; )...;</=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 puts(&quot;None of my parameters are i=
nt.&quot;);</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>Admittedly t=
hat&#39;s a toy example (I could just use if (any_of(...)) instead), and I =
don&#39;t have any non-toy examples of my own. I think Sergey&#39;s &quot;v=
ariant_ptr::invoke&quot; example is a good example of the problem, in that =
I&#39;m having a lot of trouble refactoring it into anything that works equ=
ally well in C++17.</div><div><br></div><div><br></div><div>&gt; The rules =
we originally picked for fold-expressions were deliberately very<br>&gt; co=
nservative; relaxing them is probably a good idea.<br><br>Agreed FWIW, but =
I think not useful for Sergey&#39;s use-case.<br><br></div><div>=E2=80=93Ar=
thur</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0K%2B_d_h1eby%2BnFE0wmdK%2B3%2B=
B%3DzFOG5nLp1H15jRTo0Jgg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0=
K%2B_d_h1eby%2BnFE0wmdK%2B3%2BB%3DzFOG5nLp1H15jRTo0Jgg%40mail.gmail.com</a>=
..<br />

--001a11355fc4d4b1040534de9816--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Fri, 10 Jun 2016 02:19:51 -0700 (PDT)
Raw View
------=_Part_124_1590849893.1465550392013
Content-Type: multipart/alternative;
 boundary="----=_Part_125_1398368626.1465550392014"

------=_Part_125_1398368626.1465550392014
Content-Type: text/plain; charset=UTF-8

On Thursday, 9 June 2016 21:52:16 UTC+1, Arthur O'Dwyer wrote:
>
> On Thu, Jun 9, 2016 at 1:13 PM, Richard Smith <ric...@metafoo.co.uk
> <javascript:>> wrote:
> > On Thu, Jun 9, 2016 at 12:06 PM, Arthur O'Dwyer <arthur....@gmail.com
> <javascript:>> wrote:
> >>
> >> FWIW, I don't think that today's option, "abuse of comma operator
> >> folding", is very bad. It would be nice to have a fold-expression-esque
> >> (fold-statement?) syntax for folding over semicolons; but I have no
> concrete
> >> idea of what that would look like.
> >
> > I think last time this came up the reasonable options were:
> >
> > expr_stmt() ... ;   // #1: problem: what does "if (blah) expr_stmt()
> ...;"
> > mean?
> > expr_stmt(), ... ;  // #2: make outermost parens in comma fold optional
> in
> > this context
> > ( expr_stmt(), ... ) ; // #3: status quo, a little verbose
>
> I don't care about any of the above options, because they're all
> isomorphic to #3, which we have today (well, in C++17 we will).  When I say
> "fold-statement" and "folding over semicolons", I mean folding that expands
> to things that *aren't* expr-stmts.
>
>     template<typename... Ts>
>     void f() {
>         ( if (is_same_v<int, Ts>) return; )...;
>         puts("None of my parameters are int.");
>     }
>
> Admittedly that's a toy example (I could just use if (any_of(...))
> instead), and I don't have any non-toy examples of my own. I think Sergey's
> "variant_ptr::invoke" example is a good example of the problem, in that I'm
> having a lot of trouble refactoring it into anything that works equally
> well in C++17.
>

I'm not sure that it is; it more motivates a switch than a for statement.
The C++17 equivalent would look like this:

    template<typename Func, typename... A>
    auto invoke(Func&& f, A&&... a) const {
        return switch_(std::make_index_sequence<sizeof...(V)>{},
            type_idx_,
            [&] { return std::invoke(std::forward<Func>(f), static_cast<V*>(
data_), std::forward<A>(a)...); }...,
            [] { throw std::logic_error("should never happen"); }
        );
    }

Here switch_ emulates a switch statement with variadic expansion of case
labels:

template<class T, T... I, class... F, class D>
auto switch_(std::integer_sequence<T, I...>, T i, F&&... f, D&& d) {
    switch (i) {
        case... I : return std::forward<F>(f)();
    }
    return std::forward<D>(d)();
}

switch_ is tricky but not impossible to implement today; the choices are
either to use recursion (with penalty on usability and performance) or to
use the preprocessor (via Boost.Preprocessor) with a configurable upper
limit on number of case statements.


> > The rules we originally picked for fold-expressions were deliberately
> very
> > conservative; relaxing them is probably a good idea.
>
> Agreed FWIW, but I think not useful for Sergey's use-case.
>

If we had variadic expansion of case labels that would solve that
particular use case, and very elegantly.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2d8458f8-27b2-464f-a16e-fc866ccfd2cd%40isocpp.org.

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

<div dir=3D"ltr">On Thursday, 9 June 2016 21:52:16 UTC+1, Arthur O&#39;Dwye=
r  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">On T=
hu, Jun 9, 2016 at 1:13 PM, Richard Smith &lt;<a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"broyrHSfAAAJ" rel=3D"nofollow" onmous=
edown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;javascript:&#39;;return true;">ric...@metafoo.co.uk</a>&gt; wrote=
:<br>&gt; On Thu, Jun 9, 2016 at 12:06 PM, Arthur O&#39;Dwyer &lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"broyrHSfAAAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">arthur....@g=
mail.com</a>&gt;=C2=A0<wbr>wrote:<br>&gt;&gt;<br>&gt;&gt; FWIW, I don&#39;t=
 think that today&#39;s option, &quot;abuse of comma operator<br>&gt;&gt; f=
olding&quot;, is very bad. It would be nice to have a fold-expression-esque=
<br>&gt;&gt; (fold-statement?) syntax for folding over semicolons; but I ha=
ve no concrete<br>&gt;&gt; idea of what that would look like.<br>&gt;<br>&g=
t; I think last time this came up the reasonable options were:<br>&gt;<br>&=
gt; expr_stmt() ... ; =C2=A0 // #1: problem: what does &quot;if (blah) expr=
_stmt() ...;&quot;<br>&gt; mean?<br>&gt; expr_stmt(), ... ; =C2=A0// #2: ma=
ke outermost parens in comma fold optional in<br>&gt; this context<br>&gt; =
( expr_stmt(), ... ) ; // #3: status quo, a little verbose<br><br><div>I do=
n&#39;t care about any of the above options, because they&#39;re all isomor=
phic to #3, which we have today (well, in C++17 we will).=C2=A0 When I say =
&quot;fold-statement&quot; and &quot;folding over semicolons&quot;, I mean =
folding that expands to things that <i>aren&#39;t</i> expr-stmts.</div><div=
><br></div><div>=C2=A0 =C2=A0 template&lt;typename... Ts&gt;</div><div>=C2=
=A0 =C2=A0 void f() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ( if (is_same_v=
&lt;int, Ts&gt;) return; )...;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 puts(&=
quot;None of my parameters are int.&quot;);</div><div>=C2=A0 =C2=A0 }</div>=
<div><br></div><div>Admittedly that&#39;s a toy example (I could just use i=
f (any_of(...)) instead), and I don&#39;t have any non-toy examples of my o=
wn. I think Sergey&#39;s &quot;variant_ptr::invoke&quot; example is a good =
example of the problem, in that I&#39;m having a lot of trouble refactoring=
 it into anything that works equally well in C++17.</div></div></blockquote=
><div><br></div><div>I&#39;m not sure that it is; it more motivates a switc=
h than a for statement. The C++17 equivalent would look like this:</div><di=
v><br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, =
187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Func</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
typename</span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> invoke</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Func</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> A</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;&amp;...</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> switch_</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">make_index_sequence</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">...(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">V</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)&gt;{},</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 type_idx_</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">[&amp;]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">invoke</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">Func</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">V</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*&gt;(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">data_</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">for=
ward</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">A</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)...);</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}...,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">[]</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">throw</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">logic_error</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&q=
uot;should never happen&quot;</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 <br></span></div></code></div><div><br></div><div>Here switch=
_ emulates a switch statement with variadic expansion of case labels:</div>=
<div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">class</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"styled-b=
y-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> I<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> F</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: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> D</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=
><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> switch_</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">integer_sequence</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">T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> I</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>...&gt;,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
T i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;...</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> D</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> d</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">switch</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">i</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">case</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> I </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: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)();</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">forward</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">D</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">d</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)();</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div>=
<div><br></div><div>switch_ is tricky but not impossible to implement today=
; the choices are either to use recursion (with penalty on usability and pe=
rformance) or to use the preprocessor (via Boost.Preprocessor) with a confi=
gurable upper limit on number of case statements.</div><div>=C2=A0<br></div=
><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"><div>&gt; Th=
e rules we originally picked for fold-expressions were deliberately very<br=
>&gt; conservative; relaxing them is probably a good idea.<br><br>Agreed FW=
IW, but I think not useful for Sergey&#39;s use-case.<br></div></div></bloc=
kquote><br><div>If we had variadic expansion of case labels that would solv=
e that particular use case, and very elegantly.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2d8458f8-27b2-464f-a16e-fc866ccfd2cd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2d8458f8-27b2-464f-a16e-fc866ccfd2cd=
%40isocpp.org</a>.<br />

------=_Part_125_1398368626.1465550392014--

------=_Part_124_1590849893.1465550392013--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Fri, 10 Jun 2016 03:27:48 -0700 (PDT)
Raw View
------=_Part_1739_875916692.1465554468888
Content-Type: multipart/alternative;
 boundary="----=_Part_1740_294702860.1465554468889"

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

=D1=87=D0=B5=D1=82=D0=B2=D0=B5=D1=80=D0=B3, 9 =D0=B8=D1=8E=D0=BD=D1=8F 2016=
 =D0=B3., 17:53:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Edward Catmur =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=
=D0=BB:
>
> On Wednesday, 8 June 2016 19:03:33 UTC+1, Sergey Vidyuk wrote:
>>
>> =D1=81=D1=80=D0=B5=D0=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3.,=
 21:11:21 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=
=B5=D0=BB=D1=8C Greg Marr =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>>
>>> On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4, Sergey Vidyuk wrote:
>>>>
>>>> Expression folding on a variadic template parameters pack are great an=
d=20
>>>> allows to write internal function stuff inside a function instead of=
=20
>>>> writing some recursive template code which is required to be moved out=
side=20
>>>> of the function. But when one want to repeat some statement for every=
=20
>>>> element of a parameter pack recursive templates or abusing of coma ope=
rator=20
>>>> folding are stil the only options. After facing this issue several tim=
es I=20
>>>> start to realize that it would be great to have the following extensio=
n to=20
>>>> the C++11 range-for syntax:
>>>>
>>>
>>> Have you seen Sean Parent's for_each_argument?
>>>
>>> template <class F, class... Args>
>>> void for_each_argument(F f, Args&&... args) {
>>>  [](...){}((f(std::forward<Args>(args)), 0)...);
>>> }
>>>
>>>
> Well, sure it's possible to emulate variadic for using existing=20
> language/library features, but a new language feature (built-in control=
=20
> flow construct) is more readable and integrates better; most of the same=
=20
> arguments for if constexpr (p0128r1) hold here as well.
>
> I'm not sure about the motivating example, though; it seems to me that in=
=20
> that case what you really want is a switch statement:
>
> template<typename Func, typename... A>
> auto invoke(Func&& f, A&&... a) const {
>     switch constexpr (type_idx_) {
>         case... indexof(V): return std::invoke(std::forward<Func>(f),=20
> static_cast<V*>(data_), std::forward<A>(a)...);
>     }
>     throw std::logic_error("should never happen");
> }
>
> Do you have any other examples with stronger motivation e.g. where each=
=20
> iteration has a side effect, or where you conditionally break/return=20
> depending on something more complex than a switch-style predicate?
>
>
Example which also came from the real life but requires a bit more=20
knowledge about the context. I have static reflection simulation library=20
which is based on two template classes *member_info* (parametrized by=20
pointer to member) and *property_info* (parametrized by pointer to getter=
=20
member function and setter member function). Both of them have "*static=20
constexpr const char* name*" member with the name of member or property,=20
typedefs *property_type* and *class_type* and static *get* and *set*=20
functions. Reflection information is std::tuple of those classes which is=
=20
used as type and never as variable (since all of the tuple members are=20
empty classes is'r useless). Now the example:

template<typename T, typename... PropertyInfo>
void set(T& obj, const std::string& property, const Json::Value& val) {
    bool property_found =3D false;
    for constexpr (typename PI: PropertyInfo...) {
        static_assert(std::is_same_v<PI::class_type, T>);
        if (PI::name !=3D property)
            continue;
        property_found =3D true;
        PI::set(obj, parse<PI::property_type>(val));
        break;
    }
    if (!property_found)
        throw std::runtime_error("property not found");
}

In case of DOM based JsonCpp parser this code looks like toy-example. But=
=20
in the real life I'm using SAX based RapidJson parser and I have to provide=
=20
callback which accepts json key name and change parsing event handler state=
=20
to consume events related to corresponding json value properly and with=20
such kind of constexpr for I can write the handler without recursive=20
template.

This example can also be rewritten with 'case-folding' without loosing=20
readability so if such feature will be added to the language I'll be really=
=20
happy. I was thinking  on some example which is not "do something on the=20
only element of a pack which satisfy condition evaluatable at runtime" and=
=20
didn't find anything yet but I don't think that it's real show stopper for=
=20
statement-folding based on constexpr foreach loop.
=20

> Aside from that, the syntax doesn't look to me to be distinctive enough;=
=20
> just having the for-range-initializer end in an ellipsis could be confuse=
d=20
> with e.g. a fold. (Yes, folds are parenthesized, but it's easy to overloo=
k=20
> that.) Bikeshedding a bit, but I'd follow the "if constexpr" path and spe=
ll=20
> it "for constexpr". Perhaps we could end up with a full family of constex=
pr=20
> control flow statements.
>

Agree
=20
for constexpr (typename T: L...) statement;
for constexpr (auto arg: args...) statement;


syntx might play better with the "if constexpr" syntax.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/081ec465-24af-4192-9183-3a169022e581%40isocpp.or=
g.

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

<div dir=3D"ltr">=D1=87=D0=B5=D1=82=D0=B2=D0=B5=D1=80=D0=B3, 9 =D0=B8=D1=8E=
=D0=BD=D1=8F 2016 =D0=B3., 17:53:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=
=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Edward Catmur =D0=BD=D0=B0=D0=BF=D0=
=B8=D1=81=D0=B0=D0=BB:<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">On Wednesday, 8 June 2016 19:03:33 UTC+1, Sergey Vidyuk  wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=D1=81=D1=80=D0=B5=D0=
=B4=D0=B0, 8 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 21:11:21 UTC+6 =D0=BF=
=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Greg Mar=
r =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr">On Wednesday, June 8, 2016 at 10:14:50 AM UTC-4,=
 Sergey Vidyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r">Expression folding on a variadic template parameters pack are great and =
allows to write internal function stuff inside a function instead of writin=
g some recursive template code which is required to be moved outside of the=
 function. But when one want to repeat some statement for every element of =
a parameter pack recursive templates or abusing of coma operator folding ar=
e stil the only options. After facing this issue several times I start to r=
ealize that it would be great to have the following extension to the C++11 =
range-for syntax:<br></div></blockquote><div><br></div><div>Have you seen S=
ean Parent&#39;s for_each_argument?</div><div><br></div><div style=3D"borde=
r:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,=
250,250)"><code><div><span style=3D"color:#008">template</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">class</span><span style=3D"color:#660">...</span><span style=3D"=
color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"co=
lor:#660">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"c=
olor:#008">void</span><span style=3D"color:#000"> for_each_argument</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">F f</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#606">Args</span><span style=3D"color:#660">&amp;&amp;...</span=
><span style=3D"color:#000"> args</span><span style=3D"color:#660">)</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span=
 style=3D"color:#000"><br>=C2=A0</span><span style=3D"color:#660">[](...){}=
((</span><span style=3D"color:#000">f</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#606">Arg<wbr>s</span><span style=3D"color:#660"=
>&gt;(</span><span style=3D"color:#000">args</span><span style=3D"color:#66=
0">)),</span><span style=3D"color:#000"> </span><span style=3D"color:#066">=
0</span><span style=3D"color:#660">)...);</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r><br></span></div></code></div></div></blockquote></div></blockquote><div>=
<br></div><div>Well, sure it&#39;s possible to emulate variadic for using e=
xisting language/library features, but a new language feature (built-in con=
trol flow construct) is more readable and integrates better; most of the sa=
me arguments for if constexpr (p0128r1) hold here as well.</div><div><br></=
div><div>I&#39;m not sure about the motivating example, though; it seems to=
 me that in that case what you really want is a switch statement:</div><div=
><br></div>    <div style=3D"border:1px solid rgb(187,187,187);word-wrap:br=
eak-word;background-color:rgb(250,250,250)"><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><span style=
=3D"color:#606">Func</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#660">...</span><span style=3D"color:#000"> A</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> invoke</span><span =
style=3D"color:#660">(</span><span style=3D"color:#606">Func</span><span st=
yle=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> f</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> A</span><span s=
tyle=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> a</span=
><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">const</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">switch</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">constexpr</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000">typ=
e_idx_</span><span style=3D"color:#660">)</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">case</span><s=
pan style=3D"color:#660">...</span><span style=3D"color:#000"> indexof</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">V</span><sp=
an style=3D"color:#660">):</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">return</span><span style=3D"color:#000"> std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">invoke</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">forward</span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#606">Func</span><sp=
an style=3D"color:#660">&gt;<wbr>(</span><span style=3D"color:#000">f</span=
><span style=3D"color:#660">),</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">static_cast</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#000">V</span><span style=3D"color:#660">*&gt;(</=
span><span style=3D"color:#000">data_</span><span style=3D"color:#660">),</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#000">A</span><span style=3D"color:#660">&gt;(=
</span><span style=3D"color:#000">a</span><span style=3D"color:#660">)...);=
</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color:#008">throw</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">logic_error</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#080">&quot;sho=
uld never happen&quot;</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span></div></code></div><div><br></div><div>Do you ha=
ve any other examples with stronger motivation e.g. where each iteration ha=
s a side effect, or where you conditionally break/return depending on somet=
hing more complex than a switch-style predicate?</div><div><br></div></div>=
</blockquote><div><br>Example which also came from the real life but requir=
es a bit more knowledge about the context. I have static reflection simulat=
ion library which is based on two template classes <b>member_info</b> (para=
metrized by pointer to member) and <b>property_info</b> (parametrized by po=
inter to getter member function and setter member function). Both of them h=
ave &quot;<b>static constexpr const char* name</b>&quot; member with the na=
me of member or property, typedefs <b>property_type</b> and <b>class_type</=
b> and static <b>get</b> and <b>set</b> functions. Reflection information i=
s std::tuple of those classes which is used as type and never as variable (=
since all of the tuple members are empty classes is&#39;r useless). Now the=
 example:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">template</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typ=
ename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">PropertyInfo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">set</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> obj</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">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">string</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pro=
perty</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: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Json</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Value</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> val</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> property_found <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">for</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> PI</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">PropertyInfo</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">...)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">static_assert</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">is_same_v</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">PI</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">class_type</span><span style=3D"color: #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">&gt;);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">PI</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">name </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">!=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> property</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">continue</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 property_found </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">tru=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 PI</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">se=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">obj</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> parse</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">PI</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">property_type</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify">val</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">break</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">if</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">property=
_found</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">throw</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">runtime_=
error</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;property=
 not found&quot;</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
</div></code></div><br>In case of DOM based JsonCpp parser this code looks =
like toy-example. But in the real life I&#39;m using SAX based RapidJson pa=
rser and I have to provide callback which accepts json key name and change =
parsing event handler state to consume events related to corresponding json=
 value properly and with such kind of constexpr for I can write the handler=
 without recursive template.<br><br>This example can also be rewritten with=
 &#39;case-folding&#39; without loosing readability so if such feature will=
 be added to the language I&#39;ll be really happy. I was thinking=C2=A0 on=
 some example which is not &quot;do something on the only element of a pack=
 which satisfy condition evaluatable at runtime&quot; and didn&#39;t find a=
nything yet but I don&#39;t think that it&#39;s real show stopper for state=
ment-folding based on constexpr foreach loop.<br>=C2=A0</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"><div></div><div>Aside from =
that, the syntax doesn&#39;t look to me to be distinctive enough; just havi=
ng the for-range-initializer end in an ellipsis could be confused with e.g.=
 a fold. (Yes, folds are parenthesized, but it&#39;s easy to overlook that.=
) Bikeshedding a bit, but I&#39;d follow the &quot;if constexpr&quot; path =
and spell it &quot;for constexpr&quot;. Perhaps we could end up with a full=
 family of constexpr control flow statements.</div></div></blockquote><div>=
<br>Agree<br>=C2=A0<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"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">for</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const=
expr</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> statement</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">for</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> arg</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> args</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">...)</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> statement</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span></div></code><br></div><br>syntx might play better wit=
h the &quot;if constexpr&quot; syntax.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/081ec465-24af-4192-9183-3a169022e581%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/081ec465-24af-4192-9183-3a169022e581=
%40isocpp.org</a>.<br />

------=_Part_1740_294702860.1465554468889--

------=_Part_1739_875916692.1465554468888--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Fri, 10 Jun 2016 04:05:06 -0700 (PDT)
Raw View
------=_Part_18_511481629.1465556706546
Content-Type: multipart/alternative;
 boundary="----=_Part_19_312398929.1465556706547"

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



=D0=BF=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D0=B0, 10 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 1:06:10 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Arthur O'Dwyer =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=
=B0=D0=BB:
>
> On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vidyuk wrote:
>>
>> Expression folding on a variadic template parameters pack are great and=
=20
>> allows to write internal function stuff inside a function instead of=20
>> writing some recursive template code which is required to be moved outsi=
de=20
>> of the function. But when one want to repeat some statement for every=20
>> element of a parameter pack recursive templates or abusing of coma opera=
tor=20
>> folding are stil the only options.
>>
>
> FWIW, I *don't* think that today's option, "abuse of comma operator=20
> folding", is very bad. It would be *nice* to have a fold-expression-esque=
=20
> (fold-statement?) syntax for folding over semicolons; but I have no=20
> concrete idea of what that would look like.
>

Abuse of a coma operator for function call folding is bad since this=20
approach requires protection from *operator,()* overload and it's some way=
=20
to achieve what you want without direct instrument to do it. I've never=20
used operator coma before variadic templates were added to the language. I=
=20
think it's time to think on adding direct instrument to repeat statements=
=20
for each item from a parameter pack. I think that semicolon folding whill=
=20
be worse readable and convenient to most of the C++ developers then=20
extended syntax of for-loop since most of us are writing imperative code=20
with lots of loops and rarely use some folding technics (reduce on therad=
=20
pool with Qt Concurent is the only way I've used folding in my C++ code=20
apart from meta-programming with variadic templates).
=20

> =20
>
>> After facing this issue several times I start to realize that it would b=
e=20
>> great to have the following extension to the C++11 range-for syntax:
>>
>> template<typename... L> void foo() {
>>     for (typename T: L...) {
>>         // do the stuff
>>     }
>> }
>>
>> template<typename... A> void foo(A&& a) {
>>     for (const auto& arg: a...) {
>>         // do the stuff
>>     }
>> }
>>
>> In both cases the loop is unrolled in compile time and it's body is=20
>> instantiate for each exact type in the same way as a body of template=20
>> function. Each instantiation of a body has it's own scope and there are =
no=20
>> outter scope polution posibility. Standard loop operators break and=20
>> continue should also be allowed for both cases and work in the same way =
as=20
>> in any runtime C++ loop.
>>
>
> My kneejerk reaction was that for (typename T */*...*/*) is a=20
> non-starter, because you're proposing to have it mean something very=20
> different from for (int I */*...*/*).
> Plus, you'll have troublesome grammar issues if the user tries to use the=
=20
> new syntax to replace a repeated statement where the repeated statement=
=20
> contains a "break" or "continue".
>

As it was told before by Edward Catmur *for constexpr (typename T: L...)*=
=20
might be better since it might be hard to distinguish three dots from=20
expression folding for human reader in some cases.=20

There are no problems with the languate grammar as far as I can see. Loop=
=20
operators break and continue should also work in the same way as in normal=
=20
loop. Jump to the beggining of the next iteration instantiation or to the=
=20
end of the last one. It only affect semantic since those operators will=20
work on a nearest loop which is constexpr for loop. With such kind of=20
extension of for-loop syntax such semantic change will confuse noone since=
=20
adding inner loop do the same and all of the C++ developers know it and can=
=20
handle it.
=20

> However, on further reflection, I think that I might just be approaching=
=20
> the problem from the wrong angle =E2=80=94 I've been thinking of it as "a=
 way to=20
> textually replace sizeof...(P) repeats of the same statement with a singl=
e=20
> statement" (i.e. a variant of folding), whereas I think you're thinking o=
f=20
> it as "a way to control-flow over compile-time entities" (i.e. a variant =
of=20
> if-constexpr).  I actually think your syntax is reasonable with a very=20
> small tweak, and here's why:
>
> There is currently a very well-received-in-Jacksonville proposal (P0292R1=
=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html>)=
=20
> to add "if constexpr" to the language.
> If integer indexing into packs were proposed and accepted, then the=20
> obvious syntax for looping over a pack at compile-time would be
>
>     for constexpr (size_t i=3D0; i < sizeof...(Ts); ++i) {  // new syntax=
=20
> ("for constexpr")
>         using T =3D Ts...[i];  // new syntax (pack indexing)
>         f<T>();
>     }
>
> or (arguably; anyway I'm not convinced that it's a horrible idea) that=20
> could be reduced to just
>
>     for constexpr (typename T : Ts...) {  // new syntax ("for constexpr")
>         f<T>();
>     }
>
> The remaining problem is that I'm not sure the "obvious" syntax (above)=
=20
> actually makes any sense. We want to be able to ++i, but at the same time=
=20
> use f<i>(). Perhaps i should magically be constexpr in the body of the=20
> loop, but non-constexpr in the header of the loop?
> I've emailed Jens Maurer separately to ask what the semantics of if=20
> constexpr are supposed to be in similar cases, and will report back on=20
> the results if he doesn't post here first. :)
>
> =E2=80=93Arthur
>

As you mentioned for constexpr version of a classical for-loop is quite=20
complicated challenge so I propose to extend range-for loop as a first step=
=20
since there are no explicit mutation statements which should change some=20
context which is constexpr from a loop body point of view. Rage based for=
=20
combined with std::index_sequence and inde access on parameter packs can=20
give you somethig really similair to classic indexed iteration:

template<typename TupleType, size_t... I>
void print_tuple(const TupleType& tpl, std::index_sequence<I...>) {
    for constexpr(constexpr size_t idx: I...) {
        std::cout << std::get<idx>(tpl) << std::endl;
    }
}

idx here can be treated as local variable in a scope of single iteration=20
instantiation and no "constexpr mutation allowed only inside for-loop=20
statemets only" required.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b967b669-6c28-4295-b5c8-6a2f2ed7a174%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>=D0=BF=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D0=B0, 10 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 1:06:10 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Arthur O&#39;Dwyer =D0=BD=
=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<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">On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Ser=
gey Vidyuk 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">E=
xpression folding on a variadic template parameters pack are great and allo=
ws to write internal function stuff inside a function instead of writing so=
me recursive template code which is required to be moved outside of the fun=
ction. But when one want to repeat some statement for every element of a pa=
rameter pack recursive templates or abusing of coma operator folding are st=
il the only options.</div></blockquote><div><br></div><div>FWIW, I <i>don&#=
39;t</i> think that today&#39;s option, &quot;abuse of comma operator foldi=
ng&quot;, is very bad. It would be <i>nice</i> to have a fold-expression-es=
que (fold-statement?) syntax for folding over semicolons; but I have no con=
crete idea of what that would look like.</div></div></blockquote><div><br>A=
buse of a coma operator for function call folding is bad since this approac=
h requires protection from <b>operator,()</b> overload and it&#39;s some wa=
y to achieve what you want without direct instrument to do it. I&#39;ve nev=
er used operator coma before variadic templates were added to the language.=
 I think it&#39;s time to think on adding direct instrument to repeat state=
ments for each item from a parameter pack. I think that semicolon folding w=
hill be worse readable and convenient to most of the C++ developers then ex=
tended syntax of for-loop since most of us are writing imperative code with=
 lots of loops and rarely use some folding technics (reduce on therad pool =
with Qt Concurent is the only way I&#39;ve used folding in my C++ code apar=
t from meta-programming with variadic templates).<br>=C2=A0</div><blockquot=
e 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>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"> After facing this issue=
 several times I start to realize that it would be great to have the follow=
ing extension to the C++11 range-for syntax:<br><br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-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:#660">...</span><span style=3D"co=
lor:#000"> L</span><span style=3D"color:#660">&gt;</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">void</span><span style=3D"color=
:#000"> foo</span><span style=3D"color:#660">()</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660"></span><span style=3D"=
color:#000"></span><span style=3D"color:#008">for</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">typename</span><span style=3D"color:#000"> T</span><span style=3D"color:=
#660">:</span><span style=3D"color:#000"> L</span><span style=3D"color:#660=
">...)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><=
span style=3D"color:#800">// do the stuff</span><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660"></span><span style=3D"col=
or:#660">}</span><span style=3D"color:#000"><br></span><br><code><span styl=
e=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">typename</span><span style=3D"color:#660">...</span><=
span style=3D"color:#000"> A</span><span style=3D"color:#660">&gt;</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#008">void</span><spa=
n style=3D"color:#000"> foo</span><span style=3D"color:#660">(A&amp;&amp; a=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660"></span>=
<span style=3D"color:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
for</span><span style=3D"color:#000"> </span><span style=3D"color:#660">(co=
nst auto</span><span style=3D"color:#008"></span><span style=3D"color:#000"=
>&amp; arg</span><span style=3D"color:#660">:</span><span style=3D"color:#0=
00"> a</span><span style=3D"color:#660">...)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#800">// do the s=
tuff</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#000"></span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br></span></code></div></code></div><br>In both cases the loop i=
s unrolled in compile time and it&#39;s body is instantiate for each exact =
type in the same way as a body of template function. Each instantiation of =
a body has it&#39;s own scope and there are no outter scope polution posibi=
lity. Standard loop operators break and continue should also be allowed for=
 both cases and work in the same way as in any runtime C++ loop.<br></div><=
/blockquote><div><br></div><div>My kneejerk reaction was that <font face=3D=
"courier new, monospace">for (typename T <i>/*...*/</i>)</font> is a non-st=
arter, because you&#39;re proposing to have it mean something very differen=
t from <font face=3D"courier new, monospace">for (int I <i>/*...*/</i>)</fo=
nt>.</div><div>Plus, you&#39;ll have troublesome grammar issues if the user=
 tries to use the new syntax to replace a repeated statement where the repe=
ated statement contains a &quot;break&quot; or &quot;continue&quot;.</div><=
/div></blockquote><div><br>As it was told before by Edward Catmur <b>for co=
nstexpr (typename T: L...)</b> might be better since it might be hard to di=
stinguish three dots from expression folding for human reader in some cases=
.. <br><br>There are no problems with the languate grammar as far as I can s=
ee. Loop operators break and continue should also work in the same way as i=
n normal loop. Jump to the beggining of the next iteration instantiation or=
 to the end of the last one. It only affect semantic since those operators =
will work on a nearest loop which is constexpr for loop. With such kind of =
extension of for-loop syntax such semantic change will confuse noone since =
adding inner loop do the same and all of the C++ developers know it and can=
 handle it.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div>However, on further reflection, I think that I might jus=
t be approaching the problem from the wrong angle =E2=80=94 I&#39;ve been t=
hinking of it as &quot;a way to textually replace sizeof...(P) repeats of t=
he same statement with a single statement&quot; (i.e. a variant of folding)=
, whereas I think you&#39;re thinking of it as &quot;a way to control-flow =
over compile-time entities&quot; (i.e. a variant of if-constexpr). =C2=A0I =
actually think your syntax is reasonable with a very small tweak, and here&=
#39;s why:</div><div><br></div><div>There is currently a very well-received=
-in-Jacksonville proposal (<a href=3D"http://www.open-std.org/jtc1/sc22/wg2=
1/docs/papers/2016/p0292r1.html" target=3D"_blank" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.op=
en-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0292r1.html\x26sa=
\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4XHqFSyUcCgJYvo6by_7q89thEg&#39;;return=
 true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%=
2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0292r1=
..html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF4XHqFSyUcCgJYvo6by_7q89thEg&=
#39;;return true;">P0292R1</a>) to add &quot;if constexpr&quot; to the lang=
uage.</div><div>If integer indexing into packs were proposed and accepted, =
then the obvious syntax for looping over a pack at compile-time would be</d=
iv><div><br></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
for constexpr (size_t i=3D0; i &lt; sizeof...(Ts); ++i) { =C2=A0// new synt=
ax (&quot;for constexpr&quot;)</font></div><div><font face=3D"courier new, =
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0// new s=
yntax (pack indexing)</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 }</font></div><div><br></div><div>or =
(arguably; anyway I&#39;m not convinced that it&#39;s a horrible idea) that=
 could be reduced to just</div><div><br></div><div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 for constexpr (typename T : Ts...) { =C2=
=A0// new syntax (&quot;for constexpr&quot;)</font></div><div><font face=3D=
"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();<br></fon=
t></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></=
div></div><div><br></div><div>The remaining problem is that I&#39;m not sur=
e the &quot;obvious&quot; syntax (above) actually makes any sense. We want =
to be able to <font face=3D"courier new, monospace">++i</font>, but at the =
same time use <font face=3D"courier new, monospace">f&lt;i&gt;()</font>. Pe=
rhaps <font face=3D"courier new, monospace">i</font> should magically be co=
nstexpr in the body of the loop, but non-constexpr in the header of the loo=
p?</div><div>I&#39;ve emailed Jens Maurer separately to ask what the semant=
ics of <font face=3D"courier new, monospace">if constexpr</font> are suppos=
ed to be in similar cases, and will report back on the results if he doesn&=
#39;t post here first. :)</div><div><br></div><div>=E2=80=93Arthur<br></div=
></div></blockquote><div><br>As you mentioned for constexpr version of a cl=
assical for-loop is quite complicated challenge so I propose to extend rang=
e-for loop as a first step since there are no explicit mutation statements =
which should change some context which is constexpr from a loop body point =
of view. Rage based for combined with std::index_sequence and inde access o=
n parameter packs can give you somethig really similair to classic indexed =
iteration:<br><br>template&lt;typename TupleType, size_t... I&gt;<br>void p=
rint_tuple(const TupleType&amp; tpl, std::index_sequence&lt;I...&gt;) {<br>=
=C2=A0=C2=A0=C2=A0 for constexpr(constexpr size_t idx: I...) {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::cout &lt;&lt; std::get&lt;idx&gt;(tp=
l) &lt;&lt; std::endl;<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><br>idx here can be =
treated as local variable in a scope of single iteration instantiation and =
no &quot;constexpr mutation allowed only inside for-loop statemets only&quo=
t; required.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b967b669-6c28-4295-b5c8-6a2f2ed7a174%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b967b669-6c28-4295-b5c8-6a2f2ed7a174=
%40isocpp.org</a>.<br />

------=_Part_19_312398929.1465556706547--

------=_Part_18_511481629.1465556706546--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Fri, 10 Jun 2016 04:25:37 -0700 (PDT)
Raw View
------=_Part_1914_568112390.1465557937302
Content-Type: multipart/alternative;
 boundary="----=_Part_1915_1677387621.1465557937302"

------=_Part_1915_1677387621.1465557937302
Content-Type: text/plain; charset=UTF-8


>
>
>     for constexpr (size_t i=0; i < sizeof...(Ts); ++i) {  // new syntax
> ("for constexpr")
>         using T = Ts...[i];  // new syntax (pack indexing)
>         f<T>();
>     }
>
>
I can see one more issue with such kind of for-loop extension: it's
impossible to prove that the loop will terminate in generic case so some
(probably implementation defined) limit on a number of body instantiations
required. Range based for over variadic parameters pack have no such
problem since number of items in pack known by compiler before loop
instantiation.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ecf7311a-7f6e-4401-b971-5fd10f304cca%40isocpp.org.

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

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br><div=
><font face=3D"courier new, monospace">=C2=A0 =C2=A0 for constexpr (size_t =
i=3D0; i &lt; sizeof...(Ts); ++i) { =C2=A0// new syntax (&quot;for constexp=
r&quot;)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0// new syntax (pack indexing)=
</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 f&lt;T&gt;();</font></div><div><font face=3D"courier new, monosp=
ace">=C2=A0 =C2=A0 }</font></div><div>=C2=A0</div></div></blockquote><div>I=
 can see one more issue with such kind of for-loop extension: it&#39;s impo=
ssible to prove that the loop will terminate in generic case so some (proba=
bly implementation defined) limit on a number of body instantiations requir=
ed. Range based for over variadic parameters pack have no such problem sinc=
e number of items in pack known by compiler before loop instantiation.<br><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ecf7311a-7f6e-4401-b971-5fd10f304cca%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ecf7311a-7f6e-4401-b971-5fd10f304cca=
%40isocpp.org</a>.<br />

------=_Part_1915_1677387621.1465557937302--

------=_Part_1914_568112390.1465557937302--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 10 Jun 2016 12:10:03 -0700 (PDT)
Raw View
------=_Part_2506_616312967.1465585803772
Content-Type: multipart/alternative;
 boundary="----=_Part_2507_1370402162.1465585803773"

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



On Friday, June 10, 2016 at 1:05:06 PM UTC+2, Sergey Vidyuk wrote:
>
>
>
> =D0=BF=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D0=B0, 10 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 1:06:10 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Arthur O'Dwyer=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vidyuk wrote:
>>>
>>> Expression folding on a variadic template parameters pack are great and=
=20
>>> allows to write internal function stuff inside a function instead of=20
>>> writing some recursive template code which is required to be moved outs=
ide=20
>>> of the function. But when one want to repeat some statement for every=
=20
>>> element of a parameter pack recursive templates or abusing of coma oper=
ator=20
>>> folding are stil the only options.
>>>
>>
>> FWIW, I *don't* think that today's option, "abuse of comma operator=20
>> folding", is very bad. It would be *nice* to have a=20
>> fold-expression-esque (fold-statement?) syntax for folding over semicolo=
ns;=20
>> but I have no concrete idea of what that would look like.
>>
>
> Abuse of a coma operator for function call folding is bad since this=20
> approach requires protection from *operator,()* overload and it's some=20
> way to achieve what you want without direct instrument to do it. I've nev=
er=20
> used operator coma before variadic templates were added to the language. =
I=20
> think it's time to think on adding direct instrument to repeat statements=
=20
> for each item from a parameter pack. I think that semicolon folding whill=
=20
> be worse readable and convenient to most of the C++ developers then=20
> extended syntax of for-loop since most of us are writing imperative code=
=20
> with lots of loops and rarely use some folding technics (reduce on therad=
=20
> pool with Qt Concurent is the only way I've used folding in my C++ code=
=20
> apart from meta-programming with variadic templates).
> =20
>
>> =20
>>
>>> After facing this issue several times I start to realize that it would=
=20
>>> be great to have the following extension to the C++11 range-for syntax:
>>>
>>> template<typename... L> void foo() {
>>>     for (typename T: L...) {
>>>         // do the stuff
>>>     }
>>> }
>>>
>>> template<typename... A> void foo(A&& a) {
>>>     for (const auto& arg: a...) {
>>>         // do the stuff
>>>     }
>>> }
>>>
>>> In both cases the loop is unrolled in compile time and it's body is=20
>>> instantiate for each exact type in the same way as a body of template=
=20
>>> function. Each instantiation of a body has it's own scope and there are=
 no=20
>>> outter scope polution posibility. Standard loop operators break and=20
>>> continue should also be allowed for both cases and work in the same way=
 as=20
>>> in any runtime C++ loop.
>>>
>>
>> My kneejerk reaction was that for (typename T */*...*/*) is a=20
>> non-starter, because you're proposing to have it mean something very=20
>> different from for (int I */*...*/*).
>> Plus, you'll have troublesome grammar issues if the user tries to use th=
e=20
>> new syntax to replace a repeated statement where the repeated statement=
=20
>> contains a "break" or "continue".
>>
>
> As it was told before by Edward Catmur *for constexpr (typename T: L...)*=
=20
> might be better since it might be hard to distinguish three dots from=20
> expression folding for human reader in some cases.=20
>
> There are no problems with the languate grammar as far as I can see. Loop=
=20
> operators break and continue should also work in the same way as in norma=
l=20
> loop. Jump to the beggining of the next iteration instantiation or to the=
=20
> end of the last one. It only affect semantic since those operators will=
=20
> work on a nearest loop which is constexpr for loop. With such kind of=20
> extension of for-loop syntax such semantic change will confuse noone sinc=
e=20
> adding inner loop do the same and all of the C++ developers know it and c=
an=20
> handle it.
> =20
>
>> However, on further reflection, I think that I might just be approaching=
=20
>> the problem from the wrong angle =E2=80=94 I've been thinking of it as "=
a way to=20
>> textually replace sizeof...(P) repeats of the same statement with a sing=
le=20
>> statement" (i.e. a variant of folding), whereas I think you're thinking =
of=20
>> it as "a way to control-flow over compile-time entities" (i.e. a variant=
 of=20
>> if-constexpr).  I actually think your syntax is reasonable with a very=
=20
>> small tweak, and here's why:
>>
>> There is currently a very well-received-in-Jacksonville proposal (P0292R=
1=20
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html>)=
=20
>> to add "if constexpr" to the language.
>> If integer indexing into packs were proposed and accepted, then the=20
>> obvious syntax for looping over a pack at compile-time would be
>>
>>     for constexpr (size_t i=3D0; i < sizeof...(Ts); ++i) {  // new synta=
x=20
>> ("for constexpr")
>>         using T =3D Ts...[i];  // new syntax (pack indexing)
>>         f<T>();
>>     }
>>
>> or (arguably; anyway I'm not convinced that it's a horrible idea) that=
=20
>> could be reduced to just
>>
>>     for constexpr (typename T : Ts...) {  // new syntax ("for constexpr"=
)
>>         f<T>();
>>     }
>>
>> The remaining problem is that I'm not sure the "obvious" syntax (above)=
=20
>> actually makes any sense. We want to be able to ++i, but at the same=20
>> time use f<i>(). Perhaps i should magically be constexpr in the body of=
=20
>> the loop, but non-constexpr in the header of the loop?
>> I've emailed Jens Maurer separately to ask what the semantics of if=20
>> constexpr are supposed to be in similar cases, and will report back on=
=20
>> the results if he doesn't post here first. :)
>>
>> =E2=80=93Arthur
>>
>
> As you mentioned for constexpr version of a classical for-loop is quite=
=20
> complicated challenge so I propose to extend range-for loop as a first st=
ep=20
> since there are no explicit mutation statements which should change some=
=20
> context which is constexpr from a loop body point of view. Rage based for=
=20
> combined with std::index_sequence and inde access on parameter packs can=
=20
> give you somethig really similair to classic indexed iteration:
>
> template<typename TupleType, size_t... I>
> void print_tuple(const TupleType& tpl, std::index_sequence<I...>) {
>     for constexpr(constexpr size_t idx: I...) {
>         std::cout << std::get<idx>(tpl) << std::endl;
>     }
> }
>
> idx here can be treated as local variable in a scope of single iteration=
=20
> instantiation and no "constexpr mutation allowed only inside for-loop=20
> statemets only" required.
>

 I think that `for constexpr` should be allowed to extracting parameters=20
from templates, some thing like that:
using type =3D std::tuple<int, long long, char>;

int main()
{
    for constexpr (typename T : type) //without `...`
    {
        f<T>();
    } //equal: `f<int>(); f<long long>(); f<char>();`
}

This will allow usage outside of template function and simplify complex=20
operation:
template<typename T>
using MetaFunc =3D std::tuple<int, T, T, char>;


int main()
{
    for constexpr (typename T : MetaFunc<long>)
    {
        f<T>();
    } //equal: `f<int>(); f<long>(); f<long>(); f<char>();`
    for constexpr (typename T : MetaFunc<char>)
    {
        for constexpr (typename TT : MetaFunc<T>)
        {
           g<T,TT>();
        }
    }
}


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9c425e18-e592-4cfd-9e41-b37b212a6b9d%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Friday, June 10, 2016 at 1:05:06 PM UTC+2, Serg=
ey Vidyuk 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"><br><br>=D0=BF=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D0=B0, 10 =D0=B8=D1=8E=D0=
=BD=D1=8F 2016 =D0=B3., 1:06:10 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=
=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Arthur O&#39;Dwyer =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=BB:<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">On Wednesday, June 8, 2016 at 7:14:50 AM UTC-7, Sergey Vidyuk wrot=
e:<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">Expression foldi=
ng on a variadic template parameters pack are great and allows to write int=
ernal function stuff inside a function instead of writing some recursive te=
mplate code which is required to be moved outside of the function. But when=
 one want to repeat some statement for every element of a parameter pack re=
cursive templates or abusing of coma operator folding are stil the only opt=
ions.</div></blockquote><div><br></div><div>FWIW, I <i>don&#39;t</i> think =
that today&#39;s option, &quot;abuse of comma operator folding&quot;, is ve=
ry bad. It would be <i>nice</i> to have a fold-expression-esque (fold-state=
ment?) syntax for folding over semicolons; but I have no concrete idea of w=
hat that would look like.</div></div></blockquote><div><br>Abuse of a coma =
operator for function call folding is bad since this approach requires prot=
ection from <b>operator,()</b> overload and it&#39;s some way to achieve wh=
at you want without direct instrument to do it. I&#39;ve never used operato=
r coma before variadic templates were added to the language. I think it&#39=
;s time to think on adding direct instrument to repeat statements for each =
item from a parameter pack. I think that semicolon folding whill be worse r=
eadable and convenient to most of the C++ developers then extended syntax o=
f for-loop since most of us are writing imperative code with lots of loops =
and rarely use some folding technics (reduce on therad pool with Qt Concure=
nt is the only way I&#39;ve used folding in my C++ code apart from meta-pro=
gramming with variadic templates).<br>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"> After facing this issue several times I sta=
rt to realize that it would be great to have the following extension to the=
 C++11 range-for syntax:<br><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><span style=3D"color:#008">template</span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span=
><span style=3D"color:#660">...</span><span style=3D"color:#000"> L</span><=
span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#660"></span><span style=3D"color:#000"></span><=
span style=3D"color:#008">for</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#000"> T</span><span style=3D"color:#660">:</span><span =
style=3D"color:#000"> L</span><span style=3D"color:#660">...)</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
:#800">// do the stuff</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660"></span><span style=3D"color:#660">}</span><s=
pan style=3D"color:#000"><br></span><br><code><span style=3D"color:#008">te=
mplate</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#00=
8">typename</span><span style=3D"color:#660">...</span><span style=3D"color=
:#000"> A</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">void</span><span style=3D"color:#0=
00"> foo</span><span style=3D"color:#660">(A&amp;&amp; a)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#660"></span><span style=3D"colo=
r:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">(const auto</span><spa=
n style=3D"color:#008"></span><span style=3D"color:#000">&amp; arg</span><s=
pan style=3D"color:#660">:</span><span style=3D"color:#000"> a</span><span =
style=3D"color:#660">...)</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:#800">// do the stuff</span><span st=
yle=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#000"></span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><=
/code></div></code></div><br>In both cases the loop is unrolled in compile =
time and it&#39;s body is instantiate for each exact type in the same way a=
s a body of template function. Each instantiation of a body has it&#39;s ow=
n scope and there are no outter scope polution posibility. Standard loop op=
erators break and continue should also be allowed for both cases and work i=
n the same way as in any runtime C++ loop.<br></div></blockquote><div><br><=
/div><div>My kneejerk reaction was that <font face=3D"courier new, monospac=
e">for (typename T <i>/*...*/</i>)</font> is a non-starter, because you&#39=
;re proposing to have it mean something very different from <font face=3D"c=
ourier new, monospace">for (int I <i>/*...*/</i>)</font>.</div><div>Plus, y=
ou&#39;ll have troublesome grammar issues if the user tries to use the new =
syntax to replace a repeated statement where the repeated statement contain=
s a &quot;break&quot; or &quot;continue&quot;.</div></div></blockquote><div=
><br>As it was told before by Edward Catmur <b>for constexpr (typename T: L=
....)</b> might be better since it might be hard to distinguish three dots f=
rom expression folding for human reader in some cases. <br><br>There are no=
 problems with the languate grammar as far as I can see. Loop operators bre=
ak and continue should also work in the same way as in normal loop. Jump to=
 the beggining of the next iteration instantiation or to the end of the las=
t one. It only affect semantic since those operators will work on a nearest=
 loop which is constexpr for loop. With such kind of extension of for-loop =
syntax such semantic change will confuse noone since adding inner loop do t=
he same and all of the C++ developers know it and can handle it.<br>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>However,=
 on further reflection, I think that I might just be approaching the proble=
m from the wrong angle =E2=80=94 I&#39;ve been thinking of it as &quot;a wa=
y to textually replace sizeof...(P) repeats of the same statement with a si=
ngle statement&quot; (i.e. a variant of folding), whereas I think you&#39;r=
e thinking of it as &quot;a way to control-flow over compile-time entities&=
quot; (i.e. a variant of if-constexpr). =C2=A0I actually think your syntax =
is reasonable with a very small tweak, and here&#39;s why:</div><div><br></=
div><div>There is currently a very well-received-in-Jacksonville proposal (=
<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.=
html" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;ht=
tp://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2F=
wg21%2Fdocs%2Fpapers%2F2016%2Fp0292r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNF4XHqFSyUcCgJYvo6by_7q89thEg&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc=
1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0292r1.html\x26sa\x3dD\x26sntz\x3=
d1\x26usg\x3dAFQjCNF4XHqFSyUcCgJYvo6by_7q89thEg&#39;;return true;">P0292R1<=
/a>) to add &quot;if constexpr&quot; to the language.</div><div>If integer =
indexing into packs were proposed and accepted, then the obvious syntax for=
 looping over a pack at compile-time would be</div><div><br></div><div><fon=
t face=3D"courier new, monospace">=C2=A0 =C2=A0 for constexpr (size_t i=3D0=
; i &lt; sizeof...(Ts); ++i) { =C2=A0// new syntax (&quot;for constexpr&quo=
t;)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0// new syntax (pack indexing)</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 f&lt;T&gt;();</font></div><div><font face=3D"courier new, monospace"=
>=C2=A0 =C2=A0 }</font></div><div><br></div><div>or (arguably; anyway I&#39=
;m not convinced that it&#39;s a horrible idea) that could be reduced to ju=
st</div><div><br></div><div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 for constexpr (typename T : Ts...) { =C2=A0// new syntax (&quot;=
for constexpr&quot;)</font></div><div><font face=3D"courier new, monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();<br></font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div></div><div><br></di=
v><div>The remaining problem is that I&#39;m not sure the &quot;obvious&quo=
t; syntax (above) actually makes any sense. We want to be able to <font fac=
e=3D"courier new, monospace">++i</font>, but at the same time use <font fac=
e=3D"courier new, monospace">f&lt;i&gt;()</font>. Perhaps <font face=3D"cou=
rier new, monospace">i</font> should magically be constexpr in the body of =
the loop, but non-constexpr in the header of the loop?</div><div>I&#39;ve e=
mailed Jens Maurer separately to ask what the semantics of <font face=3D"co=
urier new, monospace">if constexpr</font> are supposed to be in similar cas=
es, and will report back on the results if he doesn&#39;t post here first. =
:)</div><div><br></div><div>=E2=80=93Arthur<br></div></div></blockquote><di=
v><br>As you mentioned for constexpr version of a classical for-loop is qui=
te complicated challenge so I propose to extend range-for loop as a first s=
tep since there are no explicit mutation statements which should change som=
e context which is constexpr from a loop body point of view. Rage based for=
 combined with std::index_sequence and inde access on parameter packs can g=
ive you somethig really similair to classic indexed iteration:<br><br>templ=
ate&lt;typename TupleType, size_t... I&gt;<br>void print_tuple(const TupleT=
ype&amp; tpl, std::index_sequence&lt;I...&gt;) {<br>=C2=A0=C2=A0=C2=A0 for =
constexpr(constexpr size_t idx: I...) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 std::cout &lt;&lt; std::get&lt;idx&gt;(tpl) &lt;&lt; std::endl=
;<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><br>idx here can be treated as local vari=
able in a scope of single iteration instantiation and no &quot;constexpr mu=
tation allowed only inside for-loop statemets only&quot; required.<br></div=
></div></blockquote><div><br>=C2=A0I think that `for constexpr` should be a=
llowed to extracting parameters from templates, some thing like that:<br><d=
iv class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bor=
der-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word=
-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><span style=3D"color: #008;" class=3D"styled-by-prettify">using</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> type </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</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: #008;" class=3D"styled-by-prettify">l=
ong</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">long</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">char</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><sp=
an 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=
: #008;" class=3D"styled-by-prettify">typename</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"=
styled-by-prettify"> type</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//w=
ithout `...`</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//eq=
ual: `f&lt;int&gt;(); f&lt;long long&gt;(); f&lt;char&gt;();`</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div><=
br>This will allow usage outside of template function and simplify complex =
operation:<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-prettif=
y">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">using</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">MetaFunc</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">tuple</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=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: #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"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">char</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&gt;;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">i=
nt</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> main</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></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>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D"col=
or: #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"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">MetaFunc</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;long&gt;</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//equal: `f&lt;int&gt;(); f&=
lt;long&gt;(); f&lt;long&gt;(); f&lt;char&gt;();`</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D"col=
or: #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"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">MetaFunc</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;char&gt;</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><sp=
an 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=
: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> TT </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">MetaFunc</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0g</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #00=
0;" 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">TT</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&gt;();</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </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>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span></div></code></div><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9c425e18-e592-4cfd-9e41-b37b212a6b9d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9c425e18-e592-4cfd-9e41-b37b212a6b9d=
%40isocpp.org</a>.<br />

------=_Part_2507_1370402162.1465585803773--

------=_Part_2506_616312967.1465585803772--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 10 Jun 2016 12:22:57 -0700 (PDT)
Raw View
------=_Part_2414_1545294795.1465586577430
Content-Type: multipart/alternative;
 boundary="----=_Part_2415_1368211725.1465586577431"

------=_Part_2415_1368211725.1465586577431
Content-Type: text/plain; charset=UTF-8



On Friday, June 10, 2016 at 11:19:52 AM UTC+2, Edward Catmur wrote:
>
> On Thursday, 9 June 2016 21:52:16 UTC+1, Arthur O'Dwyer wrote:
>>
>> On Thu, Jun 9, 2016 at 1:13 PM, Richard Smith <ric...@metafoo.co.uk>
>> wrote:
>> > On Thu, Jun 9, 2016 at 12:06 PM, Arthur O'Dwyer <arthur....@gmail.com
>> > wrote:
>> >>
>> >> FWIW, I don't think that today's option, "abuse of comma operator
>> >> folding", is very bad. It would be nice to have a fold-expression-esque
>> >> (fold-statement?) syntax for folding over semicolons; but I have no
>> concrete
>> >> idea of what that would look like.
>> >
>> > I think last time this came up the reasonable options were:
>> >
>> > expr_stmt() ... ;   // #1: problem: what does "if (blah) expr_stmt()
>> ...;"
>> > mean?
>> > expr_stmt(), ... ;  // #2: make outermost parens in comma fold optional
>> in
>> > this context
>> > ( expr_stmt(), ... ) ; // #3: status quo, a little verbose
>>
>> I don't care about any of the above options, because they're all
>> isomorphic to #3, which we have today (well, in C++17 we will).  When I say
>> "fold-statement" and "folding over semicolons", I mean folding that expands
>> to things that *aren't* expr-stmts.
>>
>>     template<typename... Ts>
>>     void f() {
>>         ( if (is_same_v<int, Ts>) return; )...;
>>         puts("None of my parameters are int.");
>>     }
>>
>> Admittedly that's a toy example (I could just use if (any_of(...))
>> instead), and I don't have any non-toy examples of my own. I think Sergey's
>> "variant_ptr::invoke" example is a good example of the problem, in that I'm
>> having a lot of trouble refactoring it into anything that works equally
>> well in C++17.
>>
>
> I'm not sure that it is; it more motivates a switch than a for statement.
> The C++17 equivalent would look like this:
>
>     template<typename Func, typename... A>
>     auto invoke(Func&& f, A&&... a) const {
>         return switch_(std::make_index_sequence<sizeof...(V)>{},
>             type_idx_,
>             [&] { return std::invoke(std::forward<Func>(f), static_cast<V
> *>(data_), std::forward<A>(a)...); }...,
>             [] { throw std::logic_error("should never happen"); }
>         );
>     }
>
> Here switch_ emulates a switch statement with variadic expansion of case
> labels:
>
> template<class T, T... I, class... F, class D>
> auto switch_(std::integer_sequence<T, I...>, T i, F&&... f, D&& d) {
>     switch (i) {
>         case... I : return std::forward<F>(f)();
>     }
>     return std::forward<D>(d)();
> }
>
> switch_ is tricky but not impossible to implement today; the choices are
> either to use recursion (with penalty on usability and performance) or to
> use the preprocessor (via Boost.Preprocessor) with a configurable upper
> limit on number of case statements.
>
>
>> > The rules we originally picked for fold-expressions were deliberately
>> very
>> > conservative; relaxing them is probably a good idea.
>>
>> Agreed FWIW, but I think not useful for Sergey's use-case.
>>
>
> If we had variadic expansion of case labels that would solve that
> particular use case, and very elegantly.
>
 With `for constexpr` we should have `switch` for free:

template<typename... Types>
void select(int i)
{
    switch (i)
    {
        for constexpr (typename T : Types...)
        {
            case T::id: T::func();
            break; //break for `for constexpr`
        }
        break; //break for `switch`
    default:
        f();
        break;
    }
}



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b448d4b9-c76d-4d27-8b16-0e005478320f%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Friday, June 10, 2016 at 11:19:52 AM UTC+2, Edw=
ard Catmur 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 Thursday, 9 June 2016 21:52:16 UTC+1, Arthur O&#39;Dwyer  wrote:<blo=
ckquote 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">On Thu, Jun 9, 2016 at=
 1:13 PM, Richard Smith &lt;<a rel=3D"nofollow">ric...@metafoo.co.uk</a>&gt=
; wrote:<br>&gt; On Thu, Jun 9, 2016 at 12:06 PM, Arthur O&#39;Dwyer &lt;<a=
 rel=3D"nofollow">arthur....@gmail.com</a>&gt;=C2=A0wrote:<br>&gt;&gt;<br>&=
gt;&gt; FWIW, I don&#39;t think that today&#39;s option, &quot;abuse of com=
ma operator<br>&gt;&gt; folding&quot;, is very bad. It would be nice to hav=
e a fold-expression-esque<br>&gt;&gt; (fold-statement?) syntax for folding =
over semicolons; but I have no concrete<br>&gt;&gt; idea of what that would=
 look like.<br>&gt;<br>&gt; I think last time this came up the reasonable o=
ptions were:<br>&gt;<br>&gt; expr_stmt() ... ; =C2=A0 // #1: problem: what =
does &quot;if (blah) expr_stmt() ...;&quot;<br>&gt; mean?<br>&gt; expr_stmt=
(), ... ; =C2=A0// #2: make outermost parens in comma fold optional in<br>&=
gt; this context<br>&gt; ( expr_stmt(), ... ) ; // #3: status quo, a little=
 verbose<br><br><div>I don&#39;t care about any of the above options, becau=
se they&#39;re all isomorphic to #3, which we have today (well, in C++17 we=
 will).=C2=A0 When I say &quot;fold-statement&quot; and &quot;folding over =
semicolons&quot;, I mean folding that expands to things that <i>aren&#39;t<=
/i> expr-stmts.</div><div><br></div><div>=C2=A0 =C2=A0 template&lt;typename=
.... Ts&gt;</div><div>=C2=A0 =C2=A0 void f() {</div><div>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 ( if (is_same_v&lt;int, Ts&gt;) return; )...;</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 puts(&quot;None of my parameters are int.&quot;);</div=
><div>=C2=A0 =C2=A0 }</div><div><br></div><div>Admittedly that&#39;s a toy =
example (I could just use if (any_of(...)) instead), and I don&#39;t have a=
ny non-toy examples of my own. I think Sergey&#39;s &quot;variant_ptr::invo=
ke&quot; example is a good example of the problem, in that I&#39;m having a=
 lot of trouble refactoring it into anything that works equally well in C++=
17.</div></div></blockquote><div><br></div><div>I&#39;m not sure that it is=
; it more motivates a switch than a for statement. The C++17 equivalent wou=
ld look like this:</div><div><br></div><div style=3D"border:1px solid rgb(1=
87,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><=
div><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#0=
08">template</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#606">Func</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">typename</span><span style=3D"c=
olor:#660">...</span><span style=3D"color:#000"> A</span><span style=3D"col=
or:#660">&gt;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:#008">auto</span><span style=3D"color:#000"> invoke</span=
><span style=3D"color:#660">(</span><span style=3D"color:#606">Func</span><=
span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> f</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> A</span>=
<span style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> =
a</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">const</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span s=
tyle=3D"color:#000"> switch_</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">make_index_<wbr>sequence</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#008">sizeof</span><span style=3D"color:=
#660">...(</span><span style=3D"color:#000">V</span><span style=3D"color:#6=
60">)&gt;{},</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 type_idx_</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><=
span style=3D"color:#660">[&amp;]</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">return</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">invoke</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">forward</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#606">Func</span><=
span style=3D"color:#660">&gt;<wbr>(</span><span style=3D"color:#000">f</sp=
an><span style=3D"color:#660">),</span><span style=3D"color:#000"> </span><=
span style=3D"color:#008">static_cast</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#000">V</span><span style=3D"color:#660">*&gt;(=
</span><span style=3D"color:#000">data_</span><span style=3D"color:#660">),=
</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">forward</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#000">A</span><span style=3D"color:#660">&gt=
;(</span><span style=3D"color:#000">a</span><span style=3D"color:#660">)...=
);</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}...=
,</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#660">[]</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">throw</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">logic=
_error</span><span style=3D"color:#660">(</span><span style=3D"color:#080">=
&quot;should never happen&quot;</span><span style=3D"color:#660">);</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"=
color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"> =C2=A0 <br></s=
pan></div></code></div><div><br></div><div>Here switch_ emulates a switch s=
tatement with variadic expansion of case labels:</div><div><br></div><div s=
tyle=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;background-c=
olor:rgb(250,250,250)"><code><div><span style=3D"color:#008">template</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</sp=
an><span style=3D"color:#000"> T</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> T</span><span style=3D"color:#660">...</span><sp=
an style=3D"color:#000"> I</span><span style=3D"color:#660">,</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">class</span><span st=
yle=3D"color:#660">...</span><span style=3D"color:#000"> F</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">class</span><span style=3D"color:#000"> D</span><span style=3D"=
color:#660">&gt;</span><span style=3D"color:#000"><br></span><span style=3D=
"color:#008">auto</span><span style=3D"color:#000"> switch_</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">integer_sequence</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#000"><wbr>T</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> I</span><=
span style=3D"color:#660">...&gt;,</span><span style=3D"color:#000"> T i</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> F</span>=
<span style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> =
f</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> D</s=
pan><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000">=
 d</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">switch</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">i</span><span style=3D"color:#660">)</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">case</span><s=
pan style=3D"color:#660">...</span><span style=3D"color:#000"> I </span><sp=
an style=3D"color:#660">:</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">return</span><span style=3D"color:#000"> std</span><span=
 style=3D"color:#660">::</span><span style=3D"color:#000">forward</span><sp=
an style=3D"color:#660">&lt;</span><span style=3D"color:#000">F</span><span=
 style=3D"color:#660">&gt;(</span><span style=3D"color:#000">f</span><span =
style=3D"color:#660">)();</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#000">D</span><span style=3D"color:#660">&gt;(</span><span st=
yle=3D"color:#000">d</span><span style=3D"color:#660">)();</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code=
></div><div><br></div><div>switch_ is tricky but not impossible to implemen=
t today; the choices are either to use recursion (with penalty on usability=
 and performance) or to use the preprocessor (via Boost.Preprocessor) with =
a configurable upper limit on number of case statements.</div><div>=C2=A0<b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>&gt; =
The rules we originally picked for fold-expressions were deliberately very<=
br>&gt; conservative; relaxing them is probably a good idea.<br><br>Agreed =
FWIW, but I think not useful for Sergey&#39;s use-case.<br></div></div></bl=
ockquote><br><div>If we had variadic expansion of case labels that would so=
lve that particular use case, and very elegantly.</div></div></blockquote><=
div>=C2=A0With `for constexpr` we should have `switch` for free:<br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">template</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Types</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">select</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"colo=
r: #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"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">switch</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=
">i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">for</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexp=
r</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Types</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">...)</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">case</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">id</span><span style=3D"color: #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"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">func</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">break</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: #800;" class=3D"styled-by-p=
rettify">//break for `for constexpr`</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">break</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">//break for `switch`</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">default</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">break</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></d=
iv></code></div><br><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b448d4b9-c76d-4d27-8b16-0e005478320f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b448d4b9-c76d-4d27-8b16-0e005478320f=
%40isocpp.org</a>.<br />

------=_Part_2415_1368211725.1465586577431--

------=_Part_2414_1545294795.1465586577430--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Fri, 10 Jun 2016 13:08:55 -0700
Raw View
--001a113cd564cd307c0534f21b2e
Content-Type: text/plain; charset=UTF-8

On Fri, Jun 10, 2016 at 2:19 AM, Edward Catmur <ed@catmur.co.uk> wrote:
>
> I'm not sure that it is; it more motivates a switch than a for statement.
> The C++17 equivalent would look like this:
>
>     template<typename Func, typename... A>
>     auto invoke(Func&& f, A&&... a) const {
>         return switch_(std::make_index_sequence<sizeof...(V)>{},
>             type_idx_,
>             [&] { return std::invoke(std::forward<Func>(f), static_cast<V
> *>(data_), std::forward<A>(a)...); }...,
>             [] { throw std::logic_error("should never happen"); }
>         );
>     }
>
> Here switch_ emulates a switch statement with variadic expansion of case
> labels:
>
> template<class T, T... I, class... F, class D>
> auto switch_(std::integer_sequence<T, I...>, T i, F&&... f, D&& d) {
>     switch (i) {
>         case... I : return std::forward<F>(f)();
>     }
>     return std::forward<D>(d)();
> }
>
> switch_ is tricky but not impossible to implement today; the choices are
> either to use recursion (with penalty on usability and performance) or to
> use the preprocessor (via Boost.Preprocessor) with a configurable upper
> limit on number of case statements.
>
>
>> > The rules we originally picked for fold-expressions were deliberately
>> very
>> > conservative; relaxing them is probably a good idea.
>>
>> Agreed FWIW, but I think not useful for Sergey's use-case.
>>
>
> If we had variadic expansion of case labels that would solve that
> particular use case, and very elegantly.
>

+1

There was a library that went through the boost review process called
Boost.Switch by Steven Watanabe almost 10 years ago now (prior to C++11)
that did this and it was accepted pending addressing of some comments,
though it never ended up getting added to boost. I've contacted the author
multiple times over the years because I've found it useful on many
occasions and I use an updated version in my personal projects to this day
(I mention it in P0376R0). The docs are still hosted by someone at
http://dancinghacker.com/switch/ . It clearly had and has limits even now
that we have variadic templates. Making switch or a switch-like facility
that allows cases to be formed from from a variadic expansion would be
really useful. It doesn't necessarily have to exactly be our current
language-level switch nor imply extension of variadic expansion to
statements. A library-level version that doesn't support fall-through and
always breaks would be fine for all of the use-cases I've ever encountered.
If it were a standard library facility, it could even be implemented via
some kind of compiler intrinsics that users wouldn't need to be aware of
and would allow it to work without preprocessor expansion.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3D_fhA7p%3Dz-NEFTb57obF2O54ZLMC%3D4bQxn5EgZ%2B80-1g%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jun 10, 2016 at 2:19 AM, Edward Catmur <span dir=3D"ltr">&lt;<a href=3D=
"mailto:ed@catmur.co.uk">ed@catmur.co.uk</a>&gt;</span> wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1p=
x;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1=
ex"><div dir=3D"ltr"><div>I&#39;m not sure that it is; it more motivates a =
switch than a for statement. The C++17 equivalent would look like this:</di=
v><div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:=
break-word;background-color:rgb(250,250,250)"><code><div><span class=3D"gma=
il-"><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0 </span><span style=3D"c=
olor:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;=
</span><span style=3D"color:rgb(0,0,136)">typename</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Func</span><spa=
n style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(0,0,136)">typename</span><span style=3D"col=
or:rgb(102,102,0)">...</span><span style=3D"color:rgb(0,0,0)"> A</span><spa=
n style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">auto</span><s=
pan style=3D"color:rgb(0,0,0)"> invoke</span><span style=3D"color:rgb(102,1=
02,0)">(</span><span style=3D"color:rgb(102,0,102)">Func</span><span style=
=3D"color:rgb(102,102,0)">&amp;&amp;</span><span style=3D"color:rgb(0,0,0)"=
> f</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color=
:rgb(0,0,0)"> A</span><span style=3D"color:rgb(102,102,0)">&amp;&amp;...</s=
pan><span style=3D"color:rgb(0,0,0)"> a</span><span style=3D"color:rgb(102,=
102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(102,102,0)">{</span></span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,13=
6)">return</span><span style=3D"color:rgb(0,0,0)"> switch_</span><span styl=
e=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">std</sp=
an><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0=
,0,0)">make_index_sequence</span><span style=3D"color:rgb(102,102,0)">&lt;<=
/span><span style=3D"color:rgb(0,0,136)">sizeof</span><span style=3D"color:=
rgb(102,102,0)">...(</span><span style=3D"color:rgb(0,0,0)">V</span><span s=
tyle=3D"color:rgb(102,102,0)">)&gt;{},</span><span style=3D"color:rgb(0,0,0=
)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 type_idx_</span><span styl=
e=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,=
102,0)">[&amp;]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb(0,=
0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(0,0,0)">invoke</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(10=
2,102,0)">::</span><span style=3D"color:rgb(0,0,0)">forward</span><span sty=
le=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(102,0,102)"=
>Func</span><span style=3D"color:rgb(102,102,0)">&gt;(</span><span style=3D=
"color:rgb(0,0,0)">f</span><span style=3D"color:rgb(102,102,0)">),</span><s=
pan style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">s=
tatic_cast</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span styl=
e=3D"color:rgb(0,0,0)">V</span><span style=3D"color:rgb(102,102,0)">*&gt;(<=
/span><span style=3D"color:rgb(0,0,0)">data_</span><span style=3D"color:rgb=
(102,102,0)">),</span><span style=3D"color:rgb(0,0,0)"> std</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">forwa=
rd</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"col=
or:rgb(0,0,0)">A</span><span style=3D"color:rgb(102,102,0)">&gt;(</span><sp=
an style=3D"color:rgb(0,0,0)">a</span><span style=3D"color:rgb(102,102,0)">=
)...);</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(102,102,0)">}...,</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)"=
>[]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(0,0,136)">throw</span><span style=3D"color:rgb(0,0,0)"> std</=
span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb=
(0,0,0)">logic_error</span><span style=3D"color:rgb(102,102,0)">(</span><sp=
an style=3D"color:rgb(0,136,0)">&quot;should never happen&quot;</span><span=
 style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rg=
b(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(1=
02,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,=
0,0)"> =C2=A0 <br></span></div></code></div><div><br></div><div>Here switch=
_ emulates a switch statement with variadic expansion of case labels:</div>=
<div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:br=
eak-word;background-color:rgb(250,250,250)"><code><div><span style=3D"color=
:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</sp=
an><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"color:rgb(=
0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">,</span><span style=
=3D"color:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">...</sp=
an><span style=3D"color:rgb(0,0,0)"> I</span><span style=3D"color:rgb(102,1=
02,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(0,0,136)">class</span><span style=3D"color:rgb(102,102,0)">...</span>=
<span style=3D"color:rgb(0,0,0)"> F</span><span style=3D"color:rgb(102,102,=
0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> D</span><span st=
yle=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"><b=
r></span><span style=3D"color:rgb(0,0,136)">auto</span><span style=3D"color=
:rgb(0,0,0)"> switch_</span><span style=3D"color:rgb(102,102,0)">(</span><s=
pan style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0=
)">::</span><span style=3D"color:rgb(0,0,0)">integer_sequence</span><span s=
tyle=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">T=
</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rg=
b(0,0,0)"> I</span><span style=3D"color:rgb(102,102,0)">...&gt;,</span><spa=
n style=3D"color:rgb(0,0,0)"> T i</span><span style=3D"color:rgb(102,102,0)=
">,</span><span style=3D"color:rgb(0,0,0)"> F</span><span style=3D"color:rg=
b(102,102,0)">&amp;&amp;...</span><span style=3D"color:rgb(0,0,0)"> f</span=
><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,=
0)"> D</span><span style=3D"color:rgb(102,102,0)">&amp;&amp;</span><span st=
yle=3D"color:rgb(0,0,0)"> d</span><span style=3D"color:rgb(102,102,0)">)</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,1=
02,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:rgb(0,0,136)">switch</span><span style=3D"color:rgb(0,0,=
0)"> </span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"col=
or:rgb(0,0,0)">i</span><span style=3D"color:rgb(102,102,0)">)</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span=
><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:rgb(102=
,102,0)">...</span><span style=3D"color:rgb(0,0,0)"> I </span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb(0,=
0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(0,0,0)">forward</span><span style=3D"color:rgb(102,102,0)">&l=
t;</span><span style=3D"color:rgb(0,0,0)">F</span><span style=3D"color:rgb(=
102,102,0)">&gt;(</span><span style=3D"color:rgb(0,0,0)">f</span><span styl=
e=3D"color:rgb(102,102,0)">)();</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">}</span><span sty=
le=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0=
,0,136)">return</span><span style=3D"color:rgb(0,0,0)"> std</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">forwa=
rd</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"col=
or:rgb(0,0,0)">D</span><span style=3D"color:rgb(102,102,0)">&gt;(</span><sp=
an style=3D"color:rgb(0,0,0)">d</span><span style=3D"color:rgb(102,102,0)">=
)();</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color=
:rgb(102,102,0)">}</span></div></code></div><div><br></div><div>switch_ is =
tricky but not impossible to implement today; the choices are either to use=
 recursion (with penalty on usability and performance) or to use the prepro=
cessor (via Boost.Preprocessor) with a configurable upper limit on number o=
f case statements.</div><span class=3D"gmail-"><div>=C2=A0<br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-=
left:1ex"><div dir=3D"ltr"><div>&gt; The rules we originally picked for fol=
d-expressions were deliberately very<br>&gt; conservative; relaxing them is=
 probably a good idea.<br><br>Agreed FWIW, but I think not useful for Serge=
y&#39;s use-case.<br></div></div></blockquote><br></span><div>If we had var=
iadic expansion of case labels that would solve that particular use case, a=
nd very elegantly.</div></div></blockquote><div><br></div><div>+1</div><div=
><br></div><div>There was a library that went through the boost review proc=
ess called Boost.Switch by Steven Watanabe almost 10 years ago now (prior t=
o C++11) that did this and it was accepted pending addressing of some comme=
nts, though it never ended up getting added to boost. I&#39;ve contacted th=
e author multiple times over the years because I&#39;ve found it useful on =
many occasions and I use an updated version in my personal projects to this=
 day (I mention it in P0376R0). The docs are still hosted by someone at <a =
href=3D"http://dancinghacker.com/switch/">http://dancinghacker.com/switch/<=
/a> .=C2=A0It clearly had and has limits even now that we have variadic tem=
plates. Making switch or a switch-like facility that allows cases to be for=
med from from a variadic expansion would be really useful. It doesn&#39;t n=
ecessarily have to exactly be our current language-level switch nor imply e=
xtension of variadic expansion to statements. A library-level version that =
doesn&#39;t support fall-through and always breaks would be fine for all of=
 the use-cases I&#39;ve ever encountered. If it were a standard library fac=
ility, it could even be implemented via some kind of compiler intrinsics th=
at users wouldn&#39;t need to be aware of and would allow it to work withou=
t preprocessor expansion.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3D_fhA7p%3Dz-NEFTb57obF2O54ZL=
MC%3D4bQxn5EgZ%2B80-1g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3=
D_fhA7p%3Dz-NEFTb57obF2O54ZLMC%3D4bQxn5EgZ%2B80-1g%40mail.gmail.com</a>.<br=
 />

--001a113cd564cd307c0534f21b2e--

.


Author: ryani.sony@gmail.com
Date: Fri, 10 Jun 2016 17:55:39 -0700 (PDT)
Raw View
------=_Part_40_1821528115.1465606539659
Content-Type: multipart/alternative;
 boundary="----=_Part_41_72140968.1465606539660"

------=_Part_41_72140968.1465606539660
Content-Type: text/plain; charset=UTF-8

On Friday, June 10, 2016 at 12:22:57 PM UTC-7, inkwizyt...@gmail.com wrote:
>
>  With `for constexpr` we should have `switch` for free:
>
> template<typename... Types>
> void select(int i)
> {
>     switch (i)
>     {
>         for constexpr (typename T : Types...)
>         {
>             case T::id: T::func();
>             break; //break for `for constexpr`
>         }
>         break; //break for `switch`
>     default:
>         f();
>         break;
>     }
> }
>
>
Bikeshed: I don't think "..." is required after "Types"; you don't write
"for (x : vs...)"

Usages:

template <typename... Types>
int f()
{
    int count = 0;
    for constexpr (typename T : Types)
    {
        if(is_trivially_constructible<T>::value) count++;
    }
    return count;
}

// Reaching far into the future, when constexpr is even more magic,
// we might see code like this:

template <int... xs>
constexpr int sum()
{
    int total = 0;
    for constexpr(int x : xs)
        total += x;
    return total;
}

which seems much more readable than the current way you calculate this
function (and much more like 'idiomatic' C/C++)

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d90bb3eb-e1d4-4a29-bb7e-63c097f49f96%40isocpp.org.

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

<div dir=3D"ltr">On Friday, June 10, 2016 at 12:22:57 PM UTC-7, inkwizyt...=
@gmail.com 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"><div>=C2=A0With `for constexpr` we should have `switch` for free:<br><d=
iv 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><span=
 style=3D"color:#000"><br></span><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:#660">...</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#606">Types</span><span style=3D"color:#660">&gt;</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">void</=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">select</=
span><span style=3D"color:#660">(</span><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> i</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
switch</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">i</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">for</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">(</span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> T </span><span style=3D"color:#660">:</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Types</s=
pan><span style=3D"color:#660">...)</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span=
 style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span>=
<span style=3D"color:#008">case</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">id</span><spa=
n style=3D"color:#660">:</span><span style=3D"color:#000"> T</span><span st=
yle=3D"color:#660">::</span><span style=3D"color:#000">func</span><span sty=
le=3D"color:#660">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">break</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#800">//break for `for constexpr`</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">}<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color:#008">break</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#800">//break for `swit=
ch`</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#008">default</span><span style=3D"color:#660">:</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span style=3D"col=
or:#660">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color:#008">break</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">}</span></div></code></div><br></div></div></blockquote><di=
v><br></div><div>Bikeshed: I don&#39;t think &quot;...&quot; is required af=
ter &quot;Types&quot;; you don&#39;t write &quot;for (x : vs...)&quot;</div=
><div><br></div><div>Usages:</div><div><br></div><div>template &lt;typename=
.... Types&gt;</div><div>int f()</div><div>{</div><div>=C2=A0 =C2=A0 int cou=
nt =3D 0;</div><div>=C2=A0 =C2=A0 for constexpr (typename T : Types)</div><=
div>=C2=A0 =C2=A0 {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(is_trivially_c=
onstructible&lt;T&gt;::value) count++;</div><div>=C2=A0 =C2=A0 }</div><div>=
=C2=A0 =C2=A0 return count;</div><div>}<br></div><div><br></div><div>// Rea=
ching far into the future, when constexpr is even more magic,</div><div>// =
we might see code like this:</div><div><br></div><div>template &lt;int... x=
s&gt;<br></div><div>constexpr int sum()</div><div>{</div><div>=C2=A0 =C2=A0=
 int total =3D 0;</div><div>=C2=A0 =C2=A0 for constexpr(int x : xs)</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 total +=3D x;</div><div>=C2=A0 =C2=A0 return=
 total;</div><div>}</div><div><br></div><div>which seems much more readable=
 than the current way you calculate this function (and much more like &#39;=
idiomatic&#39; C/C++)</div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d90bb3eb-e1d4-4a29-bb7e-63c097f49f96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d90bb3eb-e1d4-4a29-bb7e-63c097f49f96=
%40isocpp.org</a>.<br />

------=_Part_41_72140968.1465606539660--

------=_Part_40_1821528115.1465606539659--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Sat, 11 Jun 2016 01:45:37 -0700 (PDT)
Raw View
------=_Part_2452_546953958.1465634738093
Content-Type: multipart/alternative;
 boundary="----=_Part_2453_478302585.1465634738094"

------=_Part_2453_478302585.1465634738094
Content-Type: text/plain; charset=UTF-8



On Saturday, 11 June 2016 01:55:39 UTC+1, ryani...@gmail.com wrote:
>
> Bikeshed: I don't think "..." is required after "Types"; you don't write
> "for (x : vs...)"
>
> Usages:
>
> template <typename... Types>
> int f()
> {
>     int count = 0;
>     for constexpr (typename T : Types)
>     {
>         if(is_trivially_constructible<T>::value) count++;
>     }
>     return count;
> }
>

That can be done already today (in --std=c++1z mode) with a fold:

template<class... Ts>
constexpr int f() {
    return (0 + ... + (is_trivially_constructible<Ts>::value ? 1 : 0));
}



> // Reaching far into the future, when constexpr is even more magic,
> // we might see code like this:
>
> template <int... xs>
> constexpr int sum()
> {
>     int total = 0;
>     for constexpr(int x : xs)
>         total += x;
>     return total;
> }
>
> which seems much more readable than the current way you calculate this
> function (and much more like 'idiomatic' C/C++)
>

And that, too:

template<int... Is>
constexpr int sum() {
    return (0 + ... + Is);
}

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Saturday, 11 June 2016 01:55:39 UTC+1, ryani...=
@gmail.com  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>Bikeshed: I don&#39;t think &quot;...&quot; is required after &qu=
ot;Types&quot;; you don&#39;t write &quot;for (x : vs...)&quot;</div><div><=
br></div><div>Usages:</div><div><br></div><div>template &lt;typename... Typ=
es&gt;</div><div>int f()</div><div>{</div><div>=C2=A0 =C2=A0 int count =3D =
0;</div><div>=C2=A0 =C2=A0 for constexpr (typename T : Types)</div><div>=C2=
=A0 =C2=A0 {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(is_trivially_construc=
tible&lt;<wbr>T&gt;::value) count++;</div><div>=C2=A0 =C2=A0 }</div><div>=
=C2=A0 =C2=A0 return count;</div><div>}<br></div></div></blockquote><div><b=
r></div><div>That can be done already today (in --std=3Dc++1z mode) with a =
fold:</div><div><div><br></div><div></div></div><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
template</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Ts</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><sp=
an 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=
: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span><span =
style=3D"color: #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">is_trivially_constructible</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Ts</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">value </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">?</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">1</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">));</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><div><br>=C2=A0</div><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"><div>// Reaching fa=
r into the future, when constexpr is even more magic,</div><div>// we might=
 see code like this:</div><div><br></div><div>template &lt;int... xs&gt;<br=
></div><div>constexpr int sum()</div><div>{</div><div>=C2=A0 =C2=A0 int tot=
al =3D 0;</div><div>=C2=A0 =C2=A0 for constexpr(int x : xs)</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 total +=3D x;</div><div>=C2=A0 =C2=A0 return total=
;</div><div>}</div><div><br></div><div>which seems much more readable than =
the current way you calculate this function (and much more like &#39;idioma=
tic&#39; C/C++)</div></div></blockquote><div><br></div><div>And that, too:<=
/div><div><br></div><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Is</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nstexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> sum</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">0</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Is</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
></div></code></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c=
%40isocpp.org</a>.<br />

------=_Part_2453_478302585.1465634738094--

------=_Part_2452_546953958.1465634738093--

.


Author: inkwizytoryankes@gmail.com
Date: Sat, 11 Jun 2016 02:29:23 -0700 (PDT)
Raw View
------=_Part_1890_1758973977.1465637363319
Content-Type: multipart/alternative;
 boundary="----=_Part_1891_1869767021.1465637363320"

------=_Part_1891_1869767021.1465637363320
Content-Type: text/plain; charset=UTF-8



On Saturday, June 11, 2016 at 2:55:39 AM UTC+2, ryani...@gmail.com wrote:
>
> On Friday, June 10, 2016 at 12:22:57 PM UTC-7, inkwizyt...@gmail.com
> wrote:
>>
>>  With `for constexpr` we should have `switch` for free:
>>
>> template<typename... Types>
>> void select(int i)
>> {
>>     switch (i)
>>     {
>>         for constexpr (typename T : Types...)
>>         {
>>             case T::id: T::func();
>>             break; //break for `for constexpr`
>>         }
>>         break; //break for `switch`
>>     default:
>>         f();
>>         break;
>>     }
>> }
>>
>>
> Bikeshed: I don't think "..." is required after "Types"; you don't write
> "for (x : vs...)"
>
> Usages:
>
> template <typename... Types>
> int f()
> {
>     int count = 0;
>     for constexpr (typename T : Types)
>     {
>         if(is_trivially_constructible<T>::value) count++;
>     }
>     return count;
> }
>
> // Reaching far into the future, when constexpr is even more magic,
> // we might see code like this:
>
> template <int... xs>
> constexpr int sum()
> {
>     int total = 0;
>     for constexpr(int x : xs)
>         total += x;
>     return total;
> }
>
> which seems much more readable than the current way you calculate this
> function (and much more like 'idiomatic' C/C++)
>
>  I think that `...` would be useful, I have suggestion to allow iterate
through parameters of template:
void f() //normal function, not need to be template or be in template class
{
    for constexpr (typename T : std::tuple<int, long, int>)
    {
        g<T>();
    } //equal: `g<int>(); g<long>(); g<int>();`
}
With `...` we could easy distinguish both cases and reduce possible changes
in behavior wen switch from single template to variadic template.
And probably biggest gran of this would be reduce of boilerplate required
to use `for constexpr`.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1c9a3ce3-0321-4602-9773-b018c432cb14%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Saturday, June 11, 2016 at 2:55:39 AM UTC+2, ry=
ani...@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 di=
r=3D"ltr">On Friday, June 10, 2016 at 12:22:57 PM UTC-7, <a>inkwizyt...@gma=
il.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"><=
div>=C2=A0With `for constexpr` we should have `switch` for free:<br><div st=
yle=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bord=
er-style:solid;border-width:1px;word-wrap:break-word"><code><div><span styl=
e=3D"color:#000"><br></span><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:#660">...</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Types</span><span style=3D"color:#660">&gt;</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#008">void</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">select</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#008">int</span><sp=
an style=3D"color:#000"> i</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">switc=
h</span><span style=3D"color:#000"> </span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">i</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span=
><span style=3D"color:#008">for</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">(</span><span style=3D"color:#008">typename</sp=
an><span style=3D"color:#000"> T </span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#606">Types</span><=
span style=3D"color:#660">...)</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span =
style=3D"color:#008">case</span><span style=3D"color:#000"> T</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#000">id</span><span styl=
e=3D"color:#660">:</span><span style=3D"color:#000"> T</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">func</span><span style=3D"=
color:#660">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">break</span><span st=
yle=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">//break for `for constexpr`</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color:#008">break</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#800">//break for `switch`</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">default</span><span style=3D"color:#660">:</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span style=3D"color:#660=
">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color:#008">break</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#660">}</span><span style=3D"color:#000"><br></span><span style=3D"color:#6=
60">}</span></div></code></div><br></div></div></blockquote><div><br></div>=
<div>Bikeshed: I don&#39;t think &quot;...&quot; is required after &quot;Ty=
pes&quot;; you don&#39;t write &quot;for (x : vs...)&quot;</div><div><br></=
div><div>Usages:</div><div><br></div><div>template &lt;typename... Types&gt=
;</div><div>int f()</div><div>{</div><div>=C2=A0 =C2=A0 int count =3D 0;</d=
iv><div>=C2=A0 =C2=A0 for constexpr (typename T : Types)</div><div>=C2=A0 =
=C2=A0 {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(is_trivially_constructibl=
e&lt;<wbr>T&gt;::value) count++;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0=
 =C2=A0 return count;</div><div>}<br></div><div><br></div><div>// Reaching =
far into the future, when constexpr is even more magic,</div><div>// we mig=
ht see code like this:</div><div><br></div><div>template &lt;int... xs&gt;<=
br></div><div>constexpr int sum()</div><div>{</div><div>=C2=A0 =C2=A0 int t=
otal =3D 0;</div><div>=C2=A0 =C2=A0 for constexpr(int x : xs)</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 total +=3D x;</div><div>=C2=A0 =C2=A0 return total=
;</div><div>}</div><div><br></div><div>which seems much more readable than =
the current way you calculate this function (and much more like &#39;idioma=
tic&#39; C/C++)</div><div><br></div></div></blockquote><div>=C2=A0I think t=
hat `...` would be useful, I have suggestion to allow iterate through param=
eters of template:<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"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">//normal function, no=
t need to be template or be in template class</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>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">for</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">constexpr</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: #008;" class=3D"styled-by-prettify">typenam=
e</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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> 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: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
long</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&gt;)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;();</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">//equal: `g&lt;int&gt;(); g&lt;long&gt;()=
; g&lt;int&gt;();`</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span></div></code></div>With `...` we could easy distinguish both case=
s and reduce possible changes in behavior wen switch from single template t=
o variadic template.<br>And probably biggest gran of this would be reduce o=
f boilerplate required to use `for constexpr`.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1c9a3ce3-0321-4602-9773-b018c432cb14%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1c9a3ce3-0321-4602-9773-b018c432cb14=
%40isocpp.org</a>.<br />

------=_Part_1891_1869767021.1465637363320--

------=_Part_1890_1758973977.1465637363319--

.


Author: Ryan Ingram <ryani.sony@gmail.com>
Date: Sat, 11 Jun 2016 02:33:34 -0700
Raw View
--001a113d140c6327df0534fd59ff
Content-Type: text/plain; charset=UTF-8

> This can be done already today with a fold

I used intentionally toy examples, everyone knows you demo for loops with
something simple like "sum" before you move on to real examples.

I really like this proposal; consider this slight modification:

int total = 0;
for constexpr(int x : xs)
{
    if(x == 0) break;
    if(x & 1) total += x;
}
return total;

It's a lot harder to implement with a c++1z fold.  You can almost certainly
do it with a custom type and operator overloading, or perhaps by abusing
the comma and ternary operators, but it's a lot uglier and I bet obscures
the meaning.

bool broken = false;
int total = 0;
((broken = broken || (xs == 0), total += ((xs & 1) != 0 && !broken) ? xs :
0), ... );
return total;

I love folds.  I write Haskell all the time.  In C and C++ the idiomatic
way to express folds is with a looping construct and a local state
variable.  Why try to fight that?  "for" has a ton of hidden power and is
understood by everyone who writes C++ code.  Avoiding it is like saying the
only way to loop in Haskell is via foldr -- sure, you can implement
everything you want with just foldr, but lots of operations are clearer
using different and/or more powerful tools.


On Sat, Jun 11, 2016 at 1:45 AM, Edward Catmur <ed@catmur.co.uk> wrote:

>
>
> On Saturday, 11 June 2016 01:55:39 UTC+1, ryani...@gmail.com wrote:
>>
>> Bikeshed: I don't think "..." is required after "Types"; you don't write
>> "for (x : vs...)"
>>
>> Usages:
>>
>> template <typename... Types>
>> int f()
>> {
>>     int count = 0;
>>     for constexpr (typename T : Types)
>>     {
>>         if(is_trivially_constructible<T>::value) count++;
>>     }
>>     return count;
>> }
>>
>
> That can be done already today (in --std=c++1z mode) with a fold:
>
> template<class... Ts>
> constexpr int f() {
>     return (0 + ... + (is_trivially_constructible<Ts>::value ? 1 : 0));
> }
>
>
>
>> // Reaching far into the future, when constexpr is even more magic,
>> // we might see code like this:
>>
>> template <int... xs>
>> constexpr int sum()
>> {
>>     int total = 0;
>>     for constexpr(int x : xs)
>>         total += x;
>>     return total;
>> }
>>
>> which seems much more readable than the current way you calculate this
>> function (and much more like 'idiomatic' C/C++)
>>
>
> And that, too:
>
> template<int... Is>
> constexpr int sum() {
>     return (0 + ... + Is);
> }
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/2hdpLnXJKkQ/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALbYwOymuWcO0WO6aSGCd1iv-dTUxPXP1BMYDdv5Pfcafw_xcQ%40mail.gmail.com.

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

<div dir=3D"ltr">&gt; This can be done already today with a fold<div><br></=
div><div>I used intentionally toy examples, everyone knows you demo for loo=
ps with something simple like &quot;sum&quot; before you move on to real ex=
amples.<br></div><div><br></div><div>I really like this proposal; consider =
this slight modification:</div><div><br></div><div>int total =3D 0;</div><d=
iv>for constexpr(int x : xs)</div><div>{</div><div>=C2=A0 =C2=A0 if(x =3D=
=3D 0) break;</div><div>=C2=A0 =C2=A0 if(x &amp; 1) total +=3D x;</div><div=
>}<br></div><div>return total;</div><div><br></div><div>It&#39;s a lot hard=
er to implement with a c++1z fold.=C2=A0 You can almost certainly do it wit=
h a custom type and operator overloading, or perhaps by abusing the comma a=
nd ternary operators, but it&#39;s a lot uglier and I bet obscures the mean=
ing.</div><div><br></div><div>bool broken =3D false;</div><div>int total =
=3D 0;</div><div>((broken =3D broken || (xs =3D=3D 0), total +=3D ((xs &amp=
; 1) !=3D 0 &amp;&amp; !broken) ? xs : 0), ... );<br></div><div>return tota=
l;</div><div><br></div><div>I love folds.=C2=A0 I write Haskell all the tim=
e.=C2=A0 In C and C++ the idiomatic way to express folds is with a looping =
construct and a local state variable.=C2=A0 Why try to fight that? =C2=A0&q=
uot;for&quot; has a ton of hidden power and is understood by everyone who w=
rites C++ code.=C2=A0 Avoiding it is like saying the only way to loop in Ha=
skell is via foldr -- sure, you can implement everything you want with just=
 foldr, but lots of operations are clearer using different and/or more powe=
rful tools.<br></div><div><br></div></div><div class=3D"gmail_extra"><br><d=
iv class=3D"gmail_quote">On Sat, Jun 11, 2016 at 1:45 AM, Edward Catmur <sp=
an dir=3D"ltr">&lt;<a href=3D"mailto:ed@catmur.co.uk" target=3D"_blank">ed@=
catmur.co.uk</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><span class=3D""><br><br>On Saturday, 11 June 2016 01:55:39 UTC+=
1, <a href=3D"mailto:ryani...@gmail.com" target=3D"_blank">ryani...@gmail.c=
om</a>  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"><div=
>Bikeshed: I don&#39;t think &quot;...&quot; is required after &quot;Types&=
quot;; you don&#39;t write &quot;for (x : vs...)&quot;</div><div><br></div>=
<div>Usages:</div><div><br></div><div>template &lt;typename... Types&gt;</d=
iv><div>int f()</div><div>{</div><div>=C2=A0 =C2=A0 int count =3D 0;</div><=
div>=C2=A0 =C2=A0 for constexpr (typename T : Types)</div><div>=C2=A0 =C2=
=A0 {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(is_trivially_constructible&l=
t;T&gt;::value) count++;</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 =
return count;</div><div>}<br></div></div></blockquote><div><br></div></span=
><div>That can be done already today (in --std=3Dc++1z mode) with a fold:</=
div><div><div><br></div><div></div></div><div style=3D"background-color:rgb=
(250,250,250);border:1px solid rgb(187,187,187);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">class</span><span style=3D"color:#660=
">...</span><span style=3D"color:#000"> </span><span style=3D"color:#606">T=
s</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r></span><span style=3D"color:#008">constexpr</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">int</span><span style=3D"color:#000"=
> f</span><span style=3D"color:#660">()</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#=
066">0</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
+</span><span style=3D"color:#000"> </span><span style=3D"color:#660">...</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">+</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">is_trivially_constructible</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#606">Ts</span><span style=3D"color:=
#660">&gt;::</span><span style=3D"color:#000">value </span><span style=3D"c=
olor:#660">?</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">1</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>:</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</s=
pan><span style=3D"color:#660">));</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></spa=
n></div></code></div><span class=3D""><div><br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>// Reaching far into the futu=
re, when constexpr is even more magic,</div><div>// we might see code like =
this:</div><div><br></div><div>template &lt;int... xs&gt;<br></div><div>con=
stexpr int sum()</div><div>{</div><div>=C2=A0 =C2=A0 int total =3D 0;</div>=
<div>=C2=A0 =C2=A0 for constexpr(int x : xs)</div><div>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 total +=3D x;</div><div>=C2=A0 =C2=A0 return total;</div><div>}</di=
v><div><br></div><div>which seems much more readable than the current way y=
ou calculate this function (and much more like &#39;idiomatic&#39; C/C++)</=
div></div></blockquote><div><br></div></span><div>And that, too:</div><div>=
<br></div><div style=3D"background-color:rgb(250,250,250);border:1px solid =
rgb(187,187,187);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">int</span><span style=3D"color:#660">...</span><span style=3D"color:=
#000"> </span><span style=3D"color:#606">Is</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#00=
8">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">int</span><span style=3D"color:#000"> sum</span><span style=3D"color:=
#660">()</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#066">0</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">+</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">...</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">+</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Is</span><span style=3D"color:#660">);</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span=
></div></code></div><div><br></div></div><span class=3D"">

<p></p>

-- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/2hdpLnXJKkQ/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/2hdpLnXJKkQ=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-4a0b-903f-8b9230d4869c%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bf02cde4-5da6-=
4a0b-903f-8b9230d4869c%40isocpp.org</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALbYwOymuWcO0WO6aSGCd1iv-dTUxPXP1BMY=
Ddv5Pfcafw_xcQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALbYwOymuWcO0WO6=
aSGCd1iv-dTUxPXP1BMYDdv5Pfcafw_xcQ%40mail.gmail.com</a>.<br />

--001a113d140c6327df0534fd59ff--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sat, 11 Jun 2016 11:54:42 +0100
Raw View
--001a11479a86934ccc0534fe7b71
Content-Type: text/plain; charset=UTF-8

On 11 Jun 2016 10:33 a.m., "Ryan Ingram" <ryani.sony@gmail.com> wrote:
>
> > This can be done already today with a fold
>
> I used intentionally toy examples, everyone knows you demo for loops with
something simple like "sum" before you move on to real examples.
>
> I really like this proposal; consider this slight modification:
>
> int total = 0;
> for constexpr(int x : xs)
> {
>     if(x == 0) break;
>     if(x & 1) total += x;
> }
> return total;
>
> It's a lot harder to implement with a c++1z fold.  You can almost
certainly do it with a custom type and operator overloading, or perhaps by
abusing the comma and ternary operators, but it's a lot uglier and I bet
obscures the meaning.

Agreed, folds only work well for simple cases. But you don't need for
constexpr to write your algorithm; you can use normal iteration over an
initializer list:

int total = 0;
for (int x : {xs...})
{
    if(x == 0) break;
    if(x & 1) total += x;
}
return total;

(And the ranges guys might have their own opinions on how better to write
this.)

I'm in favor of this proposal! But I need to see motivating examples that
are actually difficult to write today; it would wreck the proposal to be
presented along with examples that can easily be dismissed as already easy
to code.

To my mind, that means that examples need to actually exploit the
distinctive feature of for constexpr, which is that types (and templates
and constants) can be different from one iteration of the loop to the next,
while (preferably) also taking advantage of the fine-grained flow control
we get from the loop control statements. Otherwise, you could just use
boost::mpl::for_each, or (ugh) a comma fold.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdOZ5L0P6qdoer6jntOjtYwCTpV_VEGJv6bZUmGk6zmoQ2g%40mail.gmail.com.

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

<p dir=3D"ltr"><br>
On 11 Jun 2016 10:33 a.m., &quot;Ryan Ingram&quot; &lt;<a href=3D"mailto:ry=
ani.sony@gmail.com">ryani.sony@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; &gt; This can be done already today with a fold<br>
&gt;<br>
&gt; I used intentionally toy examples, everyone knows you demo for loops w=
ith something simple like &quot;sum&quot; before you move on to real exampl=
es.<br>
&gt;<br>
&gt; I really like this proposal; consider this slight modification:<br>
&gt;<br>
&gt; int total =3D 0;<br>
&gt; for constexpr(int x : xs)<br>
&gt; {<br>
&gt; =C2=A0 =C2=A0 if(x =3D=3D 0) break;<br>
&gt; =C2=A0 =C2=A0 if(x &amp; 1) total +=3D x;<br>
&gt; }<br>
&gt; return total;<br>
&gt;<br>
&gt; It&#39;s a lot harder to implement with a c++1z fold.=C2=A0 You can al=
most certainly do it with a custom type and operator overloading, or perhap=
s by abusing the comma and ternary operators, but it&#39;s a lot uglier and=
 I bet obscures the meaning.</p>
<p dir=3D"ltr">Agreed, folds only work well for simple cases. But you don&#=
39;t need for constexpr to write your algorithm; you can use normal iterati=
on over an initializer list:</p>
<p dir=3D"ltr">int total =3D 0;<br>
for (int x : {xs...})<br>
{<br>
=C2=A0 =C2=A0 if(x =3D=3D 0) break;<br>
=C2=A0 =C2=A0 if(x &amp; 1) total +=3D x;<br>
}<br>
return total;</p>
<p dir=3D"ltr">(And the ranges guys might have their own opinions on how be=
tter to write this.) </p>
<p dir=3D"ltr">I&#39;m in favor of this proposal! But I need to see motivat=
ing examples that are actually difficult to write today; it would wreck the=
 proposal to be presented along with examples that can easily be dismissed =
as already easy to code. </p>
<p dir=3D"ltr">To my mind, that means that examples need to actually exploi=
t the distinctive feature of for constexpr, which is that types (and templa=
tes and constants) can be different from one iteration of the loop to the n=
ext, while (preferably) also taking advantage of the fine-grained flow cont=
rol we get from the loop control statements. Otherwise, you could just use =
boost::mpl::for_each, or (ugh) a comma fold. <br>
</p>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnLdOZ5L0P6qdoer6jntOjtYwCTpV_VEGJv=
6bZUmGk6zmoQ2g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdOZ5L0P6qdoe=
r6jntOjtYwCTpV_VEGJv6bZUmGk6zmoQ2g%40mail.gmail.com</a>.<br />

--001a11479a86934ccc0534fe7b71--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sat, 11 Jun 2016 13:46:13 -0700
Raw View
--94eb2c059d500396a4053506bf55
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Fri, Jun 10, 2016 at 4:25 AM, Sergey Vidyuk <sir.vestnik@gmail.com>
wrote:

>
>>     for constexpr (size_t i=3D0; i < sizeof...(Ts); ++i) {  // new synta=
x
>> ("for constexpr")
>>         using T =3D Ts...[i];  // new syntax (pack indexing)
>>         f<T>();
>>     }
>>
>>
> I can see one more issue with such kind of for-loop extension: it's
> impossible to prove that the loop will terminate in generic case so some
> (probably implementation defined) limit on a number of body instantiation=
s
> required. Range based for over variadic parameters pack have no such
> problem since number of items in pack known by compiler before loop
> instantiation.
>

The non-range variant of "for constexpr" does seem more problematic than
the range variant, but I don't think termination is a problem here. "Can't
prove termination" is not a new problem (for computer science or for C++ in
particular), and the existing solutions/workarounds apply. The compiler
already has to do something reasonable with e.g.

constexpr int f() { int i =3D 42; while (true) ++i; return i; }
int main() {
    static int x[f()];
}

Clang on my machine does this:

*x.cc:1:15: **error: **constexpr function never produces a constant
expression [-Winvalid-constexpr]*

constexpr int f() { int i =3D 42; while (true) ++i; return i; }

*              ^*

*x.cc:1:46: note: *constexpr evaluation hit maximum step limit; possible
infinite loop?

constexpr int f() { int i =3D 42; while (true) ++i; return i; }

*                                             ^*
The (minor) advantage of the general-purpose for-loop syntax as opposed to
the ranged-over-pack syntax is that for any given loop-of-N-iterations, the
latter requires the compiler to construct an actual entity, a
pack-of-N-elements; whereas the former doesn't. They both take O(N) time,
but only the latter takes O(N) space as well.
In practice, determining N for an arbitrary input program is equivalent to
the Halting Problem, so compilers must implement resource limiting logic
similar to the Clang error message above. The practical limits on N for
"time" can be pretty high; whereas the practical limits on N for "space"
will in practice tend to be lower.

Clang seems to put a limit of 512 recursions within a constexpr function,
but allows upwards of 1000 iterations of loop control flow within a single
constexpr function. This matches with my intuition: Recursion requires
space, and is therefore capped tightly. Iteration requires only time, and
therefore is capped more loosely.  Therefore, any time the user-programmer
can make the tradeoff (more time <-> less space) in a constexpr context, he
should do so =E2=80=94 and ideally the language should provide the tools fo=
r doing
so (examples: C++14's unrestricting constexpr functions, C++17's
fold-expressions).

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0KfyAvXiw%3D453SXvXKKV%3DehMT7Nw2M0oa5JQAa=
9PcyXmA%40mail.gmail.com.

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

<div dir=3D"ltr">On Fri, Jun 10, 2016 at 4:25 AM, Sergey Vidyuk <span dir=
=3D"ltr">&lt;<a href=3D"mailto:sir.vestnik@gmail.com" target=3D"_blank">sir=
..vestnik@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bo=
rder-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex"><div><br><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 for constexpr (size_t i=3D0; i &lt; sizeof...(Ts); ++i) { =C2=A0// n=
ew syntax (&quot;for constexpr&quot;)</font></div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 using T =3D Ts...[i]; =C2=A0/=
/ new syntax (pack indexing)</font></div><div><font face=3D"courier new, mo=
nospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 f&lt;T&gt;();</font></div><div><font f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div><div>=C2=A0</div=
></div></blockquote></span><div>I can see one more issue with such kind of =
for-loop extension: it&#39;s impossible to prove that the loop will termina=
te in generic case so some (probably implementation defined) limit on a num=
ber of body instantiations required. Range based for over variadic paramete=
rs pack have no such problem since number of items in pack known by compile=
r before loop instantiation.</div></div></blockquote><div><br></div><div>Th=
e non-range variant of &quot;for constexpr&quot; does seem more problematic=
 than the range variant, but I don&#39;t think termination is a problem her=
e. &quot;Can&#39;t prove termination&quot; is not a new problem (for comput=
er science or for C++ in particular), and the existing solutions/workaround=
s apply. The compiler already has to do something reasonable with e.g.</div=
><div><br></div><div><font face=3D"monospace, monospace">constexpr int f() =
{ int i =3D 42; while (true) ++i; return i; }</font></div><div><font face=
=3D"monospace, monospace">int main() {</font></div><div><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 static int x[f()];</font></div><div><font fa=
ce=3D"monospace, monospace">}</font></div></div><br></div><div class=3D"gma=
il_extra">Clang on my machine does this:</div><div class=3D"gmail_extra"><b=
r></div><div class=3D"gmail_extra"><p style=3D"margin:0px;font-size:11px;li=
ne-height:normal;font-family:Menlo"><span style=3D""><b>x.cc:1:15: </b></sp=
an><span style=3D"color:rgb(195,55,32)"><b>error: </b></span><span style=3D=
""><b>constexpr function never produces a constant expression [-Winvalid-co=
nstexpr]</b></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Menlo"=
><span style=3D"">constexpr int f() { int i =3D 42; while (true) ++i; retur=
n i; }</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Menlo;=
color:rgb(52,189,38)"><span style=3D""><b>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 ^</b></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Menlo"=
><span style=3D""><b>x.cc:1:46: note: </b>constexpr evaluation hit maximum =
step limit; possible infinite loop?</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Menlo"=
><span style=3D"">constexpr int f() { int i =3D 42; while (true) ++i; retur=
n i; }</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Menlo;=
color:rgb(52,189,38)"><span style=3D""><b>=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ^</b></span></p>The (m=
inor) advantage of the general-purpose for-loop syntax as opposed to the ra=
nged-over-pack syntax is that for any given loop-of-N-iterations, the latte=
r requires the compiler to construct an actual entity, a pack-of-N-elements=
; whereas the former doesn&#39;t. They both take O(N) time, but only the la=
tter takes O(N) space as well.</div><div class=3D"gmail_extra">In practice,=
 determining N for an arbitrary input program is equivalent to the Halting =
Problem, so compilers must implement resource limiting logic similar to the=
 Clang error message above. The practical limits on N for &quot;time&quot; =
can be pretty high; whereas the practical limits on N for &quot;space&quot;=
 will in practice tend to be lower.</div><div class=3D"gmail_extra"><br></d=
iv><div class=3D"gmail_extra">Clang seems to put a limit of 512 recursions =
within a constexpr function, but allows upwards of 1000 iterations of loop =
control flow within a single constexpr function. This matches with my intui=
tion: Recursion requires space, and is therefore capped tightly. Iteration =
requires only time, and therefore is capped more loosely.=C2=A0 Therefore, =
any time the user-programmer can make the tradeoff (more time &lt;-&gt; les=
s space) in a constexpr context, he should do so =E2=80=94 and ideally the =
language should provide the tools for doing so (examples: C++14&#39;s unres=
tricting constexpr functions, C++17&#39;s fold-expressions).</div><div clas=
s=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=E2=80=93Arthur<br><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0KfyAvXiw%3D453SXvXKKV%3DehMT7N=
w2M0oa5JQAa9PcyXmA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0KfyAvX=
iw%3D453SXvXKKV%3DehMT7Nw2M0oa5JQAa9PcyXmA%40mail.gmail.com</a>.<br />

--94eb2c059d500396a4053506bf55--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 12 Jun 2016 03:23:17 -0700 (PDT)
Raw View
------=_Part_3599_734410003.1465726998079
Content-Type: multipart/alternative;
 boundary="----=_Part_3600_485256537.1465726998080"

------=_Part_3600_485256537.1465726998080
Content-Type: text/plain; charset=UTF-8



On Saturday, June 11, 2016 at 1:01:58 PM UTC+2, Edward Catmur wrote:
>
>
> I'm in favor of this proposal! But I need to see motivating examples that
> are actually difficult to write today; it would wreck the proposal to be
> presented along with examples that can easily be dismissed as already easy
> to code.
>
> To my mind, that means that examples need to actually exploit the
> distinctive feature of for constexpr, which is that types (and templates
> and constants) can be different from one iteration of the loop to the next,
> while (preferably) also taking advantage of the fine-grained flow control
> we get from the loop control statements. Otherwise, you could just use
> boost::mpl::for_each, or (ugh) a comma fold.
>

For me biggest grain would be interaction with `return`, `case` and `goto`:
template<typename... Op>
int CodeInterpretator(Uint8* code)
{
    int ret = 0;
    OpCodeState state;
    beginLoop: while (true)
    {
        switch (*code++)
        {
            for constexpr (typename T : Op...)
            {
            case T::OpCodeId:
                ret = T::OpCodeFunc(&state);
                if (ret)
                    goto specialCases;
                else
                    break;
            }
            break;
        default:
            Unreachable();
        }
    }
    specialCases:
    if (ret == R_RETURN)
        return state.RetValue;
    else if (ret == R_JUMP)
        code = *(Uint8**)code;
    else if (ret == R_ERROR)
        throw OpException("Something go wrong", state);
    goto beginLoop;
}
This code should be fast as manually written switch, it would be trivial
for compiler to create jump table to have best performance.
Only solution that are current available require deep recursion that very
easy break inlining. Not mentioning that you need chop logic in small
chunks that will be hard to maintain.


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a731ae2e-9519-4d03-81ec-506b7bbda8b5%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Saturday, June 11, 2016 at 1:01:58 PM UTC+2, Ed=
ward Catmur wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><p dir=
=3D"ltr">I&#39;m in favor of this proposal! But I need to see motivating ex=
amples that are actually difficult to write today; it would wreck the propo=
sal to be presented along with examples that can easily be dismissed as alr=
eady easy to code. </p>
<p dir=3D"ltr">To my mind, that means that examples need to actually exploi=
t the distinctive feature of for constexpr, which is that types (and templa=
tes and constants) can be different from one iteration of the loop to the n=
ext, while (preferably) also taking advantage of the fine-grained flow cont=
rol we get from the loop control statements. Otherwise, you could just use =
boost::mpl::for_each, or (ugh) a comma fold. <br></p></blockquote><div><br>=
For me biggest grain would be interaction with `return`, `case` and `goto`:=
<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"subpret=
typrint"><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: #660;" class=3D"styled-by-prettify">...</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Op</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">CodeInterpretator</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Uint8</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> code</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=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>=C2=A0 =C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> ret </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"style=
d-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">OpCodeState</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> state</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 beginLoop</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">while</s=
pan><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: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">switch</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">code</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">++)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">typename</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"> </span><span style=3D"color: #606;" class=3D"styled-by-pret=
tify">Op</span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">case</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">OpCodeId</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 ret </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</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: #606;" class=3D"styled-by-prettify">OpCodeFunc</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(&amp;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">state</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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">ret</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">goto</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> specialCases</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">else</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">break</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">break</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">default</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Unr=
eachable</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 specialCases</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">re=
t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> R_RETURN</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> st=
ate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">RetValue</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">else</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">ret </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> R_JUMP</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 code </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">*(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Uint=
8</span><span style=3D"color: #660;" class=3D"styled-by-prettify">**)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">code</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">else</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">if</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-b=
y-prettify">ret </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> R_ERROR</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">throw</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>OpException</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;S=
omething go wrong&quot;</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> state</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>goto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> begi=
nLoop</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code=
></div>This code should be fast as manually written switch, it would be tri=
vial for compiler to create jump table to have best performance.<br>Only so=
lution that are current available require deep recursion that very easy bre=
ak inlining. Not mentioning that you need chop logic in small chunks that w=
ill be hard to <span data-dobid=3D"hdw">maintain</span>.<br><br><br></div><=
/div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a731ae2e-9519-4d03-81ec-506b7bbda8b5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a731ae2e-9519-4d03-81ec-506b7bbda8b5=
%40isocpp.org</a>.<br />

------=_Part_3600_485256537.1465726998080--

------=_Part_3599_734410003.1465726998079--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 12 Jun 2016 13:25:47 +0300
Raw View
On 12 June 2016 at 13:23,  <inkwizytoryankes@gmail.com> wrote:
> This code should be fast as manually written switch, it would be trivial for
> compiler to create jump table to have best performance.


I'm sure the open-source compilers will happily accept an extension
patch that shows how trivial it is.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZBSMsJOkjDaU%3D9xz4iJ9qNadygbPiB004oCh2p3jfgFg%40mail.gmail.com.

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 12 Jun 2016 04:13:47 -0700 (PDT)
Raw View
------=_Part_861_1946261003.1465730027549
Content-Type: multipart/alternative;
 boundary="----=_Part_862_2080779481.1465730027550"

------=_Part_862_2080779481.1465730027550
Content-Type: text/plain; charset=UTF-8



On Sunday, June 12, 2016 at 12:25:50 PM UTC+2, Ville Voutilainen wrote:
>
> On 12 June 2016 at 13:23,  <inkwizyt...@gmail.com <javascript:>> wrote:
> > This code should be fast as manually written switch, it would be trivial
> for
> > compiler to create jump table to have best performance.
>
>
> I'm sure the open-source compilers will happily accept an extension
> patch that shows how trivial it is.
>
I was referring to switch after applying `for constexpr`. Some thing like
that:
switch (x)
{
    for constexpr (typename T : Op...)
    {
    case T::OpId: T::OpFunc(); break;
    }
    break;
}
//After `for constexpr` "unroll"
switch (x)
{
    case Op0::OpId: Op0::OpFunc(); break;
    case Op1::OpId: Op1::OpFunc(); break;
    case Op2::OpId: Op2::OpFunc(); break;
    case Op3::OpId: Op3::OpFunc(); break;
}
And in second switch today compilers do that I mentioned (if `OpId` create
proper range). `for constexpr` is not trivial but if it support `case` then
getting jump table from `switch` and `for constexpr` will be trivial.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8dc1e665-42a3-4ef0-a2d2-3773afab170c%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Sunday, June 12, 2016 at 12:25:50 PM UTC+2, Vil=
le Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 12 Jun=
e 2016 at 13:23, =C2=A0&lt;<a href=3D"javascript:" target=3D"_blank" gdf-ob=
fuscated-mailto=3D"B0T3BgNpAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;">inkwizyt...@gmail.com</a>&gt; wrote:
<br>&gt; This code should be fast as manually written switch, it would be t=
rivial for
<br>&gt; compiler to create jump table to have best performance.
<br>
<br>
<br>I&#39;m sure the open-source compilers will happily accept an extension
<br>patch that shows how trivial it is.
<br></blockquote><div>I was referring to switch after applying `for constex=
pr`. Some thing like that:<br><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">switch</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</s=
pan><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>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D"col=
or: #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"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Op</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">...)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">case</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">OpId</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">OpFunc</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">break</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">break</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></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">//After `for constexpr` &quot;unroll&quot;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">switch</span><span style=3D"col=
or: #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">x</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>case</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">Op0</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">OpId</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: #606;" class=
=3D"styled-by-prettify">Op0</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">OpFunc</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">break</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">case</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Op1</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">OpId</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pret=
tify">Op1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #606;" class=3D"styled-by-prettify">OpFunc</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">break</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>=C2=A0 =C2=A0 </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">case</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Op2</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">OpId</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">Op2</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">OpFunc</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">break</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">case</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Op3</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">OpId</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Op3</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">OpFunc</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">break</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></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>And in second switch today compilers do that I mentioned (if `=
OpId` create proper range). `for constexpr` is not trivial but if it suppor=
t `case` then getting jump table from `switch` and `for constexpr` will be =
trivial.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8dc1e665-42a3-4ef0-a2d2-3773afab170c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8dc1e665-42a3-4ef0-a2d2-3773afab170c=
%40isocpp.org</a>.<br />

------=_Part_862_2080779481.1465730027550--

------=_Part_861_1946261003.1465730027549--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sun, 12 Jun 2016 11:39:37 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
 255, 255); line-height: initial;">                                        =
                                              <div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">How do I break from the for constexpr, if 'break' doesn't do it=
?</div>                                                                    =
                                                                 <div style=
=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', san=
s-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backgrou=
nd-color: rgb(255, 255, 255);"><br style=3D"display:initial"></div>        =
                                                                           =
                                                                           =
                                     <div style=3D"font-size: initial; font=
-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 1=
25); text-align: initial; background-color: rgb(255, 255, 255);">Sent&nbsp;=
from&nbsp;my&nbsp;BlackBerry&nbsp;portable&nbsp;Babbage&nbsp;Device</div>  =
                                                                           =
                                                                           =
                          <table width=3D"100%" style=3D"background-color:w=
hite;border-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"font-size:=
 initial; text-align: initial; background-color: rgb(255, 255, 255);">     =
                      <div style=3D"border-style: solid none none; border-t=
op-color: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0in; =
font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;">  <div=
><b>From: </b>inkwizytoryankes@gmail.com</div><div><b>Sent: </b>Sunday, Jun=
e 12, 2016 7:13 AM</div><div><b>To: </b>ISO C++ Standard - Future Proposals=
</div><div><b>Reply To: </b>std-proposals@isocpp.org</div><div><b>Subject: =
</b>Re: [std-proposals] Re: statement folding on variadic templates paramet=
ers pack</div></div></td></tr></tbody></table><div style=3D"border-style: s=
olid none none; border-top-color: rgb(186, 188, 209); border-top-width: 1pt=
; font-size: initial; text-align: initial; background-color: rgb(255, 255, =
255);"></div><br><div id=3D"_originalContent" style=3D""><div dir=3D"ltr"><=
br><br>On Sunday, June 12, 2016 at 12:25:50 PM UTC+2, Ville Voutilainen wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">On 12 June 2016 at 13:23, &=
nbsp;&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"B0T3BgNpAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';re=
turn true;" onclick=3D"this.href=3D'javascript:';return true;">inkwizyt...@=
gmail.com</a>&gt; wrote:
<br>&gt; This code should be fast as manually written switch, it would be t=
rivial for
<br>&gt; compiler to create jump table to have best performance.
<br>
<br>
<br>I'm sure the open-source compilers will happily accept an extension
<br>patch that shows how trivial it is.
<br></blockquote><div>I was referring to switch after applying `for constex=
pr`. Some thing like that:<br><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">switch</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</s=
pan><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: #008;" class=3D"styled-by-prettify">for</span><span style=3D"col=
or: #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"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Op</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><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">case</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">OpId</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">OpFunc</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">break</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: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">break</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></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">//After `for constexpr` "unroll"</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">switch</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-b=
y-prettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">case</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Op0</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">OpId</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Op0</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">OpFunc<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">break</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">case</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">Op1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">OpId</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Op1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">OpFunc</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">break</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">case</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Op2</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">OpId</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Op2</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">OpFunc</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">break</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">case</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Op3</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">OpId</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Op3</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">OpFunc</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">brea=
k</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div>And=
 in second switch today compilers do that I mentioned (if `OpId` create pro=
per range). `for constexpr` is not trivial but if it support `case` then ge=
tting jump table from `switch` and `for constexpr` will be trivial.<br><br>=
</div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8dc1e665-42a3-4ef0-a2d2-3773afab170c%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/8dc1e665-42a3-4ef0-a2d2-3773afab=
170c%40isocpp.org</a>.<br>
<br><!--end of _originalContent --></div></body></html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20160612153937.4898897.23968.12102%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20160612153937.4898897.23968.12102%40gm=
ail.com</a>.<br />

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 12 Jun 2016 10:22:39 -0700 (PDT)
Raw View
------=_Part_341_2002008754.1465752159907
Content-Type: multipart/alternative;
 boundary="----=_Part_342_782957420.1465752159908"

------=_Part_342_782957420.1465752159908
Content-Type: text/plain; charset=UTF-8



On Sunday, June 12, 2016 at 5:39:41 PM UTC+2, Tony V E wrote:
>
> How do I break from the for constexpr, if 'break' doesn't do it?
>
> Sent from my BlackBerry portable Babbage Device
> *From: *inkwizyt...@gmail.com <javascript:>
> *Sent: *Sunday, June 12, 2016 7:13 AM
> *To: *ISO C++ Standard - Future Proposals
> *Reply To: *std-pr...@isocpp.org <javascript:>
> *Subject: *Re: [std-proposals] Re: statement folding on variadic
> templates parameters pack
>
> I was referring to switch after applying `for constexpr`. Some thing like
> that:
> switch (x)
> {
>     for constexpr (typename T : Op...)
>     {
>     case T::OpId: T::OpFunc(); break;
>     }
>     break;
> }
> //After `for constexpr` "unroll"
> switch (x)
> {
>     case Op0::OpId: Op0::OpFunc(); break;
>     case Op1::OpId: Op1::OpFunc(); break;
>     case Op2::OpId: Op2::OpFunc(); break;
>     case Op3::OpId: Op3::OpFunc(); break;
> }
> And in second switch today compilers do that I mentioned (if `OpId` create
> proper range). `for constexpr` is not trivial but if it support `case` then
> getting jump table from `switch` and `for constexpr` will be trivial.
>


`break` work same as in normal `for`, critical is last `break` in original
`switch` because `for constexpr` breaks there. I skip one transformation
stage that show it:
switch (x)
{
    case Op0::OpId: Op0::OpFunc(); goto finalFor;
    case Op1::OpId: Op1::OpFunc(); goto finalFor;
    case Op2::OpId: Op2::OpFunc(); goto finalFor;
    case Op3::OpId: Op3::OpFunc(); goto finalFor;
    finalFor: break;
}


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/57d8c679-f312-4b77-8210-705f5e093b7e%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Sunday, June 12, 2016 at 5:39:41 PM UTC+2, Tony=
 V E wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"backg=
round-color:rgb(255,255,255);line-height:initial" lang=3D"en-US">          =
                                                                           =
 <div style=3D"width:100%;font-size:initial;font-family:Calibri,&#39;Slate =
Pro&#39;,sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;back=
ground-color:rgb(255,255,255)">How do I break from the for constexpr, if &#=
39;break&#39; doesn&#39;t do it?</div>                                     =
                                                                           =
                     <div style=3D"width:100%;font-size:initial;font-family=
:Calibri,&#39;Slate Pro&#39;,sans-serif,sans-serif;color:rgb(31,73,125);tex=
t-align:initial;background-color:rgb(255,255,255)"><br style=3D"display:ini=
tial"></div>                                                               =
                                                                           =
                                                         <div style=3D"font=
-size:initial;font-family:Calibri,&#39;Slate Pro&#39;,sans-serif,sans-serif=
;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)"=
>Sent=C2=A0from=C2=A0my=C2=A0BlackBerry=C2=A0<wbr>portable=C2=A0Babbage=C2=
=A0Device</div>                                                            =
                                                                           =
                                           <table style=3D"background-color=
:white;border-spacing:0px" width=3D"100%"> <tbody><tr><td colspan=3D"2" sty=
le=3D"font-size:initial;text-align:initial;background-color:rgb(255,255,255=
)">                           <div style=3D"border-style:solid none none;bo=
rder-top-color:rgb(181,196,223);border-top-width:1pt;padding:3pt 0in 0in;fo=
nt-family:Tahoma,&#39;BB Alpha Sans&#39;,&#39;Slate Pro&#39;;font-size:10pt=
">  <div><b>From: </b><a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"ct4MmyN6AQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#3=
9;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#3=
9;;return true;">inkwizyt...@gmail.com</a></div><div><b>Sent: </b>Sunday, J=
une 12, 2016 7:13 AM</div><div><b>To: </b>ISO C++ Standard - Future Proposa=
ls</div><div><b>Reply To: </b><a href=3D"javascript:" target=3D"_blank" gdf=
-obfuscated-mailto=3D"ct4MmyN6AQAJ" rel=3D"nofollow" onmousedown=3D"this.hr=
ef=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;">std-pr...@isocpp.org</a></div><div><b>Subject: </b=
>Re: [std-proposals] Re: statement folding on variadic templates parameters=
 pack</div></div></td></tr></tbody></table><div style=3D"border-style:solid=
 none none;border-top-color:rgb(186,188,209);border-top-width:1pt;font-size=
:initial;text-align:initial;background-color:rgb(255,255,255)"></div><br><d=
iv><div dir=3D"ltr"><div>I was referring to switch after applying `for cons=
texpr`. Some thing like that:<br><div style=3D"background-color:rgb(250,250=
,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;wor=
d-wrap:break-word"><code><div><span style=3D"color:#008">switch</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">x</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span=
 style=3D"color:#008">typename</span><span style=3D"color:#000"> T </span><=
span style=3D"color:#660">:</span><span style=3D"color:#000"> </span><span =
style=3D"color:#606">Op</span><span style=3D"color:#660">...)</span><span s=
tyle=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">case</span><span style=3D"color:#000"> T</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#606">OpId</span><span style=3D"color=
:#660">:</span><span style=3D"color:#000"> T</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#606">OpFunc</span><span style=3D"color:#6=
60">();</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>break</span><span style=3D"color:#660">;</span><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"=
color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">break</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#800">//After `for constexpr` &quot;unroll&quot;</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#008">switch</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">x</span><span style=3D"color:#660">)</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">case</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#606">Op0</span=
><span style=3D"color:#660">::</span><span style=3D"color:#606">OpId</span>=
<span style=3D"color:#660">:</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#606">Op0</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#606">OpFunc</span><span style=3D"color:#660">();</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">break</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">case</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Op1</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#606">OpId</span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#606">Op1</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#606">OpFunc</span><s=
pan style=3D"color:#660">();</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">break</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">ca=
se</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Op2<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#606">OpId</=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#606">Op2</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#606">OpFunc</span><span style=3D"color:#660">();</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">break</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">case</span><span style=3D"color:#000"=
> </span><span style=3D"color:#606">Op3</span><span style=3D"color:#660">::=
</span><span style=3D"color:#606">OpId</span><span style=3D"color:#660">:</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Op3</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#606">OpFunc</sp=
an><span style=3D"color:#660">();</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">break</span><span style=3D"color:#660">;</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br></span></div></code></div>And in second switch =
today compilers do that I mentioned (if `OpId` create proper range). `for c=
onstexpr` is not trivial but if it support `case` then getting jump table f=
rom `switch` and `for constexpr` will be trivial.<br></div></div></div></di=
v></blockquote><div>=C2=A0<br><br>`break` work same as in normal `for`, cri=
tical is last `break` in original `switch` because `for constexpr` breaks t=
here. I skip one transformation stage that show it:<br><div class=3D"pretty=
print" 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-prettify">switch</span><span style=3D"colo=
r: #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">x</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cas=
e</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Op0</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">OpId</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Op0</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">OpFunc</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">goto</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> finalFor</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">case</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Op1</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">OpId</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Op1<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">OpFunc</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">goto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> finalFor</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">case</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Op2</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">OpId</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Op2</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">OpFunc</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">goto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> finalFor</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">case</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Op3<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">OpId</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Op3</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">OpFunc</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">got=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> finalFor=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 f=
inalFor</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">break</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/57d8c679-f312-4b77-8210-705f5e093b7e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/57d8c679-f312-4b77-8210-705f5e093b7e=
%40isocpp.org</a>.<br />

------=_Part_342_782957420.1465752159908--

------=_Part_341_2002008754.1465752159907--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sun, 12 Jun 2016 12:32:20 -0700
Raw View
--001a114e72029d7513053519d49f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sun, Jun 12, 2016 at 10:22 AM, <inkwizytoryankes@gmail.com> wrote:

> On Sunday, June 12, 2016 at 5:39:41 PM UTC+2, Tony V E wrote:
>>
>>
>> I was referring to switch after applying `for constexpr`. Some thing lik=
e
>> that:
>> switch (x)
>> {
>>     for constexpr (typename T : Op...)
>>     {
>>     case T::OpId: T::OpFunc(); break;
>>     }
>>     break;
>> }
>> //After `for constexpr` "unroll"
>> switch (x)
>> {
>>     case Op0::OpId: Op0::OpFunc(); break;
>>     case Op1::OpId: Op1::OpFunc(); break;
>>     case Op2::OpId: Op2::OpFunc(); break;
>>     case Op3::OpId: Op3::OpFunc(); break;
>> }
>> And in second switch today compilers do that I mentioned (if `OpId`
>> create proper range). `for constexpr` is not trivial but if it support
>> `case` then getting jump table from `switch` and `for constexpr` will be
>> trivial.
>>
>

>  How do I break from the for constexpr, if 'break' doesn't do it?
>
>
> `break` work same as in normal `for`, critical is last `break` in origina=
l
> `switch` because `for constexpr` breaks there. I skip one transformation
> stage that show it:
> switch (x)
> {
>     case Op0::OpId: Op0::OpFunc(); goto finalFor;
>     case Op1::OpId: Op1::OpFunc(); goto finalFor;
>     case Op2::OpId: Op2::OpFunc(); goto finalFor;
>     case Op3::OpId: Op3::OpFunc(); goto finalFor;
>     finalFor: break;
> }
>

No, that doesn't work.  I think Tony has a point.
Sergey's half-proposal wants to make "break" and "continue" inside a "for
constexpr" act exactly like "break" and "continue" inside a non-constexpr
"for":

    for constexpr(typename T : Ts...) {
        do_something<T>();
        if constexpr(is_same_v<T, nullptr_t>) break;
    }

This code would generate an unrolled loop of do_something<T>()s for each T
in Ts... up to and including the first instance of nullptr_t. As soon as it
generated do_something<nullptr_t>(), it would break and stop iterating over
Ts....

You can't have break work this way (Sergey's way) and also have it work for
outer switch statements; you have to pick one. And I think you've picked
the wrong one, for two reasons:

First, Ed Catmur has shown that if what you really want is a way to
pack-expand switch cases, there might be more natural syntaxes to express
that.

    // Natively (this syntax strikes me as ungraceful, I admit)
    switch (x) {
        case Op::OpId: { Op::OpFunc(); break; }...
    }

    // Or via some sort of library template
    auto switch_ =3D make_switch(
        make_switch_case( Op::OpId, [](){ return Op::OpFunc(); } )...
    );
    auto result =3D switch_.on(x) + switch_.on(y);

    template<class X, class... Cs>
    auto switch_on(X&& x, Cs&&... cases) {
        return
make_switch(std::forward<Cs>(cases)...).on(std::forward<X>(x));
    }

Second, I think you're doing the same thing I did at first, which is to
treat "for constexpr" (or whatever) as a pack-expansion primitive in the
same vein as fold-expressions, whereas what it really wants to be is a
compile-time control-flow (code-generation) primitive in the same vein as
"if constexpr" and function templates. If you stop thinking of it as
physically duplicating/unrolling its contents (the way a fold-expression
does), then you no longer have to worry about what unrolling a "break" or
"continue" statement would mean.

I found the docs for Boost.Switch
<http://dancinghacker.com/switch/boost_switch/switch_.html>. If I get the
time, I'll try to write up a modern library implementation of the above
make_switch and post it here. I'm sure it's been done before, of course, so
if someone beats me to it that's great.

=E2=80=93Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0%2BJon-6hH0JU%3DxqScearhoMu4eVWieTpvYF-N4=
2ky4Bgg%40mail.gmail.com.

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

<div dir=3D"ltr">On Sun, Jun 12, 2016 at 10:22 AM,  <span dir=3D"ltr">&lt;<=
a href=3D"mailto:inkwizytoryankes@gmail.com" target=3D"_blank">inkwizytorya=
nkes@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border=
-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On Su=
nday, June 12, 2016 at 5:39:41 PM UTC+2, Tony V E wrote:</span><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><div style=3D"background-color:rgb(255,255,255);line-height:initial" l=
ang=3D"en-US"><span class=3D"">                                            =
                                          <div style=3D"width:100%;font-siz=
e:initial;font-family:Calibri,&#39;Slate Pro&#39;,sans-serif,sans-serif;col=
or:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)"><br=
></div></span><span class=3D""><div><div dir=3D"ltr"><div>I was referring t=
o switch after applying `for constexpr`. Some thing like that:<br><div styl=
e=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);wo=
rd-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,136)">switch</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,1=
02,0)">(</span><span style=3D"color:rgb(0,0,0)">x</span><span style=3D"colo=
r:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"><br></span><span=
 style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">for</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">conste=
xpr</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">typename</span><spa=
n style=3D"color:rgb(0,0,0)"> T </span><span style=3D"color:rgb(102,102,0)"=
>:</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,0,102)">Op</span><span style=3D"color:rgb(102,102,0)">...)</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rg=
b(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:rgb=
(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:=
</span><span style=3D"color:rgb(0,0,0)"> T</span><span style=3D"color:rgb(1=
02,102,0)">::</span><span style=3D"color:rgb(102,0,102)">OpFunc</span><span=
 style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb(0,0,0)">=
 </span><span style=3D"color:rgb(0,0,136)">break</span><span style=3D"color=
:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">brea=
k</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:r=
gb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span><span st=
yle=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">//Af=
ter `for constexpr` &quot;unroll&quot;</span><span style=3D"color:rgb(0,0,0=
)"><br></span><span style=3D"color:rgb(0,0,136)">switch</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">(</span>=
<span style=3D"color:rgb(0,0,0)">x</span><span style=3D"color:rgb(102,102,0=
)">)</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color=
:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:=
rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op0</span><span st=
yle=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)">=
OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op0</span><span =
style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)=
">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">break</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,10=
2)">Op1</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"=
color:rgb(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,=
102)">Op1</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)"=
>();</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(0,0,136)">break</span><span style=3D"color:rgb(102,102,0)">;</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rg=
b(0,0,136)">case</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,0,102)">Op2</span><span style=3D"color:rgb(102,102,0)">::=
</span><span style=3D"color:rgb(102,0,102)">OpId</span><span style=3D"color=
:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"> </span><span sty=
le=3D"color:rgb(102,0,102)">Op2</span><span style=3D"color:rgb(102,102,0)">=
::</span><span style=3D"color:rgb(102,0,102)">OpFunc</span><span style=3D"c=
olor:rgb(102,102,0)">();</span><span style=3D"color:rgb(0,0,0)"> </span><sp=
an style=3D"color:rgb(0,0,136)">break</span><span style=3D"color:rgb(102,10=
2,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(102,0,102)">Op3</span><span style=3D"colo=
r:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)">OpId</span>=
<span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><span style=3D"co=
lor:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)">OpFunc</s=
pan><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">break</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></sp=
an><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,=
0,0)"><br></span></div></code></div>And in second switch today compilers do=
 that I mentioned (if `OpId` create proper range). `for constexpr` is not t=
rivial but if it support `case` then getting jump table from `switch` and `=
for constexpr` will be trivial.<br></div></div></div></span></div></blockqu=
ote></div></blockquote><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rg=
b(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex"><div style=3D"background-color:rgb(255,255,255);line-height=
:initial" lang=3D"en-US"><span class=3D""><div><div dir=3D"ltr"><div></div>=
</div></div></span></div></blockquote><div>=C2=A0<span style=3D"color:rgb(3=
1,73,125);font-family:Calibri,&#39;Slate Pro&#39;,sans-serif,sans-serif;fon=
t-size:initial;text-align:initial">How do I break from the for constexpr, i=
f &#39;break&#39; doesn&#39;t do it?</span><div style=3D"text-align:initial=
;width:688.75px;font-size:initial;font-family:Calibri,&#39;Slate Pro&#39;,s=
ans-serif,sans-serif;color:rgb(31,73,125)"><br></div><br>`break` work same =
as in normal `for`, critical is last `break` in original `switch` because `=
for constexpr` breaks there. I skip one transformation stage that show it:<=
br><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187=
,187,187);word-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,136=
)">switch</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">x</span><span s=
tyle=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"><br>=
</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rg=
b(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102=
,0,102)">Op0</span><span style=3D"color:rgb(102,102,0)">::</span><span styl=
e=3D"color:rgb(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">=
:</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,0,102)">Op0</span><span style=3D"color:rgb(102,102,0)">::</span><span st=
yle=3D"color:rgb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,=
0)">();</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color=
:rgb(0,0,136)">goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span>=
<span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0=
)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)=
">Op1</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"co=
lor:rgb(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,10=
2)">Op1</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"=
color:rgb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span s=
tyle=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2</=
span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb=
(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2=
</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:r=
gb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)"=
>goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D=
"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"=
color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><s=
pan style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,=
102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</spa=
n><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(10=
2,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span=
 style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto=
</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 finalFor</span><span style=3D"color:rgb(102,102,0)">:</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">break</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span></div></code><=
/div></div></div></blockquote><div><br></div><div>No, that doesn&#39;t work=
..=C2=A0 I think Tony has a point.</div><div>Sergey&#39;s half-proposal want=
s to make &quot;break&quot; and &quot;continue&quot; inside a &quot;for con=
stexpr&quot; act exactly like &quot;break&quot; and &quot;continue&quot; in=
side a non-constexpr &quot;for&quot;:</div><div><br></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 for constexpr(typename T : Ts...) {=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 do_something&lt;T&gt;();</font></div><div><font face=3D"monospace, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 if constexpr(is_same_v&lt;T, nullptr_=
t&gt;) break;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 }</font></div><div><br></div><div>This code would generate an unroll=
ed loop of <font face=3D"monospace, monospace">do_something&lt;T&gt;()</fon=
t>s for each=C2=A0<font face=3D"monospace, monospace">T</font> in <font fac=
e=3D"monospace, monospace">Ts...</font> up to and including the first insta=
nce of <font face=3D"monospace, monospace">nullptr_t</font>. As soon as it =
generated <font face=3D"monospace, monospace">do_something&lt;nullptr_t&gt;=
()</font>, it would break and stop iterating over <font face=3D"monospace, =
monospace">Ts...</font>.</div><div><br></div><div>You can&#39;t have break =
work this way (Sergey&#39;s way) and also have it work for outer switch sta=
tements; you have to pick one. And I think you&#39;ve picked the wrong one,=
 for two reasons:</div><div><br></div><div>First, Ed Catmur has shown that =
if what you really want is a way to pack-expand switch cases, there might b=
e more natural syntaxes to express that.</div><div><br></div><font face=3D"=
monospace, monospace">=C2=A0 =C2=A0 // Natively (this syntax strikes me as =
ungraceful, I admit)</font></div><div class=3D"gmail_quote"><font face=3D"m=
onospace, monospace">=C2=A0=C2=A0 =C2=A0switch (x)=C2=A0{<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 case Op::OpId: { Op::OpFunc(); break; }...<br>=C2=A0 =C2=A0 }=
</font></div><div class=3D"gmail_quote"><font face=3D"monospace, monospace"=
><br></font></div><div class=3D"gmail_quote"><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 // Or via some sort of library template</font></div><di=
v class=3D"gmail_quote"><span style=3D"font-family:monospace,monospace">=C2=
=A0 =C2=A0 auto switch_ =3D make_switch(</span><br></div><div class=3D"gmai=
l_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ma=
ke_switch_case( Op::OpId, [](){ return Op::OpFunc(); } )...</font></div><di=
v class=3D"gmail_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 )=
;</font></div><div class=3D"gmail_quote"><font face=3D"monospace, monospace=
">=C2=A0 =C2=A0 auto result =3D switch_.on(x) + switch_.on(y);</font></div>=
<div class=3D"gmail_quote"><font face=3D"monospace, monospace"><br></font><=
/div><div class=3D"gmail_quote"><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 template&lt;class X, class... Cs&gt;</font></div><div class=3D"gmail=
_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto switch_on(X&=
amp;&amp; x, Cs&amp;&amp;... cases) {</font></div><div class=3D"gmail_quote=
"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ma=
ke_switch(std::forward&lt;Cs&gt;(cases)...).on(std::forward&lt;X&gt;(x));</=
font></div><div class=3D"gmail_quote"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 }<br></font><div><br></div><div>Second, I think you&#39;re do=
ing the same thing I did at first, which is to treat &quot;for constexpr&qu=
ot; (or whatever) as a pack-expansion primitive in the same vein as fold-ex=
pressions, whereas what it really wants to be is a compile-time control-flo=
w (code-generation) primitive in the same vein as &quot;if constexpr&quot; =
and function templates. If you stop thinking of it as physically duplicatin=
g/unrolling its contents (the way a fold-expression does), then you no long=
er have to worry about what unrolling a &quot;break&quot; or &quot;continue=
&quot; statement would mean.</div><div><br></div><div>I found <a href=3D"ht=
tp://dancinghacker.com/switch/boost_switch/switch_.html">the docs for Boost=
..Switch</a>. If I get the time, I&#39;ll try to write up a modern library i=
mplementation of the above <font face=3D"monospace, monospace">make_switch<=
/font>=C2=A0and post it here. I&#39;m sure it&#39;s been done before, of co=
urse, so if someone beats me to it that&#39;s great.</div><div><br></div><d=
iv>=E2=80=93Arthur</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BJon-6hH0JU%3DxqScearhoMu4eV=
WieTpvYF-N42ky4Bgg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BJon=
-6hH0JU%3DxqScearhoMu4eVWieTpvYF-N42ky4Bgg%40mail.gmail.com</a>.<br />

--001a114e72029d7513053519d49f--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 12 Jun 2016 16:52:03 -0700 (PDT)
Raw View
------=_Part_493_10668978.1465775523272
Content-Type: multipart/alternative;
 boundary="----=_Part_494_1328588024.1465775523274"

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



On Sunday, June 12, 2016 at 9:32:22 PM UTC+2, Arthur O'Dwyer wrote:
>
> On Sun, Jun 12, 2016 at 10:22 AM, <inkwizyt...@gmail.com <javascript:>>=
=20
> wrote:
>
>> On Sunday, June 12, 2016 at 5:39:41 PM UTC+2, Tony V E wrote:
>>
>  How do I break from the for constexpr, if 'break' doesn't do it?
>>
>>
>> `break` work same as in normal `for`, critical is last `break` in=20
>> original `switch` because `for constexpr` breaks there. I skip one=20
>> transformation stage that show it:
>> switch (x)
>> {
>>     case Op0::OpId: Op0::OpFunc(); goto finalFor;
>>     case Op1::OpId: Op1::OpFunc(); goto finalFor;
>>     case Op2::OpId: Op2::OpFunc(); goto finalFor;
>>     case Op3::OpId: Op3::OpFunc(); goto finalFor;
>>     finalFor: break;
>> }
>>
>
> No, that doesn't work.  I think Tony has a point.
> Sergey's half-proposal wants to make "break" and "continue" inside a "for=
=20
> constexpr" act exactly like "break" and "continue" inside a non-constexpr=
=20
> "for":
>
>     for constexpr(typename T : Ts...) {
>         do_something<T>();
>         if constexpr(is_same_v<T, nullptr_t>) break;
>     }
>
> This code would generate an unrolled loop of do_something<T>()s for each =
T=20
> in Ts... up to and including the first instance of nullptr_t. As soon as=
=20
> it generated do_something<nullptr_t>(), it would break and stop iterating=
=20
> over Ts....
>
> You can't have break work this way (Sergey's way) and also have it work=
=20
> for outer switch statements; you have to pick one. And I think you've=20
> picked the wrong one, for two reasons:
>
> First, Ed Catmur has shown that if what you really want is a way to=20
> pack-expand switch cases, there might be more natural syntaxes to express=
=20
> that.
>
>     // Natively (this syntax strikes me as ungraceful, I admit)
>     switch (x) {
>         case Op::OpId: { Op::OpFunc(); break; }...
>     }
>
>
I start from that syntax and after that I switch to `for constexpr` because=
=20
it was for me lot more readable and have more usages.
=20

>     // Or via some sort of library template
>     auto switch_ =3D make_switch(
>         make_switch_case( Op::OpId, [](){ return Op::OpFunc(); } )...
>     );
>     auto result =3D switch_.on(x) + switch_.on(y);
>
>     template<class X, class... Cs>
>     auto switch_on(X&& x, Cs&&... cases) {
>         return=20
> make_switch(std::forward<Cs>(cases)...).on(std::forward<X>(x));
>     }
>
>
But it would be hard to generate code from it that will be comparable with=
=20
native `switch`.
=20

> Second, I think you're doing the same thing I did at first, which is to=
=20
> treat "for constexpr" (or whatever) as a pack-expansion primitive in the=
=20
> same vein as fold-expressions, whereas what it really wants to be is a=20
> compile-time control-flow (code-generation) primitive in the same vein as=
=20
> "if constexpr" and function templates. If you stop thinking of it as=20
> physically duplicating/unrolling its contents (the way a fold-expression=
=20
> does), then you no longer have to worry about what unrolling a "break" or=
=20
> "continue" statement would mean.
>
> I found the docs for Boost.Switch=20
> <http://dancinghacker.com/switch/boost_switch/switch_.html>. If I get the=
=20
> time, I'll try to write up a modern library implementation of the above=
=20
> make_switch and post it here. I'm sure it's been done before, of course,=
=20
> so if someone beats me to it that's great.
>
> =E2=80=93Arthur
>

 One question how will work this code?
switch (0)
{
    for (;;)
    {
        f();
        case 0: g(); break;
    }
    h();
}
It will call `g` and then `h` because `break` is from `for` not from=20
`switch`.
Now with `for constexpr`:
switch (0)
{
    for constexpr (int I : II...)
    {
        f<I>()
        case I: g<I>(); break;
    }
    h();
}
It will call `g<0>` and then `h`. Exactly same as for normal `for`. Only=20
change is how `case` is handled.

Overall I assume that `for constexpr` will conceptually "unroll" body for=
=20
each parameter pack element. This is need because each "iteration" body can=
=20
be completely different:
for constexpr (typename T : TT...)
{
    T x; //this will require creating separate variable for each iteration,=
=20
but they lifetime not overlap.
}
Probably only real difference is when some iteration could create invalid=
=20
code. In my approach it will always be invalid, in case of "dynamic"=20
control-flow it can be valid if `for` leave early.
I think It could be possible to tweak both approach to have same output=20
based on reachability of each iteration body. If is unreachable it will be=
=20
not generated. Adding `case` will made all iteration reachable and=20
generated.


--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6b2c3588-e67e-4a8b-94d6-bdacd50ac244%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Sunday, June 12, 2016 at 9:32:22 PM UTC+2, Arth=
ur O&#39;Dwyer wrote:<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">On Sun, Jun 12, 2016 at 10:22 AM,  <span dir=3D"ltr">&lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"teluL9aGAQAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">inkwizyt...@=
gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr"><span>On Sunday, June 12, 2016 at 5:39:41 PM UTC+=
2, Tony V E wrote:</span></div></blockquote><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-colo=
r:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"lt=
r"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex"><div style=3D"background-color:rgb(255,255,255);line-he=
ight:initial" lang=3D"en-US"><span><div><div dir=3D"ltr"><div></div></div><=
/div></span></div></blockquote><div>=C2=A0<span style=3D"color:rgb(31,73,12=
5);font-family:Calibri,&#39;Slate Pro&#39;,sans-serif,sans-serif;font-size:=
initial;text-align:initial">How do I break from the for constexpr, if &#39;=
break&#39; doesn&#39;t do it?</span><div style=3D"text-align:initial;width:=
688.75px;font-size:initial;font-family:Calibri,&#39;Slate Pro&#39;,sans-ser=
if,sans-serif;color:rgb(31,73,125)"><br></div><br>`break` work same as in n=
ormal `for`, critical is last `break` in original `switch` because `for con=
stexpr` breaks there. I skip one transformation stage that show it:<br><div=
 style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,18=
7);word-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,136)">swit=
ch</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">x</span><span style=3D=
"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"><br></span>=
<span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0=
)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)=
">Op0</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"co=
lor:rgb(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,10=
2)">Op0</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"=
color:rgb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span s=
tyle=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op1</=
span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb=
(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op1=
</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:r=
gb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)"=
>goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D=
"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"=
color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2</span><s=
pan style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,=
102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2</spa=
n><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(10=
2,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span=
 style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto=
</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><span=
 style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102=
)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"c=
olor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,1=
02)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto</spa=
n><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"color:rgb=
(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 fin=
alFor</span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">break</span><span=
 style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><b=
r></span><span style=3D"color:rgb(102,102,0)">}</span></div></code></div></=
div></div></blockquote><div><br></div><div>No, that doesn&#39;t work.=C2=A0=
 I think Tony has a point.</div><div>Sergey&#39;s half-proposal wants to ma=
ke &quot;break&quot; and &quot;continue&quot; inside a &quot;for constexpr&=
quot; act exactly like &quot;break&quot; and &quot;continue&quot; inside a =
non-constexpr &quot;for&quot;:</div><div><br></div><div><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 for constexpr(typename T : Ts...) {</font></=
div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do=
_something&lt;T&gt;();</font></div><div><font face=3D"monospace, monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if constexpr(is_same_v&lt;T, nullptr_t&gt;) br=
eak;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 }</=
font></div><div><br></div><div>This code would generate an unrolled loop of=
 <font face=3D"monospace, monospace">do_something&lt;T&gt;()</font>s for ea=
ch=C2=A0<font face=3D"monospace, monospace">T</font> in <font face=3D"monos=
pace, monospace">Ts...</font> up to and including the first instance of <fo=
nt face=3D"monospace, monospace">nullptr_t</font>. As soon as it generated =
<font face=3D"monospace, monospace">do_something&lt;nullptr_t&gt;()</font>,=
 it would break and stop iterating over <font face=3D"monospace, monospace"=
>Ts...</font>.</div><div><br></div><div>You can&#39;t have break work this =
way (Sergey&#39;s way) and also have it work for outer switch statements; y=
ou have to pick one. And I think you&#39;ve picked the wrong one, for two r=
easons:</div><div><br></div><div>First, Ed Catmur has shown that if what yo=
u really want is a way to pack-expand switch cases, there might be more nat=
ural syntaxes to express that.</div><div><br></div><font face=3D"monospace,=
 monospace">=C2=A0 =C2=A0 // Natively (this syntax strikes me as ungraceful=
, I admit)</font></div><div class=3D"gmail_quote"><font face=3D"monospace, =
monospace">=C2=A0=C2=A0 =C2=A0switch (x)=C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 case Op::OpId: { Op::OpFunc(); break; }...<br>=C2=A0 =C2=A0 }</font></d=
iv><div class=3D"gmail_quote"><font face=3D"monospace, monospace"><br></fon=
t></div></div></div></blockquote><div><br>I start from that syntax and afte=
r that I switch to `for constexpr` because it was for me lot more readable =
and have more usages.<br>=C2=A0</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><div class=3D"gmail_quote"><font face=3D"monos=
pace, monospace"></font></div><div class=3D"gmail_quote"><font face=3D"mono=
space, monospace">=C2=A0 =C2=A0 // Or via some sort of library template</fo=
nt></div><div class=3D"gmail_quote"><span style=3D"font-family:monospace,mo=
nospace">=C2=A0 =C2=A0 auto switch_ =3D make_switch(</span><br></div><div c=
lass=3D"gmail_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 make_switch_case( Op::OpId, [](){ return Op::OpFunc(); } )...</f=
ont></div><div class=3D"gmail_quote"><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 );</font></div><div class=3D"gmail_quote"><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 auto result =3D switch_.on(x) + switch_.on(y=
);</font></div><div class=3D"gmail_quote"><font face=3D"monospace, monospac=
e"><br></font></div><div class=3D"gmail_quote"><font face=3D"monospace, mon=
ospace">=C2=A0 =C2=A0 template&lt;class X, class... Cs&gt;</font></div><div=
 class=3D"gmail_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 au=
to switch_on(X&amp;&amp; x, Cs&amp;&amp;... cases) {</font></div><div class=
=3D"gmail_quote"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 return make_switch(std::forward&lt;Cs&gt;(<wbr>cases)...).on(std::fo=
rward&lt;X&gt;(<wbr>x));</font></div><div class=3D"gmail_quote"><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 }<br></font><div><br></div></div></=
div></div></blockquote><div><br>But it would be hard to generate code from =
it that will be comparable with native `switch`.<br>=C2=A0</div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail=
_quote"><div></div><div>Second, I think you&#39;re doing the same thing I d=
id at first, which is to treat &quot;for constexpr&quot; (or whatever) as a=
 pack-expansion primitive in the same vein as fold-expressions, whereas wha=
t it really wants to be is a compile-time control-flow (code-generation) pr=
imitive in the same vein as &quot;if constexpr&quot; and function templates=
.. If you stop thinking of it as physically duplicating/unrolling its conten=
ts (the way a fold-expression does), then you no longer have to worry about=
 what unrolling a &quot;break&quot; or &quot;continue&quot; statement would=
 mean.</div><div><br></div><div>I found <a href=3D"http://dancinghacker.com=
/switch/boost_switch/switch_.html" target=3D"_blank" rel=3D"nofollow" onmou=
sedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fdanc=
inghacker.com%2Fswitch%2Fboost_switch%2Fswitch_.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNGl9dwdGRJ8eSNXsEz2k4IY3y4l8g&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fdancinghac=
ker.com%2Fswitch%2Fboost_switch%2Fswitch_.html\x26sa\x3dD\x26sntz\x3d1\x26u=
sg\x3dAFQjCNGl9dwdGRJ8eSNXsEz2k4IY3y4l8g&#39;;return true;">the docs for Bo=
ost.Switch</a>. If I get the time, I&#39;ll try to write up a modern librar=
y implementation of the above <font face=3D"monospace, monospace">make_swit=
ch</font>=C2=A0and post it here. I&#39;m sure it&#39;s been done before, of=
 course, so if someone beats me to it that&#39;s great.</div><div><br></div=
><div>=E2=80=93Arthur</div></div></div></div></blockquote><div><br>=C2=A0On=
e question how will work this code?<br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">switch</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(;;)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cas=
e</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> g</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">break</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 =C2=A0 h</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: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div>It will call `g` and then `h` because `break` is from `for=
` not from `switch`.<br>Now with `for constexpr`:<br><div class=3D"prettypr=
int" 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"co=
lor: #008;" class=3D"styled-by-prettify">switch</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> I </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> II</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">...)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify">I</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">case</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> I</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> g</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">I</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&gt;();</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">break</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 h</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></div></code></div>It will call `g&lt;0&gt;=
` and then `h`. Exactly same as for normal `for`. Only change is how `case`=
 is handled.<br><br>Overall I assume that `for constexpr` will conceptually=
 &quot;unroll&quot; body for each parameter pack element. This is need beca=
use each &quot;iteration&quot; body can be completely different:<br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 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"s=
tyled-by-prettify"> T </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> TT</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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 T x</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">//this will require creating sep=
arate variable for each iteration, but they lifetime not overlap.</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span></div></code></div>Proba=
bly only real difference is when some iteration could create invalid code. =
In my approach it will always be invalid, in case of &quot;dynamic&quot; co=
ntrol-flow it can be valid if `for` leave early.<br>I think It could be pos=
sible to tweak both approach to have same output based on reachability of e=
ach iteration body. If is unreachable it will be not generated. Adding `cas=
e` will made all iteration reachable and generated.<br><br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6b2c3588-e67e-4a8b-94d6-bdacd50ac244%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6b2c3588-e67e-4a8b-94d6-bdacd50ac244=
%40isocpp.org</a>.<br />

------=_Part_494_1328588024.1465775523274--

------=_Part_493_10668978.1465775523272--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Sun, 12 Jun 2016 18:17:52 -0700 (PDT)
Raw View
------=_Part_3804_761039642.1465780672746
Content-Type: multipart/alternative;
 boundary="----=_Part_3805_451590462.1465780672747"

------=_Part_3805_451590462.1465780672747
Content-Type: text/plain; charset=UTF-8

On Sunday, 12 June 2016 20:32:22 UTC+1, Arthur O'Dwyer wrote:
>
> I found the docs for Boost.Switch
> <http://dancinghacker.com/switch/boost_switch/switch_.html>. If I get the
> time, I'll try to write up a modern library implementation of the above
> make_switch and post it here. I'm sure it's been done before, of course,
> so if someone beats me to it that's great.
>

Too many times to count, I'm sure! I decided to take another go at it,
trying to conform to the Boost.Switch interface but using modern
techniques, using only the standard library and Boost.Preprocessor for
iteration. My implementation is a little under 60 lines:
https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7

#define SWITCH_CASE(Z,N,_) \
  case std::tuple_element_t<N, std::tuple<std::integral_constant<T, C
>...>>{} : \
    return std::forward<F>(f)( \
      std::tuple_element_t<N, std::tuple<std::integral_constant<T, C
>...>>{}); \
    //
#define SWITCH_SPECIALIZATION(Z,N,_) \
template<class T, T... C, class F> \
struct Switch<N, std::integer_sequence<T, C...>, F> { \
  using R = std::common_type_t<std::result_of_t<F(std::integral_constant<T,
C>)>...>; \
  R operator()(T t, F&& f) { \
    switch(t) { BOOST_PP_REPEAT_ ## Z(N, SWITCH_CASE, nil) } \
  } \
  /* ... */ \
};
BOOST_PP_REPEAT(SWITCH_MAX, SWITCH_SPECIALIZATION, nil)

Much of the effort is in handling the return type from the default case if
provided; it'd be a lot easier if noreturn was part of the type system or
we had a true bottom type.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/62812f9c-7c4e-4a97-86a3-aee457c9f4a9%40isocpp.org.

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

<div dir=3D"ltr">On Sunday, 12 June 2016 20:32:22 UTC+1, Arthur O&#39;Dwyer=
  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=
<div class=3D"gmail_quote"><div>I found <a href=3D"http://dancinghacker.com=
/switch/boost_switch/switch_.html" target=3D"_blank" rel=3D"nofollow" onmou=
sedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fdanc=
inghacker.com%2Fswitch%2Fboost_switch%2Fswitch_.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNGl9dwdGRJ8eSNXsEz2k4IY3y4l8g&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fdancinghac=
ker.com%2Fswitch%2Fboost_switch%2Fswitch_.html\x26sa\x3dD\x26sntz\x3d1\x26u=
sg\x3dAFQjCNGl9dwdGRJ8eSNXsEz2k4IY3y4l8g&#39;;return true;">the docs for Bo=
ost.Switch</a>. If I get the time, I&#39;ll try to write up a modern librar=
y implementation of the above <font face=3D"monospace, monospace">make_swit=
ch</font>=C2=A0and post it here. I&#39;m sure it&#39;s been done before, of=
 course, so if someone beats me to it that&#39;s great.</div></div></div></=
div></blockquote><div><br></div><div>Too many times to count, I&#39;m sure!=
 I decided to take another go at it, trying to conform to the Boost.Switch =
interface but using modern techniques, using only the standard library and =
Boost.Preprocessor for iteration. My implementation is a little under 60 li=
nes:=C2=A0<a href=3D"https://gist.github.com/ecatmur/7f5f8b44e70f414742e4ea=
e1efdd0ca7">https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca=
7</a>=C2=A0</div><div><br></div><div><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> SWITCH_CASE</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">Z</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">N</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">_</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">\</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">case</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">tuple_element_t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">N</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">integral_constan=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;...&gt;&gt;{}</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forw=
ard</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">)(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">tuple_element_t</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">N</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tuple</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">integral_constant</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> C</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;...&gt;&gt;{});</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </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>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">//</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>#define</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> S=
WITCH_SPECIALIZATION</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>Z</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">N</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">_</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><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><span style=3D"color: #008;" class=3D"styled-by-prettify">class</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> C</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> F</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">Switch</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">N</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</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">integer_sequence<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">...&gt;,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</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">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">\</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">using</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> R </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">common_type_t</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">result_of_t</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">F</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">integral_constant</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> C</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;)&gt;...&gt;;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 R </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">operator</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">()(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">T t</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </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>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">switch</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> BOOST_PP_REPEAT_ </span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">## Z(N, SWITCH_CASE, nil) =
} \</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">/* ... */</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>BOOST_PP_REPEAT</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">SWITCH_MAX</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> SWITCH_SPECIALIZATION</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">nil</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div><div><br></div>Much of the effort is in handling the return type f=
rom the default case if provided; it&#39;d be a lot easier if noreturn was =
part of the type system or we had a true bottom type.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/62812f9c-7c4e-4a97-86a3-aee457c9f4a9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/62812f9c-7c4e-4a97-86a3-aee457c9f4a9=
%40isocpp.org</a>.<br />

------=_Part_3805_451590462.1465780672747--

------=_Part_3804_761039642.1465780672746--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sun, 12 Jun 2016 20:11:42 -0700
Raw View
--001a113f2d4074057d0535203fac
Content-Type: text/plain; charset=UTF-8

On Sun, Jun 12, 2016 at 6:17 PM, Edward Catmur <ed@catmur.co.uk> wrote:

> On Sunday, 12 June 2016 20:32:22 UTC+1, Arthur O'Dwyer wrote:
>>
>> I found the docs for Boost.Switch
>> <http://dancinghacker.com/switch/boost_switch/switch_.html>. If I get
>> the time, I'll try to write up a modern library implementation of the above
>> make_switch and post it here. I'm sure it's been done before, of course,
>> so if someone beats me to it that's great.
>>
>
> Too many times to count, I'm sure! I decided to take another go at it,
> trying to conform to the Boost.Switch interface but using modern
> techniques, using only the standard library and Boost.Preprocessor for
> iteration. My implementation is a little under 60 lines:
> https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7
>
> #define SWITCH_CASE(Z,N,_) \
>   case std::tuple_element_t<N, std::tuple<std::integral_constant<T, C
> >...>>{} : \
>     return std::forward<F>(f)( \
>       std::tuple_element_t<N, std::tuple<std::integral_constant<T, C
> >...>>{}); \
>     //
> #define SWITCH_SPECIALIZATION(Z,N,_) \
> template<class T, T... C, class F> \
> struct Switch<N, std::integer_sequence<T, C...>, F> { \
>   using R = std::common_type_t<std::result_of_t<F(std::integral_constant<T
> , C>)>...>; \
>   R operator()(T t, F&& f) { \
>     switch(t) { BOOST_PP_REPEAT_ ## Z(N, SWITCH_CASE, nil) } \
>   } \
>   /* ... */ \
> };
> BOOST_PP_REPEAT(SWITCH_MAX, SWITCH_SPECIALIZATION, nil)
>
> Much of the effort is in handling the return type from the default case if
> provided; it'd be a lot easier if noreturn was part of the type system or
> we had a true bottom type.
>

Interesting!  My implementation ended up at twice the length of yours, but
IMHO has a nicer user interface than Boost.Switch.

https://gist.github.com/Quuxplusone/3f7100f72551f6a7028844b298c43508

The "apply" example in my case looks like this: extra boilerplate to deal
with making index sequences, but the tradeoff is that my interface allows
you to switch on things that aren't consecutive integers.
The other tradeoff is that my Clang isn't smart enough to turn this into a
switch. It will go as far as inlining everything into an if-else chain (no
function calls), but it won't make a jump table. Yes, this kind of defeats
the purpose; but I'm holding out hope that it's a Quality of Implementation
issue rather than a fundamental flaw.

template<class... V, class F>
auto apply(VariantPtr<V...> p, F&& f) {
    return detail_apply_(p, std::forward<F>(f),
std::make_index_sequence<sizeof...(V)>{});
}

template<class... V, class F, size_t... Is>
auto detail_apply_(VariantPtr<V...> p, F&& f, std::index_sequence<Is...>) {
    return xstd::switch_on(p.idx,
        xstd::make_switch_case(Is, [&](){
            using elt_type = std::tuple_element_t<Is, std::tuple<V...>>;
            return std::forward<F>(f)(static_cast<elt_type*>(p.data));
        })...
    );
}


Your "enum to integer" example looks like this, which I admit isn't an
improvement on the status quo syntactically, but I'm fine with that. The
"enum to integer" example in your gist doesn't compile on my Clang because
it is trying to instantiate std::integer_sequence<E, ...> where E (being an
enum) is not an integral type; I think you have to add some boilerplate
involving std::conditional_t<std::is_enum_v<E>, std::underlying_type_t<E>,
E> and some explicit casts, at which point it doesn't even seem worth it
anymore. Having to create an entity of the form foo<..., E::A, E::B,
E::C> should
have been a red flag anyway, IMHO.


enum class E { A, B, C = 5 };

template<class E, E... Es>
int integer_value_of(E e) {
    return xstd::switch_on(e,
        xstd::make_switch_case(Es, []() { return int(Es); })...
    );
}

int f(E e) {
    return integer_value_of<E, E::A, E::B, E::C>(e);  // what's even the
point?
}

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LsL5QR9hyC_AGzGEfOuo34AMCt0gFCghtfDJ5%2Beg6nzw%40mail.gmail.com.

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

<div dir=3D"ltr"><div>On Sun, Jun 12, 2016 at 6:17 PM, Edward Catmur <span =
dir=3D"ltr">&lt;<a href=3D"mailto:ed@catmur.co.uk" target=3D"_blank">ed@cat=
mur.co.uk</a>&gt;</span> wrote:<br></div><div class=3D"gmail_extra"><div cl=
ass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);borde=
r-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On S=
unday, 12 June 2016 20:32:22 UTC+1, Arthur O&#39;Dwyer  wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1p=
x;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1=
ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>I found <a href=
=3D"http://dancinghacker.com/switch/boost_switch/switch_.html" rel=3D"nofol=
low" target=3D"_blank">the docs for Boost.Switch</a>. If I get the time, I&=
#39;ll try to write up a modern library implementation of the above <font f=
ace=3D"monospace, monospace">make_switch</font>=C2=A0and post it here. I&#3=
9;m sure it&#39;s been done before, of course, so if someone beats me to it=
 that&#39;s great.</div></div></div></div></blockquote><div><br></div></spa=
n><div>Too many times to count, I&#39;m sure! I decided to take another go =
at it, trying to conform to the Boost.Switch interface but using modern tec=
hniques, using only the standard library and Boost.Preprocessor for iterati=
on. My implementation is a little under 60 lines:=C2=A0<a href=3D"https://g=
ist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7" target=3D"_blank">=
https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7</a>=C2=A0<=
/div><div><br></div><div><div style=3D"background-color:rgb(250,250,250);bo=
rder:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span styl=
e=3D"color:rgb(136,0,0)">#define</span><span style=3D"color:rgb(0,0,0)"> SW=
ITCH_CASE</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D=
"color:rgb(0,0,0)">Z</span><span style=3D"color:rgb(102,102,0)">,</span><sp=
an style=3D"color:rgb(0,0,0)">N</span><span style=3D"color:rgb(102,102,0)">=
,</span><span style=3D"color:rgb(0,0,0)">_</span><span style=3D"color:rgb(1=
02,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(102,102,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 <=
/span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:rg=
b(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span st=
yle=3D"color:rgb(0,0,0)">tuple_element_t</span><span style=3D"color:rgb(102=
,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">N</span><span style=3D=
"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> std</span>=
<span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,=
0)">tuple</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</sp=
an><span style=3D"color:rgb(0,0,0)">integral_constant</span><span style=3D"=
color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">T</span><=
span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)=
"> C</span><span style=3D"color:rgb(102,102,0)">&gt;...&gt;&gt;{}</span><sp=
an style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=
:</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb(=
0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span styl=
e=3D"color:rgb(0,0,0)">forward</span><span style=3D"color:rgb(102,102,0)">&=
lt;</span><span style=3D"color:rgb(0,0,0)">F</span><span style=3D"color:rgb=
(102,102,0)">&gt;(</span><span style=3D"color:rgb(0,0,0)">f</span><span sty=
le=3D"color:rgb(102,102,0)">)(</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(102,102,0)">\</span><span style=3D"color:rgb(0,=
0,0)"><br>=C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0=
)">::</span><span style=3D"color:rgb(0,0,0)">tuple_element_t</span><span st=
yle=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">N<=
/span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb=
(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span sty=
le=3D"color:rgb(0,0,0)">tuple</span><span style=3D"color:rgb(102,102,0)">&l=
t;</span><span style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rg=
b(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">integral_constant</=
span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:r=
gb(0,0,0)">T</span><span style=3D"color:rgb(102,102,0)">,</span><span style=
=3D"color:rgb(0,0,0)"> C</span><span style=3D"color:rgb(102,102,0)">&gt;...=
&gt;&gt;{});</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(102,102,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(136,0,0)">//</span><span style=3D"co=
lor:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">#define</span=
><span style=3D"color:rgb(0,0,0)"> SWITCH_SPECIALIZATION</span><span style=
=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">Z</span>=
<span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0=
)">N</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"colo=
r:rgb(0,0,0)">_</span><span style=3D"color:rgb(102,102,0)">)</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">\</sp=
an><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0=
,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span=
 style=3D"color:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)">=
 T</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:=
rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">...</span><span s=
tyle=3D"color:rgb(0,0,0)"> C</span><span style=3D"color:rgb(102,102,0)">,</=
span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,=
136)">class</span><span style=3D"color:rgb(0,0,0)"> F</span><span style=3D"=
color:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"> </span><=
span style=3D"color:rgb(102,102,0)">\</span><span style=3D"color:rgb(0,0,0)=
"><br></span><span style=3D"color:rgb(0,0,136)">struct</span><span style=3D=
"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Switch</spa=
n><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(=
0,0,0)">N</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D=
"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span=
><span style=3D"color:rgb(0,0,0)">integer_sequence</span><span style=3D"col=
or:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">T</span><spa=
n style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> =
C</span><span style=3D"color:rgb(102,102,0)">...&gt;,</span><span style=3D"=
color:rgb(0,0,0)"> F</span><span style=3D"color:rgb(102,102,0)">&gt;</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0=
)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(102,102,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><s=
pan style=3D"color:rgb(0,0,136)">using</span><span style=3D"color:rgb(0,0,0=
)"> R </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"=
color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span>=
<span style=3D"color:rgb(0,0,0)">common_type_t</span><span style=3D"color:r=
gb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">std</span><span =
style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">re=
sult_of_t</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
=3D"color:rgb(0,0,0)">F</span><span style=3D"color:rgb(102,102,0)">(</span>=
<span style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102=
,0)">::</span><span style=3D"color:rgb(0,0,0)">integral_constant</span><spa=
n style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)=
">T</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color=
:rgb(0,0,0)"> C</span><span style=3D"color:rgb(102,102,0)">&gt;)&gt;...&gt;=
;</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 R </span><sp=
an style=3D"color:rgb(0,0,136)">operator</span><span style=3D"color:rgb(102=
,102,0)">()(</span><span style=3D"color:rgb(0,0,0)">T t</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> F</span=
><span style=3D"color:rgb(102,102,0)">&amp;&amp;</span><span style=3D"color=
:rgb(0,0,0)"> f</span><span style=3D"color:rgb(102,102,0)">)</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,10=
2,0)">\</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(0,0,136)">switch</span><span style=3D"color:rgb(102,1=
02,0)">(</span><span style=3D"color:rgb(0,0,0)">t</span><span style=3D"colo=
r:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> BOOS=
T_PP_REPEAT_ </span><span style=3D"color:rgb(136,0,0)">## Z(N, SWITCH_CASE,=
 nil) } \</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span st=
yle=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(102,102,0)">\</span><span style=3D"color:rgb(0,=
0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(136,0,0)">/* ... */</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0=
)">\</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color=
:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br>BOOST_PP_REP=
EAT</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color=
:rgb(0,0,0)">SWITCH_MAX</span><span style=3D"color:rgb(102,102,0)">,</span>=
<span style=3D"color:rgb(0,0,0)"> SWITCH_SPECIALIZATION</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(0,0,136)">nil</span><span style=3D"color:rgb(102,1=
02,0)">)</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></d=
iv><div><br></div>Much of the effort is in handling the return type from th=
e default case if provided; it&#39;d be a lot easier if noreturn was part o=
f the type system or we had a true bottom type.</div></div></blockquote><di=
v><br></div>Interesting!=C2=A0 My implementation ended up at twice the leng=
th of yours, but IMHO has a nicer user interface than Boost.Switch.<div><br=
></div><div><a href=3D"https://gist.github.com/Quuxplusone/3f7100f72551f6a7=
028844b298c43508">https://gist.github.com/Quuxplusone/3f7100f72551f6a702884=
4b298c43508<br></a></div><div><br></div><div>The &quot;apply&quot; example =
in my case looks like this: extra boilerplate to deal with making index seq=
uences, but the tradeoff is that my interface allows you to switch on thing=
s that aren&#39;t consecutive integers.</div><div>The other tradeoff is tha=
t my Clang isn&#39;t smart enough to turn this into a switch. It will go as=
 far as inlining everything into an if-else chain (no function calls), but =
it won&#39;t make a jump table. Yes, this kind of defeats the purpose; but =
I&#39;m holding out hope that it&#39;s a Quality of Implementation issue ra=
ther than a fundamental flaw.</div><div><br></div><div><font face=3D"monosp=
ace, monospace">template&lt;class... V, class F&gt;<br>auto apply(VariantPt=
r&lt;V...&gt; p, F&amp;&amp; f) {<br>=C2=A0 =C2=A0 return detail_apply_(p, =
std::forward&lt;F&gt;(f), std::make_index_sequence&lt;sizeof...(V)&gt;{});<=
br>}<br><br>template&lt;class... V, class F, size_t... Is&gt;<br>auto detai=
l_apply_(VariantPtr&lt;V...&gt; p, F&amp;&amp; f, std::index_sequence&lt;Is=
....&gt;) {<br>=C2=A0 =C2=A0 return xstd::switch_on(p.idx,<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 xstd::make_switch_case(Is, [&amp;](){<br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 using elt_type =3D std::tuple_element_t&lt;Is, std::t=
uple&lt;V...&gt;&gt;;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s=
td::forward&lt;F&gt;(f)(static_cast&lt;elt_type*&gt;(p.data));<br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 })...<br>=C2=A0 =C2=A0 );<br>}</font><p style=3D"margi=
n:0px;font-size:17px;line-height:normal;font-family:Menlo"><br></p>Your &qu=
ot;enum to integer&quot; example looks like this, which I admit isn&#39;t a=
n improvement on the status quo syntactically, but I&#39;m fine with that. =
The &quot;enum to integer&quot; example in your gist doesn&#39;t compile on=
 my Clang because it is trying to instantiate=C2=A0<font face=3D"monospace,=
 monospace">std::integer_sequence&lt;E, ...&gt;</font>=C2=A0where=C2=A0<fon=
t face=3D"monospace, monospace">E</font>=C2=A0(being an enum) is not an int=
egral type; I think you have to add some boilerplate involving=C2=A0<font f=
ace=3D"monospace, monospace">std::conditional_t&lt;std::is_enum_v&lt;E&gt;,=
 std::underlying_type_t&lt;E&gt;, E&gt;</font>=C2=A0and some explicit casts=
, at which point it doesn&#39;t even seem worth it anymore. Having to creat=
e an entity of the form=C2=A0<font face=3D"monospace, monospace">foo&lt;...=
, E::A, E::B, E::C&gt;</font>=C2=A0should have been a red flag anyway, IMHO=
..<p style=3D"margin:0px;font-size:17px;line-height:normal;font-family:Menlo=
"><br></p><font face=3D"monospace, monospace">enum class E { A, B, C =3D 5 =
};<br><br>template&lt;class E, E... Es&gt;<br>int integer_value_of(E e) {<b=
r>=C2=A0 =C2=A0 return xstd::switch_on(e,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 xs=
td::make_switch_case(Es, []() { return int(Es); })...<br>=C2=A0 =C2=A0 );<b=
r>}<br><br>int f(E e) {<br>=C2=A0 =C2=A0 return integer_value_of&lt;E, E::A=
, E::B, E::C&gt;(e); =C2=A0// what&#39;s even the point?<br>}</font></div><=
div><br></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0LsL5QR9hyC_AGzGEfOuo34AMCt0gFC=
ghtfDJ5%2Beg6nzw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LsL5QR9h=
yC_AGzGEfOuo34AMCt0gFCghtfDJ5%2Beg6nzw%40mail.gmail.com</a>.<br />

--001a113f2d4074057d0535203fac--

.


Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Mon, 13 Jun 2016 02:33:25 -0700 (PDT)
Raw View
------=_Part_131_1998868029.1465810405949
Content-Type: multipart/alternative;
 boundary="----=_Part_132_383559435.1465810405949"

------=_Part_132_383559435.1465810405949
Content-Type: text/plain; charset=UTF-8

On Sunday, June 12, 2016 at 11:25:50 AM UTC+1, Ville Voutilainen wrote:
>
> On 12 June 2016 at 13:23,  <inkwizyt...@gmail.com <javascript:>> wrote:
> > This code should be fast as manually written switch, it would be trivial
> for
> > compiler to create jump table to have best performance.
>
>
> I'm sure the open-source compilers will happily accept an extension
> patch that shows how trivial it is.
>

For what is worth, you can abuse GCC statement expressions plus variadics
to get variadic expansion of switch statements. Although 'case' in
statement expressions is explicitly documented not to be supported, it does
work in practice (nothing I would use in production of course).

So, while I wouldn't call it trivial, it seems to me that it souldn't be
too hard to implement the extension in GCC, and you could even consider
statement expressions as existing practice.

-- gpd

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/55892254-d646-4cc3-b10c-a0f0a5eb665c%40isocpp.org.

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

<div dir=3D"ltr">On Sunday, June 12, 2016 at 11:25:50 AM UTC+1, Ville Vouti=
lainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 12 June 2016 a=
t 13:23, =C2=A0&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated=
-mailto=3D"B0T3BgNpAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;">inkwizyt...@gmail.com</a>&gt; wrote:
<br>&gt; This code should be fast as manually written switch, it would be t=
rivial for
<br>&gt; compiler to create jump table to have best performance.
<br>
<br>
<br>I&#39;m sure the open-source compilers will happily accept an extension
<br>patch that shows how trivial it is.
<br></blockquote><div><br>For what is worth, you can abuse GCC statement ex=
pressions plus variadics to get variadic expansion of switch statements. Al=
though &#39;case&#39; in statement expressions is explicitly documented not=
 to be supported, it does work in practice (nothing I would use in producti=
on of course).<br><br>So, while I wouldn&#39;t call it trivial, it seems to=
 me that it souldn&#39;t be too hard to implement the extension in GCC, and=
 you could even consider statement expressions as existing practice.<br><br=
>-- gpd<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/55892254-d646-4cc3-b10c-a0f0a5eb665c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/55892254-d646-4cc3-b10c-a0f0a5eb665c=
%40isocpp.org</a>.<br />

------=_Part_132_383559435.1465810405949--

------=_Part_131_1998868029.1465810405949--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 13 Jun 2016 15:14:18 +0100
Raw View
--001a11479a861893ea05352981a7
Content-Type: text/plain; charset=UTF-8

On Mon, Jun 13, 2016 at 10:33 AM, Giovanni Piero Deretta <
gpderetta@gmail.com> wrote:

> On Sunday, June 12, 2016 at 11:25:50 AM UTC+1, Ville Voutilainen wrote:
>>
>> On 12 June 2016 at 13:23,  <inkwizyt...@gmail.com> wrote:
>> > This code should be fast as manually written switch, it would be
>> trivial for
>> > compiler to create jump table to have best performance.
>>
>>
>> I'm sure the open-source compilers will happily accept an extension
>> patch that shows how trivial it is.
>>
>
> For what is worth, you can abuse GCC statement expressions plus variadics
> to get variadic expansion of switch statements. Although 'case' in
> statement expressions is explicitly documented not to be supported, it does
> work in practice (nothing I would use in production of course).
>

That's amazing! I couldn't get it to work in any version after 4.9.2,
though; is there a trick I'm missing?

  switch (i) {
    ([](...){})(({ case I : g<I>(), ({ return; }), 0; })... );
  }


> So, while I wouldn't call it trivial, it seems to me that it souldn't be
> too hard to implement the extension in GCC, and you could even consider
> statement expressions as existing practice.
>

Absolutely; it'd be a nice hack to work on.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdObbLAvViULXGAq%3DR7oP%2B%2BY5%2BWHNKu0C2BapoZwDXLnR4A%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jun 13, 2016 at 10:33 AM, Giovanni Piero Deretta <span dir=3D"ltr">&lt;=
<a href=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.co=
m</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204=
);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">On Sunday, Jun=
e 12, 2016 at 11:25:50 AM UTC+1, Ville Voutilainen wrote:<span class=3D""><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex">On 12 June 2016 at 13:23, =C2=A0&lt;<a rel=3D"nofollow">ink=
wizyt...@gmail.com</a>&gt; wrote:
<br>&gt; This code should be fast as manually written switch, it would be t=
rivial for
<br>&gt; compiler to create jump table to have best performance.
<br>
<br>
<br>I&#39;m sure the open-source compilers will happily accept an extension
<br>patch that shows how trivial it is.
<br></blockquote></span><div><br>For what is worth, you can abuse GCC state=
ment expressions plus variadics to get variadic expansion of switch stateme=
nts. Although &#39;case&#39; in statement expressions is explicitly documen=
ted not to be supported, it does work in practice (nothing I would use in p=
roduction of course).<br></div></div></blockquote><div><br></div><div>That&=
#39;s amazing! I couldn&#39;t get it to work in any version after 4.9.2, th=
ough; is there a trick I&#39;m missing?</div><div><br></div><div><div><font=
 face=3D"monospace, monospace">=C2=A0 switch (i) {</font></div><div><font f=
ace=3D"monospace, monospace">=C2=A0 =C2=A0 ([](...){})(({ case I : g&lt;I&g=
t;(), ({ return; }), 0; })... );</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 }</font></div></div><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><di=
v dir=3D"ltr"><div>So, while I wouldn&#39;t call it trivial, it seems to me=
 that it souldn&#39;t be too hard to implement the extension in GCC, and yo=
u could even consider statement expressions as existing practice.<br></div>=
</div></blockquote><div><br></div><div>Absolutely; it&#39;d be a nice hack =
to work on.</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnLdObbLAvViULXGAq%3DR7oP%2B%2BY5%2=
BWHNKu0C2BapoZwDXLnR4A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdObb=
LAvViULXGAq%3DR7oP%2B%2BY5%2BWHNKu0C2BapoZwDXLnR4A%40mail.gmail.com</a>.<br=
 />

--001a11479a861893ea05352981a7--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 13 Jun 2016 15:32:28 +0100
Raw View
--001a114f3f7c0d9d67053529c215
Content-Type: text/plain; charset=UTF-8

On Mon, Jun 13, 2016 at 4:11 AM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> On Sun, Jun 12, 2016 at 6:17 PM, Edward Catmur <ed@catmur.co.uk> wrote:
>
>> On Sunday, 12 June 2016 20:32:22 UTC+1, Arthur O'Dwyer wrote:
>>>
>>> I found the docs for Boost.Switch
>>> <http://dancinghacker.com/switch/boost_switch/switch_.html>. If I get
>>> the time, I'll try to write up a modern library implementation of the above
>>> make_switch and post it here. I'm sure it's been done before, of
>>> course, so if someone beats me to it that's great.
>>>
>>
>> Too many times to count, I'm sure! I decided to take another go at it,
>> trying to conform to the Boost.Switch interface but using modern
>> techniques, using only the standard library and Boost.Preprocessor for
>> iteration. My implementation is a little under 60 lines:
>> https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7
>>
>> Interesting!  My implementation ended up at twice the length of yours,
> but IMHO has a nicer user interface than Boost.Switch.
>
> https://gist.github.com/Quuxplusone/3f7100f72551f6a7028844b298c43508
>
> The "apply" example in my case looks like this: extra boilerplate to deal
> with making index sequences, but the tradeoff is that my interface allows
> you to switch on things that aren't consecutive integers.
>

Actually, mine can switch on any integer sequence; it uses the preprocessor
iteration over N to index into the integer sequence for the case label
constant (using std::tuple_element, since that's the only available
facility in the standard library for variadic indexing).

The other tradeoff is that my Clang isn't smart enough to turn this into a
> switch. It will go as far as inlining everything into an if-else chain (no
> function calls), but it won't make a jump table. Yes, this kind of defeats
> the purpose; but I'm holding out hope that it's a Quality of Implementation
> issue rather than a fundamental flaw.
>

Yes, it's a bit disappointing that the free compilers are unable to turn a
recursive if chain into a jump table. Using a syntactic switch has other
benefits, though; it allows the compiler to automatically detect repeated
cases, and also to detect omitted cases where the controlling type is an
enum.


> The "enum to integer" example in your gist doesn't compile on my Clang
> because it is trying to instantiate std::integer_sequence<E, ...> where E (being
> an enum) is not an integral type; I think you have to add some boilerplate
> involving std::conditional_t<std::is_enum_v<E>,
> std::underlying_type_t<E>, E> and some explicit casts, at which point it
> doesn't even seem worth it anymore.
>

Hm. Clang works fine for me in versions 3.5 upward in -std=c++14 mode.


> Having to create an entity of the form foo<..., E::A, E::B, E::C> should
> have been a red flag anyway, IMHO.
>

That sequence would usually be provided by an introspection library
(BetterEnums, or whatever SG7 are up to these days), or by a code
generator.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdOY4UaYaeVGWVzNa5kwM3P-Gw8P350n7ggVDjyOEHFrC2Q%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jun 13, 2016 at 4:11 AM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@g=
mail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><span class=3D""><div>On Sun, Jun 12, 2016 at 6:17 PM, Edward Catm=
ur <span dir=3D"ltr">&lt;<a href=3D"mailto:ed@catmur.co.uk" target=3D"_blan=
k">ed@catmur.co.uk</a>&gt;</span> wrote:<br></div></span><div class=3D"gmai=
l_extra"><div class=3D"gmail_quote"><span class=3D""><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div =
dir=3D"ltr"><span>On Sunday, 12 June 2016 20:32:22 UTC+1, Arthur O&#39;Dwye=
r  wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
<div>I found <a href=3D"http://dancinghacker.com/switch/boost_switch/switch=
_.html" rel=3D"nofollow" target=3D"_blank">the docs for Boost.Switch</a>. I=
f I get the time, I&#39;ll try to write up a modern library implementation =
of the above <font face=3D"monospace, monospace">make_switch</font>=C2=A0an=
d post it here. I&#39;m sure it&#39;s been done before, of course, so if so=
meone beats me to it that&#39;s great.</div></div></div></div></blockquote>=
<div><br></div></span><div>Too many times to count, I&#39;m sure! I decided=
 to take another go at it, trying to conform to the Boost.Switch interface =
but using modern techniques, using only the standard library and Boost.Prep=
rocessor for iteration. My implementation is a little under 60 lines:=C2=A0=
<a href=3D"https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae1efdd0ca7=
" target=3D"_blank">https://gist.github.com/ecatmur/7f5f8b44e70f414742e4eae=
1efdd0ca7</a>=C2=A0</div><div><br></div></div></blockquote></span>Interesti=
ng!=C2=A0 My implementation ended up at twice the length of yours, but IMHO=
 has a nicer user interface than Boost.Switch.<div><br></div><div><a href=
=3D"https://gist.github.com/Quuxplusone/3f7100f72551f6a7028844b298c43508" t=
arget=3D"_blank">https://gist.github.com/Quuxplusone/3f7100f72551f6a7028844=
b298c43508<br></a></div><div><br></div><div>The &quot;apply&quot; example i=
n my case looks like this: extra boilerplate to deal with making index sequ=
ences, but the tradeoff is that my interface allows you to switch on things=
 that aren&#39;t consecutive integers.</div></div></div></div></blockquote>=
<div><br></div><div>Actually, mine can switch on any integer sequence; it u=
ses the preprocessor iteration over N to index into the integer sequence fo=
r the case label constant (using std::tuple_element, since that&#39;s the o=
nly available facility in the standard library for variadic indexing).</div=
><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>The other tradeoff is that=
 my Clang isn&#39;t smart enough to turn this into a switch. It will go as =
far as inlining everything into an if-else chain (no function calls), but i=
t won&#39;t make a jump table. Yes, this kind of defeats the purpose; but I=
&#39;m holding out hope that it&#39;s a Quality of Implementation issue rat=
her than a fundamental flaw.</div></div></div></div></blockquote><div><br><=
/div><div>Yes, it&#39;s a bit disappointing that the free compilers are una=
ble to turn a recursive if chain into a jump table. Using a syntactic switc=
h has other benefits, though; it allows the compiler to automatically detec=
t repeated cases, and also to detect omitted cases where the controlling ty=
pe is an enum.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div></div>=
<div>The &quot;enum to integer&quot; example in your gist doesn&#39;t compi=
le on my Clang because it is trying to instantiate=C2=A0<font face=3D"monos=
pace, monospace">std::integer_sequence&lt;E, ...&gt;</font>=C2=A0where=C2=
=A0<font face=3D"monospace, monospace">E</font>=C2=A0(being an enum) is not=
 an integral type; I think you have to add some boilerplate involving=C2=A0=
<font face=3D"monospace, monospace">std::conditional_t&lt;std::is_enum_v&lt=
;E&gt;, std::underlying_type_t&lt;E&gt;, E&gt;</font>=C2=A0and some explici=
t casts, at which point it doesn&#39;t even seem worth it anymore. </div></=
div></div></div></blockquote><div><br></div><div>Hm. Clang works fine for m=
e in versions 3.5 upward in -std=3Dc++14 mode.</div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div c=
lass=3D"gmail_quote"><div>Having to create an entity of the form=C2=A0<font=
 face=3D"monospace, monospace">foo&lt;..., E::A, E::B, E::C&gt;</font>=C2=
=A0should have been a red flag anyway, IMHO.</div></div></div></div></block=
quote><div><br></div><div>That sequence would usually be provided by an int=
rospection library (BetterEnums, or whatever SG7 are up to these days), or =
by a code generator.=C2=A0</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnLdOY4UaYaeVGWVzNa5kwM3P-Gw8P350n7=
ggVDjyOEHFrC2Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdOY4UaYaeVGW=
VzNa5kwM3P-Gw8P350n7ggVDjyOEHFrC2Q%40mail.gmail.com</a>.<br />

--001a114f3f7c0d9d67053529c215--

.


Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Mon, 13 Jun 2016 16:43:07 +0100
Raw View
--001a114110aeb634ed05352abef7
Content-Type: text/plain; charset=UTF-8

On 13 Jun 2016 3:14 p.m., "'Edward Catmur' via ISO C++ Standard - Future
Proposals" <std-proposals@isocpp.org> wrote:
>
> On Mon, Jun 13, 2016 at 10:33 AM, Giovanni Piero Deretta <
gpderetta@gmail.com> wrote:
>>
>> On Sunday, June 12, 2016 at 11:25:50 AM UTC+1, Ville Voutilainen wrote:
>>>
>>> On 12 June 2016 at 13:23,  <inkwizyt...@gmail.com> wrote:
>>> > This code should be fast as manually written switch, it would be
trivial for
>>> > compiler to create jump table to have best performance.
>>>
>>>
>>> I'm sure the open-source compilers will happily accept an extension
>>> patch that shows how trivial it is.
>>
>>
>> For what is worth, you can abuse GCC statement expressions plus
variadics to get variadic expansion of switch statements. Although 'case'
in statement expressions is explicitly documented not to be supported, it
does work in practice (nothing I would use in production of course).
>
>
> That's amazing! I couldn't get it to work in any version after 4.9.2,
though; is there a trick I'm missing?
>
>   switch (i) {
>     ([](...){})(({ case I : g<I>(), ({ return; }), 0; })... );
>   }
>

It's been a while; I remember not needing the lambda but I had to split the
line in multiple separate statement expressions. It did require a lot of
trials and errors to find a formulation that GCC would accept. I remember
never getting rerun to work (only break).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAL52AasrsDg2dfZxA8pcRiG%2BE38zy%3DL9%3DpQi0dy638niRxXLDg%40mail.gmail.com.

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

<p dir=3D"ltr"><br>
On 13 Jun 2016 3:14 p.m., &quot;&#39;Edward Catmur&#39; via ISO C++ Standar=
d - Future Proposals&quot; &lt;<a href=3D"mailto:std-proposals@isocpp.org">=
std-proposals@isocpp.org</a>&gt; wrote:<br>
&gt;<br>
&gt; On Mon, Jun 13, 2016 at 10:33 AM, Giovanni Piero Deretta &lt;<a href=
=3D"mailto:gpderetta@gmail.com">gpderetta@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Sunday, June 12, 2016 at 11:25:50 AM UTC+1, Ville Voutilainen w=
rote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On 12 June 2016 at 13:23, =C2=A0&lt;<a href=3D"mailto:inkwizyt=
....@gmail.com">inkwizyt...@gmail.com</a>&gt; wrote: <br>
&gt;&gt;&gt; &gt; This code should be fast as manually written switch, it w=
ould be trivial for <br>
&gt;&gt;&gt; &gt; compiler to create jump table to have best performance. <=
br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I&#39;m sure the open-source compilers will happily accept an =
extension <br>
&gt;&gt;&gt; patch that shows how trivial it is. <br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; For what is worth, you can abuse GCC statement expressions plus va=
riadics to get variadic expansion of switch statements. Although &#39;case&=
#39; in statement expressions is explicitly documented not to be supported,=
 it does work in practice (nothing I would use in production of course).<br=
>
&gt;<br>
&gt;<br>
&gt; That&#39;s amazing! I couldn&#39;t get it to work in any version after=
 4.9.2, though; is there a trick I&#39;m missing?<br>
&gt;<br>
&gt; =C2=A0 switch (i) {<br>
&gt; =C2=A0 =C2=A0 ([](...){})(({ case I : g&lt;I&gt;(), ({ return; }), 0; =
})... );<br>
&gt; =C2=A0 }<br>
&gt; =C2=A0</p>
<p dir=3D"ltr">It&#39;s been a while; I remember not needing the lambda but=
 I had to split the line in multiple separate statement expressions. It did=
 require a lot of trials and errors to find a formulation that GCC would ac=
cept. I remember never getting rerun to work (only break).<br>
</p>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAL52AasrsDg2dfZxA8pcRiG%2BE38zy%3DL9=
%3DpQi0dy638niRxXLDg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAL52AasrsD=
g2dfZxA8pcRiG%2BE38zy%3DL9%3DpQi0dy638niRxXLDg%40mail.gmail.com</a>.<br />

--001a114110aeb634ed05352abef7--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Mon, 13 Jun 2016 10:56:47 -0700 (PDT)
Raw View
------=_Part_522_172920184.1465840607875
Content-Type: multipart/alternative;
 boundary="----=_Part_523_718919558.1465840607876"

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

=D1=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
>  I think that `for constexpr` should be allowed to extracting parameters=
=20
> from templates, some thing like that:
> using type =3D std::tuple<int, long long, char>;
>
> int main()
> {
>     for constexpr (typename T : type) //without `...`
>     {
>         f<T>();
>     } //equal: `f<int>(); f<long long>(); f<char>();`
> }
>
>
Am I right tha the main and only reason you would like to grab template=20
parameters with 'for constexpr' is to have type list outside of template?
=20

> This will allow usage outside of template function and simplify complex=
=20
> operation:
> template<typename T>
> using MetaFunc =3D std::tuple<int, T, T, char>;
>
>
> int main()
> {
>     for constexpr (typename T : MetaFunc<long>)
>     {
>         f<T>();
>     } //equal: `f<int>(); f<long>(); f<long>(); f<char>();`
>     for constexpr (typename T : MetaFunc<char>)
>     {
>         for constexpr (typename TT : MetaFunc<T>)
>         {
>            g<T,TT>();
>         }
>     }
> }
>
>
>  I see one issue with this example. Your MetaFunc is template typedef and=
=20
instead of iteraating over single element list you are iterating through  4=
=20
elements list since you are grabbing parameters of type mapped my template=
=20
typedef but not parameters of teemplate typedef itself. The simpliest way=
=20
to have list of types which is never can accidentally create some nonvoid=
=20
variable is template typedef std::void_t which can be implemented as

template<typename... T>
using void_t =3D void;

how the following loop should work then?

for constexpr (typename T: void_t<int8_t, int16_t, int32_t, int64_t>) {
    do_something();
}

My personal opinion on such feature: there should be separate syntax to=20
grab template parameters like

for constexpr (typename T: params_of<void_t<int8_t, int16_t, int32_t,=20
int64_t>>) {
    do_something();
}

but it require some extra work on how this should actually work. In D it's=
=20
possible to implement params_of in library code since it's possible to=20
typedef parameters pack and then use it when needed. The following C++ code=
=20
rewritten in D works as expected:

template<typename... L>
struct test {
    using params =3D L;
};

int main() {
    for constexpr (typename T, test<char, int>::params) {
        std::cout << sizeof(T) << std::endl;
    }
}

From my personal point of view this way to have typelist outside of=20
template is much better then grabbing parameters from some intermediate=20
template which is needed only to enlist types you need. This approach also=
=20
allows to have better of your MetaFunc template without issues I've=20
mentioned above.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1015518c-c0e4-4397-b946-df7834a2c3c0%40isocpp.or=
g.

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

<div dir=3D"ltr">=D1=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=
=8E=D0=BD=D1=8F 2016 =D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com =D0=BD=D0=
=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<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">=C2=A0I think that `for constexpr` should be allowed=
 to extracting parameters from templates, some thing like that:<br><div><di=
v 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><span =
style=3D"color:#008">using</span><span style=3D"color:#000"> type </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">tuple</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">int</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">long</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">long</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">char</span><span style=
=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br><br></span><span=
 style=3D"color:#008">int</span><span style=3D"color:#000"> main</span><spa=
n style=3D"color:#660">()</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">for</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">typena=
me</span><span style=3D"color:#000"> T </span><span style=3D"color:#660">:<=
/span><span style=3D"color:#000"> type</span><span style=3D"color:#660">)</=
span><span style=3D"color:#000"> </span><span style=3D"color:#800">//withou=
t `...`</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 f</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#000">T</span><span style=3D"color:#660">&gt;();</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#800">//equal: `f&lt;int=
&gt;(); f&lt;long long&gt;(); f&lt;char&gt;();`</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#660">}</span></div></code></div><br>=
</div></div></blockquote><div><br>Am I right tha the main and only reason y=
ou would like to grab template=20
parameters with &#39;for constexpr&#39; is to have type list outside of=20
template?<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr"><div>This will allow usage outside of template function and sim=
plify complex operation:<br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wra=
p:break-word"><code><div><span style=3D"color:#008">template</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><sp=
an style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">using</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">MetaFunc</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">tuple</span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">int</span><span style=3D"color:#660">,</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> T</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">char</span><span style=
=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br><br><br></span><=
span style=3D"color:#008">int</span><span style=3D"color:#000"> main</span>=
<span style=3D"color:#660">()</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">for</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">constexpr</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">(</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#000"> T </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Met=
aFunc</span><span style=3D"color:#080">&lt;long&gt;</span><span style=3D"co=
lor:#660">)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 f</span><span style=3D"color:#660">&lt;</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">&gt;();</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#800">//equal: `f&lt;=
int&gt;(); f&lt;long&gt;(); f&lt;long&gt;(); f&lt;char&gt;();`</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">fo=
r</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const=
expr</span><span style=3D"color:#000"> </span><span style=3D"color:#660">(<=
/span><span style=3D"color:#008">typename</span><span style=3D"color:#000">=
 T </span><span style=3D"color:#660">:</span><span style=3D"color:#000"> </=
span><span style=3D"color:#606">MetaFunc</span><span style=3D"color:#080">&=
lt;char&gt;</span><span style=3D"color:#660">)</span><span style=3D"color:#=
000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r:#008">for</span><span style=3D"color:#000"> </span><span style=3D"color:#=
008">constexpr</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#008">typename</span><span style=3D"co=
lor:#000"> TT </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#606">MetaFunc</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"colo=
r:#660">&gt;)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0g</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000">TT</span><span style=3D"color:#660">&gt=
;();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#660">}</span></div></code></div><br><br><=
/div></div></blockquote><div>=C2=A0I see one issue with this example. Your =
MetaFunc is template typedef and instead of iteraating over single element =
list you are iterating through=C2=A0 4 elements list since you are grabbing=
 parameters of type mapped my template typedef but not parameters of teempl=
ate typedef itself. The simpliest way to have list of types which is never =
can accidentally create some nonvoid variable is template typedef std::void=
_t which can be implemented as<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">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> T</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><span style=3D"color: #008;" class=3D"styled-by-prettify">using</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> void_t </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span></div></code></div><br>how the followi=
ng loop should work then?<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">for</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">constexpr</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> void_t</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">int8_t</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> int16_t</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> int32_t</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i=
nt64_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 do_someth=
ing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></di=
v><br>My personal opinion on such feature: there should be separate syntax =
to grab template parameters like<br><br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-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-prettify">for</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">type=
name</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> params_of</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">void_t</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">int8_t</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> int16_t</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> int32_t</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> int64_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&gt;&gt;)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0=
 do_something</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></=
code></div><br>but it require some extra work on how this should actually w=
ork. In D it&#39;s possible to implement params_of in library code since it=
&#39;s possible to typedef parameters pack and then use it when needed. The=
 following C++ code rewritten in D works as expected:<br><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=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"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> test </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">using</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">params</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span style=3D"colo=
r: #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"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> main</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
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"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> test</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">char=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">params</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">cout </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">sizeof</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">endl</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-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>=
</span></div></code></div><br>From my personal point of view this way to ha=
ve typelist outside of template is much better then grabbing parameters fro=
m some intermediate template which is needed only to enlist types you need.=
 This approach also allows to have better of your MetaFunc template without=
 issues I&#39;ve mentioned above.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1015518c-c0e4-4397-b946-df7834a2c3c0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1015518c-c0e4-4397-b946-df7834a2c3c0=
%40isocpp.org</a>.<br />

------=_Part_523_718919558.1465840607876--

------=_Part_522_172920184.1465840607875--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Mon, 13 Jun 2016 11:53:58 -0700 (PDT)
Raw View
------=_Part_527_489847446.1465844038377
Content-Type: multipart/alternative;
 boundary="----=_Part_528_1047745272.1465844038377"

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

=D0=BF=D0=BE=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA, 13 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 1:32:22 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Arthur O'Dwyer=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:

> `break` work same as in normal `for`, critical is last `break` in origina=
l=20
>> `switch` because `for constexpr` breaks there. I skip one transformation=
=20
>> stage that show it:
>> switch (x)
>> {
>>     case Op0::OpId: Op0::OpFunc(); goto finalFor;
>>     case Op1::OpId: Op1::OpFunc(); goto finalFor;
>>     case Op2::OpId: Op2::OpFunc(); goto finalFor;
>>     case Op3::OpId: Op3::OpFunc(); goto finalFor;
>>     finalFor: break;
>> }
>>
>
> No, that doesn't work.  I think Tony has a point.
> Sergey's half-proposal wants to make "break" and "continue" inside a "for=
=20
> constexpr" act exactly like "break" and "continue" inside a non-constexpr=
=20
> "for":
>
>
Actually I would like break/continue to be turned into jumps to a body of=
=20
the "end of loop"/"next iteration loop body instantiation" so previous=20
example uf abusing for constexpr to case-expand parameters pack is=20
technically correct. In my third message in this converation I've posted=20
example of function set(obj, property_name, property_val_as_json)=20
{obj.proprty_name =3D=20
parse<decltype(obj.proprty_name)>(property_val_as_json);} which relies on=
=20
such behaviour. If break always terminate instantiation of loop body for=20
the rest of parameters and continue stops instantiation of statements=20
bellow then they must be forbidden inside any conditional code when=20
condition is evaluated at runtime. Only to ways to leave constexpr loop by=
=20
runtime condition remains: explicit goto (ugly) and return (require to move=
=20
part of your function implementation into some helper function). As far as=
=20
I can see continue based on runtime condition inside for constexpr will=20
only be implementable by rewriting the code with recursive templates.
=20

>     for constexpr(typename T : Ts...) {
>         do_something<T>();
>         if constexpr(is_same_v<T, nullptr_t>) break;
>     }
>
> This code would generate an unrolled loop of do_something<T>()s for each =
T=20
> in Ts... up to and including the first instance of nullptr_t. As soon as=
=20
> it generated do_something<nullptr_t>(), it would break and stop iterating=
=20
> over Ts....
>
>
I think that in such case compiler should be able to detect unreachable=20
code and cut it. May be this can be required by the for constexpr proposal.=
=20

My personal opinion on "constexpr break" (break which stops instantiation=
=20
of the rest of loop iterations): It's a step to add additional sublanguage=
=20
of "codegeneration based on constexpr conditions and lists" into C++. There=
=20
are 3 C++ sublanguages (preprocessor, templates, classic-C++) already and=
=20
this kind of language fragmentation should be avoided in the future=20
evaluation. Break which is turned into goto integrates into the langage=20
much better.

-- Sergey

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/daaa0a08-068e-4fe4-8b4d-f9ad4879a17a%40isocpp.or=
g.

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

<div dir=3D"ltr">=D0=BF=D0=BE=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=
=B8=D0=BA, 13 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 1:32:22 UTC+6 =D0=BF=
=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Arthur O=
&#39;Dwyer =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<br><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid=
;padding-left:1ex"><div dir=3D"ltr"><div>`break` work same as in normal `fo=
r`, critical is last `break` in original `switch` because `for constexpr` b=
reaks there. I skip one transformation stage that show it:<br><div style=3D=
"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);word-w=
rap:break-word"><code><div><span style=3D"color:rgb(0,0,136)">switch</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0=
)">(</span><span style=3D"color:rgb(0,0,0)">x</span><span style=3D"color:rg=
b(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"><br></span><span sty=
le=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op0</=
span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb=
(102,0,102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op0=
</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:r=
gb(102,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span>=
<span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)"=
>goto</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D=
"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"=
color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op1</span><s=
pan style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,=
102)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op1</spa=
n><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(10=
2,0,102)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span=
 style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto=
</span><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2</span><span=
 style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102=
)">OpId</span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"c=
olor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op2</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,1=
02)">OpFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto</spa=
n><span style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"color:rgb=
(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:rgb(0,0,136)">case</span><span style=3D"color:rgb(=
0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><span style=
=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)">OpI=
d</span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:r=
gb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Op3</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(102,0,102)">O=
pFunc</span><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"c=
olor:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">goto</span><spa=
n style=3D"color:rgb(0,0,0)"> finalFor</span><span style=3D"color:rgb(102,1=
02,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 finalFor<=
/span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">break</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></sp=
an><span style=3D"color:rgb(102,102,0)">}</span></div></code></div></div></=
div></blockquote><div><br></div><div>No, that doesn&#39;t work.=C2=A0 I thi=
nk Tony has a point.</div><div>Sergey&#39;s half-proposal wants to make &qu=
ot;break&quot; and &quot;continue&quot; inside a &quot;for constexpr&quot; =
act exactly like &quot;break&quot; and &quot;continue&quot; inside a non-co=
nstexpr &quot;for&quot;:</div><div><br></div></div></div></div></blockquote=
><div><br>Actually I would like break/continue to be turned into jumps to a=
 body of the &quot;end of loop&quot;/&quot;next iteration loop body instant=
iation&quot; so previous example uf abusing for constexpr to case-expand pa=
rameters pack is technically correct. In my third message in this converati=
on I&#39;ve posted example of function set(obj, property_name, property_val=
_as_json) {obj.proprty_name =3D parse&lt;decltype(obj.proprty_name)&gt;(pro=
perty_val_as_json);} which relies on such behaviour. If break always termin=
ate instantiation of loop body for the rest of parameters and continue stop=
s instantiation of statements bellow then they must be forbidden inside any=
 conditional code when condition is evaluated at runtime. Only to ways to l=
eave constexpr loop by runtime condition remains: explicit goto (ugly) and =
return (require to move part of your function implementation into some help=
er function). As far as I can see continue based on runtime condition insid=
e for constexpr will only be implementable by rewriting the code with recur=
sive templates.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div><font fac=
e=3D"monospace, monospace">=C2=A0 =C2=A0 for constexpr(typename T : Ts...) =
{</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 do_something&lt;T&gt;();</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 if constexpr(is_same_v&lt;T, nullptr=
_t&gt;) break;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 }</font></div><div><br></div><div>This code would generate an unroll=
ed loop of <font face=3D"monospace, monospace">do_something&lt;T&gt;()</fon=
t>s for each=C2=A0<font face=3D"monospace, monospace">T</font> in <font fac=
e=3D"monospace, monospace">Ts...</font> up to and including the first insta=
nce of <font face=3D"monospace, monospace">nullptr_t</font>. As soon as it =
generated <font face=3D"monospace, monospace">do_something&lt;nullptr_t&gt;=
()</font>, it would break and stop iterating over <font face=3D"monospace, =
monospace">Ts...</font>.</div><div><br></div></div></div></div></blockquote=
><div><br>I think that in such case compiler should be able to detect unrea=
chable code and cut it. May be this can be required by the for constexpr pr=
oposal. <br></div><br>My personal opinion on &quot;constexpr break&quot; (b=
reak which stops instantiation of the rest of loop iterations): It&#39;s a =
step to add additional sublanguage of &quot;codegeneration based on constex=
pr conditions and lists&quot; into C++. There are 3 C++ sublanguages (prepr=
ocessor, templates, classic-C++) already and this kind of language fragment=
ation should be avoided in the future evaluation. Break which is turned int=
o goto integrates into the langage much better.<br><br>-- Sergey<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/daaa0a08-068e-4fe4-8b4d-f9ad4879a17a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/daaa0a08-068e-4fe4-8b4d-f9ad4879a17a=
%40isocpp.org</a>.<br />

------=_Part_528_1047745272.1465844038377--

------=_Part_527_489847446.1465844038377--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 13 Jun 2016 11:58:55 -0700
Raw View
--001a113a55d4ff8ecb05352d7a20
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Jun 13, 2016 at 10:56 AM, Sergey Vidyuk <sir.vestnik@gmail.com>
wrote:

> =D1=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>>  I think that `for constexpr` should be allowed to extracting parameters
>> from templates, some thing like that:
>> using type =3D std::tuple<int, long long, char>;
>>
>> int main()
>> {
>>     for constexpr (typename T : type) //without `...`
>>     {
>>         f<T>();
>>     } //equal: `f<int>(); f<long long>(); f<char>();`
>> }
>>
>>
> Am I right tha the main and only reason you would like to grab template
> parameters with 'for constexpr' is to have type list outside of template?
>
>
>> This will allow usage outside of template function and simplify complex
>> operation:
>> template<typename T>
>> using MetaFunc =3D std::tuple<int, T, T, char>;
>>
>>
>> int main()
>> {
>>     for constexpr (typename T : MetaFunc<long>)
>>     {
>>         f<T>();
>>     } //equal: `f<int>(); f<long>(); f<long>(); f<char>();`
>>     for constexpr (typename T : MetaFunc<char>)
>>     {
>>         for constexpr (typename TT : MetaFunc<T>)
>>         {
>>            g<T,TT>();
>>         }
>>     }
>> }
>>
>>
>>  I see one issue with this example. Your MetaFunc is template typedef an=
d
> instead of iteraating over single element list you are iterating through =
 4
> elements list since you are grabbing parameters of type mapped my templat=
e
> typedef but not parameters of teemplate typedef itself. The simpliest way
> to have list of types which is never can accidentally create some nonvoid
> variable is template typedef std::void_t which can be implemented as
>
> template<typename... T>
> using void_t =3D void;
>
> how the following loop should work then?
>
> for constexpr (typename T: void_t<int8_t, int16_t, int32_t, int64_t>) {
>     do_something();
> }
>
> My personal opinion on such feature: there should be separate syntax to
> grab template parameters like
>
> for constexpr (typename T: params_of<void_t<int8_t, int16_t, int32_t,
> int64_t>>) {
>     do_something();
> }
>
> but it require some extra work on how this should actually work.
>

Sorry, that's impossible in C++.  Intuitively,

    using result =3D void_t<A,B,C,D>;
    ... some expression involving params_of<result> ...

is a non-starter for the same reason that

    auto sum =3D a + b + c + d;
    ... some expression involving addends_of<sum> ...

is a non-starter. Alias templates are referentially transparent (at compile
time) in the same way that ints are (at runtime); void_t<A,B,C,D> *is* void
as far as the compiler is concerned.  That's an intentional feature; it
allows type deduction to "see through" parameters whose types are template
aliases whereas type deduction can't "see through" parameters whose types
are member typedefs of template classes.

HTH,
Arthur

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0JihA%3DK8PMhBMG3OKkq6JTRgqDtCkNM%2B9FWnuT=
xvV-d1w%40mail.gmail.com.

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

<div dir=3D"ltr">On Mon, Jun 13, 2016 at 10:56 AM, Sergey Vidyuk <span dir=
=3D"ltr">&lt;<a href=3D"mailto:sir.vestnik@gmail.com" target=3D"_blank">sir=
..vestnik@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=D1=
=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =
=D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=
=82=D0=B5=D0=BB=D1=8C <a href=3D"mailto:inkwizyt...@gmail.com" target=3D"_b=
lank">inkwizyt...@gmail.com</a> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=
<span class=3D""><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">=
=C2=A0I think that `for constexpr` should be allowed to extracting paramete=
rs from templates, some thing like that:<br><div><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">us=
ing</span><span style=3D"color:#000"> type </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">tuple</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">lon=
g</span><span style=3D"color:#000"> </span><span style=3D"color:#008">long<=
/span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">char</span><span style=3D"color:#660">&gt;;</sp=
an><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">int=
</span><span style=3D"color:#000"> main</span><span style=3D"color:#660">()=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">for</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">constexpr</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">typename</span><span style=3D"c=
olor:#000"> T </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> type</span><span style=3D"color:#660">)</span><span style=3D"color=
:#000"> </span><span style=3D"color:#800">//without `...`</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span sty=
le=3D"color:#660">&gt;();</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">//equal: `f&lt;int&gt;(); f&lt;long long&g=
t;(); f&lt;char&gt;();`</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">}</span></div></code></div><br></div></div></blockquote=
></span><div><br>Am I right tha the main and only reason you would like to =
grab template=20
parameters with &#39;for constexpr&#39; is to have type list outside of=20
template?<br>=C2=A0</div><span class=3D""><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>This will allow usage outside of template func=
tion and simplify complex operation:<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><span style=3D"color:#008">template</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typena=
me</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">us=
ing</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Met=
aFunc</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">tuple</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660">=
,</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">,</s=
pan><span style=3D"color:#000"> T</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">char</span><s=
pan style=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br><br><br=
></span><span style=3D"color:#008">int</span><span style=3D"color:#000"> ma=
in</span><span style=3D"color:#660">()</span><span style=3D"color:#000"><br=
></span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">constexpr</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#008">typename</span><span style=3D"color:#000"> T </span><span style=3D"=
color:#660">:</span><span style=3D"color:#000"> </span><span style=3D"color=
:#606">MetaFunc</span><span style=3D"color:#080">&lt;long&gt;</span><span s=
tyle=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 f</span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#000">T</span><span style=3D"color:#660">&gt;();</span><sp=
an style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660"=
>}</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//eq=
ual: `f&lt;int&gt;(); f&lt;long&gt;(); f&lt;long&gt;(); f&lt;char&gt;();`</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or:#008">for</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">constexpr</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">typename</span><span style=3D"c=
olor:#000"> T </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#606">MetaFunc</span><span style=3D"co=
lor:#080">&lt;char&gt;</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">typename</span><span =
style=3D"color:#000"> TT </span><span style=3D"color:#660">:</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#606">MetaFunc</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span st=
yle=3D"color:#660">&gt;)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span style=3D"col=
or:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0g</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000">TT</span><span style=3D"=
color:#660">&gt;();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code=
></div><br><br></div></div></blockquote></span><div>=C2=A0I see one issue w=
ith this example. Your MetaFunc is template typedef and instead of iteraati=
ng over single element list you are iterating through=C2=A0 4 elements list=
 since you are grabbing parameters of type mapped my template typedef but n=
ot parameters of teemplate typedef itself. The simpliest way to have list o=
f types which is never can accidentally create some nonvoid variable is tem=
plate typedef std::void_t which can be implemented as<br><br><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"co=
lor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#008">using</span><span =
style=3D"color:#000"> void_t </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#008">void</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div>=
</code></div><br>how the following loop should work then?<br><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><span style=
=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=3D=
"color:#008">constexpr</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> T</span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> void_t</span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#000">int8_t</span><span style=3D"color:#660">,</span><span s=
tyle=3D"color:#000"> int16_t</span><span style=3D"color:#660">,</span><span=
 style=3D"color:#000"> int32_t</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> int64_t</span><span style=3D"color:#660">&gt;)</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 do_something</span><span style=
=3D"color:#660">();</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div></code>=
</div><br>My personal opinion on such feature: there should be separate syn=
tax to grab template parameters like<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">for</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">constexpr<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span=
><span style=3D"color:#008">typename</span><span style=3D"color:#000"> T</s=
pan><span style=3D"color:#660">:</span><span style=3D"color:#000"> params_o=
f</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">vo=
id_t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000"=
>int8_t</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> int16_t</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> int32_t</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> int64_t</span><span style=3D"color:#660">&gt;&gt;)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 do_something</span><span style=3D"color:#660">=
();</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
}</span><span style=3D"color:#000"><br></span></div></code></div><br>but it=
 require some extra work on how this should actually work.</div></div></blo=
ckquote><div><br></div><div>Sorry, that&#39;s impossible in C++.=C2=A0 Intu=
itively,</div><div><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 using result =3D void_t&lt;A,B,C,D&gt;;</font></div><div><font f=
ace=3D"monospace, monospace">=C2=A0 =C2=A0 ... some expression involving pa=
rams_of&lt;result&gt; ...</font></div><div><br></div><div>is a non-starter =
for the same reason that</div><div><br></div><div><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 auto sum =3D a + b + c + d;</font></div><div><font=
 face=3D"monospace, monospace">=C2=A0 =C2=A0 ... some expression involving =
addends_of&lt;sum&gt; ...</font></div></div><br></div><div class=3D"gmail_e=
xtra">is a non-starter. Alias templates are referentially transparent (at c=
ompile time) in the same way that ints are (at runtime); <font face=3D"mono=
space, monospace">void_t&lt;A,B,C,D&gt;</font> <b><i>is</i></b> <font face=
=3D"monospace, monospace">void</font> as far as the compiler is concerned.=
=C2=A0 That&#39;s an intentional feature; it allows type deduction to &quot=
;see through&quot; parameters whose types are template aliases whereas type=
 deduction can&#39;t &quot;see through&quot; parameters whose types are mem=
ber typedefs of template classes.</div><div class=3D"gmail_extra"><br></div=
><div class=3D"gmail_extra">HTH,</div><div class=3D"gmail_extra">Arthur</di=
v><div class=3D"gmail_extra"><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0JihA%3DK8PMhBMG3OKkq6JTRgqDtCk=
NM%2B9FWnuTxvV-d1w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0JihA%3=
DK8PMhBMG3OKkq6JTRgqDtCkNM%2B9FWnuTxvV-d1w%40mail.gmail.com</a>.<br />

--001a113a55d4ff8ecb05352d7a20--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Mon, 13 Jun 2016 12:00:52 -0700 (PDT)
Raw View
------=_Part_582_2101369963.1465844452217
Content-Type: multipart/alternative;
 boundary="----=_Part_583_567470926.1465844452218"

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

=D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=BD=D1=8C=D0=B5, 12 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 17:13:48 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=20
inkwizyt...@gmail.com =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> I was referring to switch after applying `for constexpr`. Some thing like=
=20
> that:
> switch (x)
> {
>     for constexpr (typename T : Op...)
>     {
>     case T::OpId: T::OpFunc(); break;
>     }
>     break;
> }
> //After `for constexpr` "unroll"
> switch (x)
> {
>     case Op0::OpId: Op0::OpFunc(); break;
>     case Op1::OpId: Op1::OpFunc(); break;
>     case Op2::OpId: Op2::OpFunc(); break;
>     case Op3::OpId: Op3::OpFunc(); break;
> }
> And in second switch today compilers do that I mentioned (if `OpId` creat=
e=20
> proper range). `for constexpr` is not trivial but if it support `case` th=
en=20
> getting jump table from `switch` and `for constexpr` will be trivial.
>
>
Maybe it's better to have syntax to expand parameters pack into set of case=
=20
statements. Posibility to mix switch with loops is one of the most=20
confusing and dangerous part of the language. I fill it's better to avoid=
=20
adding for constexpr as a common practice to unpack parameters pack into=20
cases.

-- Sergey=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/a7bcde4a-19e9-4916-b292-b48adf2345a4%40isocpp.or=
g.

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

<div dir=3D"ltr">=D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=BD=D1=
=8C=D0=B5, 12 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 17:13:48 UTC+6 =D0=BF=
=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C inkwizyt=
....@gmail.com =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr">I was referring to switch afte=
r applying `for constexpr`. Some thing like that:<br><div><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color=
:#008">switch</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">(</span><span style=3D"color:#000">x</span><span style=3D"color:#660=
">)</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#008">for</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#008">constexpr</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">(</span><span style=3D"color:#008">typename</span><span style=
=3D"color:#000"> T </span><span style=3D"color:#660">:</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Op</span><span style=3D"col=
or:#660">...)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">case</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">::</span><span style=3D"color:#606">Op=
Id</span><span style=3D"color:#660">:</span><span style=3D"color:#000"> T</=
span><span style=3D"color:#660">::</span><span style=3D"color:#606">OpFunc<=
/span><span style=3D"color:#660">();</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">break</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color:#008">break</span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">//After `for constexp=
r` &quot;unroll&quot;</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">switch</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">x</span><span style=3D=
"color:#660">)</span><span style=3D"color:#000"><br></span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color:#008">case</span><span style=3D"color:#000"> </span><span =
style=3D"color:#606">Op0</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#606">OpId</span><span style=3D"color:#660">:</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#606">Op0</span><span style=
=3D"color:#660">::</span><span style=3D"color:#606">OpFunc</span><span styl=
e=3D"color:#660">();</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">break</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">case</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#606">Op1</span=
><span style=3D"color:#660">::</span><span style=3D"color:#606">OpId</span>=
<span style=3D"color:#660">:</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#606">Op1</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#606">OpFunc</span><span style=3D"color:#660">();</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">break</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">case</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Op2</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#606">OpId</span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#606">Op2</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#606">OpFunc</span><s=
pan style=3D"color:#660">();</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">break</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">ca=
se</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Op3<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#606">OpId</=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#606">Op3</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#606">OpFunc</span><span style=3D"color:#660">();</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">break</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div=
></code></div>And in second switch today compilers do that I mentioned (if =
`OpId` create proper range). `for constexpr` is not trivial but if it suppo=
rt `case` then getting jump table from `switch` and `for constexpr` will be=
 trivial.<br><br></div></div></blockquote><div><br>Maybe it&#39;s better to=
 have syntax to expand parameters pack into set of case statements. Posibil=
ity to mix switch with loops is one of the most confusing and dangerous par=
t of the language. I fill it&#39;s better to avoid adding for constexpr as =
a common practice to unpack parameters pack into cases.<br><br>-- Sergey <b=
r></div><div>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a7bcde4a-19e9-4916-b292-b48adf2345a4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a7bcde4a-19e9-4916-b292-b48adf2345a4=
%40isocpp.org</a>.<br />

------=_Part_583_567470926.1465844452218--

------=_Part_582_2101369963.1465844452217--

.


Author: inkwizytoryankes@gmail.com
Date: Mon, 13 Jun 2016 16:18:24 -0700 (PDT)
Raw View
------=_Part_1127_1727022655.1465859904296
Content-Type: multipart/alternative;
 boundary="----=_Part_1128_1958846099.1465859904297"

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



On Monday, June 13, 2016 at 7:56:48 PM UTC+2, Sergey Vidyuk wrote:
>
> =D1=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>>  I think that `for constexpr` should be allowed to extracting parameters=
=20
>> from templates, some thing like that:
>> using type =3D std::tuple<int, long long, char>;
>>
>> int main()
>> {
>>     for constexpr (typename T : type) //without `...`
>>     {
>>         f<T>();
>>     } //equal: `f<int>(); f<long long>(); f<char>();`
>> }
>>
>>
> Am I right tha the main and only reason you would like to grab template=
=20
> parameters with 'for constexpr' is to have type list outside of template?
> =20
>
>> This will allow usage outside of template function and simplify complex=
=20
>> operation:
>> template<typename T>
>> using MetaFunc =3D std::tuple<int, T, T, char>;
>>
>>
>> int main()
>> {
>>     for constexpr (typename T : MetaFunc<long>)
>>     {
>>         f<T>();
>>     } //equal: `f<int>(); f<long>(); f<long>(); f<char>();`
>>     for constexpr (typename T : MetaFunc<char>)
>>     {
>>         for constexpr (typename TT : MetaFunc<T>)
>>         {
>>            g<T,TT>();
>>         }
>>     }
>> }
>>
>>
>>  I see one issue with this example. Your MetaFunc is template typedef an=
d=20
> instead of iteraating over single element list you are iterating through =
 4=20
> elements list since you are grabbing parameters of type mapped my templat=
e=20
> typedef but not parameters of teemplate typedef itself. The simpliest way=
=20
> to have list of types which is never can accidentally create some nonvoid=
=20
> variable is template typedef std::void_t which can be implemented as
>
> template<typename... T>
> using void_t =3D void;
>
> how the following loop should work then?
>
> for constexpr (typename T: void_t<int8_t, int16_t, int32_t, int64_t>) {
>     do_something();
> }
>
>
No, because type that is pass to `for` is `void` without any parameters. It=
=20
will behave same if you pass `void_t<int, long>` to template and look what=
=20
template specialization is chosen. It will be `void`.
=20

> My personal opinion on such feature: there should be separate syntax to=
=20
> grab template parameters like
>
> for constexpr (typename T: params_of<void_t<int8_t, int16_t, int32_t,=20
> int64_t>>) {
>     do_something();
> }
>
> but it require some extra work on how this should actually work. In D it'=
s=20
> possible to implement params_of in library code since it's possible to=20
> typedef parameters pack and then use it when needed. The following C++ co=
de=20
> rewritten in D works as expected:
>
> template<typename... L>
> struct test {
>     using params =3D L;
> };
>
> int main() {
>     for constexpr (typename T, test<char, int>::params) {
>         std::cout << sizeof(T) << std::endl;
>     }
> }
>
> From my personal point of view this way to have typelist outside of=20
> template is much better then grabbing parameters from some intermediate=
=20
> template which is needed only to enlist types you need. This approach als=
o=20
> allows to have better of your MetaFunc template without issues I've=20
> mentioned above.
>

My idea was that we have concrete template type with some parameters. Then=
=20
`for constexpr` will extract parameters of this template. This is why=20
template alias are skipped. They can never by concrete. They more like type=
=20
to type functions that templates.=20

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/71f9f321-59e4-452e-84d1-74d2c476c2de%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Monday, June 13, 2016 at 7:56:48 PM UTC+2, Serg=
ey Vidyuk 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">=D1=81=D1=83=D0=B1=D0=B1=D0=BE=D1=82=D0=B0, 11 =D0=B8=D1=8E=D0=BD=D1=8F =
2016 =D0=B3., 1:10:04 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=
=B0=D1=82=D0=B5=D0=BB=D1=8C <a>inkwizyt...@gmail.com</a> =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=BB:<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">=C2=A0I think that `for constexpr` should be allowed to extracting=
 parameters from templates, some thing like that:<br><div><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color=
:#008">using</span><span style=3D"color:#000"> type </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D"c=
olor:#660">::</span><span style=3D"color:#000">tuple</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#008">int</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">long</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">long</span><span style=3D"color:#660">,</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">char</span><span style=3D"color:#660">=
&gt;;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:=
#008">int</span><span style=3D"color:#000"> main</span><span style=3D"color=
:#660">()</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">typename</span><span =
style=3D"color:#000"> T </span><span style=3D"color:#660">:</span><span sty=
le=3D"color:#000"> type</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#800">//without `...`</span><=
span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span=
><span style=3D"color:#660">&gt;();</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#800">//equal: `f&lt;int&gt;(); f&lt;l=
ong long&gt;(); f&lt;char&gt;();`</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#660">}</span></div></code></div><br></div></div></=
blockquote><div><br>Am I right tha the main and only reason you would like =
to grab template=20
parameters with &#39;for constexpr&#39; is to have type list outside of=20
template?<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>This will allow usage outside of template function and simpli=
fy complex operation:<br><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:b=
reak-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"> T</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">using</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">MetaFunc</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">tuple</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">int</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> T</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#008">char</span><span style=3D"co=
lor:#660">&gt;;</span><span style=3D"color:#000"><br><br><br></span><span s=
tyle=3D"color:#008">int</span><span style=3D"color:#000"> main</span><span =
style=3D"color:#660">()</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color:#008">for</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">constexpr</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">(</span><span style=3D"color:#008">typename=
</span><span style=3D"color:#000"> T </span><span style=3D"color:#660">:</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#606">MetaFunc<=
/span><span style=3D"color:#080">&lt;long&gt;</span><span style=3D"color:#6=
60">)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 f</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&gt;();</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#800">//equal: `f&lt;int&gt=
;(); f&lt;long&gt;(); f&lt;long&gt;(); f&lt;char&gt;();`</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">constexpr<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span=
><span style=3D"color:#008">typename</span><span style=3D"color:#000"> T </=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#606">MetaFunc</span><span style=3D"color:#080">&lt;ch=
ar&gt;</span><span style=3D"color:#660">)</span><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span style=3D"=
color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">for</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
constexpr</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">typename</span><span style=3D"color:#=
000"> TT </span><span style=3D"color:#660">:</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#606">MetaFunc</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#66=
0">&gt;)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0g</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">,</s=
pan><span style=3D"color:#000">TT</span><span style=3D"color:#660">&gt;();<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r></span><span style=3D"color:#660">}</span></div></code></div><br><br></di=
v></div></blockquote><div>=C2=A0I see one issue with this example. Your Met=
aFunc is template typedef and instead of iteraating over single element lis=
t you are iterating through=C2=A0 4 elements list since you are grabbing pa=
rameters of type mapped my template typedef but not parameters of teemplate=
 typedef itself. The simpliest way to have list of types which is never can=
 accidentally create some nonvoid variable is template typedef std::void_t =
which can be implemented as<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-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</s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#000"> T</spa=
n><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">using</span><span style=3D"color:#000"> void_=
t </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">void</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"><br></span></div></code></div><br>how the fo=
llowing loop should work then?<br><br><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x;word-wrap:break-word"><code><div><span style=3D"color:#008">for</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span=
 style=3D"color:#008">typename</span><span style=3D"color:#000"> T</span><s=
pan style=3D"color:#660">:</span><span style=3D"color:#000"> void_t</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#000">int8_t</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> int16_t</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> int32_t<=
/span><span style=3D"color:#660">,</span><span style=3D"color:#000"> int64_=
t</span><span style=3D"color:#660">&gt;)</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 do_something</span><span style=3D"color:#660">();</span><span=
 style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span s=
tyle=3D"color:#000"><br></span></div></code></div><br></div></div></blockqu=
ote><div><br>No, because type that is pass to `for` is `void` without any p=
arameters. It will behave same if you pass `void_t&lt;int, long&gt;` to tem=
plate and look what template specialization is chosen. It will be `void`.<b=
r>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div>My personal opinion on such feature: there should be separate syntax =
to grab template parameters like<br><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><span style=3D"color:#008">for</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">constexpr</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#008">typename</span><span style=3D"color:#000"> T</span>=
<span style=3D"color:#660">:</span><span style=3D"color:#000"> params_of</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">void_t=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">int=
8_t</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> in=
t16_t</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
int32_t</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> int64_t</span><span style=3D"color:#660">&gt;&gt;)</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:=
#000"><br>=C2=A0 =C2=A0 do_something</span><span style=3D"color:#660">();</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</sp=
an><span style=3D"color:#000"><br></span></div></code></div><br>but it requ=
ire some extra work on how this should actually work. In D it&#39;s possibl=
e to implement params_of in library code since it&#39;s possible to typedef=
 parameters pack and then use it when needed. The following C++ code rewrit=
ten in D works as expected:<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-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</s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#000"> L</spa=
n><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">struct</span><span style=3D"color:#000"> test=
 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">using</span><span style=3D"=
color:#000"> </span><span style=3D"color:#008">params</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> L</span><span style=3D"color:#660">;</span><span style=3D"color:#=
000"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#0=
00"><br><br></span><span style=3D"color:#008">int</span><span style=3D"colo=
r:#000"> main</span><span style=3D"color:#660">()</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> T</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> test</span><span sty=
le=3D"color:#660">&lt;</span><span style=3D"color:#008">char</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">int</span><span style=3D"color:#660">&gt;::</span><span sty=
le=3D"color:#008">params</span><span style=3D"color:#660">)</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">cout </span><span style=3D"color=
:#660">&lt;&lt;</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#008">sizeof</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#000">T</span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:=
#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#=
000">endl</span><span style=3D"color:#660">;</span><span style=3D"color:#00=
0"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span></div></code></div><br>From my personal point of=
 view this way to have typelist outside of template is much better then gra=
bbing parameters from some intermediate template which is needed only to en=
list types you need. This approach also allows to have better of your MetaF=
unc template without issues I&#39;ve mentioned above.<br></div></div></bloc=
kquote><div><br>My idea was that we have concrete template type with some p=
arameters. Then `for constexpr` will extract parameters of this template. T=
his is why template alias are skipped. They can never by concrete. They mor=
e like type to type functions that templates. </div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/71f9f321-59e4-452e-84d1-74d2c476c2de%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/71f9f321-59e4-452e-84d1-74d2c476c2de=
%40isocpp.org</a>.<br />

------=_Part_1128_1958846099.1465859904297--

------=_Part_1127_1727022655.1465859904296--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Mon, 13 Jun 2016 22:02:03 -0700 (PDT)
Raw View
------=_Part_2311_1309869163.1465880523561
Content-Type: multipart/alternative;
 boundary="----=_Part_2312_420184387.1465880523564"

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



=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 5:18:24 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB
>
>
> My idea was that we have concrete template type with some parameters. The=
n=20
> `for constexpr` will extract parameters of this template. This is why=20
> template alias are skipped. They can never by concrete. They more like ty=
pe=20
> to type functions that templates.=20
>

Ok. Got the point on alias templates. But it actually means that this=20
feature is only usable when it's strong guarantie that template you are=20
using not an alias to nontrivial implementation. For example there might be=
=20
some problems with your examples if std::tuple is defined in such way:

template<typename... L>
using tuple =3D detail::tuple_impl<sizeof...(L), L...>;

grbbing template by for constexpr seems only be usable together with some=
=20
template class designed to be used for grabbing parameters. Something like:

template<typename... L>
struct types_list {};

which has strong guarantie that no extra types or nontype argument will=20
apear when it's used in "for constexpr". I think that D-like code I've=20
posted above solves the same issue in much better way:


> template<typename... L>
> struct test {
>     using params =3D L;
> };
>
> int main() {
>     for constexpr (typename T, test<char, int>::params) {
>         std::cout << sizeof(T) << std::endl;
>     }
> }
>
> =20
Thre are two different language constructs designed for their own purpuses=
=20
which allows to have type list to iterate over in nontemplate function when=
=20
those features are used together. From my personal point of view this way=
=20
is much better than grabbing template parameters unless there are some use=
=20
cases which are not just "some way to have iterable typelist in=20
non-template code". Do you have some example usecases for the feature?

-- Sergey

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0e2ea7f0-ee5e-44be-bade-413381bbb12b%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 5:18:24 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com =D0=
=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB<blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><br>My idea was that we have concrete templa=
te type with some parameters. Then `for constexpr` will extract parameters =
of this template. This is why template alias are skipped. They can never by=
 concrete. They more like type to type functions that templates. </div></di=
v></blockquote><div><br>Ok. Got the point on alias templates. But it actual=
ly means that this feature is only usable when it&#39;s strong guarantie th=
at template you are using not an alias to nontrivial implementation. For ex=
ample there might be some problems with your examples if std::tuple is defi=
ned in such way:<br><br><div class=3D"prettyprint" style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">typename</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">using</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> tuple </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> detail</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">tuple_impl</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">L</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div>=
</code></div><br>grbbing template by for constexpr seems only be usable tog=
ether with some template class designed to be used for grabbing parameters.=
 Something like:<br><br><div class=3D"prettyprint" style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">typename</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> types_list </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br=
>which has strong guarantie that no extra types or nontype argument will ap=
ear when it&#39;s used in &quot;for constexpr&quot;. I think that D-like co=
de I&#39;ve posted above solves the same issue in much better way:<br><br><=
blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(2=
04, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><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"><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
emplate</span></span><span style=3D"color:#660"><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&lt;</span></span><span style=3D"color:#008"=
><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><=
/span><span style=3D"color:#660"><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...</span></span><span style=3D"color:#000"><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> L</span></span><span style=3D"c=
olor:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</=
span></span><span style=3D"color:#000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></span><span style=3D"color:#008"><span =
style=3D"color: #008;" class=3D"styled-by-prettify">struct</span></span><sp=
an style=3D"color:#000"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> test </span></span><span style=3D"color:#660"><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">{</span></span><span style=3D"color:#0=
00"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span></span><span style=3D"color:#008"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">using</span></span><span style=3D"color:#000=
"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span></span>=
<span style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">params</span></span><span style=3D"color:#000"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span></span><span style=3D"color=
:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
</span><span style=3D"color:#000"><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> L</span></span><span style=3D"color:#660"><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span></span><span style=3D"co=
lor:#000"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></span><span style=3D"color:#660"><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span></span><span style=3D"color:#000"><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></span><span =
style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">int</span></span><span style=3D"color:#000"><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> main</span></span><span style=3D"color:#660=
"><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span></span=
><span style=3D"color:#000"><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span></span><span style=3D"color:#660"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span></span><span style=3D"color:#00=
0"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span></span><span style=3D"color:#008"><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">for</span></span><span style=3D"color:#000"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span></span><span=
 style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">constexpr</span></span><span style=3D"color:#000"><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span></span><span style=3D"color:#=
660"><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span></sp=
an><span style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">typename</span></span><span style=3D"color:#000"><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span></span><span style=
=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span></span><span style=3D"color:#000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> test</span></span><span style=3D"color:#660"><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span></span><spa=
n style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">char</span></span><span style=3D"color:#660"><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span></span><span style=3D"color:#000"=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span></span><=
span style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span></span><span style=3D"color:#660"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&gt;::</span></span><span style=3D"colo=
r:#008"><span style=3D"color: #008;" class=3D"styled-by-prettify">params</s=
pan></span><span style=3D"color:#660"><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)</span></span><span style=3D"color:#000"><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span></span><span style=
=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span></span><span style=3D"color:#000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span></span><s=
pan style=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span></span><span style=3D"color:#000"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">cout </span></span><span style=3D"color:#=
660"><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</sp=
an></span><span style=3D"color:#000"><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span></span><span style=3D"color:#008"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span></span><span st=
yle=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span></span><span style=3D"color:#000"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T</span></span><span style=3D"color:#660"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span></span><span st=
yle=3D"color:#000"><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span></span><span style=3D"color:#660"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&lt;&lt;</span></span><span style=3D"color:#000"=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span></spa=
n><span style=3D"color:#660"><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span></span><span style=3D"color:#000"><span style=3D"color=
: #000;" class=3D"styled-by-prettify">endl</span></span><span style=3D"colo=
r:#660"><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
/span><span style=3D"color:#000"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span></span><span style=3D"color:#660">=
<span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></span><s=
pan style=3D"color:#000"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span></span><span style=3D"color:#660"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">}</span></span><span style=3D"color:#00=
0"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></s=
pan></div></code></div></div></code></div><br></blockquote>=C2=A0<br>Thre a=
re two different language constructs designed for their own purpuses which =
allows to have type list to iterate over in nontemplate function when those=
 features are used together. From my personal point of view this way is muc=
h better than grabbing template parameters unless there are some use cases =
which are not just &quot;some way to have iterable typelist in non-template=
 code&quot;. Do you have some example usecases for the feature?<br><br>-- S=
ergey<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0e2ea7f0-ee5e-44be-bade-413381bbb12b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0e2ea7f0-ee5e-44be-bade-413381bbb12b=
%40isocpp.org</a>.<br />

------=_Part_2312_420184387.1465880523564--

------=_Part_2311_1309869163.1465880523561--

.


Author: inkwizytoryankes@gmail.com
Date: Tue, 14 Jun 2016 12:56:46 -0700 (PDT)
Raw View
------=_Part_2276_1897437716.1465934206205
Content-Type: multipart/alternative;
 boundary="----=_Part_2277_250413225.1465934206205"

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



On Tuesday, June 14, 2016 at 7:02:04 AM UTC+2, Sergey Vidyuk wrote:
>
>
>
> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 5:18:24 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C inkwizyt...@gmail.com=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB
>>
>>
>> My idea was that we have concrete template type with some parameters.=20
>> Then `for constexpr` will extract parameters of this template. This is w=
hy=20
>> template alias are skipped. They can never by concrete. They more like t=
ype=20
>> to type functions that templates.=20
>>
>
> Ok. Got the point on alias templates. But it actually means that this=20
> feature is only usable when it's strong guarantie that template you are=
=20
> using not an alias to nontrivial implementation. For example there might =
be=20
> some problems with your examples if std::tuple is defined in such way:
>
> template<typename... L>
> using tuple =3D detail::tuple_impl<sizeof...(L), L...>;
>
> grbbing template by for constexpr seems only be usable together with some=
=20
> template class designed to be used for grabbing parameters. Something lik=
e:
>
>
Exactly, this is downside but it have upside too. You could transform pack=
=20
in something else. This will allow push lot of junk out your way:

for constexpr (typename TT : zip_t<take_t<10, std::tuple<T...>>, std::
make_index_sequence_t<10>>)
{
    typename TT::first a; //type from T pack, but only first 10
    int a[TT::second::value]; //value from make_index_sequence_t
}




=20

> template<typename... L>
> struct types_list {};
>
> which has strong guarantie that no extra types or nontype argument will=
=20
> apear when it's used in "for constexpr". I think that D-like code I've=20
> posted above solves the same issue in much better way:
>
>
>> template<typename... L>
>> struct test {
>>     using params =3D L;
>> };
>>
>> int main() {
>>     for constexpr (typename T, test<char, int>::params) {
>>         std::cout << sizeof(T) << std::endl;
>>     }
>> }
>>
>> =20
> Thre are two different language constructs designed for their own purpuse=
s=20
> which allows to have type list to iterate over in nontemplate function wh=
en=20
> those features are used together. From my personal point of view this way=
=20
> is much better than grabbing template parameters unless there are some us=
e=20
> cases which are not just "some way to have iterable typelist in=20
> non-template code". Do you have some example usecases for the feature?
>
> -- Sergey
>
>
Some time ago was couple of discussions about exposing parameters as stand=
=20
alone entity. One example of it:=20
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-prop=
osals/parameters$20packs/std-proposals/YkHPCYb-KPQ/jqRUQ6f_Tz0J

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/aa9044ff-07f3-4822-8d18-b2c94776a448%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Tuesday, June 14, 2016 at 7:02:04 AM UTC+2, Ser=
gey Vidyuk 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"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D0=B8=D1=8E=D0=
=BD=D1=8F 2016 =D0=B3., 5:18:24 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=
=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C <a>inkwizyt...@gmail.com</a> =D0=BD=D0=
=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div><br>My idea was that we have concrete template type wit=
h some parameters. Then `for constexpr` will extract parameters of this tem=
plate. This is why template alias are skipped. They can never by concrete. =
They more like type to type functions that templates. </div></div></blockqu=
ote><div><br>Ok. Got the point on alias templates. But it actually means th=
at this feature is only usable when it&#39;s strong guarantie that template=
 you are using not an alias to nontrivial implementation. For example there=
 might be some problems with your examples if std::tuple is defined in such=
 way:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(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:#6=
60">&lt;</span><span style=3D"color:#008">typename</span><span style=3D"col=
or:#660">...</span><span style=3D"color:#000"> L</span><span style=3D"color=
:#660">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#008">using</span><span style=3D"color:#000"> tuple </span><span style=3D=
"color:#660">=3D</span><span style=3D"color:#000"> detail</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">tuple_impl</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#008">sizeof</span><sp=
an style=3D"color:#660">...(</span><span style=3D"color:#000">L</span><span=
 style=3D"color:#660"><wbr>),</span><span style=3D"color:#000"> L</span><sp=
an style=3D"color:#660">...&gt;;</span><span style=3D"color:#000"><br></spa=
n></div></code></div><br>grbbing template by for constexpr seems only be us=
able together with some template class designed to be used for grabbing par=
ameters. Something like:<br><br></div></div></blockquote><div><br>Exactly, =
this is downside but it have upside too. You could transform pack in someth=
ing else. This will allow push lot of junk out your way:<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> TT </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> zip_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">take_t</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">10</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">...&gt;&gt;,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span class=3D"mw-geshi cpp source-cpp"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">make_index_sequence_t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">10</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&gt;</span></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> TT</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">first a</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">//type from =
T pack, but only first 10</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">[</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
TT</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">second</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">value</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">];</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">//value from make_index_sequence_t</span><span sty=
le=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: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><br><br><br=
><br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,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:#=
660">...</span><span style=3D"color:#000"> L</span><span style=3D"color:#66=
0">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#0=
08">struct</span><span style=3D"color:#000"> types_list </span><span style=
=3D"color:#660">{};</span><span style=3D"color:#000"><br></span></div></cod=
e></div><br>which has strong guarantie that no extra types or nontype argum=
ent will apear when it&#39;s used in &quot;for constexpr&quot;. I think tha=
t D-like code I&#39;ve posted above solves the same issue in much better wa=
y:<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><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><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"><span style=3D"color:#008">template</span></span><span style=3D"=
color:#660"><span style=3D"color:#660">&lt;</span></span><span style=3D"col=
or:#008"><span style=3D"color:#008">typename</span></span><span style=3D"co=
lor:#660"><span style=3D"color:#660">...</span></span><span style=3D"color:=
#000"><span style=3D"color:#000"> L</span></span><span style=3D"color:#660"=
><span style=3D"color:#660">&gt;</span></span><span style=3D"color:#000"><s=
pan style=3D"color:#000"><br></span></span><span style=3D"color:#008"><span=
 style=3D"color:#008">struct</span></span><span style=3D"color:#000"><span =
style=3D"color:#000"> test </span></span><span style=3D"color:#660"><span s=
tyle=3D"color:#660">{</span></span><span style=3D"color:#000"><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span></span><span style=3D"color:#008">=
<span style=3D"color:#008">using</span></span><span style=3D"color:#000"><s=
pan style=3D"color:#000"> </span></span><span style=3D"color:#008"><span st=
yle=3D"color:#008">params</span></span><span style=3D"color:#000"><span sty=
le=3D"color:#000"> </span></span><span style=3D"color:#660"><span style=3D"=
color:#660">=3D</span></span><span style=3D"color:#000"><span style=3D"colo=
r:#000"> L</span></span><span style=3D"color:#660"><span style=3D"color:#66=
0">;</span></span><span style=3D"color:#000"><span style=3D"color:#000"><br=
></span></span><span style=3D"color:#660"><span style=3D"color:#660">};</sp=
an></span><span style=3D"color:#000"><span style=3D"color:#000"><br><br></s=
pan></span><span style=3D"color:#008"><span style=3D"color:#008">int</span>=
</span><span style=3D"color:#000"><span style=3D"color:#000"> main</span></=
span><span style=3D"color:#660"><span style=3D"color:#660">()</span></span>=
<span style=3D"color:#000"><span style=3D"color:#000"> </span></span><span =
style=3D"color:#660"><span style=3D"color:#660">{</span></span><span style=
=3D"color:#000"><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span></span>=
<span style=3D"color:#008"><span style=3D"color:#008">for</span></span><spa=
n style=3D"color:#000"><span style=3D"color:#000"> </span></span><span styl=
e=3D"color:#008"><span style=3D"color:#008">constexpr</span></span><span st=
yle=3D"color:#000"><span style=3D"color:#000"> </span></span><span style=3D=
"color:#660"><span style=3D"color:#660">(</span></span><span style=3D"color=
:#008"><span style=3D"color:#008">typename</span></span><span style=3D"colo=
r:#000"><span style=3D"color:#000"> T</span></span><span style=3D"color:#66=
0"><span style=3D"color:#660">,</span></span><span style=3D"color:#000"><sp=
an style=3D"color:#000"> test</span></span><span style=3D"color:#660"><span=
 style=3D"color:#660">&lt;</span></span><span style=3D"color:#008"><span st=
yle=3D"color:#008">char</span></span><span style=3D"color:#660"><span style=
=3D"color:#660">,</span></span><span style=3D"color:#000"><span style=3D"co=
lor:#000"> </span></span><span style=3D"color:#008"><span style=3D"color:#0=
08">int</span></span><span style=3D"color:#660"><span style=3D"color:#660">=
&gt;::</span></span><span style=3D"color:#008"><span style=3D"color:#008">p=
arams</span></span><span style=3D"color:#660"><span style=3D"color:#660">)<=
/span></span><span style=3D"color:#000"><span style=3D"color:#000"> </span>=
</span><span style=3D"color:#660"><span style=3D"color:#660">{</span></span=
><span style=3D"color:#000"><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 std</span></span><span style=3D"color:#660"><span style=3D"co=
lor:#660">::</span></span><span style=3D"color:#000"><span style=3D"color:#=
000">cout </span></span><span style=3D"color:#660"><span style=3D"color:#66=
0">&lt;&lt;</span></span><span style=3D"color:#000"><span style=3D"color:#0=
00"> </span></span><span style=3D"color:#008"><span style=3D"color:#008">si=
zeof</span></span><span style=3D"color:#660"><span style=3D"color:#660">(</=
span></span><span style=3D"color:#000"><span style=3D"color:#000">T</span><=
/span><span style=3D"color:#660"><span style=3D"color:#660">)</span></span>=
<span style=3D"color:#000"><span style=3D"color:#000"> </span></span><span =
style=3D"color:#660"><span style=3D"color:#660">&lt;&lt;</span></span><span=
 style=3D"color:#000"><span style=3D"color:#000"> std</span></span><span st=
yle=3D"color:#660"><span style=3D"color:#660">::</span></span><span style=
=3D"color:#000"><span style=3D"color:#000">endl</span></span><span style=3D=
"color:#660"><span style=3D"color:#660">;</span></span><span style=3D"color=
:#000"><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span></span><span sty=
le=3D"color:#660"><span style=3D"color:#660">}</span></span><span style=3D"=
color:#000"><span style=3D"color:#000"><br></span></span><span style=3D"col=
or:#660"><span style=3D"color:#660">}</span></span><span style=3D"color:#00=
0"><span style=3D"color:#000"><br></span></span></div></code></div></div></=
code></div><br></blockquote>=C2=A0<br>Thre are two different language const=
ructs designed for their own purpuses which allows to have type list to ite=
rate over in nontemplate function when those features are used together. Fr=
om my personal point of view this way is much better than grabbing template=
 parameters unless there are some use cases which are not just &quot;some w=
ay to have iterable typelist in non-template code&quot;. Do you have some e=
xample usecases for the feature?<br><br>-- Sergey<br><br></div></div></bloc=
kquote><div><br>Some time ago was couple of discussions about exposing para=
meters as stand alone entity. One example of it: https://groups.google.com/=
a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/parameters$20packs/s=
td-proposals/YkHPCYb-KPQ/jqRUQ6f_Tz0J<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/aa9044ff-07f3-4822-8d18-b2c94776a448%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/aa9044ff-07f3-4822-8d18-b2c94776a448=
%40isocpp.org</a>.<br />

------=_Part_2277_250413225.1465934206205--

------=_Part_2276_1897437716.1465934206205--

.