Date: Tue, 4 Oct 2022 05:48:34 -0400
I've floated Jonathan's idea on SG14 yesterday. I think it's interesting,
and I'd go for it (I don't mind writing a make_function-style factory
function for lambdas / to make sure the static_assert check is there
without spelling it out every time), but I also hear it only solves part of
the problem for at least some of them.
In fact, my understanding is that some need an inplace_function<F,Sz> with
a configurable buffer size such that they can just use a bigger buffer if
need be instead of having no fallback if std::function would allocate.
In practice, there will be desire for both a way to statically assert that
there would be no allocation (still a good idea, thanks!), and an
alternative mechanism with a compile-time controllable buffer. I'll let
people discuss it a bit, but I expect there will be papers for both.
Cheers!
Le mar. 4 oct. 2022 à 04:47, Mathias Stearn <redbeard0531+isocpp_at_[hidden]>
a écrit :
>
>
> On Mon, 3 Oct 2022, 19.52 Jonathan Wakely via Lib, <lib_at_[hidden]>
> wrote:
>
>>
>>
>> On Mon, 3 Oct 2022, 18:21 Patrice Roy via Lib, <lib_at_[hidden]>
>> wrote:
>>
>>> Yeah, floated the idea of exposing the size at which SBO threshold is
>>> set (through traits or something similar) thinking this would do the job
>>> (people could use std::function on their own function objects and
>>> static_assert on that object's size begin sufficiently small), but this did
>>> not get much traction yet; there seems to be more appetite (if I read
>>> SG14's wishes well) for a never-allocating cousin of std::function, at
>>> least so far... Discussions on this topic are not closed yet, so we'll see.
>>>
>>
>>
>> What about making the constructor conditionally noexcept? The
>> implementation knows whether a given type will be stored on the heap, and
>> if that type can be constructed without throwing, so can easily expose that.
>>
>> What people care about is a property of the constructor, so why not make
>> it part of the constructor signature?
>>
>> You can static assert is_nothrow_constructible.
>>
>
> One problem is that you would need to wrap it in something to make it
> usable. Because lambdas are unutterable unique types you can't cleanly
> separate the construction of the function from the static assertion,
> especially if you want to stay in expression space (I hate reading code
> that declares used-once lambda variables rather than defining them in the
> argument position).
>
> If you had that, you could easily declare a subclass of std::function
> which only declared a forwarding constructor with the nothrow constraint. I
> think that would make it a lot more ergonomic. But then that raises the
> question of if you need to do that for it to be usable (in some domains)
> why not just standardize std::noalloc_function (and noalloc_unique_function
> I guess) so it can be used as a vocab type?
>
>
> That said, we've made our implementation of UniqueFunction always allocate
> and just hold a unique_ptr<Impl> because a) the smaller object and cheaper
> moves are nice if you have a fast allocator, and b) we found it was very
> common for lambdas to capture std::functions/UniqueFunctions, which means
> that no matter how big the SBO size it would need to allocate anyway. So we
> wouldn't have a use for that type, although I understand that others have
> different tradeoffs that would make it indispensable.
>
>
>
>
>>
>>> Le lun. 3 oct. 2022 à 12:40, Ben Craig <ben.craig_at_[hidden]> a écrit :
>>>
>>>> Are there any examples of implementations that cause allocations,
>>>> syscalls, or non-deterministic behavior for std::function when it is used
>>>> with a function pointer, stateless lambda, or std::reference_wrapper? Is
>>>> that std::function implementation claiming to be standards conforming?
>>>>
>>>> Best I can tell, std::function is already specified to meet these
>>>> requirements as best as can be done with the current specification
>>>> techniques.
>>>>
>>>> My suspicion is that the reluctance to use std::function is based off
>>>> of some combination of general STL fear, and possibly some other
>>>> requirements (e.g. user controllable small buffer optimization (SBO)
>>>> instead of implementation tuned SBO).
>>>>
>>>>
>>>>
>>>> *From:* Lib <lib-bounces_at_[hidden]> *On Behalf Of *Björn
>>>> Andersson via Lib
>>>> *Sent:* Monday, October 3, 2022 11:58 AM
>>>> *To:* sg14_at_[hidden]
>>>> *Cc:* Björn Andersson <bjorn.andersson_at_[hidden]>; lib_at_[hidden];
>>>> Patrice Roy <patricer_at_[hidden]>
>>>> *Subject:* [EXTERNAL] Re: [isocpp-lib] [SG14] std::function
>>>>
>>>>
>>>>
>>>> Den ons 21 sep. 2022 kl 03:07 skrev Patrice Roy via SG14 <
>>>> sg14_at_[hidden]>:
>>>>
>>>> Indeed, this type is part of a set of requests SG14 is working on these
>>>> days.
>>>>
>>>>
>>>>
>>>> The problem (for low-latency people) is that there's no programmatic
>>>> way to know, in user code, if a given std::function instantiation will or
>>>> will not allocate, so that makes this type unusable for some use cases (in
>>>> particular, many game development companies will not touch std:function
>>>> precisely for this reason; they don't just need an optimization, they need
>>>> a guarantee).
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Incidentally, this is exactly what the safety-critical people need as
>>>> well: Not just the performance, but the guarantee of no
>>>> syscall/deterministic behaviour.
>>>>
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Björn
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Cheers!
>>>>
>>>>
>>>>
>>>> Le mar. 20 sept. 2022 à 12:19, Arthur O'Dwyer via Lib <
>>>> lib_at_[hidden]> a écrit :
>>>>
>>>> On Tue, Sep 20, 2022 at 9:22 AM Bjarne Stroustrup via Lib <
>>>> lib_at_[hidden]> wrote:
>>>>
>>>> I thought we had a variant of std::function that didn't allocate on
>>>> free
>>>> store for simple functions; it didn't make it for C++20? Is it still in
>>>> process? and if so where would I look for the current state of the
>>>> proposal.
>>>>
>>>>
>>>>
>>>> [cc: SG14]
>>>>
>>>> SG14 has implemented, and I maintain, a type-erased
>>>> `stdext::inplace_function<void(), Capacity, Align>` based on an informal
>>>> proposal by Carl Cook in 2016:
>>>>
>>>> https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDabzpusS$>
>>>>
>>>>
>>>> https://github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h
>>>> <https://urldefense.com/v3/__https:/github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVgSckTs$>
>>>>
>>>>
>>>> https://groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ
>>>> <https://urldefense.com/v3/__https:/groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDQVrHXUy$>
>>>>
>>>>
>>>> https://github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDZ7r8JVu$>
>>>>
>>>>
>>>>
>>>> It has never had a P-numbered proposal, and the area hasn't seen any
>>>> movement that I'm aware of since circa 2018.
>>>>
>>>>
>>>>
>>>> https://github.com/WG21-SG14/SG14/issues/125
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/125__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDXFqTwly$>
>>>> inspired the implicit-move changes in C++20 (P1155 More Implicit Move).
>>>>
>>>> https://github.com/WG21-SG14/SG14/issues/150
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/150__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDUy1jqED$>
>>>> is still an important practical issue, where I happen to believe that the
>>>> STL has chosen the wrong default as usual, and why I stopped caring much
>>>> about the introduction of new type-erased types into the STL and started
>>>> evangelizing type erasure *as a technique* so that people can just
>>>> write their own.
>>>>
>>>>
>>>> https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/
>>>> <https://urldefense.com/v3/__https:/quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVs2z3X3$>
>>>> is related.
>>>>
>>>>
>>>>
>>>> HTH,
>>>>
>>>> Arthur
>>>>
>>>> _______________________________________________
>>>> Lib mailing list
>>>> Lib_at_[hidden]
>>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/lib__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDWOp6UJJ$>
>>>> Link to this post: http://lists.isocpp.org/lib/2022/09/23737.php
>>>> <https://urldefense.com/v3/__http:/lists.isocpp.org/lib/2022/09/23737.php__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDa3aziyr$>
>>>>
>>>> _______________________________________________
>>>> SG14 mailing list
>>>> SG14_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/sg14__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDcXjZ4Fg$>
>>>>
>>>>
>>>> INTERNAL - NI CONFIDENTIAL
>>>>
>>> _______________________________________________
>>> Lib mailing list
>>> Lib_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>> Link to this post: http://lists.isocpp.org/lib/2022/10/23961.php
>>>
>> _______________________________________________
>> Lib mailing list
>> Lib_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>> Link to this post: http://lists.isocpp.org/lib/2022/10/23962.php
>>
>
and I'd go for it (I don't mind writing a make_function-style factory
function for lambdas / to make sure the static_assert check is there
without spelling it out every time), but I also hear it only solves part of
the problem for at least some of them.
In fact, my understanding is that some need an inplace_function<F,Sz> with
a configurable buffer size such that they can just use a bigger buffer if
need be instead of having no fallback if std::function would allocate.
In practice, there will be desire for both a way to statically assert that
there would be no allocation (still a good idea, thanks!), and an
alternative mechanism with a compile-time controllable buffer. I'll let
people discuss it a bit, but I expect there will be papers for both.
Cheers!
Le mar. 4 oct. 2022 à 04:47, Mathias Stearn <redbeard0531+isocpp_at_[hidden]>
a écrit :
>
>
> On Mon, 3 Oct 2022, 19.52 Jonathan Wakely via Lib, <lib_at_[hidden]>
> wrote:
>
>>
>>
>> On Mon, 3 Oct 2022, 18:21 Patrice Roy via Lib, <lib_at_[hidden]>
>> wrote:
>>
>>> Yeah, floated the idea of exposing the size at which SBO threshold is
>>> set (through traits or something similar) thinking this would do the job
>>> (people could use std::function on their own function objects and
>>> static_assert on that object's size begin sufficiently small), but this did
>>> not get much traction yet; there seems to be more appetite (if I read
>>> SG14's wishes well) for a never-allocating cousin of std::function, at
>>> least so far... Discussions on this topic are not closed yet, so we'll see.
>>>
>>
>>
>> What about making the constructor conditionally noexcept? The
>> implementation knows whether a given type will be stored on the heap, and
>> if that type can be constructed without throwing, so can easily expose that.
>>
>> What people care about is a property of the constructor, so why not make
>> it part of the constructor signature?
>>
>> You can static assert is_nothrow_constructible.
>>
>
> One problem is that you would need to wrap it in something to make it
> usable. Because lambdas are unutterable unique types you can't cleanly
> separate the construction of the function from the static assertion,
> especially if you want to stay in expression space (I hate reading code
> that declares used-once lambda variables rather than defining them in the
> argument position).
>
> If you had that, you could easily declare a subclass of std::function
> which only declared a forwarding constructor with the nothrow constraint. I
> think that would make it a lot more ergonomic. But then that raises the
> question of if you need to do that for it to be usable (in some domains)
> why not just standardize std::noalloc_function (and noalloc_unique_function
> I guess) so it can be used as a vocab type?
>
>
> That said, we've made our implementation of UniqueFunction always allocate
> and just hold a unique_ptr<Impl> because a) the smaller object and cheaper
> moves are nice if you have a fast allocator, and b) we found it was very
> common for lambdas to capture std::functions/UniqueFunctions, which means
> that no matter how big the SBO size it would need to allocate anyway. So we
> wouldn't have a use for that type, although I understand that others have
> different tradeoffs that would make it indispensable.
>
>
>
>
>>
>>> Le lun. 3 oct. 2022 à 12:40, Ben Craig <ben.craig_at_[hidden]> a écrit :
>>>
>>>> Are there any examples of implementations that cause allocations,
>>>> syscalls, or non-deterministic behavior for std::function when it is used
>>>> with a function pointer, stateless lambda, or std::reference_wrapper? Is
>>>> that std::function implementation claiming to be standards conforming?
>>>>
>>>> Best I can tell, std::function is already specified to meet these
>>>> requirements as best as can be done with the current specification
>>>> techniques.
>>>>
>>>> My suspicion is that the reluctance to use std::function is based off
>>>> of some combination of general STL fear, and possibly some other
>>>> requirements (e.g. user controllable small buffer optimization (SBO)
>>>> instead of implementation tuned SBO).
>>>>
>>>>
>>>>
>>>> *From:* Lib <lib-bounces_at_[hidden]> *On Behalf Of *Björn
>>>> Andersson via Lib
>>>> *Sent:* Monday, October 3, 2022 11:58 AM
>>>> *To:* sg14_at_[hidden]
>>>> *Cc:* Björn Andersson <bjorn.andersson_at_[hidden]>; lib_at_[hidden];
>>>> Patrice Roy <patricer_at_[hidden]>
>>>> *Subject:* [EXTERNAL] Re: [isocpp-lib] [SG14] std::function
>>>>
>>>>
>>>>
>>>> Den ons 21 sep. 2022 kl 03:07 skrev Patrice Roy via SG14 <
>>>> sg14_at_[hidden]>:
>>>>
>>>> Indeed, this type is part of a set of requests SG14 is working on these
>>>> days.
>>>>
>>>>
>>>>
>>>> The problem (for low-latency people) is that there's no programmatic
>>>> way to know, in user code, if a given std::function instantiation will or
>>>> will not allocate, so that makes this type unusable for some use cases (in
>>>> particular, many game development companies will not touch std:function
>>>> precisely for this reason; they don't just need an optimization, they need
>>>> a guarantee).
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Incidentally, this is exactly what the safety-critical people need as
>>>> well: Not just the performance, but the guarantee of no
>>>> syscall/deterministic behaviour.
>>>>
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Björn
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Cheers!
>>>>
>>>>
>>>>
>>>> Le mar. 20 sept. 2022 à 12:19, Arthur O'Dwyer via Lib <
>>>> lib_at_[hidden]> a écrit :
>>>>
>>>> On Tue, Sep 20, 2022 at 9:22 AM Bjarne Stroustrup via Lib <
>>>> lib_at_[hidden]> wrote:
>>>>
>>>> I thought we had a variant of std::function that didn't allocate on
>>>> free
>>>> store for simple functions; it didn't make it for C++20? Is it still in
>>>> process? and if so where would I look for the current state of the
>>>> proposal.
>>>>
>>>>
>>>>
>>>> [cc: SG14]
>>>>
>>>> SG14 has implemented, and I maintain, a type-erased
>>>> `stdext::inplace_function<void(), Capacity, Align>` based on an informal
>>>> proposal by Carl Cook in 2016:
>>>>
>>>> https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDabzpusS$>
>>>>
>>>>
>>>> https://github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h
>>>> <https://urldefense.com/v3/__https:/github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVgSckTs$>
>>>>
>>>>
>>>> https://groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ
>>>> <https://urldefense.com/v3/__https:/groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDQVrHXUy$>
>>>>
>>>>
>>>> https://github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDZ7r8JVu$>
>>>>
>>>>
>>>>
>>>> It has never had a P-numbered proposal, and the area hasn't seen any
>>>> movement that I'm aware of since circa 2018.
>>>>
>>>>
>>>>
>>>> https://github.com/WG21-SG14/SG14/issues/125
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/125__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDXFqTwly$>
>>>> inspired the implicit-move changes in C++20 (P1155 More Implicit Move).
>>>>
>>>> https://github.com/WG21-SG14/SG14/issues/150
>>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/150__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDUy1jqED$>
>>>> is still an important practical issue, where I happen to believe that the
>>>> STL has chosen the wrong default as usual, and why I stopped caring much
>>>> about the introduction of new type-erased types into the STL and started
>>>> evangelizing type erasure *as a technique* so that people can just
>>>> write their own.
>>>>
>>>>
>>>> https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/
>>>> <https://urldefense.com/v3/__https:/quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVs2z3X3$>
>>>> is related.
>>>>
>>>>
>>>>
>>>> HTH,
>>>>
>>>> Arthur
>>>>
>>>> _______________________________________________
>>>> Lib mailing list
>>>> Lib_at_[hidden]
>>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/lib__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDWOp6UJJ$>
>>>> Link to this post: http://lists.isocpp.org/lib/2022/09/23737.php
>>>> <https://urldefense.com/v3/__http:/lists.isocpp.org/lib/2022/09/23737.php__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDa3aziyr$>
>>>>
>>>> _______________________________________________
>>>> SG14 mailing list
>>>> SG14_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/sg14__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDcXjZ4Fg$>
>>>>
>>>>
>>>> INTERNAL - NI CONFIDENTIAL
>>>>
>>> _______________________________________________
>>> Lib mailing list
>>> Lib_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>> Link to this post: http://lists.isocpp.org/lib/2022/10/23961.php
>>>
>> _______________________________________________
>> Lib mailing list
>> Lib_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>> Link to this post: http://lists.isocpp.org/lib/2022/10/23962.php
>>
>
Received on 2022-10-04 09:48:46