Short form: We propose to add library functions that allow the systematic use of allocators as a customisation point for dynamic allocations. The new functions complete the following picture:
using operator {new,delete} | using allocator | |
---|---|---|
Manual | T * p = new T(args...) | auto p = allocate_new<T>(alloc, args...) |
delete p | allocate_delete(alloc, p) | |
Unique pointer | make_unique<T>(args...) | allocate_unique<T>(alloc, args...) |
default_delete<T> | allocator_delete<T> | |
Shared pointer | make_shared<T>(args...) | allocate_shared<T>(alloc, args...) |
Long form: The standard library rarely uses
new
/delete
directly, but instead allows customisation of dynamic
allocation and object construction via allocators. Currently this customisation is only
available for container elements and for shared_ptr
(as well as for
a few other types that require dynamically allocated memory), but not for the top-level
objects themselves.
The proposal is to complete the library facilities for
allocator-based customisation by providing a direct mechanism for creating and destroying
a dynamically stored object through an allocator, as well as a new deleter type for
unique_ptr
to hold an allocator-managed unique pointee, together with the
appropriate factory function.
std::allocate_unique<std::vector<T,
ScopedArenaAlloc<T>>>(arena_alloc)
allows this. (Here we assume the
use of the usual alias idiom template <typename T> using ScopedArenaAlloc =
std::scoped_allocator_adaptor<ArenaAlloc<T>>
;).auto p =
std::allocate_new<std::vector<T,
ScopedShmemAlloc<T>>>(shmem_alloc)
. The returned pointer is
presumably an offset pointer, and its offset value needs to be communicated to the other
participating processes. The last process to use the container calls
allocate_delete(shmem_alloc, p)
.To allow std::unique_ptr
to use custom allocators, we first need a deleter template that stores the allocator:
The factory function is:
The type T
must not be an array type.
noexcept
).allocate_new
take an explicit typename T
as a parameter, or use A::value_type
?allocate_delete
for both for the function
template that replaces delete
and for the class template that replaces
default_delete
to keep using the word “allocate” consistently.
That would require saying the unwieldy struct allocate_delete
in the
allocate_unique
function template, though.