Topic: Array of lambdas


Author: "dgutson ." <danielgutson@gmail.com>
Date: Wed, 24 Jun 2015 12:03:10 -0300
Raw View
--001a11393bba268a11051944ce6a
Content-Type: text/plain; charset=UTF-8

The reason that this cannot be done

const std::array<decltype([](){ return 0;}), 3> x = {
[](){return 1;},
[](){return 2;},
[](){return 3;}
};

is that each lambda has its own unique type?
Of course this can be done with an array of std::function.

Daniel.

--

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

--001a11393bba268a11051944ce6a
Content-Type: text/html; charset=UTF-8

<p dir="ltr">The reason that this cannot be done</p>
<p dir="ltr">const std::array&lt;decltype([](){ return 0;}), 3&gt; x = {<br>
[](){return 1;},<br>
[](){return 2;},<br>
[](){return 3;}<br>
};</p>
<p dir="ltr">is that each lambda has its own unique type?<br>
Of course this can be done with an array of std::function.</p>
<p dir="ltr">Daniel.</p>

<p></p>

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

--001a11393bba268a11051944ce6a--

.


Author: "dgutson ." <danielgutson@gmail.com>
Date: Wed, 24 Jun 2015 12:06:47 -0300
Raw View
--001a114914ae1071ee051944db9b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

El 24/6/2015 12:03, "dgutson ." <danielgutson@gmail.com> escribi=C3=B3:
>
> The reason that this cannot be done
>
> const std::array<decltype([](){ return 0;}), 3> x =3D {
> [](){return 1;},
> [](){return 2;},
> [](){return 3;}
> };
>
> is that each lambda has its own unique type?
> Of course this can be done with an array of std::function.

The reason I'm posting it here is to analyze whether such code should make
sense or not. At least from a performance POV, that example I think would
be faster than the array of std::function.

>
> Daniel.

--=20

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

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

<p dir=3D"ltr"><br>
El 24/6/2015 12:03, &quot;dgutson .&quot; &lt;<a href=3D"mailto:danielgutso=
n@gmail.com">danielgutson@gmail.com</a>&gt; escribi=C3=B3:<br>
&gt;<br>
&gt; The reason that this cannot be done<br>
&gt;<br>
&gt; const std::array&lt;decltype([](){ return 0;}), 3&gt; x =3D {<br>
&gt; [](){return 1;},<br>
&gt; [](){return 2;},<br>
&gt; [](){return 3;}<br>
&gt; };<br>
&gt;<br>
&gt; is that each lambda has its own unique type?<br>
&gt; Of course this can be done with an array of std::function.</p>
<p dir=3D"ltr">The reason I&#39;m posting it here is to analyze whether suc=
h code should make sense or not. At least from a performance POV, that exam=
ple I think would be faster than the array of std::function.<br></p>
<p dir=3D"ltr">&gt;<br>
&gt; Daniel.</p>

<p></p>

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

--001a114914ae1071ee051944db9b--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 24 Jun 2015 10:19:35 -0500
Raw View
--047d7b5d88ed35e82e0519450bcc
Content-Type: text/plain; charset=UTF-8

On 24 June 2015 at 10:03, dgutson . <danielgutson@gmail.com> wrote:

> The reason that this cannot be done
>
> const std::array<decltype([](){ return 0;}), 3> x = {
> [](){return 1;},
> [](){return 2;},
> [](){return 3;}
> };
>
> is that each lambda has its own unique type?
> Of course this can be done with an array of std::function.
>
Because you have captureless lambdas, this should work:

const std::array<int(*)(), 3> x = {
[](){return 1;},
[](){return 2;},
[](){return 3;}
};
Note:  You cannot use decltype on the lambda, because you are not allowed
to use a lambda expression in an unevaluated context.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

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

--047d7b5d88ed35e82e0519450bcc
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 2=
4 June 2015 at 10:03, dgutson . <span dir=3D"ltr">&lt;<a href=3D"mailto:dan=
ielgutson@gmail.com" target=3D"_blank">danielgutson@gmail.com</a>&gt;</span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-s=
tyle:solid;padding-left:1ex"><p dir=3D"ltr">The reason that this cannot be =
done</p>
<p dir=3D"ltr">const std::array&lt;decltype([](){ return 0;}), 3&gt; x =3D =
{<br>
[](){return 1;},<br>
[](){return 2;},<br>
[](){return 3;}<br>
};</p>
<p dir=3D"ltr">is that each lambda has its own unique type?<br>
Of course this can be done with an array of std::function.</p></blockquote>=
<div>Because you have captureless lambdas, this should work:</div><div><p d=
ir=3D"ltr">const std::array&lt;int(*)(), 3&gt; x =3D {<br>[](){return 1;},<=
br>[](){return 2;},<br>[](){return 3;}<br>};</p></div><div>Note: =C2=A0You =
cannot use decltype on the lambda, because you are not allowed to use a lam=
bda expression in an unevaluated context.</div></div>-- <br><div class=3D"g=
mail_signature">=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=
=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com=
</a>&gt;=C2=A0 (847) 691-1404</div>
</div></div>

<p></p>

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

--047d7b5d88ed35e82e0519450bcc--

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Wed, 24 Jun 2015 18:38:24 +0300
Raw View
This is a multi-part message in MIME format.
--------------050301050206030502040708
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 24/06/15 18:06, dgutson . wrote:
>
>
> El 24/6/2015 12:03, "dgutson ." <danielgutson@gmail.com
> <mailto:danielgutson@gmail.com>> escribi=C3=B3:
> >
> > The reason that this cannot be done
> >
> > const std::array<decltype([](){ return 0;}), 3> x =3D {
> > [](){return 1;},
> > [](){return 2;},
> > [](){return 3;}
> > };
> >
> > is that each lambda has its own unique type?
> > Of course this can be done with an array of std::function.
>
> The reason I'm posting it here is to analyze whether such code should
> make sense or not. At least from a performance POV, that example I
> think would be faster than the array of std::function.
>
std::function is horrible. It allocates dynamically, causing it to be
useless in many cases that would otherwise need it.

However, even had that not been the case, calling a lmbda is faster, for
precisely the same reason your array won't work. When you call a lmbda,
its address is being resolved by the linker, not at run time. This is
achieved by giving each lambda its own type. If you check the sizeof of
a captureless lambda, it will be 1 (mostly because C++ forbids types of
size zero). It simply does not carry any useful information beyond its
static type.

Shachar

--=20

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

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

<html style=3D"direction: ltr;">
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
    <style type=3D"text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt=
; } </style>
  </head>
  <body style=3D"direction: ltr;" bidimailui-charset-is-forced=3D"true"
    bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 24/06/15 18:06, dgutson . wrote:<br>
    </div>
    <blockquote
cite=3D"mid:CAFdMc-3Nfa1hPOhNTnZXNNZT5nQEFuE6BnPXujY7y-xcJnUfCg@mail.gmail.=
com"
      type=3D"cite">
      <p dir=3D"ltr"><br>
        El 24/6/2015 12:03, "dgutson ." &lt;<a moz-do-not-send=3D"true"
          href=3D"mailto:danielgutson@gmail.com">danielgutson@gmail.com</a>=
&gt;
        escribi=C3=B3:<br>
        &gt;<br>
        &gt; The reason that this cannot be done<br>
        &gt;<br>
        &gt; const std::array&lt;decltype([](){ return 0;}), 3&gt; x =3D {<=
br>
        &gt; [](){return 1;},<br>
        &gt; [](){return 2;},<br>
        &gt; [](){return 3;}<br>
        &gt; };<br>
        &gt;<br>
        &gt; is that each lambda has its own unique type?<br>
        &gt; Of course this can be done with an array of std::function.</p>
      <p dir=3D"ltr">The reason I'm posting it here is to analyze whether
        such code should make sense or not. At least from a performance
        POV, that example I think would be faster than the array of
        std::function.<br>
      </p>
    </blockquote>
    std::function is horrible. It allocates dynamically, causing it to
    be useless in many cases that would otherwise need it.<br>
    <br>
    However, even had that not been the case, calling a lmbda is faster,
    for precisely the same reason your array won't work. When you call a
    lmbda, its address is being resolved by the linker, not at run time.
    This is achieved by giving each lambda its own type. If you check
    the sizeof of a captureless lambda, it will be 1 (mostly because C++
    forbids types of size zero). It simply does not carry any useful
    information beyond its static type.<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------050301050206030502040708--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 24 Jun 2015 23:41:34 +0800
