293 lines
12 KiB
Markdown
293 lines
12 KiB
Markdown
[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<class Alloc> 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<class T> using rebind_alloc = *see below*; template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; 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<pointer, size_type> allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); template<class T, class... Args>static constexpr void construct(Alloc& a, T* p, Args&&... args); template<class T>static 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<pointer>::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<pointer>::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<pointer>::rebind<const void>[.](#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<pointer>::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<difference_type>[.](#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<Alloc>::type[.](#types-10.sentence-1)
|
||
|
||
[ð](#lib:rebind_alloc,allocator_traits)
|
||
|
||
`template<class T> using rebind_alloc = see below;
|
||
`
|
||
|
||
[11](#types-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1834)
|
||
|
||
*Alias template*: Alloc::rebind<T>::other if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::rebind<T>::other is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,Alloc<T, Args> if Alloc is a class template instantiation
|
||
of the form Alloc<U, Args>, 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<pointer, size_type> 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<class T, class... Args>
|
||
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>(args)...) if that call is well-formed;
|
||
otherwise, invokes construct_at(p, std::forward<Args>(args)...)[.](#members-6.sentence-1)
|
||
|
||
[ð](#lib:destroy,allocator_traits)
|
||
|
||
`template<class T>
|
||
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<size_type>::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)
|