Yes, it's possible. All containers in the standard library satisfy the allocator-aware requirement. In simple terms, this means that the container has to store an allocator as a subobject, and handle this object correctly when the container is copied, moved, etc. There are two approaches to implementing stateful allocators:
Stateful Static Allocators
template <typename T>
struct mmap_allocator { /* ... */ };
mmap_allocator<data> create_mmap_allocator(std::string_view file) { /* ... */ }
auto create_vec() {
std::vector<data, mmap_allocator<data>> result(create_mmap_allocator());
/* ... */
return result;
}
mmap_allocator
can store state, such as which file was opened, a pointer to the mapped memory, etc. An obvious downside is that this std::vector
is now distinct from a regular std::vector
, since it uses a custom allocator.
Polymorphic Allocators
If you want even more customization, such as using a totally different type of allocator in the same vector type, this becomes annoying.
It's also annoying that std::vector<T>
and std::vector<T, mmap_allocator<T>>
are incompatible.
To solve this, there are polymorphic allocators:
struct mmap_resource : std::pmr::memory_resource { /* ... */ };
mmap_resource create_mmap_resource(std::string_view file) {
/* ... */
}
auto use_vec() {
// TODO: the allocator doesn't own the memory resource, so
// we might need to bundle the vector and the resource in
// a struct, etc.
auto resource = create_mmap_resource(...);
std::pmr::polymorphic_allocator alloc = &resource;
std::pmr::vector<data> result(alloc);
/* ... */
}
Polymorphic allocators are wrappers for a polymorphic class std::pmr::memory_resource
, which you can customize.
Also see: polymorphic_allocator: when and why should I use it?