Raw View
--Apple-Mail=_9C0613C7-7373-4A1C-A68C-6345C35E8CB2
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9306=E2=80=9324, at 11:03 PM, dgutson . <danielgutson@gmail=
..com> wrote:
> The reason that this cannot be done
>=20
> is that each lambda has its own unique type?
>=20
Correct.
> Of course this can be done with an array of std::function.
>=20

Since those lambdas are all captureless, it can also be done with an array =
of void(*)().

If you do have captures, but you=E2=80=99re interested in something lighter=
 than std::function, ideally you could pass it a non-allocating allocator. =
Then it=E2=80=99s basically a function pointer plus space for three word-si=
ze captures. (More or less=E2=80=A6 but usually three.)

Unfortunately, this doesn=E2=80=99t currently work in GCC (doesn=E2=80=99t =
find the function constructor) nor Clang (tries to call non_allocator::allo=
cate). It does work under my own implementation <https://github.com/potswa/=
cxx_function>=E2=80=A6 likely to work in real life the long run, FWIW.

template< typename t =3D char >
struct non_allocator : std::allocator< t > {
    t * allocate( std::size_t ) =3D delete; // Don=E2=80=99t really allocat=
e anything!

    template< typename u >
    non_allocator( non_allocator< u > ) {}
    template< typename u >
    struct rebind { typedef non_allocator< u > other; };
};

const std::array<std::function< int() >, 3> x =3D {
{ std::allocator_arg, non_allocator<>{}, [](){return 1;} }, // OK: small fu=
nctions don=E2=80=99t need heap allocation
{ std::allocator_arg, non_allocator<>{}, [](){return 2;} },
{ std::allocator_arg, non_allocator<>{}, [](){return 3;} },
{ std::allocator_arg, non_allocator<>{}, [ cap =3D std::array< int, 20 >() =
](){return 4;} } // Error: not small
};

--=20

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

--Apple-Mail=_9C0613C7-7373-4A1C-A68C-6345C35E8CB2
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9306=
=E2=80=9324, at 11:03 PM, dgutson . &lt;<a href=3D"mailto:danielgutson@gmai=
l.com" class=3D"">danielgutson@gmail.com</a>&gt; wrote:</div><div class=3D"=
"><p dir=3D"ltr" class=3D"">The reason that this cannot be done</p><p dir=
=3D"ltr" class=3D"">is that each lambda has its own unique type?</p></div><=
/blockquote><div>Correct.</div><blockquote type=3D"cite" class=3D""><div cl=
ass=3D""><p dir=3D"ltr" class=3D"">
Of course this can be done with an array of std::function.</p></div></block=
quote></div><div>Since those lambdas are all captureless, it can also be do=
ne with an array of <font face=3D"Courier" class=3D"">void(*)()</font>.</di=
v><div><br class=3D""></div><div>If you do have captures, but you=E2=80=99r=
e interested in something lighter than&nbsp;<font face=3D"Courier" class=3D=
"">std::function</font>, ideally you could pass it a non-allocating allocat=
or. Then it=E2=80=99s basically a function pointer plus space for three wor=
d-size captures. (More or less=E2=80=A6 but usually three.)</div><div><font=
 face=3D"Courier" class=3D""><br class=3D""></font>Unfortunately, this does=
n=E2=80=99t currently work in GCC (doesn=E2=80=99t find the <font face=3D"C=
ourier" class=3D"">function</font> constructor) nor Clang (tries to call&nb=
sp;<font face=3D"Courier" class=3D"">non_allocator::allocate</font>). It do=
es work under my own&nbsp;<a href=3D"https://github.com/potswa/cxx_function=
" class=3D"">implementation</a>=E2=80=A6 likely to work in real life the lo=
ng run, FWIW.</div><div><br class=3D""></div><div><font face=3D"Courier" cl=
ass=3D"">template&lt; typename t =3D char &gt;</font></div><div><font face=
=3D"Courier" class=3D"">struct non_allocator : std::allocator&lt; t &gt; {<=
/font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; t * alloca=
te( std::size_t ) =3D delete; // Don=E2=80=99t really allocate anything!</f=
ont></div><div><font face=3D"Courier" class=3D""><br class=3D""></font></di=
v><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; template&lt; typenam=
e u &gt;</font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; n=
on_allocator( non_allocator&lt; u &gt; ) {}</font></div><div><font face=3D"=
Courier" class=3D"">&nbsp; &nbsp; template&lt; typename u &gt;</font></div>=
<div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; struct rebind { typede=
f non_allocator&lt; u &gt; other; };</font></div><div><font face=3D"Courier=
" class=3D"">};</font></div><div><font face=3D"Courier" class=3D""><br clas=
s=3D""></font></div><div><font face=3D"Courier" class=3D"">const std::array=
&lt;std::function&lt; int() &gt;, 3&gt; x =3D {<br class=3D"">{ std::alloca=
tor_arg,&nbsp;</font><span style=3D"font-family: Courier;" class=3D"">non_a=
llocator&lt;&gt;{},</span><font face=3D"Courier" class=3D"">&nbsp;[](){retu=
rn 1;} }, // OK:&nbsp;small functions don=E2=80=99t need heap allocation</f=
ont></div><div><font face=3D"Courier" class=3D"">{ std::allocator_arg,&nbsp=
;</font><span style=3D"font-family: Courier;" class=3D"">non_allocator&lt;&=
gt;{},</span><span style=3D"font-family: Courier;" class=3D"">&nbsp;[](){re=
turn 2;} },</span></div><div><font face=3D"Courier" class=3D"">{ std::alloc=
ator_arg,&nbsp;</font><span style=3D"font-family: Courier;" class=3D"">non_=
allocator&lt;&gt;{},</span><span style=3D"font-family: Courier;" class=3D""=
>&nbsp;[](){return 3;} },</span></div><div><font face=3D"Courier" class=3D"=
">{ std::allocator_arg,&nbsp;</font><span style=3D"font-family: Courier;" c=
lass=3D"">non_allocator&lt;&gt;{},</span><span style=3D"font-family: Courie=
r;" class=3D"">&nbsp;[&nbsp;</span><font face=3D"Courier" class=3D"">cap =
=3D std::array&lt; int, 20 &gt;()&nbsp;</font><span style=3D"font-family: C=
ourier;" class=3D"">](){return 4;} } // Error: not small</span></div><div><=
font face=3D"Courier" class=3D"">};<br class=3D""></font><br class=3D""></d=
iv></body></html>

<p></p>

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

--Apple-Mail=_9C0613C7-7373-4A1C-A68C-6345C35E8CB2--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 24 Jun 2015 11:00:29 -0500
Raw View
--f46d04428f347d0e5f0519459dae
Content-Type: text/plain; charset=UTF-8

On 24 June 2015 at 10:38, Shachar Shemesh <shachar@lingnu.com> wrote:

> std::function is horrible. It allocates dynamically, causing it to be
> useless in many cases that would otherwise need it.
>

Given that most std::function implementations implement the small object
optimization, and a captureless lambda is about as small an object as you
can have, can you elaborate on why you think dynamic allocation is an in
the case (other than the size of the array might be a little bigger)?
 (Note:  it could be if the held object had a throwing move constructor and
the particular implementation of std::function had a noexcept move
constructor, but captureless lambdas don't have throwing move constructors),
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On 24 June 2015 at 10:38, Shachar Shemesh <span dir=3D"ltr">&lt;<a href=3D"=
mailto:shachar@lingnu.com" target=3D"_blank">shachar@lingnu.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div style=3D"direction:ltr" b=
gcolor=3D"#FFFFFF" text=3D"#000000">std::function is horrible. It allocates=
 dynamically, causing it to
    be useless in many cases that would otherwise need it.<br></div></block=
quote><div><br></div><div>Given that most std::function implementations imp=
lement the small object optimization, and a captureless lambda is about as =
small an object as you can have, can you elaborate on why you think dynamic=
 allocation is an in the case (other than the size of the array might be a =
little bigger)? =C2=A0(Note: =C2=A0it could be if the held object had a thr=
owing move constructor and the particular implementation of std::function h=
ad a noexcept move constructor, but captureless lambdas don&#39;t have thro=
wing move constructors),</div></div>-- <br><div>=C2=A0Nevin &quot;:-)&quot;=
 Liber=C2=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D=
"_blank">nevin@eviloverlord.com</a>&gt;=C2=A0 <a href=3D"tel:%28847%29%2069=
1-1404" value=3D"+18476911404" target=3D"_blank">(847) 691-1404</a></div>
</div></div>

<p></p>

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

--f46d04428f347d0e5f0519459dae--

.


Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 24 Jun 2015 19:00:59 +0300
Raw View
24.06.2015 18:03, dgutson .:
> The reason that this cannot be done
>
> const std::array<decltype([](){ return 0;}), 3> x = {
> [](){return 1;},
> [](){return 2;},
> [](){return 3;}
> };
>
> is that each lambda has its own unique type?

Yes, each lambda has its own type. As others said - in your case you can
just convert lambda to pointer.
In general case, when you cannot convert lambda to pointer, another
option is to use some kind of hetergogeneus container, like std::tuple
or boost::fusion::vector, for example:
http://coliru.stacked-crooked.com/a/5947c7c35194321f

double x = 0.5;
int y = 11;
char z = 'a';

auto closures = fusion::make_vector
(
     [&]{ return x; },
     [&]{ return y; },
     [&]{ return z; }
);

fusion::for_each(closures, [](auto a)
{
     cout << a() << endl;
});


--
Evgeny Panasyuk

--

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

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Wed, 24 Jun 2015 21:00:57 +0300
Raw View
This is a multi-part message in MIME format.
--------------080700030200020005030809
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 24/06/15 18:41, David Krauss wrote:
>
>> On 2015=E2=80=9306=E2=80=9324, at 11:03 PM, dgutson . <danielgutson@gmai=
l.com
>> <mailto:danielgutson@gmail.com>> wrote:
>>
>> The reason that this cannot be done
>>
>> is that each lambda has its own unique type?
>>
> Correct.
>>
>> Of course this can be done with an array of std::function.
>>
> Since those lambdas are all captureless, it can also be done with an
> array of void(*)().
>
> If you do have captures, but you=E2=80=99re interested in something light=
er
> than std::function, ideally you could pass it a non-allocating
> allocator. Then it=E2=80=99s basically a function pointer plus space for =
three
> word-size captures. (More or less=E2=80=A6 but usually three.)
Can you elaborate how you reached this number? Or is this just your
estimation of the average?

For a lambda where the capture is composed only of variables passed by
reference, one pointer ought to have been enough. This is the situation
in, e.g., D (where a delegate is defined to be the size of two pointers,
one of which is the pointer to the actual function). At least under gcc,
this is, sadly, not the case:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D53097

Shachar

--=20

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

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

<html style=3D"direction: ltr;">
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
    <style type=3D"text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt=
; } </style>
  </head>
  <body style=3D"direction: ltr;" bidimailui-charset-is-forced=3D"true"
    bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 24/06/15 18:41, David Krauss wrote:<b=
