You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm a Microsoft employee working on one of our large internal codebases (happy to discuss more offline :)). CppCoreGuidelines proposes that there should be a gsl::dyn_array type:
We've been beginning to embrace span<T> and unique_ptr<T, OurCustomDeleter>. However, we've noticed that there's a missing type for migrating existing code.
Namely, we have:
unique_ptr<T> for owned single elements,
unique_ptr<T[]> for owned arrays where we need not track the length
vector<T> (and some custom equivalents) for owned, resizeable arrays
```span`` for borrowed/unowned arrays with length tracked
And a gap (which appears that dyn_array<T> would fill if it existed) for owned, non-resizable arrays.
For us, our operator delete is global (and thus the corresponding deleter is compressible). However, our operator new is stateful / it requires a pointer to the allocator to use (because we do arena allocation and the like).
So, the gap dyn_array<T, Deleter> could fill is instead filled with:
Separate unique_ptr<T[]> and length arguments (e.g. inout arguments instead of returning a class using NVRO) - clunky and easy to make mistakes
Separate T* and length - even worse than the previou soption.
vector<T> can't fill the gap either - instead of sizeof(size_t) +sizeof(T*) (call it 16 bytes on 64 bit arches), vector<T> imposes an additional sizeof(T*) due to the length and capacity split, and usually at least another sizeof(T*) for the custom allocator.
A dyn_array<T, Deleter> thus would be very useful to us, as it has no additional stack overhead (ignoring structure vs primitive type argument passing differences in e.g. msvc's ABI, which are unfortunate but probably livable). In other words, it would be a drop-in replacement with the same semantics as having a unique_ptr<T[], Deleter>, but safer.
While our use case is somewhat niche, I suspect we're not the only codebase internally or externally who would find this useful, so I thought I should file an issue and ask if there are plans to add it.
Thank you for providing a detailed description of the issues you are facing and what you would like to see out of a solution. It is very helpful. As per the linked CppCoreGuidelines issue, we are finalizing a proposal to guide the implementation of a gsl::dyn_array and will be passing it on for feedback in the coming weeks.
Good day folks,
I'm a Microsoft employee working on one of our large internal codebases (happy to discuss more offline :)). CppCoreGuidelines proposes that there should be a gsl::dyn_array type:
dyn_array // ??? needed ??? A heap-allocated array. The number of elements is determined at construction and fixed thereafter. The elements are mutable unless T is a const type. Basically a span that allocates and owns its elements.
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#gslowner-ownership-pointers
We've been beginning to embrace
span<T>
andunique_ptr<T, OurCustomDeleter>
. However, we've noticed that there's a missing type for migrating existing code.Namely, we have:
unique_ptr<T>
for owned single elements,unique_ptr<T[]>
for owned arrays where we need not track the lengthvector<T>
(and some custom equivalents) for owned, resizeable arraysdyn_array<T>
would fill if it existed) for owned, non-resizable arrays.For us, our operator delete is global (and thus the corresponding deleter is compressible). However, our operator new is stateful / it requires a pointer to the allocator to use (because we do arena allocation and the like).
So, the gap
dyn_array<T, Deleter>
could fill is instead filled with:unique_ptr<T[]>
and length arguments (e.g. inout arguments instead of returning a class using NVRO) - clunky and easy to make mistakesT*
and length - even worse than the previou soption.vector<T>
can't fill the gap either - instead ofsizeof(size_t) +sizeof(T*)
(call it 16 bytes on 64 bit arches),vector<T>
imposes an additionalsizeof(T*)
due to the length and capacity split, and usually at least anothersizeof(T*)
for the custom allocator.A
dyn_array<T, Deleter>
thus would be very useful to us, as it has no additional stack overhead (ignoring structure vs primitive type argument passing differences in e.g. msvc's ABI, which are unfortunate but probably livable). In other words, it would be a drop-in replacement with the same semantics as having aunique_ptr<T[], Deleter>
, but safer.While our use case is somewhat niche, I suspect we're not the only codebase internally or externally who would find this useful, so I thought I should file an issue and ask if there are plans to add it.
Related issues:
isocpp/CppCoreGuidelines#1633
#348
#505
#890
The text was updated successfully, but these errors were encountered: