C++ Logo

sg14

Advanced search

Re: [isocpp-lib] std::function

From: Barath Kannan <barathwaj.kannan_at_[hidden]>
Date: Tue, 4 Oct 2022 23:10:16 +1100
Here are the list of customisation points I'd like on an erased function
abstraction:

- inplace buffer size, and exceed policy (concept failure vs defer to
allocator), alignment
- allocator
- move only/copyable/non-relocatable
- nullability, non nullables can assume the function object is set instead
of checking and throwing (can kind of already achieve this with
__builtin_unreachable)
- trivially relocatable, so that the function object can be passed around
by value
- noexcept on constructor and call operator, and copy/move (latter can be
made part of the signature)
- owning vs non-owning (function ref vs other)
- overload sets

As long as there are differing requirements, people are going to want
different sets of these so it'd be nice if we can just capture all of the
above in a single abstraction via a policy set passed as a trait.

Would be nice if compatible policy sets also allowed implicit conversion
(in the direction of relaxing requirements). E.g. trivial -> non trivial,
conversion to object with larger SBO, copyable+moveable to move only, etc.
Enabling this conversion may also be a trait people want to configure.


On Tue, 4 Oct 2022, 22:51 Jonathan Wakely via SG14, <sg14_at_[hidden]>
wrote:

>
>
> On Tue, 4 Oct 2022 at 10:48, Patrice Roy <patricer_at_[hidden]> wrote:
>
>> 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.
>>
>
> This will always be the case. Trying to please everybody, especially in
> specialist domains, is just going to be a waste of time.
>
>
>> 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.
>>
>
> Does this deserve to be in the standard though? It's less useful as a
> vocabulary type if you use Sz=16 and I use Sz=32, because now we have a
> proliferation of different types. You can work around that by using a
> function template that accepts any Sz, but if you're going to use templates
> everywhere you might as well just accept an arbitrary callable type and not
> wrap it in a type-erased function at all.
>
>
>
>>
>> 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
>>>>
>>> _______________________________________________
> SG14 mailing list
> SG14_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>

Received on 2022-10-04 12:10:28