r>
    </div>
    <blockquote
      cite=3D"mid:359C3CEB-28AB-4462-A3A2-A228C9021057@gmail.com"
      type=3D"cite">
      <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8">
      <br class=3D"">
      <div>
        <blockquote type=3D"cite" class=3D"">
          <div class=3D"">On 2015=E2=80=9306=E2=80=9324, at 11:03 PM, dguts=
on . &lt;<a
              moz-do-not-send=3D"true"
              href=3D"mailto:danielgutson@gmail.com" class=3D"">danielgutso=
n@gmail.com</a>&gt;
            wrote:</div>
          <div class=3D"">
            <p dir=3D"ltr" class=3D"">The reason that this cannot be done</=
p>
            <p dir=3D"ltr" class=3D"">is that each lambda has its own uniqu=
e
              type?</p>
          </div>
        </blockquote>
        <div>Correct.</div>
        <blockquote type=3D"cite" class=3D"">
          <div class=3D"">
            <p dir=3D"ltr" class=3D"">
              Of course this can be done with an array of std::function.</p=
>
          </div>
        </blockquote>
      </div>
      <div>Since those lambdas are all captureless, it can also be done
        with an array of <font class=3D"" face=3D"Courier">void(*)()</font>=
..</div>
      <div><br class=3D"">
      </div>
      <div>If you do have captures, but you=E2=80=99re interested in someth=
ing
        lighter than=C2=A0<font class=3D"" face=3D"Courier">std::function</=
font>,
        ideally you could pass it a non-allocating allocator. Then it=E2=80=
=99s
        basically a function pointer plus space for three word-size
        captures. (More or less=E2=80=A6 but usually three.)</div>
    </blockquote>
    Can you elaborate how you reached this number? Or is this just your
    estimation of the average?<br>
    <br>
    For a lambda where the capture is composed only of variables passed
    by reference, one pointer ought to have been enough. This is the
    situation in, e.g., D (where a delegate is defined to be the size of
    two pointers, one of which is the pointer to the actual function).
    At least under gcc, this is, sadly, not the case:
    <a class=3D"moz-txt-link-freetext" href=3D"https://gcc.gnu.org/bugzilla=
/show_bug.cgi?id=3D53097">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D53=
097</a><br>
    <br>
    Shachar<br>
    <br>
  </body>
</html>

<p></p>

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

--------------080700030200020005030809--

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Wed, 24 Jun 2015 21:10:02 +0300
Raw View
This is a multi-part message in MIME format.
--------------080408030800080807030806
Content-Type: text/plain; charset=UTF-8

On 24/06/15 19:00, Nevin Liber wrote:
>
> Given that most std::function implementations implement the small
> object optimization, and a captureless lambda is about as small an
> object as you can have, can you elaborate on why you think dynamic
> allocation is an in the case (other than the size of the array might
> be a little bigger)?
I don't know about "most". What I can do is relate my personal
experience. While working on fakeroot-ng
(http://fakeroot-ng.lingnu.com), I had to pass a function with context
between two threads. I created an interface based on std::function. When
it gave horrid performance, I ran a profiler to find out why. The reason
was the dynamic allocation. See
http://sourceforge.net/p/fakerootng/source/ci/efc254eccaa212fe9cb96133a9004e1ade9c638c/
for the commit that dumps the use of std::function.

Part of the blame for this might be gcc's implementation of by reference
capture variables. Instead of saving just the pointer to the frame from
which these variables can be found, gcc saves a reference to each and
every such variable. See my reply to David to the open bug about it.
This greatly increases the size of lambda types, and may be the reason
that in place allocation doesn't kick in.

Either way, in practice, std::function is useless for low latency
programming with gcc.

>  (Note:  it could be if the held object had a throwing move
> constructor and the particular implementation of std::function had a
> noexcept move constructor, but captureless lambdas don't have throwing
> move constructors),
No, that's not it.

Shachar

--

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

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

<html style=3D"direction: ltr;">
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
    <style type=3D"text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt=
; } </style>
  </head>
  <body style=3D"direction: ltr;" bidimailui-charset-is-forced=3D"true"
    bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 24/06/15 19:00, Nevin Liber wrote:<br=
>
    </div>
    <blockquote
