13 KiB
[mem.poly.allocator.class]
20 Memory management library [mem]
20.5 Memory resources [mem.res]
20.5.3 Class template polymorphic_allocator [mem.poly.allocator.class]
20.5.3.1 General [mem.poly.allocator.class.general]
A specialization of class template pmr::polymorphic_allocator meets the Cpp17Allocator requirements ([allocator.requirements.general]) if its template argument is a cv-unqualified object type.
Constructed with different memory resources, different instances of the same specialization of pmr::polymorphic_allocator can exhibit entirely different allocation behavior.
This runtime polymorphism allows objects that use polymorphic_allocator to behave as if they used different allocator types at run time even though they use the same static allocator type.
A specialization of class template pmr::polymorphic_allocator meets the allocator completeness requirements ([allocator.requirements.completeness]) if its template argument is a cv-unqualified object type.
namespace std::pmr {template class polymorphic_allocator { memory_resource* memory_rsrc; // exposition onlypublic:using value_type = Tp; // [mem.poly.allocator.ctor], constructors polymorphic_allocator() noexcept; polymorphic_allocator(memory_resource* r);
polymorphic_allocator(const polymorphic_allocator& other) = default; template polymorphic_allocator(const polymorphic_allocator& other) noexcept;
polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; // [mem.poly.allocator.mem], member functions Tp* allocate(size_t n); void deallocate(Tp* p, size_t n); void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t)); void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t)); template T* allocate_object(size_t n = 1); template void deallocate_object(T* p, size_t n = 1); template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args); template void delete_object(T* p); template<class T, class... Args>void construct(T* p, Args&&... args); templatevoid destroy(T* p);
polymorphic_allocator select_on_container_copy_construction() const;
memory_resource* resource() const; // friendsfriend bool operator==(const polymorphic_allocator& a, const polymorphic_allocator& b) noexcept {return *a.resource() == *b.resource(); }};}
20.5.3.2 Constructors [mem.poly.allocator.ctor]
polymorphic_allocator() noexcept;
Effects: Sets memory_rsrc to get_default_resource().
polymorphic_allocator(memory_resource* r);
Preconditions: r is non-null.
Effects: Sets memory_rsrc to r.
Throws: Nothing.
[Note 1:
This constructor provides an implicit conversion from memory_resource*.
â end note]
template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
Effects: Sets memory_rsrc to other.resource().
20.5.3.3 Member functions [mem.poly.allocator.mem]
Tp* allocate(size_t n);
Effects: If numeric_limits<size_t>::max() / sizeof(Tp) < n, throws bad_array_new_length.
Otherwise equivalent to:return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
void deallocate(Tp* p, size_t n);
Preconditions: p was allocated from a memory resource x, equal to *memory_rsrc, using x.allocate(n * sizeof(Tp), alignof(Tp)).
Effects: Equivalent to memory_rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp)).
Throws: Nothing.
void* allocate_bytes(size_t nbytes, size_t alignment = alignof(max_align_t));
Effects: Equivalent to: return memory_rsrc->allocate(nbytes, alignment);
[Note 1:
The return type is void* (rather than, e.g., byte*) to support conversion to an arbitrary pointer type U* by static_cast<U*>, thus facilitating construction of a U object in the allocated memory.
â end note]
void deallocate_bytes(void* p, size_t nbytes, size_t alignment = alignof(max_align_t));
Effects: Equivalent to memory_rsrc->deallocate(p, nbytes, alignment).
template<class T> T* allocate_object(size_t n = 1);
Effects: Allocates memory suitable for holding an array of n objects of type T, as follows:
if numeric_limits<size_t>::max() / sizeof(T) < n, throws bad_array_new_length,
otherwise equivalent to:return static_cast<T*>(allocate_bytes(n*sizeof(T), alignof(T)));
[Note 2:
T is not deduced and must therefore be provided as a template argument.
â end note]
template<class T> void deallocate_object(T* p, size_t n = 1);
Effects: Equivalent to deallocate_bytes(p, n*sizeof(T), alignof(T)).
template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args);
Effects: Allocates and constructs an object of type T, as follows.
Equivalent to:T* p = allocate_object();try { construct(p, std::forward(ctor_args)...);} catch (...) { deallocate_object(p); throw;}return p;
[Note 3:
T is not deduced and must therefore be provided as a template argument.
â end note]
template<class T> void delete_object(T* p);
Effects: Equivalent to:destroy(p); deallocate_object(p);
template<class T, class... Args> void construct(T* p, Args&&... args);
Mandates: Uses-allocator construction of T with allocator *this (see [allocator.uses.construction]) and constructor arguments std::forward(args)... is well-formed.
Effects: Constructs a T object in the storage whose address is represented by p by uses-allocator construction with allocator *this and constructor arguments std::forward(args)....
Throws: Nothing unless the constructor for T throws.
template<class T> void destroy(T* p);
Effects: Equivalent to p->~T().
polymorphic_allocator select_on_container_copy_construction() const;
Returns: polymorphic_allocator().
[Note 4:
The memory resource is not propagated.
â end note]
memory_resource* resource() const;
Returns: memory_rsrc.
20.5.3.4 Equality [mem.poly.allocator.eq]
template<class T1, class T2> bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept;
Returns: *a.resource() == *b.resource().