Date: Sun, 12 Mar 2023 15:50:30 -0300
> All our use-cases so far are use-cases for the
allocating-but-not-constructing entrypoint.
Even on std::make_shared<std::string[]>(10) ? That is a case of allocating
and constructing.
On Sun, Mar 12, 2023 at 3:43 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:
> On Sun, Mar 12, 2023 at 1:59 PM Breno Guimarães <brenorg_at_[hidden]> wrote:
>
>> >And now I'm confused: Is this make_contiguous_*objects* or
>> make_contiguous_*storage*? Because most library users will need the
>> latter, not the former.
>>
>> It's "_objects". I don't agree most library users would need the latter.
>> At least it's not in the use cases I looked at.
>>
>
> You give the following use-cases in the paper:
>
>
> https://github.com/llvm/llvm-project/blob/2f887c9a760dfdffa584ce84361912fe122ad79f/libcxx/include/__memory/shared_ptr.h#L1139
> (btw, you call this "the LLVM implementation," but it would be clearer to
> say "the libc++ implementation of make_shared")
> requires allocation without construction (it needs to pass Args... to the
> ctor).
>
>
> https://github.com/abseil/abseil-cpp/blob/d8933b836b1e1aac982b1dd42cc6ac1343a878d5/absl/container/internal/raw_hash_set.h#L1342
> performs allocation without construction, although it probably doesn't
> care (its types being constructed are trivial).
>
>
> https://github.com/mattreecebentley/plf_hive/blob/8c2bf6d9606df1d76900751ffffc472e994b529b/plf_hive.h#L174
> requires allocation without construction (it doesn't want to construct `T`
> objects yet), although the current implementation wraps `T` in a union both
> for this reason and for other reasons, so
> default-constructing-the-union-type ends up doing the same thing as
> not-constructing, in the end.
>
>
>> Some might want to defer the initialization of some arrays, but then they
>> use it like `std::make_contiguous_objects<Metadata,
>> ElementAlignedStorage>(nElements, nElements)`
>> And manually do part of the work.
>> But make_contiguous objects would give the buffer size calculation
>> (including alignment) and the exception-safe creation of the metadata array.
>>
>
> Right, that's why the storage-allocating version is still a value-add over
> "nothing at all." It does the buffer size calculation, including alignment,
> and hands back the component-array pointers to the caller. (Ville, this
> answers your question about "why is this better than just using the
> allocator directly.")
>
> But I don't see any use-cases yet where we want the T objects to be
> default-constructed. Default-constructing the T objects is *explicitly
> impossible *in some cases and *harmless but unnecessarily slow* in
> others. We haven't yet seen a case where it's helpful. That doesn't mean
> you can't provide an additional entrypoint that does construct the Ts; it
> just means that we haven't yet seen a positive use-case for that
> entrypoint. All our use-cases so far are use-cases for the
> allocating-but-not-constructing entrypoint.
>
> –Arthur
>
allocating-but-not-constructing entrypoint.
Even on std::make_shared<std::string[]>(10) ? That is a case of allocating
and constructing.
On Sun, Mar 12, 2023 at 3:43 PM Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:
> On Sun, Mar 12, 2023 at 1:59 PM Breno Guimarães <brenorg_at_[hidden]> wrote:
>
>> >And now I'm confused: Is this make_contiguous_*objects* or
>> make_contiguous_*storage*? Because most library users will need the
>> latter, not the former.
>>
>> It's "_objects". I don't agree most library users would need the latter.
>> At least it's not in the use cases I looked at.
>>
>
> You give the following use-cases in the paper:
>
>
> https://github.com/llvm/llvm-project/blob/2f887c9a760dfdffa584ce84361912fe122ad79f/libcxx/include/__memory/shared_ptr.h#L1139
> (btw, you call this "the LLVM implementation," but it would be clearer to
> say "the libc++ implementation of make_shared")
> requires allocation without construction (it needs to pass Args... to the
> ctor).
>
>
> https://github.com/abseil/abseil-cpp/blob/d8933b836b1e1aac982b1dd42cc6ac1343a878d5/absl/container/internal/raw_hash_set.h#L1342
> performs allocation without construction, although it probably doesn't
> care (its types being constructed are trivial).
>
>
> https://github.com/mattreecebentley/plf_hive/blob/8c2bf6d9606df1d76900751ffffc472e994b529b/plf_hive.h#L174
> requires allocation without construction (it doesn't want to construct `T`
> objects yet), although the current implementation wraps `T` in a union both
> for this reason and for other reasons, so
> default-constructing-the-union-type ends up doing the same thing as
> not-constructing, in the end.
>
>
>> Some might want to defer the initialization of some arrays, but then they
>> use it like `std::make_contiguous_objects<Metadata,
>> ElementAlignedStorage>(nElements, nElements)`
>> And manually do part of the work.
>> But make_contiguous objects would give the buffer size calculation
>> (including alignment) and the exception-safe creation of the metadata array.
>>
>
> Right, that's why the storage-allocating version is still a value-add over
> "nothing at all." It does the buffer size calculation, including alignment,
> and hands back the component-array pointers to the caller. (Ville, this
> answers your question about "why is this better than just using the
> allocator directly.")
>
> But I don't see any use-cases yet where we want the T objects to be
> default-constructed. Default-constructing the T objects is *explicitly
> impossible *in some cases and *harmless but unnecessarily slow* in
> others. We haven't yet seen a case where it's helpful. That doesn't mean
> you can't provide an additional entrypoint that does construct the Ts; it
> just means that we haven't yet seen a positive use-case for that
> entrypoint. All our use-cases so far are use-cases for the
> allocating-but-not-constructing entrypoint.
>
> –Arthur
>
Received on 2023-03-12 18:50:42