cite=3D"mid:CAGg_6+O-bZqw2YO7r2Tks9TVrS8vGnABkgpN01N6YWvNAtt9FQ@mail.gmail.=
com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_extra">
          <div class=3D"gmail_quote"><br>
            <div>Given that most std::function implementations implement
              the small object optimization, and a captureless lambda is
              about as small an object as you can have, can you
              elaborate on why you think dynamic allocation is an in the
              case (other than the size of the array might be a little
              bigger)?</div>
          </div>
        </div>
      </div>
    </blockquote>
    I don't know about "most". What I can do is relate my personal
    experience. While working on fakeroot-ng
    (<a class=3D"moz-txt-link-freetext" href=3D"http://fakeroot-ng.lingnu.c=
om">http://fakeroot-ng.lingnu.com</a>), I had to pass a function with
    context between two threads. I created an interface based on
    std::function. When it gave horrid performance, I ran a profiler to
    find out why. The reason was the dynamic allocation. See
    <a class=3D"moz-txt-link-freetext" href=3D"http://sourceforge.net/p/fak=
erootng/source/ci/efc254eccaa212fe9cb96133a9004e1ade9c638c/">http://sourcef=
orge.net/p/fakerootng/source/ci/efc254eccaa212fe9cb96133a9004e1ade9c638c/</=
a>
    for the commit that dumps the use of std::function.<br>
    <br>
    Part of the blame for this might be gcc's implementation of by
    reference capture variables. Instead of saving just the pointer to
    the frame from which these variables can be found, gcc saves a
    reference to each and every such variable. See my reply to David to
    the open bug about it. This greatly increases the size of lambda
    types, and may be the reason that in place allocation doesn't kick
    in.<br>
    <br>
    Either way, in practice, std::function is useless for low latency
    programming with gcc.<br>
    <br>
    <blockquote
cite=3D"mid:CAGg_6+O-bZqw2YO7r2Tks9TVrS8vGnABkgpN01N6YWvNAtt9FQ@mail.gmail.=
com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_extra">
          <div class=3D"gmail_quote">
            <div> =C2=A0(Note: =C2=A0it could be if the held object had a t=
hrowing
              move constructor and the particular implementation of
              std::function had a noexcept move constructor, but
              captureless lambdas don't have throwing move
              constructors),</div>
          </div>
        </div>
      </div>
    </blockquote>
    No, that's not it.<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------080408030800080807030806--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 24 Jun 2015 16:26:44 -0700
Raw View
On Wednesday 24 June 2015 21:00:57 Shachar Shemesh wrote:
> For a lambda where the capture is composed only of variables passed by
> reference, one pointer ought to have been enough.

Qualification required: variables in the same scope that are captured by
reference.

If those variables are in different scopes, then the it needs to capture the
different scopes.

> This is the situation
> in, e.g., D (where a delegate is defined to be the size of two pointers,
> one of which is the pointer to the actual function). At least under gcc,
> this is, sadly, not the case:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53097

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

--

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

.


Author: David Krauss <potswa@mac.com>
Date: Thu, 25 Jun 2015 07:59:21 +0800
Raw View
--Apple-Mail=_F9B76170-B687-4773-AB46-A9B9CFD79918
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9306=E2=80=9325, at 2:00 AM, Shachar Shemesh <shachar@lingn=
u.com> wrote:
>=20
>>  (More or less=E2=80=A6 but usually three.)
> Can you elaborate how you reached this number? Or is this just your estim=
ation of the average?

The is the amount of storage recommended in [func.wrap.func.con] =C2=A720.9=
..12.2.1/5: =E2=80=9CImplementations are encouraged to avoid the use of dyna=
mically allocated memory for small callable objects, for example, where f=
=E2=80=99s target is an object holding only a pointer or reference to an ob=
ject and a member function pointer.=E2=80=9D It is the amount of storage pr=
ovided by GCC, Clang, and most third-party libraries <https://github.com/ja=
mboree/CxxFunctionBenchmark/>. A PTMF is two words, and an object pointer i=
s one, on typical ABIs.


> On 2015=E2=80=9306=E2=80=9325, at 7:26 AM, Thiago Macieira <thiago@maciei=
ra.org> wrote:
>=20
> Qualification required: variables in the same scope that are captured by=
=20
> reference.
>=20
> If those variables are in different scopes, then the it needs to capture =
the=20
> different scopes.

One pointer should be enough, and it would usually be a pointer to the curr=
ent stack frame. The only scopes from which you can capture are inside the =
current function, and the only eligible variables are of automatic storage =
duration.

I=E2=80=99ve raised this issue occasionally for years. Thanks, Sachar, for =
the bug. The response I recall is that the common ABI defines the layout of=
 lambda functions. I=E2=80=99m not sure how seriously this is taken.

--=20

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

--Apple-Mail=_F9B76170-B687-4773-AB46-A9B9CFD79918
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9306=
=E2=80=9325, at 2:00 AM, Shachar Shemesh &lt;<a href=3D"mailto:shachar@ling=
nu.com" class=3D"">shachar@lingnu.com</a>&gt; wrote:</div><br class=3D"Appl=
e-interchange-newline"><div class=3D""><div bidimailui-charset-is-forced=3D=
"true" bgcolor=3D"#FFFFFF" text=3D"#000000" style=3D"direction: ltr;" class=
=3D""><blockquote cite=3D"mid:359C3CEB-28AB-4462-A3A2-A228C9021057@gmail.co=
m" type=3D"cite" style=3D"font-family: Helvetica; font-size: 12px; font-sty=
le: normal; font-variant: normal; font-weight: normal; letter-spacing: norm=
al; line-height: normal; orphans: auto; text-align: start; text-indent: 0px=
; text-transform: none; white-space: normal; widows: auto; word-spacing: 0p=
x; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" c=
lass=3D""><div class=3D""><span class=3D"Apple-converted-space">&nbsp;</spa=
n>(More or less=E2=80=A6 but usually three.)</div></blockquote><span style=
=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-varia=
nt: normal; font-weight: normal; letter-spacing: normal; line-height: norma=
l; orphans: auto; text-align: start; text-indent: 0px; text-transform: none=
; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke=
-width: 0px; background-color: rgb(255, 255, 255); float: none; display: in=
line !important;" class=3D"">Can you elaborate how you reached this number?=
 Or is this just your estimation of the average?</span></div></div></blockq=
uote></div><br class=3D""><div class=3D"">The is the amount of storage reco=
mmended in [func.wrap.func.con] =C2=A720.9.12.2.1/5: =E2=80=9CImplementatio=
ns are encouraged to avoid the use of dynamically&nbsp;allocated memory for=
 small callable objects, for example, where&nbsp;<font face=3D"Courier" cla=
ss=3D"">f</font>=E2=80=99s target is an object holding only a&nbsp;pointer =
or&nbsp;reference to an object and a member function pointer.=E2=80=9D It i=
s the amount of storage provided by GCC, Clang, and&nbsp;<a href=3D"https:/=
/github.com/jamboree/CxxFunctionBenchmark/" class=3D"">most third-party lib=
raries</a>. A PTMF is two words, and an object pointer is one, on typical A=
BIs.</div><div class=3D""><br class=3D""></div><div class=3D""><br class=3D=
""></div><div class=3D""><blockquote type=3D"cite" class=3D""><div class=3D=
"">On 2015=E2=80=9306=E2=80=9325, at 7:26 AM, Thiago Macieira &lt;<a href=
=3D"mailto:thiago@macieira.org" class=3D"">thiago@macieira.org</a>&gt; wrot=
e:</div><br class=3D"Apple-interchange-newline"><div class=3D""><span class=
=3D"" style=3D"float: none; display: inline !important;">Qualification requ=
ired: variables in the same scope that are captured by&nbsp;</span><br clas=
s=3D""><span class=3D"" style=3D"float: none; display: inline !important;">=
reference.</span><br class=3D""><br class=3D""><span class=3D"" style=3D"fl=
oat: none; display: inline !important;">If those variables are in different=
 scopes, then the it needs to capture the&nbsp;</span><br class=3D""><span =
class=3D"" style=3D"float: none; display: inline !important;">different sco=
pes.</span><br class=3D"Apple-interchange-newline"></div></blockquote><br c=
lass=3D""></div><div class=3D"">One pointer should be enough, and it would =
usually be a pointer to the current stack frame. The only scopes from which=
 you can capture are inside the current function, and the only eligible var=
iables are of automatic storage duration.</div><div class=3D""><br class=3D=
""></div><div class=3D"">I=E2=80=99ve raised this issue occasionally for ye=
ars. Thanks, Sachar, for the bug. The response I recall is that the common =
ABI defines the layout of lambda functions. I=E2=80=99m not sure how seriou=
sly this is taken.</div></body></html>

<p></p>

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

--Apple-Mail=_F9B76170-B687-4773-AB46-A9B9CFD79918--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 24 Jun 2015 17:22:31 -0700
Raw View
--001a1133c16e88670005194c9ef2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jun 24, 2015 at 4:59 PM, David Krauss <potswa@mac.com> wrote:

>
> On 2015=E2=80=9306=E2=80=9325, at 2:00 AM, Shachar Shemesh <shachar@lingn=
u.com> wrote:
>
>  (More or less=E2=80=A6 but usually three.)
>
> Can you elaborate how you reached this number? Or is this just your
> estimation of the average?
>
>
> The is the amount of storage recommended in [func.wrap.func.con]
> =C2=A720.9.12.2.1/5: =E2=80=9CImplementations are encouraged to avoid the=
 use of
> dynamically allocated memory for small callable objects, for example, whe=
re
> f=E2=80=99s target is an object holding only a pointer or reference to an=
 object
> and a member function pointer.=E2=80=9D It is the amount of storage provi=
ded by
> GCC, Clang, and most third-party libraries
> <https://github.com/jamboree/CxxFunctionBenchmark/>. A PTMF is two words,
> and an object pointer is one, on typical ABIs.
>
>
> On 2015=E2=80=9306=E2=80=9325, at 7:26 AM, Thiago Macieira <thiago@maciei=
ra.org> wrote:
>
> Qualification required: variables in the same scope that are captured by
> reference.
>
> If those variables are in different scopes, then the it needs to capture
> the
> different scopes.
>
>
> One pointer should be enough, and it would usually be a pointer to the
> current stack frame. The only scopes from which you can capture are insid=
e
> the current function, and the only eligible variables are of automatic
> storage duration.
>
> I=E2=80=99ve raised this issue occasionally for years. Thanks, Sachar, fo=
r the
> bug. The response I recall is that the common ABI defines the layout of
> lambda functions.
>

The Itanium C++ ABI does not do so (though it should, in the cases where
the layout is visible across translation units). The problem is that it's
extremely difficult to use a pointer to the stack frame or similar. For
instance, it depends on a number of factors that are not visible until some
stage in code generation, and must be decided during parsing / semantic
analysis because it affects observable properties of the closure type, such
as its size. It would also force not just the layout of the closure type,
but *the stack frame layout of the enclosing function*, to be part of the
ABI if it applied to lambdas in inline functions or function templates,
which is a completely unreasonable thing for an ABI to require. It's also
not clear that it's unambiguously a good thing in the remaining cases: it
puts some pretty stringent constraints on the stack layout of the enclosing
function, and very likely makes it uninlineable.

--=20

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

--001a1133c16e88670005194c9ef2
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 W=
ed, Jun 24, 2015 at 4:59 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"=
mailto:potswa@mac.com" target=3D"_blank">potswa@mac.com</a>&gt;</span> wrot=
e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex"><div style=3D"word-wrap:break-word"><span class=3D""=
><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=9306=E2=80=9325, at =
2:00 AM, Shachar Shemesh &lt;<a href=3D"mailto:shachar@lingnu.com" target=
=3D"_blank">shachar@lingnu.com</a>&gt; wrote:</div><br><div><div bgcolor=3D=
"#FFFFFF" text=3D"#000000" style=3D"direction:ltr"><blockquote type=3D"cite=
" style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-vari=
ant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text=
-align:start;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px;background-color:rgb(255,255,255)"><div><span>=C2=A0</span>(More =
or less=E2=80=A6 but usually three.)</div></blockquote><span style=3D"font-=
family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-=
weight:normal;letter-spacing:normal;line-height:normal;text-align:start;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:=
none;display:inline!important;background-color:rgb(255,255,255)">Can you el=
aborate how you reached this number? Or is this just your estimation of the=
 average?</span></div></div></blockquote></div><br></span><div>The is the a=
