220 32882 <b4bd172a-05c9-4a92-83fa-beba24150472@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: peetpaul69@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: constexpr for loop?
Date: Sun, 25 Jun 2017 13:39:11 -0700 (PDT)
Lines: 255
Approved: news@gmane.org
Message-ID: <b4bd172a-05c9-4a92-83fa-beba24150472@isocpp.org>
References: <46c1d5fc-6215-44f5-be84-651085690b0d@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1507_901239115.1498423151817"
X-Trace: blaine.gmane.org 1498423157 27155 195.159.176.226 (25 Jun 2017 20:39:17 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 25 Jun 2017 20:39:17 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDG53NMEJEIPBPWAZICRUBFO4UVZK@isocpp.org Sun Jun 25 22:39:13 2017
Return-path: <std-proposals+bncBDG53NMEJEIPBPWAZICRUBFO4UVZK@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yb0-f197.google.com ([209.85.213.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDG53NMEJEIPBPWAZICRUBFO4UVZK@isocpp.org>)
	id 1dPEJI-0006as-J3
	for gclcip-std-proposals@m.gmane.org; Sun, 25 Jun 2017 22:39:08 +0200
Original-Received: by mail-yb0-f197.google.com with SMTP id p207sf71964975yba.13
        for <gclcip-std-proposals@m.gmane.org>; Sun, 25 Jun 2017 13:39:13 -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
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=DNqHAe4ftTyseoT6t4KyoYB11fkoOWiWcFGuGTve9u4=;
        b=wI2i3C8CNuB89u/qra9mirmimoz9jRkRuUiUzaDCWH+ob963txem66C2FopCDmVeeO
         SLAS8CnftHqlESo50zi5bUlTpzPkXUVTbtYUzNmtl8MblIOXKHYvCWEqiEB+2P/UZUUv
         QmpmlfNisL36rfd0vm6G6ct9wNzamROnfDd5HnNOy9PdnFF2B9l1Qur5btLiys2spjD/
         hvSET1BaE/J+rmzrvn/pKsBVhyFKisJzyOmCDxwXS032GTEYEsvTgJrh9urgNo45V2hs
         S9oynS8mz7gCQ4OnYLczNvAjNo3/l/tMDPPtTXI2DmLYlo1hrB4CKeg2Lxg4oJL9WzCc
         uYXQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=DNqHAe4ftTyseoT6t4KyoYB11fkoOWiWcFGuGTve9u4=;
        b=hTpJUpJTxT+FtIgNdcZ11vGiwObNEwZrIwxm+4wVVMAD0QcKClByHVK6ouH3bh2il0
         3dAwUx1mBScc3rpr8/cp4NbB6OyIAnD9vWiTw/MEfS5Hv6YdXeU46M1A7iww+RqqAUmG
         LBdbUGRH9KogrLbeQu1196dH1ZLeRWrgtED6SkWUMir8RG8ALBFmtLX2hgZEdr0SOQpB
         2T53Jfc1vI9qhy5CssIqBsKRfYUdv3kfEReeaZXqZyfE9ZkIzEuMnlGwgpPXUPnJrxfw
         8vghiTiduAmT6URPwQQzupNsiMAG88uo8tmR5uldCIZJnEFtL76aB6oDq21D4QWL/7gx
         45Nw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        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=DNqHAe4ftTyseoT6t4KyoYB11fkoOWiWcFGuGTve9u4=;
        b=ggn+++RzAzh6lvSIHWObvQN8UAz3uoNY08uN93XP6HWpKDNvkXbROyi+iPjcBLsqSM
         gcPSgjNErsJeqctWjDjy5rbwGLF+D4nqzEF0D7zqAOZ+lStcV489+GycU35UXks7Qaeq
         RKwoOtGIBRR79rT9/9d1g4n9udjnPRFAC0L8F6V9kI2qLvT/JrrlHypUKVTZL4Dz3Z1i
         uHfIe5IgErF4Ym4YLShF+Jz5xz0ZjW4TQelPzd2+jcC1fFCe7ixUiW61hCTs4DZq0OzM
         kqMmd2FNAufwQCz76YZQ1XeMf8QNpX9WLNsSmiKw3eV9PpvkGW34ToQ8JapvIANqiJhm
         dSKQ==
X-Gm-Message-State: AKS2vOzoXPz9SOxZMDmuyWnyKncoGe0Be/QqySmetoZrumhSuR40bxoj
	CIJuEecvg0vWJ+0S
X-Received: by 10.129.162.194 with SMTP id z185mr10638758ywg.18.1498423153336;
        Sun, 25 Jun 2017 13:39:13 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.56.153 with SMTP id p25ls11815632otc.34.gmail; Sun, 25 Jun
 2017 13:39:12 -0700 (PDT)
X-Received: by 10.157.51.175 with SMTP id u47mr128098otc.4.1498423152349;
        Sun, 25 Jun 2017 13:39:12 -0700 (PDT)
In-Reply-To: <46c1d5fc-6215-44f5-be84-651085690b0d@isocpp.org>
X-Original-Sender: peetpaul69@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <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:32882
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32882>

------=_Part_1507_901239115.1498423151817
Content-Type: multipart/alternative; 
	boundary="----=_Part_1508_681461918.1498423151818"

------=_Part_1508_681461918.1498423151818
Content-Type: text/plain; charset="UTF-8"

It seems that this could be really useful, especially for static reflection.

And actually, there is a fork of clang by Andrew Sutton which basically 
implements the "constexpr" (evaluation/unrolling at compile-time) loop:

Here is a demo: https://godbolt.org/g/maV08o

More 
info: https://www.reddit.com/r/cpp/comments/68ljh4/there_is_no_interface_keyword_in_c_herbsutter/

On Sunday, June 25, 2017 at 2:12:58 AM UTC+2, Evan Teran wrote:
>
> I was just thinking the other day. Now that we are getting constexpr if, 
> what else could we allow at compile time? What occurs to me is that we 
> could have a nice compile time means to do loop unrolling. What I imagine 
> is something like this:
>
>
> constexpr for(int i = 0; i < 4; ++i) {
>     whatever();
> }
>
>
> would cause the compile to simply emit:
>
> whatever();
> whatever();
> whatever();
> whatever();
>
> Obviously the loop bounds would have to be trivially known at compile time 
> for this to work, and should throw a hard error if it isn't. Many compilers 
> already are doing this analysis that would enable this, so why not make 
> that analysis able to be leveraged by the developer?
>
> I know that the conventional wisdom is to just write the loop, and if the 
> compiler deems it optimal to unroll the loop, then it will. But sometimes, 
> people just know better.
>
> I can imagine versions of many algorithms that are functionally identical 
> the standard ones, but allow the user to specify how much to unroll via 
> template parameters, like this (parden any typos):
>
> namespace unrolled {
>
> template <int N, class In, class Size, class F>
> F for_each_n(In first, Size Count, F fn) {
>     Size rounded = (count / N) * N; // round count down to nearest 
> multiple of N
>     Size i = 0;
>
>
>     // do as much as possible in chunks of unrolled size N
>     while(i < rounded) {
>         constexpr for(int j = 0; j < N; ++j) {
>             fn(first[j]);
>         }
>         i += N;
>     }
>
>
>     while(i < count) {
>         fn(first[i++]);
>     }
> }
>
> }
>
> Which would enable code like this:
>
> unrolled::for_each_n<3>(std::begin(arr), 30, [](auto elem) {
>     // do whatever with elem
> }
>
>
> It would be functionally the same as a regular std::for_each_n, but 
> unrolled into blocks of size 3 as much as possible.
>
> Thoughts? Is this just not worth the effort?
> Evan
>

-- 
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/b4bd172a-05c9-4a92-83fa-beba24150472%40isocpp.org.

------=_Part_1508_681461918.1498423151818
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">It seems that this could be really useful, especially for =
static reflection.<div><br></div><div>And actually, there is a fork of clan=
g by Andrew Sutton which basically implements the &quot;constexpr&quot; (ev=
aluation/unrolling at compile-time) loop:</div><div><br></div><div>Here is =
a demo:=C2=A0https://godbolt.org/g/maV08o</div><div><br></div><div>More inf=
o:=C2=A0https://www.reddit.com/r/cpp/comments/68ljh4/there_is_no_interface_=
keyword_in_c_herbsutter/<br><br>On Sunday, June 25, 2017 at 2:12:58 AM UTC+=
2, Evan Teran 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"ltr">I was just thinking the other day. Now that we are getting constex=
pr if, what else could we allow at compile time? What occurs to me is that =
we could have a nice compile time means to do loop unrolling. What I imagin=
e is something like this:<br><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">constexpr</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">for</span><=
span style=3D"color:#660">(</span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"> i </span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#066">4</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#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 whatever</span><span style=3D"color:#660">();</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></co=
de></div><div><br></div><div><br></div><div>would cause the compile to simp=
ly emit:<br><br></div><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:#000">whatever</span><span style=3D=
"color:#660">();</span><span style=3D"color:#000"><br>whatever</span><span =
style=3D"color:#660">();</span><span style=3D"color:#000"><br>whatever</spa=
n><span style=3D"color:#660">();</span><span style=3D"color:#000"><br>whate=
ver</span><span style=3D"color:#660">();</span></div></code></div><div><br>=
</div><div>Obviously the loop bounds would have to be trivially known at co=
mpile time for this to work, and should throw a hard error if it isn&#39;t.=
 Many compilers already are doing this analysis that would enable this, so =
why not make that analysis able to be leveraged by the developer?</div><div=
><br>I know that the conventional wisdom is to just write the loop, and if =
the compiler deems it optimal to unroll the loop, then it will. But sometim=
es, people just know better.</div><div><br></div><div>I can imagine version=
s of many algorithms that are functionally identical the standard ones, but=
 allow the user to specify how much to unroll via template parameters, like=
 this (parden any typos):<br><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">namespace</span><s=
pan style=3D"color:#000"> unrolled </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">temp=
late</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">int</span><span style=3D"color:#000"> N=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">class</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">In</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">class</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Size</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>F for_each_n</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#606">In</span><s=
pan style=3D"color:#000"> first</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">Size</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Count</span><span=
 style=3D"color:#660">,</span><span style=3D"color:#000"> F fn</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:#606">Size</span><span style=3D"color:#000"> rounded =
</span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">count </s=
pan><span style=3D"color:#660">/</span><span style=3D"color:#000"> N</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">*</span><span style=3D"color:#000"> N</span><span sty=
le=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=3D=
"color:#800">// round count down to nearest multiple of N</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#606">Size</s=
pan><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span><s=
pan style=3D"color:#660">;</span><span style=3D"color:#000"><br><br><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#800">// do as much as possible in c=
hunks of unrolled size N</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:#008">while</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">i </span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000"> rounded</span><span style=3D"color:#660">=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span =
style=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">for</span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">int</span><span style=3D"color:#000"> j </span><span s=
tyle=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"> j </span><span style=3D"color:#660">&lt;</span><span style=3D"=
color:#000"> N</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">++</span><span style=3D"color:#0=
00">j</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 fn</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">first</span><span style=3D"color:#660=
">[</span><span style=3D"color:#000">j</span><span style=3D"color:#660">]);=
</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 i </span><span style=3D"color:#660">+=3D</span><span styl=
e=3D"color:#000"> N</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><s=
pan style=3D"color:#000"><br><br><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">while</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#000">i </span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#000"> count</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 =C2=A0 =C2=A0 fn</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">first</span><span style=3D"color:#660">[</sp=
an><span style=3D"color:#000">i</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><span style=3D"color:#000"><br><br></span><span style=3D"color:=
#660">}</span></div></code></div><div><br></div>Which would enable code lik=
e this:<br><br></div><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:#000">unrolled</span><span style=3D"=
color:#660">::</span><span style=3D"color:#000">for_each_n</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#066">3</span><span style=
=3D"color:#660">&gt;(</span><span style=3D"color:#000">std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#008">b<wbr>egin</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">arr</span><span st=
yle=3D"color:#660">),</span><span style=3D"color:#000"> </span><span style=
=3D"color:#066">30</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">[](</span><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> elem</span><span style=3D"c=
olor:#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 sty=
le=3D"color:#800">// do whatever with elem</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#660">}</span></div></code></div><div><br>=
</div><div><br></div><div>It would be functionally the same as a regular st=
d::for_each_n, but unrolled into blocks of size 3 as much as possible.</div=
><div><br></div><div>Thoughts? Is this just not worth the effort?</div><div=
>Evan</div></div></blockquote></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/b4bd172a-05c9-4a92-83fa-beba24150472%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b4bd172a-05c9-4a92-83fa-beba24150472=
%40isocpp.org</a>.<br />

------=_Part_1508_681461918.1498423151818--

------=_Part_1507_901239115.1498423151817--

.
