[mem.poly.allocator.class] (original) (raw)

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_allocatorcan exhibit entirely different allocation behavior.

This runtime polymorphism allows objects that use polymorphic_allocatorto 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_allocatormeets the allocator completeness requirements ([allocator.requirements.completeness]) if its template argument is a cv-unqualified object type.

namespace std::pmr { template<class Tp = byte> class polymorphic_allocator { memory_resource* memory_rsrc; public: using value_type = Tp; polymorphic_allocator() noexcept; polymorphic_allocator(memory_resource* r); polymorphic_allocator(const polymorphic_allocator& other) = default;template<class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept; polymorphic_allocator& operator=(const polymorphic_allocator&) = delete; 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<class T> T* allocate_object(size_t n = 1);template<class T> void deallocate_object(T* p, size_t n = 1);template<class T, class... CtorArgs> T* new_object(CtorArgs&&... ctor_args);template<class T> void delete_object(T* p);template<class T, class... Args> void construct(T* p, Args&&... args);template<class T> void destroy(T* p); polymorphic_allocator select_on_container_copy_construction() const; memory_resource* resource() const;friend 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.

[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]

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)).

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 Uobject 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:

[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<T>();try { construct(p, std::forward<CtorArgs>(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 Twith allocator *this (see [allocator.uses.construction]) and constructor arguments std​::​forward<Args>(args)... is well-formed.

Effects: Construct a T object in the storage whose address is represented by pby uses-allocator construction with allocator *thisand constructor arguments std​::​forward<Args>(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;

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().