mount of storage recommended in [func.wrap.func.con] =C2=A720.9.12.2.1/5: =
=E2=80=9CImplementations are encouraged to avoid the use of dynamically=C2=
=A0allocated memory for small callable objects, for example, where=C2=A0<fo=
nt face=3D"Courier">f</font>=E2=80=99s target is an object holding only a=
=C2=A0pointer or=C2=A0reference to an object and a member function pointer.=
=E2=80=9D It is the amount of storage provided by GCC, Clang, and=C2=A0<a h=
ref=3D"https://github.com/jamboree/CxxFunctionBenchmark/" target=3D"_blank"=
>most third-party libraries</a>. A PTMF is two words, and an object pointer=
 is one, on typical ABIs.</div><span class=3D""><div><br></div><div><br></d=
iv><div><blockquote type=3D"cite"><div>On 2015=E2=80=9306=E2=80=9325, at 7:=
26 AM, Thiago Macieira &lt;<a href=3D"mailto:thiago@macieira.org" target=3D=
"_blank">thiago@macieira.org</a>&gt; wrote:</div><br><div><span style=3D"fl=
oat:none;display:inline!important">Qualification required: variables in the=
 same scope that are captured by=C2=A0</span><br><span style=3D"float:none;=
display:inline!important">reference.</span><br><br><span style=3D"float:non=
e;display:inline!important">If those variables are in different scopes, the=
n the it needs to capture the=C2=A0</span><br><span style=3D"float:none;dis=
play:inline!important">different scopes.</span><br></div></blockquote><br><=
/div></span><div>One pointer should be enough, and it would usually be a po=
inter to the current stack frame. The only scopes from which you can captur=
e are inside the current function, and the only eligible variables are of a=
utomatic storage duration.</div><div><br></div><div>I=E2=80=99ve raised thi=
s issue occasionally for years. Thanks, Sachar, for the bug. The response I=
 recall is that the common ABI defines the layout of lambda functions.</div=
></div></blockquote><div><br></div><div>The Itanium C++ ABI does not do so =
(though it should, in the cases where the layout is visible across translat=
ion units). The problem is that it&#39;s extremely difficult to use a point=
er to the stack frame or similar. For instance, it depends on a number of f=
actors that are not visible until some stage in code generation, and must b=
e decided during parsing / semantic analysis because it affects observable =
properties of the closure type, such as its size. It would also force not j=
ust the layout of the closure type, but=C2=A0<i>the stack frame layout of t=
he enclosing function</i>, to be part of the ABI if it applied to lambdas i=
n inline functions or function templates, which is a completely unreasonabl=
e thing for an ABI to require. It&#39;s also not clear that it&#39;s unambi=
guously a good thing in the remaining cases: it puts some pretty stringent =
constraints on the stack layout of the enclosing function, and very likely =
makes it uninlineable.<br></div></div></div></div>

<p></p>

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

--001a1133c16e88670005194c9ef2--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 25 Jun 2015 11:26:41 +0800
Raw View
--Apple-Mail=_0E227E9F-9F88-4C7E-A0B1-5275238EF14D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9306=E2=80=9325, at 8:22 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>=20
> The Itanium C++ ABI does not do so (though it should, in the cases where =
the layout is visible across translation units).

=E2=80=A6 and this implies that the lambda layout should not be sensitive t=
o stack frame layout, because the inlined function body in TU #1 may call t=
he un-inlined copy from TU #2 if it tries to recurse.

> The problem is that it's extremely difficult to use a pointer to the stac=
k frame or similar. For instance, it depends on a number of factors that ar=
e not visible until some stage in code generation, and must be decided duri=
ng parsing / semantic analysis because it affects observable properties of =
the closure type, such as its size.

Huh? The point is to decouple the size of the closure from its reference ca=
ptures.

But, yeah, copies of an unrolled loop (for example) could have different st=
ack layouts.

> It would also force not just the layout of the closure type, but the stac=
k frame layout of the enclosing function, to be part of the ABI if it appli=
ed to lambdas in inline functions or function templates, which is a complet=
ely unreasonable thing for an ABI to require. It's also not clear that it's=
 unambiguously a good thing in the remaining cases: it puts some pretty str=
ingent constraints on the stack layout of the enclosing function, and very =
likely makes it uninlineable.

I see. New idea, then: implement a local, invisible struct in the scope of =
the outermost capture. Populate it with the reference captures, adding assi=
gnment operations as targeted variables=E2=80=99 lifetimes begin. The lambd=
a points to the invisible struct. In the common case, the assignments can b=
e hoisted out of loops or such, all back out to the scope with the struct.

The indirection should only add one memory access per lambda call, and loca=
lity is good so it should never have much negative performance impact. The =
performance benefit with std::function on the other hand is significant.

--=20

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

