Except for array, all of the containers defined in [containers],
[stacktrace.basic], [basic.string], and [re.results]
meet the additional requirements of an *allocator-aware container*,
as described below.

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 of type T or const T,
and an rvalue rv of type T,
the following terms are defined.

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

- T is
means that the following expression is well-formed: allocator_traits<A>::construct(m, p)*Cpp17DefaultInsertable*into X - An element of X is
*default-inserted*if it is initialized by evaluation of the expression allocator_traits<A>::construct(m, p) where p is the address of the uninitialized storage for the element allocated within X. - T is
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.*Cpp17MoveInsertable*into X - T is
means that, in addition to T being*Cpp17CopyInsertable*into X*Cpp17MoveInsertable*into X, 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. - T is
, for zero or more arguments args, means that the following expression is well-formed: allocator_traits<A>::construct(m, p, args)*Cpp17EmplaceConstructible*into X from args - T is
means that the following expression is well-formed: allocator_traits<A>::destroy(m, p)*Cpp17Erasable*from X

In this subclause,

- X denotes an allocator-aware container class with a value_type of T using an allocator of type A,
- u denotes a variable,
- a and b denote non-const lvalues of type X,
- c denotes an lvalue of type const X,
- t denotes an lvalue or a const rvalue of type X,
- rv denotes a non-const rvalue of type X, and
- m is a value of type A.

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.

```
typename X::allocator_type
```

```
c.get_allocator()
```

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

```
X u(m);
```

```
X u(t, m);
```

```
X u(rv);
```

```
X u(rv, m);
```

```
a = t
```

```
a = rv
```

```
a.swap(b)
```