220 26305 <6b2c3588-e67e-4a8b-94d6-bdacd50ac244@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: inkwizytoryankes@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: statement folding on variadic templates
 parameters pack
Date: Sun, 12 Jun 2016 16:52:03 -0700 (PDT)
Lines: 463
Approved: news@gmane.org
Message-ID: <6b2c3588-e67e-4a8b-94d6-bdacd50ac244@isocpp.org>
References: <1e3daa7c-e10a-4589-8118-26f47bc1a0df@isocpp.org>
 <2d8458f8-27b2-464f-a16e-fc866ccfd2cd@isocpp.org> <b448d4b9-c76d-4d27-8b16-0e005478320f@isocpp.org>
 <d90bb3eb-e1d4-4a29-bb7e-63c097f49f96@isocpp.org> <bf02cde4-5da6-4a0b-903f-8b9230d4869c@isocpp.org>
 <CALbYwOymuWcO0WO6aSGCd1iv-dTUxPXP1BMYDdv5Pfcafw_xcQ@mail.gmail.com>
 <CAJnLdOZ5L0P6qdoer6jntOjtYwCTpV_VEGJv6bZUmGk6zmoQ2g@mail.gmail.com>
 <a731ae2e-9519-4d03-81ec-506b7bbda8b5@isocpp.org> <CAFk2RUZBSMsJOkjDaU=9xz4iJ9qNadygbPiB004oCh2p3jfgFg@mail.gmail.com>
 <8dc1e665-42a3-4ef0-a2d2-3773afab170c@isocpp.org> <20160612153937.4898897.23968.12102@gmail.com>
 <57d8c679-f312-4b77-8210-705f5e093b7e@isocpp.org>
 <CADvuK0+Jon-6hH0JU=xqScearhoMu4eVWieTpvYF-N42ky4Bgg@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_493_10668978.1465775523272"
X-Trace: ger.gmane.org 1465775534 30792 80.91.229.3 (12 Jun 2016 23:52:14 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 12 Jun 2016 23:52:14 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDDLTAGNTIBBBJHL665AKGQET4M3DKQ@isocpp.org Mon Jun 13 01:52:08 2016
Return-path: <std-proposals+bncBDDLTAGNTIBBBJHL665AKGQET4M3DKQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-io0-f197.google.com ([209.85.223.197])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDDLTAGNTIBBBJHL665AKGQET4M3DKQ@isocpp.org>)
	id 1bCFAk-0006Ma-Rn
	for gclcip-std-proposals@m.gmane.org; Mon, 13 Jun 2016 01:52:07 +0200
Original-Received: by mail-io0-f197.google.com with SMTP id d2sf72924583iof.3
        for <gclcip-std-proposals@m.gmane.org>; Sun, 12 Jun 2016 16:52:06 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=HAOels+femTfJEHh85ordxb45j1/5HchEXVJHgyd378=;
        b=eir1jVIfwCJ68KtDkstlvQ6latCKtBpHj7UsTOScW/PmU/ktvtGAj2keuIQp8fXyEc
         +1Ks/xQhNsgKtQQre67o16zMn4wGz8HijUxC0vp7GOfMWkzc1PpsFp2YBRte+mobL4UB
         BSgP2TdsMnRHKht3pW46pK2qJfH/Roxl/T+DV7hNKrYShAkYnDxK/mbnDcFyE3daIzx/
         qDvctaokzDkt15pS5S8ttfIIYYTxmvjyX/wJs0THeLlggSqsoEfc0dQU7N+25QPUJt1F
         Lg4BesRS46sSedXZqurmQQGlhjEHhxBIWKPq/JlQ43rRMtjja8BM1BB7/6h+G5CMwvm9
         0NZA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=HAOels+femTfJEHh85ordxb45j1/5HchEXVJHgyd378=;
        b=bDgWzEj6WliFtUi6Pyl8Tia7fsFyJlDXkEjCa8z7PMMDTUCrfaOPSW+NYDDm0ShTY9
         4mRDXYanGJNBUaV5sX5cKkwPX2v/BZJa1SXdKFBe5YovuR+5RFu0nJ1V5WCXQl2rzo5H
         NFIfpUcd8kxGOxxTjR+3cwcZV4XP3l2RZyHTrpchyxotDxVcCI4dB06/nYCDPpcoFSnA
         4Jo35BzcajjLC53ETlqMgnZ2mkvgvwRCsqVsydJQxUn+GzULp/oyjYALCUnli774d5pP
         aQMV7LwiC3kO6xeYA99cK+mKrN57jkAwkn4i3VT9kT0ryKukmYIaj+rXF1yxDyNV8O9d
         VwUg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=HAOels+femTfJEHh85ordxb45j1/5HchEXVJHgyd378=;
        b=SYt68kExGOQcSnNkFgpdX0R33urISXe1OrnrFah2VAbfGaifr0KqMnZ8UE7Y6OYASI
         BRTowHuR9CBVERnUCJHObXgQlbHSJNiUyDw8I3WlJ27KmBy0D4z55WdUSDepwyzgs2N+
         bv0ru8duddwr6j+uZ4H+UbNEhRIudzmYw4tzD2oC61wtJG2yv9QkURPA/uPo1v5u5ip7
         0CW40iuxcHkSuhOECS0aLVL9UcQP2TyGfmReBIsbKL0kryH4L8pEC5MOwFgmYeq/IjMk
         Z7fsb9X3lRWjw/XsTuk+gjrt4iPMi/tJspXbgz2VuPZCe8G8NtPIbRJ3mhVGlE6aniAm
         UbUw==
X-Gm-Message-State: ALyK8tKsTbDzF5eZJ30SWtSbR6wNEfKkyDHahKb0JhidnlsqtLIEve6KBof4L9mUbocjrg==
X-Received: by 10.107.143.12 with SMTP id r12mr2893323iod.9.1465775525851;
        Sun, 12 Jun 2016 16:52:05 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.36.85 with SMTP id f82ls861141ita.33.canary; Sun, 12 Jun
 2016 16:52:04 -0700 (PDT)
X-Received: by 10.36.249.140 with SMTP id l134mr37499ith.9.1465775524561;
        Sun, 12 Jun 2016 16:52:04 -0700 (PDT)
In-Reply-To: <CADvuK0+Jon-6hH0JU=xqScearhoMu4eVWieTpvYF-N42ky4Bgg@mail.gmail.com>
X-Original-Sender: inkwizytoryankes@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:26305
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/26305>

------=_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--

.