--Apple-Mail=_0E227E9F-9F88-4C7E-A0B1-5275238EF14D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9306=
=E2=80=9325, at 8:22 AM, Richard Smith &lt;<a href=3D"mailto:richard@metafo=
o.co.uk" class=3D"">richard@metafoo.co.uk</a>&gt; wrote:</div><br class=3D"=
Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" style=3D"font-f=
amily: Helvetica; font-size: 12px; font-style: normal; font-variant: normal=
; font-weight: normal; letter-spacing: normal; line-height: normal; orphans=
: auto; text-align: start; text-indent: 0px; text-transform: none; white-sp=
ace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0p=
x;" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div c=
lass=3D"">The Itanium C++ ABI does not do so (though it should, in the case=
s where the layout is visible across translation units). </div></div></div>=
</div></div></blockquote><div><br class=3D""></div><div>=E2=80=A6 and this =
implies that the lambda layout should not be sensitive to stack frame layou=
t, because the inlined function body in TU #1 may call the un-inlined copy =
from TU #2 if it tries to recurse.</div><div><br class=3D""></div><blockquo=
te type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" style=3D"font-=
family: Helvetica; font-size: 12px; font-style: normal; font-variant: norma=
l; font-weight: normal; letter-spacing: normal; line-height: normal; orphan=
s: auto; text-align: start; text-indent: 0px; text-transform: none; white-s=
pace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0=
px;" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div =
class=3D"">The problem is that it's extremely difficult to use a pointer to=
 the stack frame or similar. For instance, it depends on a number of factor=
s that are not visible until some stage in code generation, and must be dec=
ided during parsing / semantic analysis because it affects observable prope=
rties of the closure type, such as its size. </div></div></div></div></div>=
</blockquote><div><br class=3D""></div><div>Huh? The point is to decouple t=
he size of the closure from its reference captures.</div><div><br class=3D"=
"></div><div>But, yeah, copies of an unrolled loop (for example) could have=
 different stack layouts.</div><br class=3D""><blockquote type=3D"cite" cla=
ss=3D""><div class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; f=
ont-size: 12px; font-style: normal; font-variant: normal; font-weight: norm=
al; letter-spacing: normal; line-height: normal; orphans: auto; text-align:=
 start; text-indent: 0px; text-transform: none; white-space: normal; widows=
: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><div=
 class=3D"gmail_extra"><div class=3D"gmail_quote"><div class=3D"">It would =
also force not just the layout of the closure type, but&nbsp;<i class=3D"">=
the stack frame layout of the enclosing function</i>, to be part of the ABI=
 if it applied to lambdas in inline functions or function templates, which =
is a completely unreasonable thing for an ABI to require. It's also not cle=
ar that it's unambiguously a good thing in the remaining cases: it puts som=
e pretty stringent constraints on the stack layout of the enclosing functio=
n, and very likely makes it uninlineable.<br class=3D""></div></div></div><=
/div></div></blockquote><br class=3D""></div><div>I see. New idea, then: im=
plement a local, invisible struct in the scope of the outermost capture. Po=
pulate it with the reference captures, adding assignment operations as targ=
eted variables=E2=80=99 lifetimes begin. The lambda points to the invisible=
 struct. In the common case, the assignments can be hoisted out of loops or=
 such, all back out to the scope with the struct.</div><div><br class=3D"">=
</div><div>The indirection should only add one memory access per lambda cal=
l, and locality is good so it should never have much negative performance i=
mpact. The performance benefit&nbsp;with&nbsp;<font face=3D"Courier" class=
=3D"">std::function</font>&nbsp;on the other hand is significant.</div></bo=
dy></html>

<p></p>

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

--Apple-Mail=_0E227E9F-9F88-4C7E-A0B1-5275238EF14D--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 24 Jun 2015 20:46:38 -0700
Raw View
--089e0118377a88247105194f78f9
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, Jun 24, 2015 at 8:26 PM, David Krauss <potswa@gmail.com> wrote:

>
> On 2015=E2=80=9306=E2=80=9325, at 8:22 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>
> The Itanium C++ ABI does not do so (though it should, in the cases where
> the layout is visible across translation units).
>
>
> =E2=80=A6 and this implies that the lambda layout should not be sensitive=
 to stack
> frame layout, because the inlined function body in TU #1 may call the
> un-inlined copy from TU #2 if it tries to recurse.
>
> The problem is that it's extremely difficult to use a pointer to the stac=
k
> frame or similar. For instance, it depends on a number of factors that ar=
e
> not visible until some stage in code generation, and must be decided duri=
ng
> parsing / semantic analysis because it affects observable properties of t=
he
> closure type, such as its size.
>
>
> Huh? The point is to decouple the size of the closure from its reference
> captures.
>

Right, but it means the decision of whether to perform the optimization
must be made immediately. It can't be deferred until we have enough
information to know whether it's a good idea.


> But, yeah, copies of an unrolled loop (for example) could have different
> stack layouts.
>
> It would also force not just the layout of the closure type, but *the
> stack frame layout of the enclosing function*, to be part of the ABI if
> it applied to lambdas in inline functions or function templates, which is=
 a
> completely unreasonable thing for an ABI to require. It's also not clear
> that it's unambiguously a good thing in the remaining cases: it puts some
> pretty stringent constraints on the stack layout of the enclosing functio=
n,
> and very likely makes it uninlineable.
>
>
> I see. New idea, then: implement a local, invisible struct in the scope o=
f
> the outermost capture. Populate it with the reference captures, adding
> assignment operations as targeted variables=E2=80=99 lifetimes begin. The=
 lambda
> points to the invisible struct. In the common case, the assignments can b=
e
> hoisted out of loops or such, all back out to the scope with the struct.
>
> The indirection should only add one memory access per lambda call, and
> locality is good so it should never have much negative performance impact=
..
> The performance benefit with std::function on the other hand is
> significant.
>

That's an interesting approach. The only obvious costs are the extra
indirection (which, as you say, should be cheap) and extra stack usage (but
even there, we win if there's more than one such lambda object alive at
once for any particular function).

--=20

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

--089e0118377a88247105194f78f9
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 W=
ed, Jun 24, 2015 at 8:26 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"=
mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> =
wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word=
"><br><div><span class=3D""><blockquote type=3D"cite"><div>On 2015=E2=80=93=
06=E2=80=9325, at 8:22 AM, Richard Smith &lt;<a href=3D"mailto:richard@meta=
foo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt; wrote:</div><br>=
<div><div dir=3D"ltr" style=3D"font-family:Helvetica;font-size:12px;font-st=
yle:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;lin=
e-height:normal;text-align:start;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><div>The Itanium C++ ABI does not do so (though it should, in the=
 cases where the layout is visible across translation units). </div></div><=
/div></div></div></blockquote><div><br></div></span><div>=E2=80=A6 and this=
 implies that the lambda layout should not be sensitive to stack frame layo=
ut, because the inlined function body in TU #1 may call the un-inlined copy=
 from TU #2 if it tries to recurse.</div><span class=3D""><div><br></div><b=
lockquote type=3D"cite"><div><div dir=3D"ltr" style=3D"font-family:Helvetic=
a;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;l=
etter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;te=
xt-transform:none;white-space:normal;word-spacing:0px"><div class=3D"gmail_=
extra"><div class=3D"gmail_quote"><div>The problem is that it&#39;s extreme=
ly difficult to use a pointer to the stack frame or similar. For instance, =
it depends on a number of factors that are not visible until some stage in =
code generation, and must be decided during parsing / semantic analysis bec=
ause it affects observable properties of the closure type, such as its size=
.. </div></div></div></div></div></blockquote><div><br></div></span><div>Huh=
? The point is to decouple the size of the closure from its reference captu=
res.</div></div></div></blockquote><div><br></div><div>Right, but it means =
the decision of whether to perform the optimization must be made immediatel=
y. It can&#39;t be deferred until we have enough information to know whethe=
r it&#39;s a good idea.</div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div style=3D"word-wrap:break-word"><div><div>But, yeah, copies of an unr=
olled loop (for example) could have different stack layouts.</div><span cla=
ss=3D""><br><blockquote type=3D"cite"><div><div dir=3D"ltr" style=3D"font-f=
amily:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-w=
eight:normal;letter-spacing:normal;line-height:normal;text-align:start;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><div>It would also force no=
t just the layout of the closure type, but=C2=A0<i>the stack frame layout o=
f the enclosing function</i>, to be part of the ABI if it applied to lambda=
s in inline functions or function templates, which is a completely unreason=
able thing for an ABI to require. It&#39;s also not clear that it&#39;s una=
mbiguously a good thing in the remaining cases: it puts some pretty stringe=
nt constraints on the stack layout of the enclosing function, and very like=
ly makes it uninlineable.<br></div></div></div></div></div></blockquote><br=
></span></div><div>I see. New idea, then: implement a local, invisible stru=
ct in the scope of the outermost capture. Populate it with the reference ca=
ptures, adding assignment operations as targeted variables=E2=80=99 lifetim=
es begin. The lambda points to the invisible struct. In the common case, th=
e assignments can be hoisted out of loops or such, all back out to the scop=
e with the struct.</div><div><br></div><div>The indirection should only add=
 one memory access per lambda call, and locality is good so it should never=
 have much negative performance impact. The performance benefit=C2=A0with=
