[allocator.traits] # 20 Memory management library [[mem]](./#mem) ## 20.2 Memory [[memory]](memory#allocator.traits) ### 20.2.9 Allocator traits [allocator.traits] #### [20.2.9.1](#general) General [[allocator.traits.general]](allocator.traits.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1640) The class template allocator_traits supplies a uniform interface to all allocator types[.](#general-1.sentence-1) An allocator cannot be a non-class type, however, even if allocator_traits supplies the entire required interface[.](#general-1.sentence-2) [*Note [1](#general-note-1)*: Thus, it is always possible to create a derived class from an allocator[.](#general-1.sentence-3) — *end note*] If a program declares an explicit or partial specialization of allocator_traits, the program is ill-formed, no diagnostic required[.](#general-1.sentence-4) [🔗](#lib:allocator_traits) namespace std {template struct allocator_traits {using allocator_type = Alloc; using value_type = typename Alloc::value_type; using pointer = *see below*; using const_pointer = *see below*; using void_pointer = *see below*; using const_void_pointer = *see below*; using difference_type = *see below*; using size_type = *see below*; using propagate_on_container_copy_assignment = *see below*; using propagate_on_container_move_assignment = *see below*; using propagate_on_container_swap = *see below*; using is_always_equal = *see below*; template using rebind_alloc = *see below*; template using rebind_traits = allocator_traits>; static constexpr pointer allocate(Alloc& a, size_type n); static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static constexpr allocation_result allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); templatestatic constexpr void construct(Alloc& a, T* p, Args&&... args); templatestatic constexpr void destroy(Alloc& a, T* p); static constexpr size_type max_size(const Alloc& a) noexcept; static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); };} #### [20.2.9.2](#types) Member types [[allocator.traits.types]](allocator.traits.types) [🔗](#lib:pointer,allocator_traits) `using pointer = see below; ` [1](#types-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1705) *Type*: Alloc​::​pointer if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​pointer is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise, value_type*[.](#types-1.sentence-1) [🔗](#lib:const_pointer,allocator_traits) `using const_pointer = see below; ` [2](#types-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1717) *Type*: Alloc​::​const_pointer if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​const_pointer is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits​::​rebind<​const value_type>[.](#types-2.sentence-1) [🔗](#lib:void_pointer,allocator_traits) `using void_pointer = see below; ` [3](#types-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1730) *Type*: Alloc​::​void_pointer if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​void_pointer is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits​::​rebind<​void>[.](#types-3.sentence-1) [🔗](#lib:const_void_pointer,allocator_traits) `using const_void_pointer = see below; ` [4](#types-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1743) *Type*: Alloc​::​const_void_pointer if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​const_void_pointer is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits​::​​rebind[.](#types-4.sentence-1) [🔗](#lib:difference_type,allocator_traits) `using difference_type = see below; ` [5](#types-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1756) *Type*: Alloc​::​difference_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​difference_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits​::​difference_type[.](#types-5.sentence-1) [🔗](#lib:size_type,allocator_traits) `using size_type = see below; ` [6](#types-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1769) *Type*: Alloc​::​size_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​size_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,make_unsigned_t[.](#types-6.sentence-1) [🔗](#lib:propagate_on_container_copy_assignment,allocator_traits) `using propagate_on_container_copy_assignment = see below; ` [7](#types-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1782) *Type*: Alloc​::​propagate_on_container_copy_assignment if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​propagate_on_container_copy_assignment is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-7.sentence-1) [🔗](#lib:propagate_on_container_move_assignment,allocator_traits) `using propagate_on_container_move_assignment = see below; ` [8](#types-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1795) *Type*: Alloc​::​propagate_on_container_move_assignment if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​propagate_on_container_move_assignment is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-8.sentence-1) [🔗](#lib:propagate_on_container_swap,allocator_traits) `using propagate_on_container_swap = see below; ` [9](#types-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1808) *Type*: Alloc​::​propagate_on_container_swap if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​propagate_on_container_swap is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#types-9.sentence-1) [🔗](#lib:is_always_equal,allocator_traits) `using is_always_equal = see below; ` [10](#types-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1821) *Type*: Alloc​::​is_always_equal if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​is_always_equal is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise is_empty​::​type[.](#types-10.sentence-1) [🔗](#lib:rebind_alloc,allocator_traits) `template using rebind_alloc = see below; ` [11](#types-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1834) *Alias template*: Alloc​::​rebind​::​other if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc​::​rebind​::​other is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,Alloc if Alloc is a class template instantiation of the form Alloc, where Args is zero or more type arguments; otherwise, the instantiation of rebind_alloc is ill-formed[.](#types-11.sentence-1) #### [20.2.9.3](#members) Static member functions [[allocator.traits.members]](allocator.traits.members) [🔗](#lib:allocate,allocator_traits) `static constexpr pointer allocate(Alloc& a, size_type n); ` [1](#members-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1851) *Returns*: a.allocate(n)[.](#members-1.sentence-1) [🔗](#lib:allocate,allocator_traits_) `static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); ` [2](#members-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1862) *Returns*: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n)[.](#members-2.sentence-1) [🔗](#lib:allocate_at_least,allocator_traits) `static constexpr allocation_result allocate_at_least(Alloc& a, size_type n); ` [3](#members-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1873) *Returns*: a.allocate_at_least(n) if that expression is well-formed; otherwise, {a.allocate(n), n}[.](#members-3.sentence-1) [🔗](#lib:deallocate,allocator_traits) `static constexpr void deallocate(Alloc& a, pointer p, size_type n); ` [4](#members-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1885) *Effects*: Calls a.deallocate(p, n)[.](#members-4.sentence-1) [5](#members-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1889) *Throws*: Nothing[.](#members-5.sentence-1) [🔗](#lib:construct,allocator_traits) `template static constexpr void construct(Alloc& a, T* p, Args&&... args); ` [6](#members-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1901) *Effects*: Calls a.construct(p, std​::​forward(args)...) if that call is well-formed; otherwise, invokes construct_at(p, std​::​forward(args)...)[.](#members-6.sentence-1) [🔗](#lib:destroy,allocator_traits) `template static constexpr void destroy(Alloc& a, T* p); ` [7](#members-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1915) *Effects*: Calls a.destroy(p) if that call is well-formed; otherwise, invokesdestroy_at(p)[.](#members-7.sentence-1) [🔗](#lib:max_size,allocator_traits) `static constexpr size_type max_size(const Alloc& a) noexcept; ` [8](#members-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1927) *Returns*: a.max_size() if that expression is well-formed; otherwise,numeric_limits​::​​max() / sizeof(value_type)[.](#members-8.sentence-1) [🔗](#lib:select_on_container_copy_construction,allocator_traits) `static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); ` [9](#members-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1939) *Returns*: rhs.select_on_container_copy_construction() if that expression is well-formed; otherwise, rhs[.](#members-9.sentence-1) #### [20.2.9.4](#other) Other [[allocator.traits.other]](allocator.traits.other) [1](#other-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1947) The class template allocation_result has the template parameters, data members, and special members specified above[.](#other-1.sentence-1) It has no base classes or members other than those specified[.](#other-1.sentence-2)