[container.alloc.reqmts]

# 23 Containers library [[containers]](./#containers)

## 23.2 Requirements [[container.requirements]](container.requirements#container.alloc.reqmts)

### 23.2.2 General containers [[container.requirements.general]](container.requirements.general#container.alloc.reqmts)

#### 23.2.2.5 Allocator-aware containers [container.alloc.reqmts]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L957)

Except for array and inplace_vector,
all of the containers defined in [[containers]](containers "23 Containers library"),[[stacktrace.basic]](stacktrace.basic "19.6.4 Class template basic_­stacktrace"), [[basic.string]](basic.string "27.4.3 Class template basic_­string"), and [[re.results]](re.results "28.6.9 Class template match_­results") meet the additional requirements of an [*allocator-aware container*](#def:container,allocator-aware "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]"),
as described below[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L964)

Given an allocator type A and given a container type X having a value_type identical to T and an allocator_type identical to allocator_traits<A>​::​rebind_alloc<T> and given an lvalue m of type A,
a pointer p of type T*,
an expression v that denotes
an lvalue of type T or const T or
an rvalue of type const T,
and an rvalue rv of type T,
the following terms are defined[.](#2.sentence-1)

If X is not allocator-aware or is a specialization of basic_string,
the terms below are defined as if A wereallocator<T> â no allocator object needs to be created
and user specializations of allocator<T> are not instantiated:

- [(2.1)](#2.1)

T is [**Cpp17DefaultInsertable* into X*](#def:Cpp17DefaultInsertable_into_X "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]") means that the following expression is well-formed:allocator_traits<A>::construct(m, p)

- [(2.2)](#2.2)

An element of X is [*default-inserted*](#def:default-inserted "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]") if it is initialized
by evaluation of the expressionallocator_traits<A>::construct(m, p) where p is the address of the uninitialized storage for the element
allocated within X.

- [(2.3)](#2.3)

T is [**Cpp17MoveInsertable* into X*](#def:Cpp17MoveInsertable_into_X "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]") means that the following expression
is well-formed:allocator_traits<A>::construct(m, p, rv) and its evaluation causes the following postcondition to hold: The value
of *p is equivalent to the value of rv before the evaluation. [*Note [1](#note-1)*:
  rv remains a valid object[.](#2.3.sentence-2)
  Its state is unspecified[.](#2.3.sentence-3)
 â *end note*]

- [(2.4)](#2.4)

T is [**Cpp17CopyInsertable* into X*](#def:Cpp17CopyInsertable_into_X "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]") means that, in addition to T being *Cpp17MoveInsertable* intoX, the following expression is well-formed:allocator_traits<A>::construct(m, p, v) and its evaluation causes the following postcondition to hold:
The value of v is unchanged and is equivalent to *p.

- [(2.5)](#2.5)

T is[**Cpp17EmplaceConstructible* into X from args*](#def:Cpp17EmplaceConstructible_into_X_from_args "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]"),
for zero
or more arguments args, means that the following expression is well-formed:allocator_traits<A>::construct(m, p, args)

- [(2.6)](#2.6)

T is[**Cpp17Erasable* from X*](#def:Cpp17Erasable_from_X "23.2.2.5 Allocator-aware containers [container.alloc.reqmts]") means that the following expression is well-formed:allocator_traits<A>::destroy(m, p)

[*Note [2](#note-2)*:

A container calls allocator_traits<A>​::​construct(m, p, args) to construct an element at p using args,
with m == get_allocator()[.](#2.sentence-3)

The default construct in allocator will
call ​::​new((void*)p) T(args),
but specialized allocators can choose a different definition[.](#2.sentence-4)

â *end note*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1051)

In this subclause,

- [(3.1)](#3.1)

X denotes an allocator-aware container class
with a value_type of T using an allocator of type A,

- [(3.2)](#3.2)

u denotes a variable,

- [(3.3)](#3.3)

a and b denote non-const lvalues of type X,

- [(3.4)](#3.4)

c denotes an lvalue of type const X,

- [(3.5)](#3.5)

t denotes an lvalue or a const rvalue of type X,

- [(3.6)](#3.6)

rv denotes a non-const rvalue of type X, and

- [(3.7)](#3.7)

m is a value of type A[.](#3.sentence-1)

A type X meets the allocator-aware container requirements
if X meets the container requirements and
the following types, statements, and expressions are well-formed and have
the specified semantics[.](#3.sentence-2)

[ð](#lib:allocator_type,containers)

`typename X::allocator_type
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1100)

*Result*: A

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1104)

*Mandates*: allocator_type​::​value_type is the same as X​::​value_type[.](#5.sentence-1)

[ð](#lib:get_allocator,containers)

`c.get_allocator()
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1115)

*Result*: A

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1119)

*Complexity*: Constant[.](#7.sentence-1)

[ð](#itemdecl:3)

`X u;
X u = X();
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1130)

*Preconditions*: A meets the *Cpp17DefaultConstructible* requirements[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1134)

*Postconditions*: u.empty() returns true, u.get_allocator() == A()[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1138)

*Complexity*: Constant[.](#10.sentence-1)

[ð](#itemdecl:4)

`X u(m);
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1148)

*Postconditions*: u.empty() returns true, u.get_allocator() == m[.](#11.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1152)

*Complexity*: Constant[.](#12.sentence-1)

[ð](#itemdecl:5)

`X u(t, m);
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1162)

*Preconditions*: T is *Cpp17CopyInsertable* into X[.](#13.sentence-1)

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1166)

*Postconditions*: u == t, u.get_allocator() == m[.](#14.sentence-1)

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1170)

*Complexity*: Linear[.](#15.sentence-1)

[ð](#itemdecl:6)

`X u(rv);
`

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1180)

*Postconditions*: u has the same elements as rv had before this construction;
the value of u.get_allocator() is the same as
the value of rv.get_allocator() before this construction[.](#16.sentence-1)

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1186)

*Complexity*: Constant[.](#17.sentence-1)

[ð](#itemdecl:7)

`X u(rv, m);
`

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1196)

*Preconditions*: T is *Cpp17MoveInsertable* into X[.](#18.sentence-1)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1200)

*Postconditions*: u has the same elements, or copies of the elements,
that rv had before this construction,u.get_allocator() == m[.](#19.sentence-1)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1206)

*Complexity*: Constant if m == rv.get_allocator(), otherwise linear[.](#20.sentence-1)

[ð](#itemdecl:8)

`a = t
`

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1216)

*Result*: X&[.](#21.sentence-1)

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1220)

*Preconditions*: T is *Cpp17CopyInsertable* into X and*Cpp17CopyAssignable*[.](#22.sentence-1)

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1225)

*Postconditions*: a == t is true[.](#23.sentence-1)

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1229)

*Complexity*: Linear[.](#24.sentence-1)

[ð](#lib:operator=,containers)

`a = rv
`

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1240)

*Result*: X&[.](#25.sentence-1)

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1244)

*Preconditions*: Ifallocator_traits<allocator_type>​::​propagate_on_container_move_assignment​::​value is false,T is *Cpp17MoveInsertable* into X and*Cpp17MoveAssignable*[.](#26.sentence-1)

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1252)

*Effects*: All existing elements of a are either move assigned to or destroyed[.](#27.sentence-1)

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1256)

*Postconditions*: If a and rv do not refer to the same object,a is equal to the value that rv had before this assignment[.](#28.sentence-1)

[29](#29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1261)

*Complexity*: Linear[.](#29.sentence-1)

[ð](#lib:swap,containers)

`a.swap(b)
`

[30](#30)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1272)

*Result*: void

[31](#31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1276)

*Effects*: Exchanges the contents of a and b[.](#31.sentence-1)

[32](#32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L1280)

*Complexity*: Constant[.](#32.sentence-1)