=C2=A0<font face=3D"Courier">std::function</font>=C2=A0on the other hand is=
 significant.</div></div></blockquote><div><br></div><div>That&#39;s an int=
eresting approach. The only obvious costs are the extra indirection (which,=
 as you say, should be cheap) and extra stack usage (but even there, we win=
 if there&#39;s more than one such lambda object alive at once for any part=
icular function).</div></div></div></div>

<p></p>

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

--089e0118377a88247105194f78f9--

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Thu, 25 Jun 2015 07:57:09 +0300
Raw View
This is a multi-part message in MIME format.
--------------010109000602070103090504
Content-Type: text/plain; charset=UTF-8

On 25/06/15 02:26, Thiago Macieira wrote:
> On Wednesday 24 June 2015 21:00:57 Shachar Shemesh wrote:
>> For a lambda where the capture is composed only of variables passed by
>> reference, one pointer ought to have been enough.
> Qualification required: variables in the same scope that are captured by
> reference.
>
> If those variables are in different scopes, then the it needs to capture the
> different scopes.
The lambda is defined while inside one scope. Everything accessible by
the lmbda's definition is accessible from within this one scope, be it
global, a member of the enclosing class (in which case "this" is
accessible from within the scope) or an automatic variable. I see no
reason for a lambda's capture that gets arguments by reference to be
more than one pointer in length (unless there is an ABI where the scope
itself is more, in which case that length).

Shachar

--

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

--------------010109000602070103090504
Content-Type: text/html; charset=UTF-8

<html style="direction: ltr;">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <style type="text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt; } </style>
  </head>
  <body style="direction: ltr;" bidimailui-charset-is-forced="true"
    bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 25/06/15 02:26, Thiago Macieira
      wrote:<br>
    </div>
    <blockquote cite="mid:1789734.C9Gegyg2EF@tjmaciei-mobl4" type="cite">
      <pre wrap="">On Wednesday 24 June 2015 21:00:57 Shachar Shemesh wrote:
</pre>
      <blockquote type="cite">
        <pre wrap="">For a lambda where the capture is composed only of variables passed by
reference, one pointer ought to have been enough.
</pre>
      </blockquote>
      <pre wrap="">
Qualification required: variables in the same scope that are captured by
reference.

If those variables are in different scopes, then the it needs to capture the
different scopes.
</pre>
    </blockquote>
    The lambda is defined while inside one scope. Everything accessible
    by the lmbda's definition is accessible from within this one scope,
    be it global, a member of the enclosing class (in which case "this"
    is accessible from within the scope) or an automatic variable. I see
    no reason for a lambda's capture that gets arguments by reference to
    be more than one pointer in length (unless there is an ABI where the
    scope itself is more, in which case that length).<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------010109000602070103090504--

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Thu, 25 Jun 2015 08:02:32 +0300
Raw View
This is a multi-part message in MIME format.
--------------080109020102050209010609
Content-Type: text/plain; charset=UTF-8

On 25/06/15 03:22, Richard Smith wrote:
> It would also force not just the layout of the closure type, but /the
> stack frame layout of the enclosing function/
That's true whether you concentrate the size of the lambda to a single
(whatever) pointer or not.

If you want to employ loop unrolling and duplicate a variable, it
doesn't matter if you are storing a single pointer to the frame or a
pointer to the variable in question. Either way, you cannot duplicate
that variable if there is an outside reference to it.

Also, bear in mind that a lambda's capture cannot reference variables
not yet defined in the function inside which it is defined. As such, I
doubt your observation makes a difference in this particular case.

I might be missing something. If that's the case, please provide an
example to illustrate your point.

Shachar

--

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

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

<html style=3D"direction: ltr;">
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
    <style type=3D"text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt=
; } </style>
  </head>
  <body style=3D"direction: ltr;" bidimailui-charset-is-forced=3D"true"
    bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 25/06/15 03:22, Richard Smith wrote:<=
br>
    </div>
    <blockquote
cite=3D"mid:CAOfiQqn=3DbVpQrW87v9HjjisDPE_jXWkBbgw_RvkLe7CREAxFhA@mail.gmai=
l.com"
      type=3D"cite">It would also force not just the layout of the closure
      type, but=C2=A0<i>the stack frame layout of the enclosing function</i=
></blockquote>
    That's true whether you concentrate the size of the lambda to a
    single (whatever) pointer or not.<br>
    <br>
    If you want to employ loop unrolling and duplicate a variable, it
    doesn't matter if you are storing a single pointer to the frame or a
    pointer to the variable in question. Either way, you cannot
    duplicate that variable if there is an outside reference to it.<br>
    <br>
    Also, bear in mind that a lambda's capture cannot reference
    variables not yet defined in the function inside which it is
    defined. As such, I doubt your observation makes a difference in
    this particular case.<br>
    <br>
    I might be missing something. If that's the case, please provide an
    example to illustrate your point.<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------080109020102050209010609--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 25 Jun 2015 15:20:52 -0700
Raw View
--bcaec51a826c591a2205195f0979
Content-Type: text/plain; charset=UTF-8

On Wed, Jun 24, 2015 at 10:02 PM, Shachar Shemesh <shachar@lingnu.com>
wrote:

>  On 25/06/15 03:22, Richard Smith wrote:
>
> It would also force not just the layout of the closure type, but *the
> stack frame layout of the enclosing function*
>
> That's true whether you concentrate the size of the lambda to a single
> (whatever) pointer or not.
>

Read the next part of the sentence that you snipped:

"to be part of the ABI". If the closure type only holds pointers to locals,
the lambda call operator doesn't need to know anything about the frame
layout of the enclosing function. If it just holds a pointer to the
enclosing stack frame, it needs to know where within that frame the local
variables live.

If you want to employ loop unrolling and duplicate a variable, it doesn't
> matter if you are storing a single pointer to the frame or a pointer to the
> variable in question. Either way, you cannot duplicate that variable if
> there is an outside reference to it.
>
> Also, bear in mind that a lambda's capture cannot reference variables not
> yet defined in the function inside which it is defined. As such, I doubt
> your observation makes a difference in this particular case.
>
> I might be missing something. If that's the case, please provide an
> example to illustrate your point.
>
> Shachar
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

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

--bcaec51a826c591a2205195f0979
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 W=
ed, Jun 24, 2015 at 10:02 PM, Shachar Shemesh <span dir=3D"ltr">&lt;<a href=
=3D"mailto:shachar@lingnu.com" target=3D"_blank">shachar@lingnu.com</a>&gt;=
</span> wrote:<br><blockquote class=3D"gmail_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">
 =20
   =20
   =20
 =20
  <div style=3D"direction:ltr" bgcolor=3D"#FFFFFF" text=3D"#000000"><span c=
lass=3D"">
    <div>On 25/06/15 03:22, Richard Smith wrote:<br>
    </div>
    <blockquote type=3D"cite">It would also force not just the layout of th=
e closure
      type, but=C2=A0<i>the stack frame layout of the enclosing function</i=
></blockquote></span>
    That&#39;s true whether you concentrate the size of the lambda to a
    single (whatever) pointer or not.<br></div></blockquote><div><br></div>=
<div>Read the next part of the sentence that you snipped:</div><div><br></d=
iv><div>&quot;to be part of the ABI&quot;. If the closure type only holds p=
ointers to locals, the lambda call operator doesn&#39;t need to know anythi=
ng about the frame layout of the enclosing function. If it just holds a poi=
nter to the enclosing stack frame, it needs to know where within that frame=
 the local variables live.</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style=
=3D"direction:ltr" bgcolor=3D"#FFFFFF" text=3D"#000000">
    If you want to employ loop unrolling and duplicate a variable, it
    doesn&#39;t matter if you are storing a single pointer to the frame or =
a
    pointer to the variable in question. Either way, you cannot
    duplicate that variable if there is an outside reference to it.<br>
    <br>
    Also, bear in mind that a lambda&#39;s capture cannot reference
    variables not yet defined in the function inside which it is
    defined. As such, I doubt your observation makes a difference in
    this particular case.<br>
    <br>
    I might be missing something. If that&#39;s the case, please provide an
    example to illustrate your point.<span class=3D""><font color=3D"#88888=
8"><br>
    <br>
    Shachar<br>
  </font></span></div><div class=3D""><div class=3D"h5">


<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

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

--bcaec51a826c591a2205195f0979--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 26 Jun 2015 08:52:52 -0700
Raw View
On Thursday 25 June 2015 07:57:09 Shachar Shemesh wrote:
> On 25/06/15 02:26, Thiago Macieira wrote:
> > On Wednesday 24 June 2015 21:00:57 Shachar Shemesh wrote:
> >> For a lambda where the capture is composed only of variables passed by
> >> reference, one pointer ought to have been enough.
> >
> > Qualification required: variables in the same scope that are captured by
> > reference.
> >
> > If those variables are in different scopes, then the it needs to capture
> > the different scopes.
>
> The lambda is defined while inside one scope. Everything accessible by
> the lmbda's definition is accessible from within this one scope, be it
> global, a member of the enclosing class (in which case "this" is
> accessible from within the scope) or an automatic variable. I see no
> reason for a lambda's capture that gets arguments by reference to be
> more than one pointer in length (unless there is an ABI where the scope
> itself is more, in which case that length).

It's easy to create a counter-example. Just make the lambda leave the scope it
is created in:

auto create_lambda(int &i, int &j)
{
 return [&]{ ++i; ++j; return i + j; }
}

The above clearly requires two word-sized references to be stored in the
lambda.

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

--

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

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Fri, 26 Jun 2015 22:01:52 +0300
Raw View
This is a multi-part message in MIME format.
--------------010807090106040707080301
Content-Type: text/plain; charset=UTF-8

On 26/06/15 18:52, Thiago Macieira wrote:
> It's easy to create a counter-example. Just make the lambda leave the scope it
> is created in:
>
> auto create_lambda(int &i, int &j)
> {
>  return [&]{ ++i; ++j; return i + j; }
> }
>
> The above clearly requires two word-sized references to be stored in the
> lambda.
>
I stand corrected. There is also the case where the lambda is only
accessing members of the class in which method it was defined, where you
wouldn't want to limit the lambda's scope to the method in which it was
defined.

Please note, however, that the compiler can easily detect those cases,
and act accordingly. In my specific case, it could replace the scope's
reference with a copy of "this". In your case it does, indeed, have no
choice but to store two references inside the capture.

Either way, I've realized that this behavior bothers me less than the
fact I don't have a "pointer to lambda" construct. std::function is too
versatile, which costs it in performance. I'll open a separate thread
for that, however.

Shachar

--

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

--------------010807090106040707080301
Content-Type: text/html; charset=UTF-8

<html style="direction: ltr;">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <style type="text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt; } </style>
  </head>
  <body style="direction: ltr;" bidimailui-charset-is-forced="true"
    bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 26/06/15 18:52, Thiago Macieira
      wrote:
    </div>
    <blockquote cite="mid:1740159.j7vAh75gAD@tjmaciei-mobl4" type="cite">
      <pre wrap="">
It's easy to create a counter-example. Just make the lambda leave the scope it
is created in:

auto create_lambda(int &amp;i, int &amp;j)
{
 return [&amp;]{ ++i; ++j; return i + j; }
}

The above clearly requires two word-sized references to be stored in the
lambda.

</pre>
    </blockquote>
    I stand corrected. There is also the case where the lambda is only
    accessing members of the class in which method it was defined, where
    you wouldn't want to limit the lambda's scope to the method in which
    it was defined.<br>
    <br>
    Please note, however, that the compiler can easily detect those
    cases, and act accordingly. In my specific case, it could replace
    the scope's reference with a copy of "this". In your case it does,
    indeed, have no choice but to store two references inside the
    capture.<br>
    <br>
    Either way, I've realized that this behavior bothers me less than
    the fact I don't have a "pointer to lambda" construct. std::function
    is too versatile, which costs it in performance. I'll open a
    separate thread for that, however.<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------010807090106040707080301--

.


Author: Shachar Shemesh <shachar@lingnu.com>
Date: Fri, 26 Jun 2015 22:05:56 +0300
Raw View
This is a multi-part message in MIME format.
--------------050208010009040200090402
Content-Type: text/plain; charset=UTF-8

On 26/06/15 01:20, Richard Smith wrote:
> On Wed, Jun 24, 2015 at 10:02 PM, Shachar Shemesh <shachar@lingnu.com
> <mailto:shachar@lingnu.com>> wrote:
>
>     On 25/06/15 03:22, Richard Smith wrote:
>>     It would also force not just the layout of the closure type,
>>     but /the stack frame layout of the enclosing function/
>     That's true whether you concentrate the size of the lambda to a
>     single (whatever) pointer or not.
>
>
> Read the next part of the sentence that you snipped:
>
> "to be part of the ABI". If the closure type only holds pointers to
> locals, the lambda call operator doesn't need to know anything about
> the frame layout of the enclosing function. If it just holds a pointer
> to the enclosing stack frame, it needs to know where within that frame
> the local variables live.
While true, I would love to know why it is important. The compiler needs
to know the frame layout in order to create the lambda object. I fail to
see how storing that information inside the capture initialization code,
rather than inside the generated body code, provides any advantage.

Also, I take issue with the ABI even bothering to define this structure.
The only "interface" to define here is how you go about calling a
lambda, passing it its capture. The capture layout is defined in the
same place (same compilation unit, same function, same everything) as
the code that uses that layout, and it thus doesn't need to be subject
to any standardization.

Shachar

--

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

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

<html style=3D"direction: ltr;">
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
    <style type=3D"text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt=
; } </style>
  </head>
  <body style=3D"direction: ltr;" bidimailui-charset-is-forced=3D"true"
    bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 26/06/15 01:20, Richard Smith wrote:<=
br>
    </div>
    <blockquote
cite=3D"mid:CAOfiQqm3cXo2XnNC32ijZnUiPTuMtUf0rVwYdos5AqnjX8osOA@mail.gmail.=
com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_extra">
          <div class=3D"gmail_quote">On Wed, Jun 24, 2015 at 10:02 PM,
            Shachar Shemesh <span dir=3D"ltr">&lt;<a
                moz-do-not-send=3D"true" href=3D"mailto:shachar@lingnu.com"
                target=3D"_blank">shachar@lingnu.com</a>&gt;</span> wrote:<=
br>
            <blockquote class=3D"gmail_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 style=3D"direction:ltr" bgcolor=3D"#FFFFFF"
                text=3D"#000000"><span class=3D"">
                  <div>On 25/06/15 03:22, Richard Smith wrote:<br>
                  </div>
                  <blockquote type=3D"cite">It would also force not just
                    the layout of the closure type, but=C2=A0<i>the stack
                      frame layout of the enclosing function</i></blockquot=
e>
                </span> That's true whether you concentrate the size of
                the lambda to a single (whatever) pointer or not.<br>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Read the next part of the sentence that you snipped:</div>
            <div><br>
            </div>
            <div>"to be part of the ABI". If the closure type only holds
              pointers to locals, the lambda call operator doesn't need
              to know anything about the frame layout of the enclosing
              function. If it just holds a pointer to the enclosing
              stack frame, it needs to know where within that frame the
              local variables live.</div>
          </div>
        </div>
      </div>
    </blockquote>
    While true, I would love to know why it is important. The compiler
    needs to know the frame layout in order to create the lambda object.
    I fail to see how storing that information inside the capture
    initialization code, rather than inside the generated body code,
    provides any advantage.<br>
    <br>
    Also, I take issue with the ABI even bothering to define this
    structure. The only "interface" to define here is how you go about
    calling a lambda, passing it its capture. The capture layout is
    defined in the same place (same compilation unit, same function,
    same everything) as the code that uses that layout, and it thus
    doesn't need to be subject to any standardization.<br>
    <br>
    Shachar<br>
  </body>
</html>

<p></p>

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

--------------050208010009040200090402--

.