23 Containers library [containers]


23.1 General [containers.general]

23.2 Requirements [container.requirements]

23.2.1 Preamble [container.requirements.pre]

23.2.2 General containers [container.requirements.general]

23.2.2.1 Introduction [container.intro.reqmts]

23.2.2.2 Container requirements [container.reqmts]

23.2.2.3 Reversible container requirements [container.rev.reqmts]

23.2.2.4 Optional container requirements [container.opt.reqmts]

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

23.2.3 Container data races [container.requirements.dataraces]

23.2.4 Sequence containers [sequence.reqmts]

23.2.5 Node handles [container.node]

23.2.5.1 Overview [container.node.overview]

23.2.5.2 Constructors, copy, and assignment [container.node.cons]

23.2.5.3 Destructor [container.node.dtor]

23.2.5.4 Observers [container.node.observers]

23.2.5.5 Modifiers [container.node.modifiers]

23.2.6 Insert return type [container.insert.return]

23.2.7 Associative containers [associative.reqmts]

23.2.7.1 General [associative.reqmts.general]

23.2.7.2 Exception safety guarantees [associative.reqmts.except]

23.2.8 Unordered associative containers [unord.req]

23.2.8.1 General [unord.req.general]

23.2.8.2 Exception safety guarantees [unord.req.except]

23.3 Sequence containers [sequences]

23.3.1 General [sequences.general]

23.3.2 Header <array> synopsis [array.syn]

23.3.3 Class template array [array]

23.3.3.1 Overview [array.overview]

23.3.3.2 Constructors, copy, and assignment [array.cons]

23.3.3.3 Member functions [array.members]

23.3.3.4 Specialized algorithms [array.special]

23.3.3.5 Zero-sized arrays [array.zero]

23.3.3.6 Array creation functions [array.creation]

23.3.3.7 Tuple interface [array.tuple]

23.3.4 Header <deque> synopsis [deque.syn]

23.3.5 Class template deque [deque]

23.3.5.1 Overview [deque.overview]

23.3.5.2 Constructors, copy, and assignment [deque.cons]

23.3.5.3 Capacity [deque.capacity]

23.3.5.4 Modifiers [deque.modifiers]

23.3.5.5 Erasure [deque.erasure]

23.3.6 Header <forward_list> synopsis [forward.list.syn]

23.3.7 Class template forward_list [forward.list]

23.3.7.1 Overview [forward.list.overview]

23.3.7.2 Constructors, copy, and assignment [forward.list.cons]

23.3.7.3 Iterators [forward.list.iter]

23.3.7.4 Element access [forward.list.access]

23.3.7.5 Modifiers [forward.list.modifiers]

23.3.7.6 Operations [forward.list.ops]

23.3.7.7 Erasure [forward.list.erasure]

23.3.8 Header <hive> synopsis [hive.syn]

23.3.9 Class template hive [hive]

23.3.9.1 Overview [hive.overview]

23.3.9.2 Constructors, copy, and assignment [hive.cons]

23.3.9.3 Capacity [hive.capacity]

23.3.9.4 Modifiers [hive.modifiers]

23.3.9.5 Operations [hive.operations]

23.3.9.6 Erasure [hive.erasure]

23.3.10 Header <list> synopsis [list.syn]

23.3.11 Class template list [list]

23.3.11.1 Overview [list.overview]

23.3.11.2 Constructors, copy, and assignment [list.cons]

23.3.11.3 Capacity [list.capacity]

23.3.11.4 Modifiers [list.modifiers]

23.3.11.5 Operations [list.ops]

23.3.11.6 Erasure [list.erasure]

23.3.12 Header <vector> synopsis [vector.syn]

23.3.13 Class template vector [vector]

23.3.13.1 Overview [vector.overview]

23.3.13.2 Constructors [vector.cons]

23.3.13.3 Capacity [vector.capacity]

23.3.13.4 Data [vector.data]

23.3.13.5 Modifiers [vector.modifiers]

23.3.13.6 Erasure [vector.erasure]

23.3.14 Specialization of vector for bool [vector.bool]

23.3.14.1 Partial class template specialization vector<bool, Allocator> [vector.bool.pspc]

23.3.14.2 Formatter specialization for vector<bool> [vector.bool.fmt]

23.3.15 Header <inplace_vector> synopsis [inplace.vector.syn]

23.3.16 Class template inplace_vector [inplace.vector]

23.3.16.1 Overview [inplace.vector.overview]

23.3.16.2 Constructors [inplace.vector.cons]

23.3.16.3 Capacity [inplace.vector.capacity]

23.3.16.4 Data [inplace.vector.data]

23.3.16.5 Modifiers [inplace.vector.modifiers]

23.3.16.6 Erasure [inplace.vector.erasure]

23.4 Associative containers [associative]

23.4.1 General [associative.general]

23.4.2 Header <map> synopsis [associative.map.syn]

23.4.3 Class template map [map]

23.4.3.1 Overview [map.overview]

23.4.3.2 Constructors, copy, and assignment [map.cons]

23.4.3.3 Element access [map.access]

23.4.3.4 Modifiers [map.modifiers]

23.4.3.5 Erasure [map.erasure]

23.4.4 Class template multimap [multimap]

23.4.4.1 Overview [multimap.overview]

23.4.4.2 Constructors [multimap.cons]

23.4.4.3 Modifiers [multimap.modifiers]

23.4.4.4 Erasure [multimap.erasure]

23.4.5 Header <set> synopsis [associative.set.syn]

23.4.6 Class template set [set]

23.4.6.1 Overview [set.overview]

23.4.6.2 Constructors, copy, and assignment [set.cons]

23.4.6.3 Erasure [set.erasure]

23.4.6.4 Modifiers [set.modifiers]

23.4.7 Class template multiset [multiset]

23.4.7.1 Overview [multiset.overview]

23.4.7.2 Constructors [multiset.cons]

23.4.7.3 Erasure [multiset.erasure]

23.5 Unordered associative containers [unord]

23.5.1 General [unord.general]

23.5.2 Header <unordered_map> synopsis [unord.map.syn]

23.5.3 Class template unordered_map [unord.map]

23.5.3.1 Overview [unord.map.overview]

23.5.3.2 Constructors [unord.map.cnstr]

23.5.3.3 Element access [unord.map.elem]

23.5.3.4 Modifiers [unord.map.modifiers]

23.5.3.5 Erasure [unord.map.erasure]

23.5.4 Class template unordered_multimap [unord.multimap]

23.5.4.1 Overview [unord.multimap.overview]

23.5.4.2 Constructors [unord.multimap.cnstr]

23.5.4.3 Modifiers [unord.multimap.modifiers]

23.5.4.4 Erasure [unord.multimap.erasure]

23.5.5 Header <unordered_set> synopsis [unord.set.syn]

23.5.6 Class template unordered_set [unord.set]

23.5.6.1 Overview [unord.set.overview]

23.5.6.2 Constructors [unord.set.cnstr]

23.5.6.3 Erasure [unord.set.erasure]

23.5.6.4 Modifiers [unord.set.modifiers]

23.5.7 Class template unordered_multiset [unord.multiset]

23.5.7.1 Overview [unord.multiset.overview]

23.5.7.2 Constructors [unord.multiset.cnstr]

23.5.7.3 Erasure [unord.multiset.erasure]

23.6 Container adaptors [container.adaptors]

23.6.1 General [container.adaptors.general]

23.6.2 Header <queue> synopsis [queue.syn]

23.6.3 Class template queue [queue]

23.6.3.1 Definition [queue.defn]

23.6.3.2 Constructors [queue.cons]

23.6.3.3 Constructors with allocators [queue.cons.alloc]

23.6.3.4 Modifiers [queue.mod]

23.6.3.5 Operators [queue.ops]

23.6.3.6 Specialized algorithms [queue.special]

23.6.4 Class template priority_queue [priority.queue]

23.6.4.1 Overview [priqueue.overview]

23.6.4.2 Constructors [priqueue.cons]

23.6.4.3 Constructors with allocators [priqueue.cons.alloc]

23.6.4.4 Members [priqueue.members]

23.6.4.5 Specialized algorithms [priqueue.special]

23.6.5 Header <stack> synopsis [stack.syn]

23.6.6 Class template stack [stack]

23.6.6.1 General [stack.general]

23.6.6.2 Definition [stack.defn]

23.6.6.3 Constructors [stack.cons]

23.6.6.4 Constructors with allocators [stack.cons.alloc]

23.6.6.5 Modifiers [stack.mod]

23.6.6.6 Operators [stack.ops]

23.6.6.7 Specialized algorithms [stack.special]

23.6.7 Header <flat_map> synopsis [flat.map.syn]

23.6.8 Class template flat_map [flat.map]

23.6.8.1 Overview [flat.map.overview]

23.6.8.2 Definition [flat.map.defn]

23.6.8.3 Constructors [flat.map.cons]

23.6.8.4 Constructors with allocators [flat.map.cons.alloc]

23.6.8.5 Capacity [flat.map.capacity]

23.6.8.6 Access [flat.map.access]

23.6.8.7 Modifiers [flat.map.modifiers]

23.6.8.8 Erasure [flat.map.erasure]

23.6.9 Class template flat_multimap [flat.multimap]

23.6.9.1 Overview [flat.multimap.overview]

23.6.9.2 Definition [flat.multimap.defn]

23.6.9.3 Constructors [flat.multimap.cons]

23.6.9.4 Constructors with allocators [flat.multimap.cons.alloc]

23.6.9.5 Erasure [flat.multimap.erasure]

23.6.10 Header <flat_set> synopsis [flat.set.syn]

23.6.11 Class template flat_set [flat.set]

23.6.11.1 Overview [flat.set.overview]

23.6.11.2 Definition [flat.set.defn]

23.6.11.3 Constructors [flat.set.cons]

23.6.11.4 Constructors with allocators [flat.set.cons.alloc]

23.6.11.5 Modifiers [flat.set.modifiers]

23.6.11.6 Erasure [flat.set.erasure]

23.6.12 Class template flat_multiset [flat.multiset]

23.6.12.1 Overview [flat.multiset.overview]

23.6.12.2 Definition [flat.multiset.defn]

23.6.12.3 Constructors [flat.multiset.cons]

23.6.12.4 Constructors with allocators [flat.multiset.cons.alloc]

23.6.12.5 Modifiers [flat.multiset.modifiers]

23.6.12.6 Erasure [flat.multiset.erasure]

23.6.13 Container adaptors formatting [container.adaptors.format]

23.7 Views [views]

23.7.1 General [views.general]

23.7.2 Contiguous access [views.contiguous]

23.7.2.1 Header <span> synopsis [span.syn]

23.7.2.2 Class template span [views.span]

23.7.2.2.1 Overview [span.overview]

23.7.2.2.2 Constructors, copy, and assignment [span.cons]

23.7.2.2.3 Deduction guides [span.deduct]

23.7.2.2.4 Subviews [span.sub]

23.7.2.2.5 Observers [span.obs]

23.7.2.2.6 Element access [span.elem]

23.7.2.2.7 Iterator support [span.iterators]

23.7.2.3 Views of object representation [span.objectrep]

23.7.3 Multidimensional access [views.multidim]

23.7.3.1 Overview [mdspan.overview]

23.7.3.2 Header <mdspan> synopsis [mdspan.syn]

23.7.3.3 Class template extents [mdspan.extents]

23.7.3.3.1 Overview [mdspan.extents.overview]

23.7.3.3.2 Exposition-only helpers [mdspan.extents.expo]

23.7.3.3.3 Constructors [mdspan.extents.cons]

23.7.3.3.4 Observers of the multidimensional index space [mdspan.extents.obs]

23.7.3.3.5 Comparison operators [mdspan.extents.cmp]

23.7.3.3.6 Alias template dextents [mdspan.extents.dextents]

23.7.3.3.7 Alias template dims [mdspan.extents.dims]

23.7.3.4 Layout mapping [mdspan.layout]

23.7.3.4.1 General [mdspan.layout.general]

23.7.3.4.2 Requirements [mdspan.layout.reqmts]

23.7.3.4.3 Layout mapping policy requirements [mdspan.layout.policy.reqmts]

23.7.3.4.4 Layout mapping policies [mdspan.layout.policy.overview]

23.7.3.4.5 Class template layout_left​::​mapping [mdspan.layout.left]

23.7.3.4.5.1 Overview [mdspan.layout.left.overview]

23.7.3.4.5.2 Constructors [mdspan.layout.left.cons]

23.7.3.4.5.3 Observers [mdspan.layout.left.obs]

23.7.3.4.6 Class template layout_right​::​mapping [mdspan.layout.right]

23.7.3.4.6.1 Overview [mdspan.layout.right.overview]

23.7.3.4.6.2 Constructors [mdspan.layout.right.cons]

23.7.3.4.6.3 Observers [mdspan.layout.right.obs]

23.7.3.4.7 Class template layout_stride​::​mapping [mdspan.layout.stride]

23.7.3.4.7.1 Overview [mdspan.layout.stride.overview]

23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]

23.7.3.4.7.3 Constructors [mdspan.layout.stride.cons]

23.7.3.4.7.4 Observers [mdspan.layout.stride.obs]

23.7.3.4.8 Class template layout_left_padded​::​mapping [mdspan.layout.leftpad]

23.7.3.4.8.1 Overview [mdspan.layout.leftpad.overview]

23.7.3.4.8.2 Exposition-only members [mdspan.layout.leftpad.expo]

23.7.3.4.8.3 Constructors [mdspan.layout.leftpad.cons]

23.7.3.4.8.4 Observers [mdspan.layout.leftpad.obs]

23.7.3.4.9 Class template layout_right_padded​::​mapping [mdspan.layout.rightpad]

23.7.3.4.9.1 Overview [mdspan.layout.rightpad.overview]

23.7.3.4.9.2 Exposition-only members [mdspan.layout.rightpad.expo]

23.7.3.4.9.3 Constructors [mdspan.layout.rightpad.cons]

23.7.3.4.9.4 Observers [mdspan.layout.rightpad.obs]

23.7.3.5 Accessor policy [mdspan.accessor]

23.7.3.5.1 General [mdspan.accessor.general]

23.7.3.5.2 Requirements [mdspan.accessor.reqmts]

23.7.3.5.3 Class template default_accessor [mdspan.accessor.default]

23.7.3.5.3.1 Overview [mdspan.accessor.default.overview]

23.7.3.5.3.2 Members [mdspan.accessor.default.members]

23.7.3.5.4 Class template aligned_accessor [mdspan.accessor.aligned]

23.7.3.5.4.1 Overview [mdspan.accessor.aligned.overview]

23.7.3.5.4.2 Members [mdspan.accessor.aligned.members]

23.7.3.6 Class template mdspan [mdspan.mdspan]

23.7.3.6.1 Overview [mdspan.mdspan.overview]

23.7.3.6.2 Constructors [mdspan.mdspan.cons]

23.7.3.6.3 Members [mdspan.mdspan.members]

23.7.3.7 submdspan [mdspan.sub]

23.7.3.7.1 Overview [mdspan.sub.overview]

23.7.3.7.2 Range slices [mdspan.sub.range.slices]

23.7.3.7.3 submdspan_mapping_result [mdspan.sub.map.result]

23.7.3.7.4 Exposition-only helpers [mdspan.sub.helpers]

23.7.3.7.5 submdspan slice canonicalization [mdspan.sub.canonical]

23.7.3.7.6 subextents function [mdspan.sub.extents]

23.7.3.7.7 Specializations of submdspan_mapping [mdspan.sub.map]

23.7.3.7.7.1 Sliceable layout mapping requirements [mdspan.sub.map.sliceable]

23.7.3.7.7.2 Common [mdspan.sub.map.common]

23.7.3.7.7.3 layout_left specialization of submdspan_mapping [mdspan.sub.map.left]

23.7.3.7.7.4 layout_right specialization of submdspan_mapping [mdspan.sub.map.right]

23.7.3.7.7.5 layout_stride specialization of submdspan_mapping [mdspan.sub.map.stride]

23.7.3.7.7.6 layout_left_padded specialization of submdspan_mapping [mdspan.sub.map.leftpad]

23.7.3.7.7.7 layout_right_padded specialization of submdspan_mapping [mdspan.sub.map.rightpad]

23.7.3.7.8 submdspan function template [mdspan.sub.sub]

23.7.3.8 Multidimensional copy algorithms [mdspan.copy]


23.1 General [containers.general]

This Clause describes components that C++ programs may use to organize collections of information.
The following subclauses describe container requirements, and components for sequence containers and associative containers, as summarized in Table Clause 74.
Table 74 — Containers library summary [tab:containers.summary]
Subclause
Header
Requirements
Sequence containers
<array>, <deque>, <forward_list>, <hive>,
<inplace_vector>, <list>, <vector>
Associative containers
<map>, <set>
Unordered associative containers
<unordered_map>, <unordered_set>
Container adaptors
<queue>, <stack>, <flat_map>, <flat_set>
Views
<span>, <mdspan>

23.2 Requirements [container.requirements]

23.2.1 Preamble [container.requirements.pre]

Containers are objects that store other objects.
They control allocation and deallocation of these objects through constructors, destructors, insert and erase operations.
All of the complexity requirements in this Clause are stated solely in terms of the number of operations on the contained objects.
[Example 1: 
The copy constructor of type vector<vector<int>> has linear complexity, even though the complexity of copying each contained vector<int> is itself linear.
— end example]
Allocator-aware containers ([container.alloc.reqmts]) other than basic_string construct elements using the function allocator_traits<allocator_type>​::​rebind_traits<U>​::​​construct and destroy elements using the function allocator_traits<allocator_type>​::​rebind_traits<U>​::​​destroy ([allocator.traits.members]), where U is either allocator_type​::​value_type or an internal type used by the container.
These functions are called only for the container's element type, not for internal types used by the container.
[Note 1: 
This means, for example, that a node-based container would need to construct nodes containing aligned buffers and call construct to place the element into the buffer.
— end note]

23.2.2 General containers [container.requirements.general]

23.2.2.1 Introduction [container.intro.reqmts]

In [container.requirements.general],
  • X denotes a container class containing objects of type T,
  • a denotes a value of type X,
  • b and c denote values of type (possibly const) X,
  • i and j denote values of type (possibly const) X​::​iterator,
  • u denotes an identifier,
  • v denotes an lvalue of type (possibly const) X or an rvalue of type const X,
  • s and t denote non-const lvalues of type X, and
  • rv denotes a non-const rvalue of type X.
The following exposition-only concept is used in the definition of containers: template<class R, class T> concept container-compatible-range = // exposition only ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;

23.2.2.2 Container requirements [container.reqmts]

A type X meets the container requirements if the following types, statements, and expressions are well-formed and have the specified semantics.
typename X::value_type
Result: T.
Preconditions: T is Cpp17Erasable from X (see [container.alloc.reqmts], below).
typename X::reference
Result: T&.
typename X::const_reference
Result: const T&.
typename X::iterator
Result: A type that meets the forward iterator requirements ([forward.iterators]) with value type T.
The type X​::​iterator is convertible to X​::​const_iterator.
typename X::const_iterator
Result: A type that meets the requirements of a constant iterator and those of a forward iterator with value type T.
typename X::difference_type
Result: A signed integer type, identical to the difference type of X​::​iterator and X​::​const_iterator.
typename X::size_type
Result: An unsigned integer type that can represent any non-negative value of X​::​difference_type.
X u; X u = X();
Postconditions: u.empty().
Complexity: Constant.
X u(v); X u = v;
Preconditions: T is Cpp17CopyInsertable into X (see below).
Postconditions: u == v.
Complexity: Linear.
X u(rv); X u = rv;
Postconditions: u is equal to the value that rv had before this construction.
Complexity: Linear for array and inplace_vector and constant for all other standard containers.
t = v
Result: X&.
Postconditions: t == v.
Complexity: Linear.
t = rv
Result: X&.
Effects: All existing elements of t are either move assigned to or destroyed.
Postconditions: If t and rv do not refer to the same object, t is equal to the value that rv had before this assignment.
Complexity: Linear.
a.~X()
Result: void.
Effects: Destroys every element of a; any memory obtained is deallocated.
Complexity: Linear.
b.begin()
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator referring to the first element in the container.
Complexity: Constant.
b.end()
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator which is the past-the-end value for the container.
Complexity: Constant.
b.cbegin()
Result: const_iterator.
Returns: const_cast<X const&>(b).begin().
Complexity: Constant.
b.cend()
Result: const_iterator.
Returns: const_cast<X const&>(b).end().
Complexity: Constant.
i <=> j
Result: strong_ordering.
Constraints: X​::​iterator meets the random access iterator requirements.
Complexity: Constant.
c == b
Preconditions: T meets the Cpp17EqualityComparable requirements.
Result: bool.
Returns: equal(c.begin(), c.end(), b.begin(), b.end()).
[Note 1: 
The algorithm equal is defined in [alg.equal].
— end note]
Complexity: Constant if c.size() != b.size(), linear otherwise.
Remarks: == is an equivalence relation.
c != b
Effects: Equivalent to !(c == b).
t.swap(s)
Result: void.
Effects: Exchanges the contents of t and s.
Complexity: Linear for array and inplace_vector, and constant for all other standard containers.
swap(t, s)
Effects: Equivalent to t.swap(s).
c.size()
Result: size_type.
Returns: distance(c.begin(), c.end()), i.e., the number of elements in the container.
Complexity: Constant.
Remarks: The number of elements is defined by the rules of constructors, inserts, and erases.
c.max_size()
Result: size_type.
Returns: distance(begin(), end()) for the largest possible container.
Complexity: Constant.
c.empty()
Result: bool.
Returns: c.begin() == c.end()
Complexity: Constant.
Remarks: If the container is empty, then c.empty() is true.
In the expressions i == j i != j i < j i <= j i >= j i > j i <=> j i - j where i and j denote objects of a container's iterator type, either or both may be replaced by an object of the container's const_iterator type referring to the same element with no change in semantics.
Unless otherwise specified, all containers defined in this Clause obtain memory using an allocator (see [allocator.requirements]).
[Note 2: 
In particular, containers and iterators do not store references to allocated elements other than through the allocator's pointer type, i.e., as objects of type P or pointer_traits<P>​::​template rebind<unspecified>, where P is allocator_traits<allocator_type>​::​pointer.
— end note]
Copy constructors for these container types obtain an allocator by calling allocator_traits<allocator_type>​::​select_on_container_copy_construction on the allocator belonging to the container being copied.
Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved.
Such move construction of the allocator shall not exit via an exception.
All other constructors for these container types take a const allocator_type& argument.
[Note 3: 
If an invocation of a constructor uses the default value of an optional allocator argument, then the allocator type must support value-initialization.
— end note]
A copy of this allocator is used for any memory allocation and element construction performed, by these constructors and by all other member functions, during the lifetime of each container object or until the allocator is replaced.
The allocator may be replaced only via assignment or swap().
Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only if
  • allocator_traits<allocator_type>​::​propagate_on_container_copy_assignment​::​value,
  • allocator_traits<allocator_type>​::​propagate_on_container_move_assignment​::​value, or
  • allocator_traits<allocator_type>​::​propagate_on_container_swap​::​value
is true within the implementation of the corresponding container operation.
In all container types defined in this Clause, the member get_allocator() returns a copy of the allocator used to construct the container or, if that allocator has been replaced, a copy of the most recent replacement.
The expression a.swap(b), for containers a and b of a standard container type other than array and inplace_vector, shall exchange the values of a and b without invoking any move, copy, or swap operations on the individual container elements.
Any Compare, Pred, or Hash types belonging to a and b shall meet the Cpp17Swappable requirements and shall be exchanged by calling swap as described in [swappable.requirements].
If allocator_traits<allocator_type>​::​propagate_on_container_swap​::​value is true, then allocator_type shall meet the Cpp17Swappable requirements and the allocators of a and b shall also be exchanged by calling swap as described in [swappable.requirements].
Otherwise, the allocators shall not be swapped, and the behavior is undefined unless a.get_allocator() == b.get_allocator().
Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap.
It is unspecified whether an iterator with value a.end() before the swap will have value b.end() after the swap.
Unless otherwise specified (see [associative.reqmts.except], [unord.req.except], [deque.modifiers], [inplace.vector.modifiers], and [vector.modifiers]) all container types defined in this Clause meet the following additional requirements:
  • If an exception is thrown by an insert() or emplace() function while inserting a single element, that function has no effects.
  • If an exception is thrown by a push_back(), push_front(), emplace_back(), or emplace_front() function, that function has no effects.
  • No erase(), clear(), pop_back() or pop_front() function throws an exception.
  • No copy constructor or assignment operator of a returned iterator throws an exception.
  • No swap() function throws an exception.
  • No swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped.
    [Note 4: 
    The end() iterator does not refer to any element, so it can be invalidated.
    — end note]
Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.
A contiguous container is a container whose member types iterator and const_iterator meet the Cpp17RandomAccessIterator requirements ([random.access.iterators]) and model contiguous_iterator ([iterator.concept.contiguous]).
The behavior of certain container member functions and deduction guides depends on whether types qualify as input iterators or allocators.
The extent to which an implementation determines that a type cannot be an input iterator is unspecified, except that as a minimum integral types shall not qualify as input iterators.
Likewise, the extent to which an implementation determines that a type cannot be an allocator is unspecified, except that as a minimum a type A shall not qualify as an allocator unless it meets both of the following conditions:
  • The qualified-id A​::​value_type is valid and denotes a type ([temp.deduct]).
  • The expression declval<A&>().allocate(size_t{}) is well-formed when treated as an unevaluated operand.

23.2.2.3 Reversible container requirements [container.rev.reqmts]

A type X meets the reversible container requirements if X meets the container requirements, the iterator type of X belongs to the bidirectional or random access iterator categories ([iterator.requirements]), and the following types and expressions are well-formed and have the specified semantics.
typename X::reverse_iterator
Result: The type reverse_iterator<X​::​iterator>, an iterator type whose value type is T.
typename X::const_reverse_iterator
Result: The type reverse_iterator<X​::​const_iterator>, a constant iterator type whose value type is T.
a.rbegin()
Result: const_reverse_iterator if a is of type const X; reverse_iterator otherwise.
Returns: reverse_iterator(end()).
Complexity: Constant.
a.rend()
Result: const_reverse_iterator if a is of type const X; reverse_iterator otherwise.
Returns: reverse_iterator(begin()).
Complexity: Constant.
a.crbegin()
Result: const_reverse_iterator.
Returns: const_cast<X const&>(a).rbegin()
Complexity: Constant.
a.crend()
Result: const_reverse_iterator.
Returns: const_cast<X const&>(a).rend()
Complexity: Constant.

23.2.2.4 Optional container requirements [container.opt.reqmts]

The following operations are provided for some types of containers but not others.
Those containers for which the listed operations are provided shall implement the semantics as described unless otherwise stated.
If the iterators passed to lexicographical_compare_three_way meet the constexpr iterator requirements ([iterator.requirements.general]) then the operations described below are implemented by constexpr functions.
a <=> b
Result: synth-three-way-result<X​::​value_type>.
Preconditions: Either T models three_way_comparable, or < is defined for values of type (possibly const) T and < is a total ordering relationship.
Returns: lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(),
synth-three-way)
.
[Note 1: 
The algorithm lexicographical_compare_three_way is defined in [algorithms].
— end note]
Complexity: Linear.

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

Except for array and inplace_vector, 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 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.
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 Cpp17DefaultInsertable into X means that the following expression is well-formed: allocator_traits<A>::construct(m, p)
  • 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 Cpp17MoveInsertable into X means that the expression allocator_traits<A>::construct(m, p, rv) is well-formed 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: 
    rv remains a valid object.
    Its state is unspecified.
    — end note]
  • T is Cpp17CopyInsertable into X means that, in addition to T being Cpp17MoveInsertable into X, the expression allocator_traits<A>::construct(m, p, v) is well-formed and its evaluation causes the following postcondition to hold: The value of v is unchanged and is equivalent to *p.
  • T is Cpp17EmplaceConstructible into X from args, for zero or more arguments args, means that the following expression is well-formed: allocator_traits<A>::construct(m, p, args)
  • T is Cpp17Erasable from X means that the following expression is well-formed: allocator_traits<A>::destroy(m, p)
[Note 2: 
A container calls allocator_traits<A>​::​construct(m, p, args) to construct an element at p using args, with m == get_allocator().
The default construct in allocator will call ​::​new((void*)p) T(args), but specialized allocators can choose a different definition.
— end note]
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
Result: A.
Mandates: allocator_type​::​value_type is the same as X​::​value_type.
c.get_allocator()
Result: A.
Complexity: Constant.
X u; X u = X();
Preconditions: A meets the Cpp17DefaultConstructible requirements.
Postconditions: u.empty() returns true, u.get_allocator() == A().
Complexity: Constant.
X u(m);
Postconditions: u.empty() returns true, u.get_allocator() == m.
Complexity: Constant.
X u(t, m);
Preconditions: T is Cpp17CopyInsertable into X.
Postconditions: u == t, u.get_allocator() == m.
Complexity: Linear.
X u(rv);
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.
Complexity: Constant.
X u(rv, m);
Preconditions: T is Cpp17MoveInsertable into X.
Postconditions: u has the same elements, or copies of the elements, that rv had before this construction, u.get_allocator() == m.
Complexity: Constant if m == rv.get_allocator(), otherwise linear.
a = t
Result: X&.
Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
Postconditions: a == t is true.
Complexity: Linear.
a = rv
Result: X&.
Preconditions: If allocator_traits<allocator_type>​::​propagate_on_container_move_assignment​::​value is false, T is Cpp17MoveInsertable into X and Cpp17MoveAssignable.
Effects: All existing elements of a are either move assigned to or destroyed.
Postconditions: If a and rv do not refer to the same object, a is equal to the value that rv had before this assignment.
Complexity: Linear.
a.swap(b)
Result: void.
Effects: Exchanges the contents of a and b.
Complexity: Constant.

23.2.3 Container data races [container.requirements.dataraces]

For purposes of avoiding data races ([res.on.data.races]), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at and, except in associative or unordered associative containers, operator[].
Notwithstanding [res.on.data.races], implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting vector<bool>, are modified concurrently.
[Note 1: 
For a vector<int> x with a size greater than one, x[1] = 5 and *x.begin() = 10 can be executed concurrently without a data race, but x[0] = 5 and *x.begin() = 10 executed concurrently can result in a data race.
As an exception to the general rule, for a vector<bool> y, y[0] = true can race with y[1] = true.
— end note]

23.2.4 Sequence containers [sequence.reqmts]

A sequence container organizes a finite set of objects, all of the same type, into a strictly linear arrangement.
The library provides the following basic kinds of sequence containers: vector, inplace_vector, forward_list, list, and deque.
In addition, array and hive are provided as sequence containers which provide limited sequence operations, in array's case because it has a fixed number of elements, and in hive's case because insertion order is unspecified.
The library also provides container adaptors that make it easy to construct abstract data types, such as stacks, queues, flat_maps, flat_multimaps, flat_sets, or flat_multisets, out of the basic sequence container kinds (or out of other program-defined sequence containers).
In this subclause,
  • X denotes a sequence container class,
  • a denotes a value of type X containing elements of type T,
  • u denotes the name of a variable being declared,
  • A denotes X​::​allocator_type if the qualified-id X​::​allocator_type is valid and denotes a type ([temp.deduct]) and allocator<T> if it doesn't,
  • i and j denote iterators that meet the Cpp17InputIterator requirements and refer to elements implicitly convertible to value_type,
  • [i, j) denotes a valid range,
  • rg denotes a value of a type R that models container-compatible-range<T>,
  • il designates an object of type initializer_list<value_type>,
  • n denotes a value of type X​::​size_type,
  • p denotes a valid constant iterator to a,
  • q denotes a valid dereferenceable constant iterator to a,
  • [q1, q2) denotes a valid range of constant iterators in a,
  • t denotes an lvalue or a const rvalue of X​::​value_type, and
  • rv denotes a non-const rvalue of X​::​value_type.
  • Args denotes a template parameter pack;
  • args denotes a function parameter pack with the pattern Args&&.
The complexities of the expressions are sequence dependent.
A type X meets the sequence container requirements if X meets the container requirements and the following statements and expressions are well-formed and have the specified semantics.
X u(n, t);
Preconditions: T is Cpp17CopyInsertable into X.
Effects: Constructs a sequence container with n copies of t.
Postconditions: distance(u.begin(), u.end()) == n is true.
X u(i, j);
Preconditions: T is Cpp17EmplaceConstructible into X from *i.
For vector, if the iterator does not meet the Cpp17ForwardIterator requirements ([forward.iterators]), T is also Cpp17MoveInsertable into X.
Effects: Constructs a sequence container equal to the range [i, j).
Each iterator in the range [i, j) is dereferenced exactly once.
Postconditions: distance(u.begin(), u.end()) == distance(i, j) is true.
X(from_range, rg)
Preconditions: T is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
For vector, if R models ranges​::​approximately_sized_range but not ranges​::​sized_range or models ranges​::​input_range but not ranges​::​forward_range, T is also Cpp17MoveInsertable into X.
Effects: Constructs a sequence container equal to the range rg.
Each iterator in the range rg is dereferenced exactly once.
Recommended practice: If R models ranges​::​approximately_sized_range and ranges​::​distance(rg) <= ranges​::​reserve_hint(rg) is true, an implementation should not perform more than a single reallocation.
Postconditions: distance(begin(), end()) == ranges​::​distance(rg) is true.
X(il)
Effects: Equivalent to X(il.begin(), il.end()).
a = il
Result: X&.
Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
Effects: Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.
Returns: *this.
a.emplace(p, args)
Result: iterator.
Preconditions: T is Cpp17EmplaceConstructible into X from args.
For vector, inplace_vector, and deque, T is also Cpp17MoveInsertable into X and Cpp17MoveAssignable.
Effects: Inserts an object of type T constructed with std​::​forward<Args>(args)... before p.
[Note 1: 
args can directly or indirectly refer to a value in a.
— end note]
Returns: An iterator that points to the new element.
a.insert(p, t)
Result: iterator.
Preconditions: T is Cpp17CopyInsertable into X.
For vector, inplace_vector, and deque, T is also Cpp17CopyAssignable.
Effects: Inserts a copy of t before p.
Returns: An iterator that points to the copy of t inserted into a.
a.insert(p, rv)
Result: iterator.
Preconditions: T is Cpp17MoveInsertable into X.
For vector, inplace_vector, and deque, T is also Cpp17MoveAssignable.
Effects: Inserts a copy of rv before p.
Returns: An iterator that points to the copy of rv inserted into a.
a.insert(p, n, t)
Result: iterator.
Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
Effects: Inserts n copies of t before p.
Returns: An iterator that points to the copy of the first element inserted into a, or p if n == 0.
a.insert(p, i, j)
Result: iterator.
Preconditions: T is Cpp17EmplaceConstructible into X from *i.
For vector, inplace_vector, and deque, T is also Cpp17MoveInsertable into X, and T meets the Cpp17MoveConstructible, Cpp17MoveAssignable, and Cpp17Swappable ([swappable.requirements]) requirements.
Neither i nor j are iterators into a.
Effects: Inserts copies of elements in [i, j) before p.
Each iterator in the range [i, j) shall be dereferenced exactly once.
Returns: An iterator that points to the copy of the first element inserted into a, or p if i == j.
a.insert_range(p, rg)
Result: iterator.
Preconditions: T is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
For vector, inplace_vector, and deque, T is also Cpp17MoveInsertable into X, and T meets the Cpp17MoveConstructible, Cpp17MoveAssignable, and Cpp17Swappable ([swappable.requirements]) requirements.
rg and a do not overlap.
Effects: Inserts copies of elements in rg before p.
Each iterator in the range rg is dereferenced exactly once.
Returns: An iterator that points to the copy of the first element inserted into a, or p if rg is empty.
a.insert(p, il)
Effects: Equivalent to a.insert(p, il.begin(), il.end()).
a.erase(q)
Result: iterator.
Preconditions: For vector, inplace_vector, and deque, T is Cpp17MoveAssignable.
Effects: Erases the element pointed to by q.
Returns: An iterator that points to the element immediately following q prior to the element being erased.
If no such element exists, a.end() is returned.
a.erase(q1, q2)
Result: iterator.
Preconditions: For vector, inplace_vector, and deque, T is Cpp17MoveAssignable.
Effects: Erases the elements in the range [q1, q2).
Returns: An iterator that points to the element pointed to by q2 prior to any elements being erased.
If no such element exists, a.end() is returned.
a.clear()
Result: void.
Effects: Destroys all elements in a.
Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator.
Postconditions: a.empty() is true.
Complexity: Linear.
a.assign(i, j)
Result: void.
Preconditions: T is Cpp17EmplaceConstructible into X from *i and assignable from *i.
For vector, if the iterator does not meet the forward iterator requirements ([forward.iterators]), T is also Cpp17MoveInsertable into X.
Neither i nor j are iterators into a.
Effects: Replaces elements in a with a copy of [i, j).
Invalidates all references, pointers and iterators referring to the elements of a.
For vector and deque, also invalidates the past-the-end iterator.
Each iterator in the range [i, j) is dereferenced exactly once.
a.assign_range(rg)
Result: void.
Mandates: assignable_from<T&, ranges​::​range_reference_t<R>> is modeled.
For inplace_vector, if ranges​::​size(rg) is a constant expression, then ranges​::​size(rg)  ≤ a.max_size().
Preconditions: T is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
For vector, if R models ranges​::​approximately_sized_range but not ranges​::​sized_range or models ranges​::​input_range but not ranges​::​forward_range, T is also Cpp17MoveInsertable into X.
rg and a do not overlap.
Effects: Replaces elements in a with a copy of each element in rg.
Invalidates all references, pointers, and iterators referring to the elements of a.
For vector and deque, also invalidates the past-the-end iterator.
Each iterator in the range rg is dereferenced exactly once.
Recommended practice: If R models ranges​::​approximately_sized_range and ranges​::​distance(rg) <= ranges​::​reserve_hint(rg) is true, an implementation should not perform any reallocation.
a.assign(il)
Effects: Equivalent to a.assign(il.begin(), il.end()).
a.assign(n, t)
Result: void.
Preconditions: T is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
t is not a reference into a.
Effects: Replaces elements in a with n copies of t.
Invalidates all references, pointers and iterators referring to the elements of a.
For vector and deque, also invalidates the past-the-end iterator.
For every sequence container defined in this Clause and in [strings]:
  • If the constructor template<class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); is called with a type InputIterator that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.
  • If the member functions of the forms: template<class InputIterator> return-type F(const_iterator p, InputIterator first, InputIterator last); // such as insert template<class InputIterator> return-type F(InputIterator first, InputIterator last); // such as append, assign template<class InputIterator> return-type F(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last); // such as replace are called with a type InputIterator that does not qualify as an input iterator, then these functions shall not participate in overload resolution.
  • A deduction guide for a sequence container shall not participate in overload resolution if it has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter, or if it has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
The following operations are provided for some types of sequence containers but not others.
Operations other than prepend_range and append_range are implemented so as to take amortized constant time.
a.front()
Result: const_reference if a is of type const X; reference otherwise.
Hardened preconditions: a.empty() is false.
Returns: *a.begin().
Remarks: Required for basic_string, array, deque, forward_list, inplace_vector, list, and vector.
a.back()
Result: const_reference if a is of type const X; reference otherwise.
Hardened preconditions: a.empty() is false.
Effects: Equivalent to: auto tmp = a.end(); --tmp; return *tmp;
Remarks: Required for basic_string, array, deque, inplace_vector, list, and vector.
a.emplace_front(args)
Result: reference.
Preconditions: T is Cpp17EmplaceConstructible into X from args.
Effects: Prepends an object of type T constructed with std​::​forward<Args>(args)....
Returns: a.front().
Remarks: Required for deque, forward_list, and list.
a.emplace_back(args)
Result: reference.
Preconditions: T is Cpp17EmplaceConstructible into X from args.
For vector, T is also Cpp17MoveInsertable into X.
Effects: Appends an object of type T constructed with std​::​forward<Args>(args)....
Returns: a.back().
Remarks: Required for deque, inplace_vector, list, and vector.
a.push_front(t)
Result: void.
Preconditions: T is Cpp17CopyInsertable into X.
Effects: Prepends a copy of t.
Remarks: Required for deque, forward_list, and list.
a.push_front(rv)
Result: void.
Preconditions: T is Cpp17MoveInsertable into X.
Effects: Prepends a copy of rv.
Remarks: Required for deque, forward_list, and list.
a.prepend_range(rg)
Result: void.
Preconditions: T is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
For deque, T is also Cpp17MoveInsertable into X, and T meets the Cpp17MoveConstructible, Cpp17MoveAssignable, and Cpp17Swappable ([swappable.requirements]) requirements.
Effects: Inserts copies of elements in rg before begin().
Each iterator in the range rg is dereferenced exactly once.
[Note 2: 
The order of elements in rg is not reversed.
— end note]
Remarks: Required for deque, forward_list, and list.
a.push_back(t)
Result: void.
Preconditions: T is Cpp17CopyInsertable into X.
Effects: Appends a copy of t.
Remarks: Required for basic_string, deque, inplace_vector, list, and vector.
a.push_back(rv)
Result: void.
Preconditions: T is Cpp17MoveInsertable into X.
Effects: Appends a copy of rv.
Remarks: Required for basic_string, deque, inplace_vector, list, and vector.
a.append_range(rg)
Result: void.
Preconditions: T is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
For vector, T is also Cpp17MoveInsertable into X.
Effects: Inserts copies of elements in rg before end().
Each iterator in the range rg is dereferenced exactly once.
Remarks: Required for deque, inplace_vector, list, and vector.
a.pop_front()
Result: void.
Hardened preconditions: a.empty() is false.
Effects: Destroys the first element.
Remarks: Required for deque, forward_list, and list.
a.pop_back()
Result: void.
Hardened preconditions: a.empty() is false.
Effects: Destroys the last element.
Remarks: Required for basic_string, deque, inplace_vector, list, and vector.
a[n]
Result: const_reference if a is of type const X; reference otherwise.
Hardened preconditions: n < a.size() is true.
Effects: Equivalent to: return *(a.begin() + n);
Remarks: Required for basic_string, array, deque, inplace_vector, and vector.
a.at(n)
Result: const_reference if a is of type const X; reference otherwise.
Returns: *(a.begin() + n).
Throws: out_of_range if n >= a.size().
Remarks: Required for basic_string, array, deque, inplace_vector, and vector.

23.2.5 Node handles [container.node]

23.2.5.1 Overview [container.node.overview]

A node handle is an object that accepts ownership of a single element from an associative container ([associative.reqmts]) or an unordered associative container ([unord.req]).
It may be used to transfer that ownership to another container with compatible nodes.
Containers with compatible nodes have the same node handle type.
Elements may be transferred in either direction between container types in the same row of Table Clause 75.
Table 75 — Container types with compatible nodes [tab:container.node.compat]
map<K, T, C1, A>
map<K, T, C2, A>
map<K, T, C1, A>
multimap<K, T, C2, A>
set<K, C1, A>
set<K, C2, A>
set<K, C1, A>
multiset<K, C2, A>
unordered_map<K, T, H1, E1, A>
unordered_map<K, T, H2, E2, A>
unordered_map<K, T, H1, E1, A>
unordered_multimap<K, T, H2, E2, A>
unordered_set<K, H1, E1, A>
unordered_set<K, H2, E2, A>
unordered_set<K, H1, E1, A>
unordered_multiset<K, H2, E2, A>
If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container when the element was extracted.
If a node handle is empty, it contains no allocator.
Class node-handle is for exposition only.
If a user-defined specialization of pair exists for pair<const Key, T> or pair<Key, T>, where Key is the container's key_type and T is the container's mapped_type, the behavior of operations involving node handles is undefined.
template<unspecified> class node-handle { public: // These type declarations are described in [associative.reqmts] and [unord.req]. using value_type = see below; // not present for map containers using key_type = see below; // not present for set containers using mapped_type = see below; // not present for set containers using allocator_type = see below; private: using container-node-type = unspecified; // exposition only using ator-traits = allocator_traits<allocator_type>; // exposition only typename ator-traits::template rebind_traits<container-node-type>::pointer ptr_; // exposition only optional<allocator_type> alloc_; // exposition only public: // [container.node.cons], constructors, copy, and assignment constexpr node-handle() noexcept : ptr_(), alloc_() {} constexpr node-handle(node-handle&&) noexcept; constexpr node-handle& operator=(node-handle&&); // [container.node.dtor], destructor constexpr ~node-handle(); // [container.node.observers], observers constexpr value_type& value() const; // not present for map containers key_type& key() const; // not present for set containers constexpr mapped_type& mapped() const; // not present for set containers constexpr allocator_type get_allocator() const; constexpr explicit operator bool() const noexcept; constexpr bool empty() const noexcept; // [container.node.modifiers], modifiers constexpr void swap(node-handle&) noexcept(ator-traits::propagate_on_container_swap::value || ator-traits::is_always_equal::value); friend constexpr void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } };

23.2.5.2 Constructors, copy, and assignment [container.node.cons]

constexpr node-handle(node-handle&& nh) noexcept;
Effects: Constructs a node-handle object initializing ptr_ with nh.ptr_.
Move constructs alloc_ with nh.alloc_.
Assigns nullptr to nh.ptr_ and assigns nullopt to nh.alloc_.
constexpr node-handle& operator=(node-handle&& nh);
Preconditions: Either !alloc_ is true, or ator-traits​::​propagate_on_container_move_assignment​::​value is true, or alloc_ == nh.alloc_ is true.
Effects:
  • If ptr_ != nullptr is true, destroys the value_type subobject in the container-node-type object pointed to by ptr_ by calling ator-traits​::​destroy, then deallocates ptr_ by calling ator-traits​::​template rebind_traits<container-node-type>​::​deallocate.
  • Assigns nh.ptr_ to ptr_.
  • If !alloc_ is true or ator-traits​::​propagate_on_container_move_assignment​::​value is true, move assigns nh.alloc_ to alloc_.
  • Assigns nullptr to nh.ptr_ and assigns nullopt to nh.alloc_.
Returns: *this.
Throws: Nothing.

23.2.5.3 Destructor [container.node.dtor]

constexpr ~node-handle();
Effects: If ptr_ != nullptr is true, destroys the value_type subobject in the container-node-type object pointed to by ptr_ by calling ator-traits​::​destroy, then deallocates ptr_ by calling ator-traits​::​template rebind_traits<container-node-type>​::​deallocate.

23.2.5.4 Observers [container.node.observers]

constexpr value_type& value() const;
Preconditions: empty() == false.
Returns: A reference to the value_type subobject in the container-node-type object pointed to by ptr_.
Throws: Nothing.
key_type& key() const;
Preconditions: empty() == false.
Returns: A non-const reference to the key_type member of the value_type subobject in the container-node-type object pointed to by ptr_.
Throws: Nothing.
Remarks: Modifying the key through the returned reference is permitted.
constexpr mapped_type& mapped() const;
Preconditions: empty() == false.
Returns: A reference to the mapped_type member of the value_type subobject in the container-node-type object pointed to by ptr_.
Throws: Nothing.
constexpr allocator_type get_allocator() const;
Preconditions: empty() == false.
Returns: *alloc_.
Throws: Nothing.
constexpr explicit operator bool() const noexcept;
Returns: ptr_ != nullptr.
constexpr bool empty() const noexcept;
Returns: ptr_ == nullptr.

23.2.5.5 Modifiers [container.node.modifiers]

constexpr void swap(node-handle& nh) noexcept(ator-traits::propagate_on_container_swap::value || ator-traits::is_always_equal::value);
Preconditions: !alloc_ is true, or !nh.alloc_, or ator-traits​::​propagate_on_container_swap​::​value is true, or alloc_ == nh.alloc_ is true.
Effects: Calls swap(ptr_, nh.ptr_).
If !alloc_ is true, or !nh.alloc_ is true, or ator-traits​::​propagate_on_container_swap​::​value is true calls swap(alloc_, nh.alloc_).

23.2.6 Insert return type [container.insert.return]

The associative containers with unique keys and the unordered containers with unique keys have a member function insert that returns a nested type insert_return_type.
That return type is a specialization of the template specified in this subclause.
template<class Iterator, class NodeType> struct insert-return-type { Iterator position; bool inserted; NodeType node; };
The name insert-return-type is for exposition only.
insert-return-type has the template parameters, data members, and special members specified above.
It has no base classes or members other than those specified.

23.2.7 Associative containers [associative.reqmts]

23.2.7.1 General [associative.reqmts.general]

Associative containers provide fast retrieval of data based on keys.
The library provides four basic kinds of associative containers: set, multiset, map and multimap.
The library also provides container adaptors that make it easy to construct abstract data types, such as flat_maps, flat_multimaps, flat_sets, or flat_multisets, out of the basic sequence container kinds (or out of other program-defined sequence containers).
Each associative container is parameterized on Key and an ordering relation Compare that induces a strict weak ordering ([alg.sorting]) on elements of Key.
In addition, map and multimap associate an arbitrary mapped type T with the Key.
The object of type Compare is called the comparison object of a container.
The phrase “equivalence of keys” means the equivalence relation imposed by the comparison object.
That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false.
[Note 1: 
This is not necessarily the same as the result of k1 == k2.
— end note]
For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.
An associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys.
The set and map classes support unique keys; the multiset and multimap classes support equivalent keys.
For multiset and multimap, insert, emplace, and erase preserve the relative ordering of equivalent elements.
For set and multiset the value type is the same as the key type.
For map and multimap it is equal to pair<const Key, T>.
iterator of an associative container is of the bidirectional iterator category.
For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.
It is unspecified whether or not iterator and const_iterator are the same type.
[Note 2: 
iterator and const_iterator have identical semantics in this case, and iterator is convertible to const_iterator.
Users can avoid violating the one-definition rule by always using const_iterator in their function parameter lists.
— end note]
In this subclause,
  • X denotes an associative container class,
  • a denotes a value of type X,
  • a2 denotes a value of a type with nodes compatible with type X (Table Clause 75),
  • b denotes a value of type X or const X,
  • u denotes the name of a variable being declared,
  • a_uniq denotes a value of type X when X supports unique keys,
  • a_eq denotes a value of type X when X supports equivalent keys,
  • a_tran denotes a value of type X or const X when the qualified-id X​::​key_compare​::​is_transparent is valid and denotes a type ([temp.deduct]),
  • i and j meet the Cpp17InputIterator requirements and refer to elements implicitly convertible to value_type,
  • [i, j) denotes a valid range,
  • rg denotes a value of a type R that models container-compatible-range<value_type>,
  • p denotes a valid constant iterator to a,
  • q denotes a valid dereferenceable constant iterator to a,
  • r denotes a valid dereferenceable iterator to a,
  • [q1, q2) denotes a valid range of constant iterators in a,
  • il designates an object of type initializer_list<value_type>,
  • t denotes a value of type X​::​value_type,
  • k denotes a value of type X​::​key_type, and
  • c denotes a value of type X​::​key_compare or const X​::​key_compare;
  • kl is a value such that a is partitioned ([alg.sorting]) with respect to c(x, kl), with x the key value of e and e in a;
  • ku is a value such that a is partitioned with respect to !c(ku, x), with x the key value of e and e in a;
  • ke is a value such that a is partitioned with respect to c(x, ke) and !c(ke, x), with c(x, ke) implying !c(ke, x) and with x the key value of e and e in a;
  • kx is a value such that
    • a is partitioned with respect to c(x, kx) and !c(kx, x), with c(x, kx) implying !c(kx, x) and with x the key value of e and e in a, and
    • kx is not convertible to either iterator or const_iterator; and
  • A denotes the storage allocator used by X, if any, or allocator<X​::​value_type> otherwise,
  • m denotes an allocator of a type convertible to A, and nh denotes a non-const rvalue of type X​::​node_type.
A type X meets the associative container requirements if X meets all the requirements of an allocator-aware container ([container.alloc.reqmts]) and the following types, statements, and expressions are well-formed and have the specified semantics, except that for map and multimap, the requirements placed on value_type in [container.reqmts] apply instead to key_type and mapped_type.
[Note 3: 
For example, in some cases key_type and mapped_type need to be Cpp17CopyAssignable even though the associated value_type, pair<const key_type, mapped_type>, is not Cpp17CopyAssignable.
— end note]
typename X::key_type
Result: Key.
typename X::mapped_type
Result: T.
Remarks: For map and multimap only.
typename X::value_type
Result: Key for set and multiset only; pair<const Key, T> for map and multimap only.
Preconditions: X​::​value_type is Cpp17Erasable from X.
typename X::key_compare
Result: Compare.
Preconditions: key_compare is Cpp17CopyConstructible.
typename X::value_compare
Result: A binary predicate type.
It is the same as key_compare for set and multiset; is an ordering relation on pairs induced by the first component (i.e., Key) for map and multimap.
typename X::node_type
Result: A specialization of the node-handle class template ([container.node]), such that the public nested types are the same types as the corresponding types in X.
X(c)
Effects: Constructs an empty container.
Uses a copy of c as a comparison object.
Complexity: Constant.
X u = X(); X u;
Preconditions: key_compare meets the Cpp17DefaultConstructible requirements.
Effects: Constructs an empty container.
Uses Compare() as a comparison object.
Complexity: Constant.
X(i, j, c)
Preconditions: value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container and inserts elements from the range [i, j) into it; uses c as a comparison object.
Complexity: in general, where N has the value distance(i, j); linear if [i, j) is sorted with respect to value_comp().
X(i, j)
Preconditions: key_compare meets the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container and inserts elements from the range [i, j) into it; uses Compare() as a comparison object.
Complexity: in general, where N has the value distance(i, j); linear if [i, j) is sorted with respect to value_comp().
X(from_range, rg, c)
Preconditions: value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container and inserts each element from rg into it.
Uses c as the comparison object.
Complexity: in general, where N has the value ranges​::​distance(rg); linear if rg is sorted with respect to value_comp().
X(from_range, rg)
Preconditions: key_compare meets the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container and inserts each element from rg into it.
Uses Compare() as the comparison object.
Complexity: Same as X(from_range, rg, c).
X(il, c)
Effects: Equivalent to X(il.begin(), il.end(), c).
X(il)
Effects: Equivalent to X(il.begin(), il.end()).
a = il
Result: X&
Preconditions: value_type is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
Effects: Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.
Complexity: in general, where N has the value il.size() + a.size(); linear if [il.begin(), il.end()) is sorted with respect to value_comp().
b.key_comp()
Result: X​::​key_compare
Returns: The comparison object out of which b was constructed.
Complexity: Constant.
b.value_comp()
Result: X​::​value_compare
Returns: An object of value_compare constructed out of the comparison object.
Complexity: Constant.
a_uniq.emplace(args)
Result: pair<iterator, bool>
Preconditions: value_type is Cpp17EmplaceConstructible into X from args.
Effects: Inserts a value_type object t constructed with std​::​forward<Args>(args)... if and only if there is no element in the container with key equivalent to the key of t.
Returns: The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
Complexity: Logarithmic.
a_eq.emplace(args)
Result: iterator
Preconditions: value_type is Cpp17EmplaceConstructible into X from args.
Effects: Inserts a value_type object t constructed with std​::​forward<Args>(args)....
If a range containing elements equivalent to t exists in a_eq, t is inserted at the end of that range.
Returns: An iterator pointing to the newly inserted element.
Complexity: Logarithmic.
a.emplace_hint(p, args)
Result: iterator
Effects: Equivalent to a.emplace(std​::​forward<Args>(args)...), except that the element is inserted as close as possible to the position just prior to p.
Returns: The iterator returned by emplace.
Complexity: Logarithmic in general, but amortized constant if the element is inserted right before p.
a_uniq.insert(t)
Result: pair<iterator, bool>
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Inserts t if and only if there is no element in the container with key equivalent to the key of t.
Returns: The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
Complexity: Logarithmic.
a_eq.insert(t)
Result: iterator
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Inserts t and returns the iterator pointing to the newly inserted element.
If a range containing elements equivalent to t exists in a_eq, t is inserted at the end of that range.
Complexity: Logarithmic.
a.insert(p, t)
Result: iterator
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Inserts t if and only if there is no element with key equivalent to the key of t in containers with unique keys; always inserts t in containers with equivalent keys.
t is inserted as close as possible to the position just prior to p.
Returns: An iterator pointing to the element with key equivalent to the key of t.
Complexity: Logarithmic in general, but amortized constant if t is inserted right before p.
a.insert(i, j)
Result: void
Preconditions: value_type is Cpp17EmplaceConstructible into X from *i.
Neither i nor j are iterators into a.
Effects: Inserts each element from the range [i, j) if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys.
Complexity: , where N has the value distance(i, j).
a.insert_range(rg)
Result: void
Preconditions: value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
rg and a do not overlap.
Effects: Inserts each element from rg if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys.
Complexity: , where N has the value ranges​::​distance(rg).
a.insert(il)
Effects: Equivalent to a.insert(il.begin(), il.end()).
a_uniq.insert(nh)
Result: insert_return_type
Preconditions: nh is empty or a_uniq.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect.
Otherwise, inserts the element owned by nh if and only if there is no element in the container with a key equivalent to nh.key().
Returns: If nh is empty, inserted is false, position is end(), and node is empty.
Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty; if the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().
Complexity: Logarithmic.
a_eq.insert(nh)
Result: iterator
Preconditions: nh is empty or a_eq.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect and returns a_eq.end().
Otherwise, inserts the element owned by nh and returns an iterator pointing to the newly inserted element.
If a range containing elements with keys equivalent to nh.key() exists in a_eq, the element is inserted at the end of that range.
Postconditions: nh is empty.
Complexity: Logarithmic.
a.insert(p, nh)
Result: iterator
Preconditions: nh is empty or a.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect and returns a.end().
Otherwise, inserts the element owned by nh if and only if there is no element with key equivalent to nh.key() in containers with unique keys; always inserts the element owned by nh in containers with equivalent keys.
The element is inserted as close as possible to the position just prior to p.
Postconditions: nh is empty if insertion succeeds, unchanged if insertion fails.
Returns: An iterator pointing to the element with key equivalent to nh.key().
Complexity: Logarithmic in general, but amortized constant if the element is inserted right before p.
a.extract(k)
Result: node_type
Effects: Removes the first element in the container with key equivalent to k.
Returns: A node_type owning the element if found, otherwise an empty node_type.
Complexity:
a_tran.extract(kx)
Result: node_type
Effects: Removes the first element in the container with key r such that !c(r, kx) && !c(kx, r) is true.
Returns: A node_type owning the element if found, otherwise an empty node_type.
Complexity:
a.extract(q)
Result: node_type
Effects: Removes the element pointed to by q.
Returns: A node_type owning that element.
Complexity: Amortized constant.
a.merge(a2)
Result: void
Preconditions: a.get_allocator() == a2.get_allocator() is true.
Effects: Attempts to extract each element in a2 and insert it into a using the comparison object of a.
In containers with unique keys, if there is an element in a with key equivalent to the key of an element from a2, then that element is not extracted from a2.
Postconditions: Pointers and references to the transferred elements of a2 refer to those same elements but as members of a.
If a.begin() and a2.begin() have the same type, iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators into a, not into a2.
Throws: Nothing unless the comparison object throws.
Complexity: , where N has the value a2.size().
a.erase(k)
Result: size_type
Effects: Erases all elements in the container with key equivalent to k.
Returns: The number of erased elements.
Complexity:
a_tran.erase(kx)
Result: size_type
Effects: Erases all elements in the container with key r such that !c(r, kx) && !c(kx, r) is true.
Returns: The number of erased elements.
Complexity:
a.erase(q)
Result: iterator
Effects: Erases the element pointed to by q.
Returns: An iterator pointing to the element immediately following q prior to the element being erased.
If no such element exists, returns a.end().
Complexity: Amortized constant.
a.erase(r)
Result: iterator
Effects: Erases the element pointed to by r.
Returns: An iterator pointing to the element immediately following r prior to the element being erased.
If no such element exists, returns a.end().
Complexity: Amortized constant.
a.erase(q1, q2)
Result: iterator
Effects: Erases all the elements in the range [q1, q2).
Returns: An iterator pointing to the element pointed to by q2 prior to any elements being erased.
If no such element exists, a.end() is returned.
Complexity: , where N has the value distance(q1, q2).
a.clear()
Effects: Equivalent to a.erase(a.begin(), a.end()).
Postconditions: a.empty() is true.
Complexity: Linear in a.size().
b.find(k)
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator pointing to an element with the key equivalent to k, or b.end() if such an element is not found.
Complexity: Logarithmic.
a_tran.find(ke)
Result: const_iterator if a_tran is of type const X; iterator otherwise.
Returns: An iterator pointing to an element with key r such that !c(r, ke) && !c(ke, r) is true, or a_tran.end() if such an element is not found.
Complexity: Logarithmic.
b.count(k)
Result: size_type
Returns: The number of elements with key equivalent to k.
Complexity:
a_tran.count(ke)
Result: size_type
Returns: The number of elements with key r such that !c(r, ke) && !c(ke, r).
Complexity:
b.contains(k)
Result: bool
Effects: Equivalent to: return b.find(k) != b.end();
a_tran.contains(ke)
Result: bool
Effects: Equivalent to: return a_tran.find(ke) != a_tran.end();
b.lower_bound(k)
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator pointing to the first element with key not less than k, or b.end() if such an element is not found.
Complexity: Logarithmic.
a_tran.lower_bound(kl)
Result: const_iterator if a_tran is of type const X; iterator otherwise.
Returns: An iterator pointing to the first element with key r such that !c(r, kl), or a_tran.end() if such an element is not found.
Complexity: Logarithmic.
b.upper_bound(k)
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator pointing to the first element with key greater than k, or b.end() if such an element is not found.
Complexity: Logarithmic.
a_tran.upper_bound(ku)
Result: const_iterator if a_tran is of type const X; iterator otherwise.
Returns: An iterator pointing to the first element with key r such that c(ku, r), or a_tran.end() if such an element is not found.
Complexity: Logarithmic.
b.equal_range(k)
Result: pair<const_iterator, const_iterator> if b is of type const X; pair<iterator, iterator> otherwise.
Effects: Equivalent to: return make_pair(b.lower_bound(k), b.upper_bound(k));
Complexity: Logarithmic.
a_tran.equal_range(ke)
Result: pair<const_iterator, const_iterator> if a_tran is of type const X; pair<iterator, iterator> otherwise.
Effects: Equivalent to: return make_pair(a_tran.lower_bound(ke), a_tran.upper_bound(ke));
Complexity: Logarithmic.
The insert, insert_range, and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
The extract members invalidate only iterators to the removed element; pointers and references to the removed element remain valid.
However, accessing the element through such pointers and references while the element is owned by a node_type is undefined behavior.
References and pointers to an element obtained while it is owned by a node_type are invalidated if the element is successfully inserted.
The fundamental property of iterators of associative containers is that they iterate through the containers in the non-descending order of keys where non-descending is defined by the comparison that was used to construct them.
For any two dereferenceable iterators i and j such that distance from i to j is positive, the following condition holds: value_comp(*j, *i) == false
For associative containers with unique keys the stronger condition holds: value_comp(*i, *j) != false
When an associative container is constructed by passing a comparison object the container shall not store a pointer or reference to the passed object, even if that object is passed by reference.
When an associative container is copied, through either a copy constructor or an assignment operator, the target container shall then use the comparison object from the container being copied, as if that comparison object had been passed to the target container in its constructor.
The member function templates find, count, contains, lower_bound, upper_bound, equal_range, erase, and extract shall not participate in overload resolution unless the qualified-id Compare​::​is_transparent is valid and denotes a type ([temp.deduct]).
Additionally, the member function templates extract and erase shall not participate in overload resolution if is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator> is true, where K is the type substituted as the first template argument.
A deduction guide for an associative container shall not participate in overload resolution if any of the following are true:
  • It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • It has a Compare template parameter and a type that qualifies as an allocator is deduced for that parameter.

23.2.7.2 Exception safety guarantees [associative.reqmts.except]

For associative containers, no clear() function throws an exception.
erase(k) does not throw an exception unless that exception is thrown by the container's Compare object (if any).
For associative containers, if an exception is thrown by any operation from within an insert or emplace function inserting a single element, the insertion has no effect.
For associative containers, no swap function throws an exception unless that exception is thrown by the swap of the container's Compare object (if any).

23.2.8 Unordered associative containers [unord.req]

23.2.8.1 General [unord.req.general]

Unordered associative containers provide an ability for fast retrieval of data based on keys.
The worst-case complexity for most operations is linear, but the average case is much faster.
The library provides four unordered associative containers: unordered_set, unordered_map, unordered_multiset, and unordered_multimap.
Unordered associative containers conform to the requirements for Containers ([container.requirements]), except that the expressions a == b and a != b have different semantics than for the other container types.
Each unordered associative container is parameterized by Key, by a function object type Hash that meets the Cpp17Hash requirements ([hash.requirements]) and acts as a hash function for argument values of type Key, and by a binary predicate Pred that induces an equivalence relation on values of type Key.
Additionally, unordered_map and unordered_multimap associate an arbitrary mapped type T with the Key.
The container's object of type Hash — denoted by hash — is called the hash function of the container.
The container's object of type Pred — denoted by pred — is called the key equality predicate of the container.
Two values k1 and k2 are considered equivalent if the container's key equality predicate pred(k1, k2) is valid and returns true when passed those values.
If k1 and k2 are equivalent, the container's hash function shall return the same value for both.
[Note 1: 
Thus, when an unordered associative container is instantiated with a non-default Pred parameter it usually needs a non-default Hash parameter as well.
— end note]
For any two keys k1 and k2 in the same container, calling pred(k1, k2) shall always return the same value.
For any key k in a container, calling hash(k) shall always return the same value.
An unordered associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys.
unordered_set and unordered_map support unique keys.
unordered_multiset and unordered_multimap support equivalent keys.
In containers that support equivalent keys, elements with equivalent keys are adjacent to each other in the iteration order of the container.
Thus, although the absolute order of elements in an unordered container is not specified, its elements are grouped into equivalent-key groups such that all elements of each group have equivalent keys.
Mutating operations on unordered containers shall preserve the relative order of elements within each equivalent-key group unless otherwise specified.
For unordered_set and unordered_multiset the value type is the same as the key type.
For unordered_map and unordered_multimap it is pair<const Key, T>.
For unordered containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.
It is unspecified whether or not iterator and const_iterator are the same type.
[Note 2: 
iterator and const_iterator have identical semantics in this case, and iterator is convertible to const_iterator.
Users can avoid violating the one-definition rule by always using const_iterator in their function parameter lists.
— end note]
The elements of an unordered associative container are organized into buckets.
Keys with the same hash code appear in the same bucket.
The number of buckets is automatically increased as elements are added to an unordered associative container, so that the average number of elements per bucket is kept below a bound.
Rehashing invalidates iterators, changes ordering between elements, and changes which buckets elements appear in, but does not invalidate pointers or references to elements.
For unordered_multiset and unordered_multimap, rehashing preserves the relative ordering of equivalent elements.
In this subclause,
  • X denotes an unordered associative container class,
  • a denotes a value of type X,
  • a2 denotes a value of a type with nodes compatible with type X (Table Clause 75),
  • b denotes a value of type X or const X,
  • a_uniq denotes a value of type X when X supports unique keys,
  • a_eq denotes a value of type X when X supports equivalent keys,
  • a_tran denotes a value of type X or const X when the qualified-ids X​::​key_equal​::​is_transparent and X​::​hasher​::​is_transparent are both valid and denote types ([temp.deduct]),
  • i and j denote input iterators that refer to value_type,
  • [i, j) denotes a valid range,
  • rg denotes a value of a type R that models container-compatible-range<value_type>,
  • p and q2 denote valid constant iterators to a,
  • q and q1 denote valid dereferenceable constant iterators to a,
  • r denotes a valid dereferenceable iterator to a,
  • [q1, q2) denotes a valid range in a,
  • il denotes a value of type initializer_list<value_type>,
  • t denotes a value of type X​::​value_type,
  • k denotes a value of type key_type,
  • hf denotes a value of type hasher or const hasher,
  • eq denotes a value of type key_equal or const key_equal,
  • ke is a value such that
    • eq(r1, ke) == eq(ke, r1),
    • hf(r1) == hf(ke) if eq(r1, ke) is true, and
    • if any two of eq(r1, ke), eq(r2, ke), and eq(r1, r2) are true, then all three are true,
    where r1 and r2 are keys of elements in a_tran,
  • kx is a value such that
    • eq(r1, kx) == eq(kx, r1),
    • hf(r1) == hf(kx) if eq(r1, kx) is true,
    • if any two of eq(r1, kx), eq(r2, kx), and eq(r1, r2) are true, then all three are true, and
    • kx is not convertible to either iterator or const_iterator,
    where r1 and r2 are keys of elements in a_tran,
  • n denotes a value of type size_type,
  • z denotes a value of type float, and
  • nh denotes an rvalue of type X​::​node_type.
A type X meets the unordered associative container requirements if X meets all the requirements of an allocator-aware container ([container.alloc.reqmts]) and the following types, statements, and expressions are well-formed and have the specified semantics, except that for unordered_map and unordered_multimap, the requirements placed on value_type in [container.reqmts] apply instead to key_type and mapped_type.
[Note 3: 
For example, key_type and mapped_type sometimes need to be Cpp17CopyAssignable even though the associated value_type, pair<const key_type, mapped_type>, is not Cpp17CopyAssignable.
— end note]
typename X::key_type
Result: Key.
typename X::mapped_type
Result: T.
Remarks: For unordered_map and unordered_multimap only.
typename X::value_type
Result: Key for unordered_set and unordered_multiset only; pair<const Key, T> for unordered_map and unordered_multimap only.
Preconditions: value_type is Cpp17Erasable from X.
typename X::hasher
Result: Hash.
Preconditions: Hash is a unary function object type such that the expression hf(k) has type size_t.
typename X::key_equal
Result: Pred.
Preconditions: Pred meets the Cpp17CopyConstructible requirements.
Pred is a binary predicate that takes two arguments of type Key.
Pred is an equivalence relation.
typename X::local_iterator
Result: An iterator type whose category, value type, difference type, and pointer and reference types are the same as X​::​iterator's.
[Note 4: 
A local_iterator object can be used to iterate through a single bucket, but cannot be used to iterate across buckets.
— end note]
typename X::const_local_iterator
Result: An iterator type whose category, value type, difference type, and pointer and reference types are the same as X​::​const_iterator's.
[Note 5: 
A const_local_iterator object can be used to iterate through a single bucket, but cannot be used to iterate across buckets.
— end note]
typename X::node_type
Result: A specialization of a node-handle class template ([container.node]), such that the public nested types are the same types as the corresponding types in X.
X(n, hf, eq)
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and eq as the key equality predicate.
Complexity:
X(n, hf)
Preconditions: key_equal meets the Cpp17DefaultConstructible requirements.
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and key_equal() as the key equality predicate.
Complexity:
X(n)
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
Effects: Constructs an empty container with at least n buckets, using hasher() as the hash function and key_equal() as the key equality predicate.
Complexity:
X a = X(); X a;
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
Effects: Constructs an empty container with an unspecified number of buckets, using hasher() as the hash function and key_equal() as the key equality predicate.
Complexity: Constant.
X(i, j, n, hf, eq)
Preconditions: value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and eq as the key equality predicate, and inserts elements from [i, j) into it.
Complexity: Average case (N is distance(i, j)), worst case .
X(i, j, n, hf)
Preconditions: key_equal meets the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and key_equal() as the key equality predicate, and inserts elements from [i, j) into it.
Complexity: Average case (N is distance(i, j)), worst case .
X(i, j, n)
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container with at least n buckets, using hasher() as the hash function and key_equal() as the key equality predicate, and inserts elements from [i, j) into it.
Complexity: Average case (N is distance(i, j)), worst case .
X(i, j)
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *i.
Effects: Constructs an empty container with an unspecified number of buckets, using hasher() as the hash function and key_equal() as the key equality predicate, and inserts elements from [i, j) into it.
Complexity: Average case (N is distance(i, j)), worst case .
X(from_range, rg, n, hf, eq)
Preconditions: value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and eq as the key equality predicate, and inserts elements from rg into it.
Complexity: Average case (N is ranges​::​distance(rg)), worst case .
X(from_range, rg, n, hf)
Preconditions: key_equal meets the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and key_equal() as the key equality predicate, and inserts elements from rg into it.
Complexity: Average case (N is ranges​::​distance(rg)), worst case .
X(from_range, rg, n)
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container with at least n buckets, using hasher() as the hash function and key_equal() as the key equality predicate, and inserts elements from rg into it.
Complexity: Average case (N is ranges​::​distance(rg)), worst case .
X(from_range, rg)
Preconditions: hasher and key_equal meet the Cpp17DefaultConstructible requirements.
value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
Effects: Constructs an empty container with an unspecified number of buckets, using hasher() as the hash function and key_equal() as the key equality predicate, and inserts elements from rg into it.
Complexity: Average case (N is ranges​::​distance(rg)), worst case .
X(il)
Effects: Equivalent to X(il.begin(), il.end()).
X(il, n)
Effects: Equivalent to X(il.begin(), il.end(), n).
X(il, n, hf)
Effects: Equivalent to X(il.begin(), il.end(), n, hf).
X(il, n, hf, eq)
Effects: Equivalent to X(il.begin(), il.end(), n, hf, eq).
X(b)
Effects: In addition to the container requirements ([container.reqmts]), copies the hash function, predicate, and maximum load factor.
Complexity: Average case linear in b.size(), worst case quadratic.
a = b
Result: X&
Effects: In addition to the container requirements, copies the hash function, predicate, and maximum load factor.
Complexity: Average case linear in b.size(), worst case quadratic.
a = il
Result: X&
Preconditions: value_type is Cpp17CopyInsertable into X and Cpp17CopyAssignable.
Effects: Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.
Complexity: Average case linear in il.size(), worst case quadratic.
b.hash_function()
Result: hasher
Returns: b's hash function.
Complexity: Constant.
b.key_eq()
Result: key_equal
Returns: b's key equality predicate.
Complexity: Constant.
a_uniq.emplace(args)
Result: pair<iterator, bool>
Preconditions: value_type is Cpp17EmplaceConstructible into X from args.
Effects: Inserts a value_type object t constructed with std​::​forward<Args>(args)... if and only if there is no element in the container with key equivalent to the key of t.
Returns: The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
Complexity: Average case , worst case .
a_eq.emplace(args)
Result: iterator
Preconditions: value_type is Cpp17EmplaceConstructible into X from args.
Effects: Inserts a value_type object t constructed with std​::​forward<Args>(args)....
Returns: An iterator pointing to the newly inserted element.
Complexity: Average case , worst case .
a.emplace_hint(p, args)
Result: iterator
Effects: Equivalent to a.emplace(std​::​forward<Args>(args)...), except that the const_iterator p is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.
Returns: The iterator returned by emplace.
a_uniq.insert(t)
Result: pair<iterator, bool>
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Inserts t if and only if there is no element in the container with key equivalent to the key of t.
Returns: The bool component of the returned pair indicates whether the insertion takes place, and the iterator component points to the element with key equivalent to the key of t.
Complexity: Average case , worst case .
a_eq.insert(t)
Result: iterator
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Inserts t.
Returns: An iterator pointing to the newly inserted element.
Complexity: Average case , worst case .
a.insert(p, t)
Result: iterator
Preconditions: If t is a non-const rvalue, value_type is Cpp17MoveInsertable into X; otherwise, value_type is Cpp17CopyInsertable into X.
Effects: Equivalent to a.insert(t).
The iterator p is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.
Returns: An iterator pointing to the element with the key equivalent to that of t.
Complexity: Average case , worst case .
a.insert(i, j)
Result: void
Preconditions: value_type is Cpp17EmplaceConstructible into X from *i.
Neither i nor j are iterators into a.
Effects: Equivalent to a.insert(t) for each element in [i, j).
Complexity: Average case , where N is distance(i, j), worst case .
a.insert_range(rg)
Result: void
Preconditions: value_type is Cpp17EmplaceConstructible into X from *ranges​::​begin(rg).
rg and a do not overlap.
Effects: Equivalent to a.insert(t) for each element t in rg.
Complexity: Average case , where N is ranges​::​distance(rg), worst case .
a.insert(il)
Effects: Equivalent to a.insert(il.begin(), il.end()).
a_uniq.insert(nh)
Result: insert_return_type
Preconditions: nh is empty or a_uniq.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect.
Otherwise, inserts the element owned by nh if and only if there is no element in the container with a key equivalent to nh.key().
Postconditions: If nh is empty, inserted is false, position is end(), and node is empty.
Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty; if the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().
Complexity: Average case , worst case .
a_eq.insert(nh)
Result: iterator
Preconditions: nh is empty or a_eq.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect and returns a_eq.end().
Otherwise, inserts the element owned by nh and returns an iterator pointing to the newly inserted element.
Postconditions: nh is empty.
Complexity: Average case , worst case .
a.insert(q, nh)
Result: iterator
Preconditions: nh is empty or a.get_allocator() == nh.get_allocator() is true.
Effects: If nh is empty, has no effect and returns a.end().
Otherwise, inserts the element owned by nh if and only if there is no element with key equivalent to nh.key() in containers with unique keys; always inserts the element owned by nh in containers with equivalent keys.
The iterator q is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.
Postconditions: nh is empty if insertion succeeds, unchanged if insertion fails.
Returns: An iterator pointing to the element with key equivalent to nh.key().
Complexity: Average case , worst case .
a.extract(k)
Result: node_type
Effects: Removes an element in the container with key equivalent to k.
Returns: A node_type owning the element if found, otherwise an empty node_type.
Complexity: Average case , worst case .
a_tran.extract(kx)
Result: node_type
Effects: Removes an element in the container with key equivalent to kx.
Returns: A node_type owning the element if found, otherwise an empty node_type.
Complexity: Average case , worst case .
a.extract(q)
Result: node_type
Effects: Removes the element pointed to by q.
Returns: A node_type owning that element.
Complexity: Average case , worst case .
a.merge(a2)
Result: void
Preconditions: a.get_allocator() == a2.get_allocator().
Effects: Attempts to extract each element in a2 and insert it into a using the hash function and key equality predicate of a.
In containers with unique keys, if there is an element in a with key equivalent to the key of an element from a2, then that element is not extracted from a2.
Postconditions: Pointers and references to the transferred elements of a2 refer to those same elements but as members of a.
Iterators referring to the transferred elements and all iterators referring to a will be invalidated, but iterators to elements remaining in a2 will remain valid.
Complexity: Average case , where N is a2.size(), worst case .
a.erase(k)
Result: size_type
Effects: Erases all elements with key equivalent to k.
Returns: The number of elements erased.
Complexity: Average case , worst case .
a_tran.erase(kx)
Result: size_type
Effects: Erases all elements with key equivalent to kx.
Returns: The number of elements erased.
Complexity: Average case , worst case .
a.erase(q)
Result: iterator
Effects: Erases the element pointed to by q.
Returns: The iterator immediately following q prior to the erasure.
Complexity: Average case , worst case .
a.erase(r)
Result: iterator
Effects: Erases the element pointed to by r.
Returns: The iterator immediately following r prior to the erasure.
Complexity: Average case , worst case .
a.erase(q1, q2)
Result: iterator
Effects: Erases all elements in the range [q1, q2).
Returns: The iterator immediately following the erased elements prior to the erasure.
Complexity: Average case linear in distance(q1, q2), worst case .
a.clear()
Result: void
Effects: Erases all elements in the container.
Postconditions: a.empty() is true.
Complexity: Linear in a.size().
b.find(k)
Result: const_iterator if b is of type const X; iterator otherwise.
Returns: An iterator pointing to an element with key equivalent to k, or b.end() if no such element exists.
Complexity: Average case , worst case .
a_tran.find(ke)
Result: const_iterator if a_tran is of type const X; iterator otherwise.
Returns: An iterator pointing to an element with key equivalent to ke, or a_tran.end() if no such element exists.
Complexity: Average case , worst case .
b.count(k)
Result: size_type
Returns: The number of elements with key equivalent to k.
Complexity: Average case , worst case .
a_tran.count(ke)
Result: size_type
Returns: The number of elements with key equivalent to ke.
Complexity: Average case , worst case .
b.contains(k)
Effects: Equivalent to b.find(k) != b.end().
a_tran.contains(ke)
Effects: Equivalent to a_tran.find(ke) != a_tran.end().
b.equal_range(k)
Result: pair<const_iterator, const_iterator> if b is of type const X; pair<iterator, iterator> otherwise.
Returns: A range containing all elements with keys equivalent to k.
Returns make_pair(b.end(), b.end()) if no such elements exist.
Complexity: Average case , worst case .
a_tran.equal_range(ke)
Result: pair<const_iterator, const_iterator> if a_tran is of type const X; pair<iterator, iterator> otherwise.
Returns: A range containing all elements with keys equivalent to ke.
Returns make_pair(a_tran.end(), a_tran.end()) if no such elements exist.
Complexity: Average case , worst case .
b.bucket_count()
Result: size_type
Returns: The number of buckets that b contains.
Complexity: Constant.
b.max_bucket_count()
Result: size_type
Returns: An upper bound on the number of buckets that b can ever contain.
Complexity: Constant.
b.bucket(k)
Result: size_type
Preconditions: b.bucket_count() > 0.
Returns: The index of the bucket in which elements with keys equivalent to k would be found, if any such element existed.
The return value is in the range [0, b.bucket_count()).
Complexity: Constant.
a_tran.bucket(ke)
Result: size_type
Preconditions: a_tran.bucket_count() > 0.
Postconditions: The return value is in the range [0, a_tran.bucket_count()).
Returns: The index of the bucket in which elements with keys equivalent to ke would be found, if any such element existed.
Complexity: Constant.
b.bucket_size(n)
Result: size_type
Preconditions: n shall be in the range [0, b.bucket_count()).
Returns: The number of elements in the bucket.
Complexity:
b.begin(n)
Result: const_local_iterator if b is of type const X; local_iterator otherwise.
Preconditions: n is in the range [0, b.bucket_count()).
Returns: An iterator referring to the first element in the bucket.
If the bucket is empty, then b.begin(n) == b.end(n).
Complexity: Constant.
b.end(n)
Result: const_local_iterator if b is of type const X; local_iterator otherwise.
Preconditions: n is in the range [0, b.bucket_count()).
Returns: An iterator which is the past-the-end value for the bucket.
Complexity: Constant.
b.cbegin(n)
Result: const_local_iterator
Preconditions: n shall be in the range [0, b.bucket_count()).
Returns: An iterator referring to the first element in the bucket.
If the bucket is empty, then b.cbegin(n) == b.cend(n).
Complexity: Constant.
b.cend(n)
Result: const_local_iterator
Preconditions: n is in the range [0, b.bucket_count()).
Returns: An iterator which is the past-the-end value for the bucket.
Complexity: Constant.
b.load_factor()
Result: float
Returns: The average number of elements per bucket.
Complexity: Constant.
b.max_load_factor()
Result: float
Returns: A positive number that the container attempts to keep the load factor less than or equal to.
The container automatically increases the number of buckets as necessary to keep the load factor below this number.
Complexity: Constant.
a.max_load_factor(z)
Result: void
Preconditions: z is positive.
May change the container's maximum load factor, using z as a hint.
Complexity: Constant.
a.rehash(n)
Result: void
Postconditions: a.bucket_count() >= a.size() / a.max_load_factor() and a.bucket_count() >= n.
Complexity: Average case linear in a.size(), worst case quadratic.
a.reserve(n)
Effects: Equivalent to a.rehash(ceil(n / a.max_load_factor())).
Two unordered containers a and b compare equal if a.size() == b.size() and, for every equivalent-key group [Ea1, Ea2) obtained from a.equal_range(Ea1), there exists an equivalent-key group [Eb1, Eb2) obtained from b.equal_range(Ea1), such that is_permutation(Ea1, Ea2, Eb1, Eb2) returns true.
For unordered_set and unordered_map, the complexity of operator== (i.e., the number of calls to the == operator of the value_type, to the predicate returned by key_eq(), and to the hasher returned by hash_function()) is proportional to N in the average case and to in the worst case, where N is a.size().
For unordered_multiset and unordered_multimap, the complexity of operator== is proportional to in the average case and to in the worst case, where N is a.size(), and is the size of the equivalent-key group in a.
However, if the respective elements of each corresponding pair of equivalent-key groups and are arranged in the same order (as is commonly the case, e.g., if a and b are unmodified copies of the same container), then the average-case complexity for unordered_multiset and unordered_multimap becomes proportional to N (but worst-case complexity remains , e.g., for a pathologically bad hash function).
The behavior of a program that uses operator== or operator!= on unordered containers is undefined unless the Pred function object has the same behavior for both containers and the equality comparison function for Key is a refinement¹⁷³ of the partition into equivalent-key groups produced by Pred.
The iterator types iterator and const_iterator of an unordered associative container are of at least the forward iterator category.
For unordered associative containers where the key type and value type are the same, both iterator and const_iterator are constant iterators.
The insert, insert_range, and emplace members shall not affect the validity of references to container elements, but may invalidate all iterators to the container.
The erase members shall invalidate only iterators and references to the erased elements, and preserve the relative order of the elements that are not erased.
The insert, insert_range, and emplace members shall not affect the validity of iterators if (N + n) <= z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container's bucket count, and z is the container's maximum load factor.
The extract members invalidate only iterators to the removed element, and preserve the relative order of the elements that are not erased; pointers and references to the removed element remain valid.
However, accessing the element through such pointers and references while the element is owned by a node_type is undefined behavior.
References and pointers to an element obtained while it is owned by a node_type are invalidated if the element is successfully inserted.
The member function templates find, count, equal_range, contains, extract, erase, and bucket shall not participate in overload resolution unless the qualified-ids Pred​::​is_transparent and Hash​::​is_transparent are both valid and denote types ([temp.deduct]).
Additionally, the member function templates extract and erase shall not participate in overload resolution if is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator> is true, where K is the type substituted as the first template argument.
A deduction guide for an unordered associative container shall not participate in overload resolution if any of the following are true:
  • It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • It has a Hash template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter.
  • It has a Pred template parameter and a type that qualifies as an allocator is deduced for that parameter.
173)173)
Equality comparison is a refinement of partitioning if no two objects that compare equal fall into different partitions.

23.2.8.2 Exception safety guarantees [unord.req.except]

For unordered associative containers, no clear() function throws an exception.
erase(k) does not throw an exception unless that exception is thrown by the container's Hash or Pred object (if any).
For unordered associative containers, if an exception is thrown by any operation other than the container's hash function from within an insert or emplace function inserting a single element, the insertion has no effect.
For unordered associative containers, no swap function throws an exception unless that exception is thrown by the swap of the container's Hash or Pred object (if any).
For unordered associative containers, if an exception is thrown from within a rehash() function other than by the container's hash function or comparison function, the rehash() function has no effect.

23.3 Sequence containers [sequences]

23.3.1 General [sequences.general]

The headers <array>, <deque>, <forward_list>, <hive>, <inplace_vector>, <list>, and <vector> define class templates that meet the requirements for sequence containers.
The following exposition-only alias template may appear in deduction guides for sequence containers: template<class InputIterator> using iter-value-type = iterator_traits<InputIterator>::value_type; // exposition only

23.3.2 Header <array> synopsis [array.syn]

// mostly freestanding #include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [array], class template array template<class T, size_t N> struct array; // partially freestanding template<class T, size_t N> constexpr bool operator==(const array<T, N>& x, const array<T, N>& y); template<class T, size_t N> constexpr synth-three-way-result<T> operator<=>(const array<T, N>& x, const array<T, N>& y); // [array.special], specialized algorithms template<class T, size_t N> constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y))); // [array.creation], array creation functions template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]); template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // [array.tuple], tuple interface template<class T> struct tuple_size; template<size_t I, class T> struct tuple_element; template<class T, size_t N> struct tuple_size<array<T, N>>; template<size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>; template<size_t I, class T, size_t N> constexpr T& get(array<T, N>&) noexcept; template<size_t I, class T, size_t N> constexpr T&& get(array<T, N>&&) noexcept; template<size_t I, class T, size_t N> constexpr const T& get(const array<T, N>&) noexcept; template<size_t I, class T, size_t N> constexpr const T&& get(const array<T, N>&&) noexcept; }

23.3.3 Class template array [array]

23.3.3.1 Overview [array.overview]

The header <array> defines a class template for storing fixed-size sequences of objects.
An array is a contiguous container.
An instance of array<T, N> stores N elements of type T, so that size() == N is an invariant.
An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.
An array meets all of the requirements of a container ([container.reqmts]) and of a reversible container ([container.rev.reqmts]), except that a default constructed array object is not empty if .
An array meets some of the requirements of a sequence container.
Descriptions are provided here only for operations on array that are not described in one of these tables and for operations where there is additional semantic information.
array<T, N> is a structural type ([temp.param]) if T is a structural type.
Two values a1 and a2 of type array<T, N> are template-argument-equivalent if and only if each pair of corresponding elements in a1 and a2 are template-argument-equivalent.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class T, size_t N> struct array { // types using value_type = T; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using size_type = size_t; using difference_type = ptrdiff_t; using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // no explicit construct/copy/destroy for aggregate type constexpr void fill(const T& u); constexpr void swap(array&) noexcept(is_nothrow_swappable_v<T>); // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); // freestanding-deleted constexpr const_reference at(size_type n) const; // freestanding-deleted constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; constexpr T* data() noexcept; constexpr const T* data() const noexcept; }; template<class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>; }

23.3.3.2 Constructors, copy, and assignment [array.cons]

An array relies on the implicitly-declared special member functions ([class.default.ctor], [class.dtor], [class.copy.ctor]) to conform to the container requirements table in [container.requirements].
In addition to the requirements specified in the container requirements table, the implicitly-declared move constructor and move assignment operator for array require that T be Cpp17MoveConstructible or Cpp17MoveAssignable, respectively.
template<class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>;
Mandates: (is_same_v<T, U> && ...) is true.

23.3.3.3 Member functions [array.members]

constexpr size_type size() const noexcept;
Returns: N.
constexpr T* data() noexcept; constexpr const T* data() const noexcept;
Returns: A pointer such that [data(), data() + size()) is a valid range.
For a non-empty array, data() == addressof(front()) is true.
constexpr void fill(const T& u);
Effects: As if by fill_n(begin(), N, u).
constexpr void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
Effects: Equivalent to swap_ranges(begin(), end(), y.begin()).
[Note 1: 
Unlike the swap function for other containers, array​::​swap takes linear time, can exit via an exception, and does not cause iterators to become associated with the other container.
— end note]

23.3.3.4 Specialized algorithms [array.special]

template<class T, size_t N> constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
Constraints: N == 0 or is_swappable_v<T> is true.
Effects: As if by x.swap(y).
Complexity: Linear in N.

23.3.3.5 Zero-sized arrays [array.zero]

array shall provide support for the special case N == 0.
In the case that N == 0, begin() == end() == unique value.
The return value of data() is unspecified.
Member function swap() shall have a non-throwing exception specification.

23.3.3.6 Array creation functions [array.creation]

template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
Mandates: is_array_v<T> is false and is_constructible_v<remove_cv_t<T>, T&> is true.
Preconditions: T meets the Cpp17CopyConstructible requirements.
Returns: {{ a[0], , a[N - 1] }}.
template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
Mandates: is_array_v<T> is false and is_constructible_v<remove_cv_t<T>, T> is true.
Preconditions: T meets the Cpp17MoveConstructible requirements.
Returns: {{ std​::​move(a[0]), , std​::​move(a[N - 1]) }}.

23.3.3.7 Tuple interface [array.tuple]

template<class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
template<size_t I, class T, size_t N> struct tuple_element<I, array<T, N>> { using type = T; };
Mandates: I < N is true.
template<size_t I, class T, size_t N> constexpr T& get(array<T, N>& a) noexcept; template<size_t I, class T, size_t N> constexpr T&& get(array<T, N>&& a) noexcept; template<size_t I, class T, size_t N> constexpr const T& get(const array<T, N>& a) noexcept; template<size_t I, class T, size_t N> constexpr const T&& get(const array<T, N>&& a) noexcept;
Mandates: I < N is true.
Returns: A reference to the element of a, where indexing is zero-based.

23.3.4 Header <deque> synopsis [deque.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [deque], class template deque template<class T, class Allocator = allocator<T>> class deque; template<class T, class Allocator> constexpr bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y); template<class T, class Allocator> constexpr synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, const deque<T, Allocator>& y); template<class T, class Allocator> constexpr void swap(deque<T, Allocator>& x, deque<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // [deque.erasure], erasure template<class T, class Allocator, class U = T> constexpr typename deque<T, Allocator>::size_type erase(deque<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> constexpr typename deque<T, Allocator>::size_type erase_if(deque<T, Allocator>& c, Predicate pred); namespace pmr { template<class T> using deque = std::deque<T, polymorphic_allocator<T>>; } }

23.3.5 Class template deque [deque]

23.3.5.1 Overview [deque.overview]

A deque is a sequence container that supports random access iterators.
In addition, it supports constant time insert and erase operations at the beginning or the end; insert and erase in the middle take linear time.
That is, a deque is especially optimized for pushing and popping elements at the beginning and end.
Storage management is handled automatically.
A deque meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of a sequence container, including the optional sequence container requirements ([sequence.reqmts]).
Descriptions are provided here only for operations on deque that are not described in one of these tables or for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class T, class Allocator = allocator<T>> class deque { public: // types using value_type = T; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // [deque.cons], construct/copy/destroy constexpr deque() : deque(Allocator()) { } constexpr explicit deque(const Allocator&); constexpr explicit deque(size_type n, const Allocator& = Allocator()); constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<container-compatible-range<T> R> constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr deque(const deque& x); constexpr deque(deque&&); constexpr deque(const deque&, const type_identity_t<Allocator>&); constexpr deque(deque&&, const type_identity_t<Allocator>&); constexpr deque(initializer_list<T>, const Allocator& = Allocator()); constexpr ~deque(); constexpr deque& operator=(const deque& x); constexpr deque& operator=(deque&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr deque& operator=(initializer_list<T>); template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const T& t); constexpr void assign(initializer_list<T>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // [deque.capacity], capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; constexpr void resize(size_type sz); constexpr void resize(size_type sz, const T& c); constexpr void shrink_to_fit(); // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); constexpr const_reference at(size_type n) const; constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; // [deque.modifiers], modifiers template<class... Args> constexpr reference emplace_front(Args&&... args); template<class... Args> constexpr reference emplace_back(Args&&... args); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg); constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T>); constexpr void pop_front(); constexpr void pop_back(); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(deque&) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr void clear() noexcept; }; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> deque(InputIterator, InputIterator, Allocator = Allocator()) -> deque<iter-value-type<InputIterator>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> deque(from_range_t, R&&, Allocator = Allocator()) -> deque<ranges::range_value_t<R>, Allocator>; }

23.3.5.2 Constructors, copy, and assignment [deque.cons]

constexpr explicit deque(const Allocator&);
Effects: Constructs an empty deque, using the specified allocator.
Complexity: Constant.
constexpr explicit deque(size_type n, const Allocator& = Allocator());
Preconditions: T is Cpp17DefaultInsertable into deque.
Effects: Constructs a deque with n default-inserted elements using the specified allocator.
Complexity: Linear in n.
constexpr deque(size_type n, const T& value, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into deque.
Effects: Constructs a deque with n copies of value, using the specified allocator.
Complexity: Linear in n.
template<class InputIterator> constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a deque equal to the range [first, last), using the specified allocator.
Complexity: Linear in distance(first, last).
template<container-compatible-range<T> R> constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator());
Effects: Constructs a deque with the elements of the range rg, using the specified allocator.
Complexity: Linear in ranges​::​distance(rg).

23.3.5.3 Capacity [deque.capacity]

constexpr void resize(size_type sz);
Preconditions: T is Cpp17MoveInsertable and Cpp17DefaultInsertable into deque.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() default-inserted elements to the sequence.
constexpr void resize(size_type sz, const T& c);
Preconditions: T is Cpp17CopyInsertable into deque.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() copies of c to the sequence.
constexpr void shrink_to_fit();
Preconditions: T is Cpp17MoveInsertable into deque.
Effects: shrink_to_fit is a non-binding request to reduce memory use but does not change the size of the sequence.
[Note 1: 
The request is non-binding to allow latitude for implementation-specific optimizations.
— end note]
If the size is equal to the old capacity, or if an exception is thrown other than by the move constructor of a non-Cpp17CopyInsertable T, then there are no effects.
Complexity: If the size is not equal to the old capacity, linear in the size of the sequence; otherwise constant.
Remarks: If the size is not equal to the old capacity, then invalidates all the references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end iterator.

23.3.5.4 Modifiers [deque.modifiers]

constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T>); template<class... Args> constexpr reference emplace_front(Args&&... args); template<class... Args> constexpr reference emplace_back(Args&&... args); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg);
Effects: An insertion in the middle of the deque invalidates all the iterators and references to elements of the deque.
An insertion at either end of the deque invalidates all the iterators to the deque, but has no effect on the validity of references to elements of the deque.
Complexity: The complexity is linear in the number of elements inserted plus the lesser of the distances to the beginning and end of the deque.
Inserting a single element at either the beginning or end of a deque always takes constant time and causes a single call to a constructor of T.
Remarks: If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T, there are no effects.
If an exception is thrown while inserting a single element at either end, there are no effects.
Otherwise, if an exception is thrown by the move constructor of a non-Cpp17CopyInsertable T, the effects are unspecified.
constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_front(); constexpr void pop_back();
Effects: An erase operation that erases the last element of a deque invalidates only the past-the-end iterator and all iterators and references to the erased elements.
An erase operation that erases the first element of a deque but not the last element invalidates only iterators and references to the erased elements.
An erase operation that erases neither the first element nor the last element of a deque invalidates the past-the-end iterator and all iterators and references to all the elements of the deque.
[Note 1: 
pop_front and pop_back are erase operations.
— end note]
Throws: Nothing unless an exception is thrown by the assignment operator of T.
Complexity: The number of calls to the destructor of T is the same as the number of elements erased, but the number of calls to the assignment operator of T is no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements.

23.3.5.5 Erasure [deque.erasure]

template<class T, class Allocator, class U = T> constexpr typename deque<T, Allocator>::size_type erase(deque<T, Allocator>& c, const U& value);
Effects: Equivalent to: auto it = remove(c.begin(), c.end(), value); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;
template<class T, class Allocator, class Predicate> constexpr typename deque<T, Allocator>::size_type erase_if(deque<T, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto it = remove_if(c.begin(), c.end(), pred); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;

23.3.6 Header <forward_list> synopsis [forward.list.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [forward.list], class template forward_list template<class T, class Allocator = allocator<T>> class forward_list; template<class T, class Allocator> constexpr bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y); template<class T, class Allocator> constexpr synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y); template<class T, class Allocator> constexpr void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // [forward.list.erasure], erasure template<class T, class Allocator, class U = T> constexpr typename forward_list<T, Allocator>::size_type erase(forward_list<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> constexpr typename forward_list<T, Allocator>::size_type erase_if(forward_list<T, Allocator>& c, Predicate pred); namespace pmr { template<class T> using forward_list = std::forward_list<T, polymorphic_allocator<T>>; } }

23.3.7 Class template forward_list [forward.list]

23.3.7.1 Overview [forward.list.overview]

A forward_list is a container that supports forward iterators and allows constant time insert and erase operations anywhere within the sequence, with storage management handled automatically.
Fast random access to list elements is not supported.
[Note 1: 
It is intended that forward_list have zero space or time overhead relative to a hand-written C-style singly linked list.
Features that would conflict with that goal have been omitted.
— end note]
A forward_list meets all of the requirements of a container ([container.reqmts]), except that the size() member function is not provided and operator== has linear complexity.
A forward_list also meets all of the requirements for an allocator-aware container ([container.alloc.reqmts]).
In addition, a forward_list provides the assign member functions and several of the optional sequence container requirements ([sequence.reqmts]).
Descriptions are provided here only for operations on forward_list that are not described in that table or for operations where there is additional semantic information.
[Note 2: 
Modifying any list requires access to the element preceding the first element of interest, but in a forward_list there is no constant-time way to access a preceding element.
For this reason, erase_after and splice_after take fully-open ranges, not semi-open ranges.
— end note]
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class T, class Allocator = allocator<T>> class forward_list { public: // types using value_type = T; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] // [forward.list.cons], construct/copy/destroy constexpr forward_list() : forward_list(Allocator()) { } constexpr explicit forward_list(const Allocator&); constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<container-compatible-range<T> R> constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr forward_list(const forward_list& x); constexpr forward_list(forward_list&& x); constexpr forward_list(const forward_list& x, const type_identity_t<Allocator>&); constexpr forward_list(forward_list&& x, const type_identity_t<Allocator>&); constexpr forward_list(initializer_list<T>, const Allocator& = Allocator()); constexpr ~forward_list(); constexpr forward_list& operator=(const forward_list& x); constexpr forward_list& operator=(forward_list&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr forward_list& operator=(initializer_list<T>); template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const T& t); constexpr void assign(initializer_list<T>); constexpr allocator_type get_allocator() const noexcept; // [forward.list.iter], iterators constexpr iterator before_begin() noexcept; constexpr const_iterator before_begin() const noexcept; constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cbefore_begin() const noexcept; constexpr const_iterator cend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type max_size() const noexcept; // [forward.list.access], element access constexpr reference front(); constexpr const_reference front() const; // [forward.list.modifiers], modifiers template<class... Args> constexpr reference emplace_front(Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg); constexpr void pop_front(); template<class... Args> constexpr iterator emplace_after(const_iterator position, Args&&... args); constexpr iterator insert_after(const_iterator position, const T& x); constexpr iterator insert_after(const_iterator position, T&& x); constexpr iterator insert_after(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert_after(const_iterator position, InputIterator first, InputIterator last); constexpr iterator insert_after(const_iterator position, initializer_list<T> il); template<container-compatible-range<T> R> constexpr iterator insert_range_after(const_iterator position, R&& rg); constexpr iterator erase_after(const_iterator position); constexpr iterator erase_after(const_iterator position, const_iterator last); constexpr void swap(forward_list&) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr void resize(size_type sz); constexpr void resize(size_type sz, const value_type& c); constexpr void clear() noexcept; // [forward.list.ops], forward_list operations constexpr void splice_after(const_iterator position, forward_list& x); constexpr void splice_after(const_iterator position, forward_list&& x); constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i); constexpr void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last); constexpr size_type remove(const T& value); template<class Predicate> constexpr size_type remove_if(Predicate pred); constexpr size_type unique(); template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred); constexpr void merge(forward_list& x); constexpr void merge(forward_list&& x); template<class Compare> constexpr void merge(forward_list& x, Compare comp); template<class Compare> constexpr void merge(forward_list&& x, Compare comp); constexpr void sort(); template<class Compare> constexpr void sort(Compare comp); constexpr void reverse() noexcept; }; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> forward_list(InputIterator, InputIterator, Allocator = Allocator()) -> forward_list<iter-value-type<InputIterator>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> forward_list(from_range_t, R&&, Allocator = Allocator()) -> forward_list<ranges::range_value_t<R>, Allocator>; }
An incomplete type T may be used when instantiating forward_list if the allocator meets the allocator completeness requirements.
T shall be complete before any member of the resulting specialization of forward_list is referenced.

23.3.7.2 Constructors, copy, and assignment [forward.list.cons]

constexpr explicit forward_list(const Allocator&);
Effects: Constructs an empty forward_list object using the specified allocator.
Complexity: Constant.
constexpr explicit forward_list(size_type n, const Allocator& = Allocator());
Preconditions: T is Cpp17DefaultInsertable into forward_list.
Effects: Constructs a forward_list object with n default-inserted elements using the specified allocator.
Complexity: Linear in n.
constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into forward_list.
Effects: Constructs a forward_list object with n copies of value using the specified allocator.
Complexity: Linear in n.
template<class InputIterator> constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a forward_list object equal to the range [first, last).
Complexity: Linear in distance(first, last).
template<container-compatible-range<T> R> constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
Effects: Constructs a forward_list object with the elements of the range rg.
Complexity: Linear in ranges​::​distance(rg).

23.3.7.3 Iterators [forward.list.iter]

constexpr iterator before_begin() noexcept; constexpr const_iterator before_begin() const noexcept; constexpr const_iterator cbefore_begin() const noexcept;
Effects: cbefore_begin() is equivalent to const_cast<forward_list const&>(*this).before_begin().
Returns: A non-dereferenceable iterator that, when incremented, is equal to the iterator returned by begin().
Remarks: before_begin() == end() shall equal false.

23.3.7.4 Element access [forward.list.access]

constexpr reference front(); constexpr const_reference front() const;
Returns: *begin()

23.3.7.5 Modifiers [forward.list.modifiers]

The member functions in this subclause do not affect the validity of iterators and references when inserting elements, and when erasing elements invalidate iterators and references to the erased elements only.
If an exception is thrown by any of these member functions there is no effect on the container.
Inserting n elements into a forward_list is linear in n, and the number of calls to the copy or move constructor of T is exactly equal to n.
Erasing n elements from a forward_list is linear in n and the number of calls to the destructor of type T is exactly equal to n.
template<class... Args> constexpr reference emplace_front(Args&&... args);
Effects: Inserts an object of type value_type constructed with value_type(std​::​forward<Args>(​args)...) at the beginning of the list.
constexpr void push_front(const T& x); constexpr void push_front(T&& x);
Effects: Inserts a copy of x at the beginning of the list.
template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg);
Effects: Inserts a copy of each element of rg at the beginning of the list.
[Note 1: 
The order of elements is not reversed.
— end note]
constexpr void pop_front();
Effects: As if by erase_after(before_begin()).
constexpr iterator insert_after(const_iterator position, const T& x);
Preconditions: T is Cpp17CopyInsertable into forward_list.
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts a copy of x after position.
Returns: An iterator pointing to the copy of x.
constexpr iterator insert_after(const_iterator position, T&& x);
Preconditions: T is Cpp17MoveInsertable into forward_list.
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts a copy of x after position.
Returns: An iterator pointing to the copy of x.
constexpr iterator insert_after(const_iterator position, size_type n, const T& x);
Preconditions: T is Cpp17CopyInsertable into forward_list.
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts n copies of x after position.
Returns: An iterator pointing to the last inserted copy of x, or position if n == 0 is true.
template<class InputIterator> constexpr iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
Preconditions: T is Cpp17EmplaceConstructible into forward_list from *first.
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
Neither first nor last are iterators in *this.
Effects: Inserts copies of elements in [first, last) after position.
Returns: An iterator pointing to the last inserted element, or position if first == last is true.
template<container-compatible-range<T> R> constexpr iterator insert_range_after(const_iterator position, R&& rg);
Preconditions: T is Cpp17EmplaceConstructible into forward_list from *ranges​::​begin(rg).
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
rg and *this do not overlap.
Effects: Inserts copies of elements in the range rg after position.
Returns: An iterator pointing to the last inserted element, or position if rg is empty.
constexpr iterator insert_after(const_iterator position, initializer_list<T> il);
Effects: Equivalent to: return insert_after(position, il.begin(), il.end());
template<class... Args> constexpr iterator emplace_after(const_iterator position, Args&&... args);
Preconditions: T is Cpp17EmplaceConstructible into forward_list from std​::​forward<Args>(args)....
position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts an object of type value_type direct-non-list-initialized with std​::​forward<Args>(args)... after position.
Returns: An iterator pointing to the new object.
constexpr iterator erase_after(const_iterator position);
Preconditions: The iterator following position is dereferenceable.
Effects: Erases the element pointed to by the iterator following position.
Returns: An iterator pointing to the element following the one that was erased, or end() if no such element exists.
Throws: Nothing.
constexpr iterator erase_after(const_iterator position, const_iterator last);
Preconditions: All iterators in the range (position, last) are dereferenceable.
Effects: Erases the elements in the range (position, last).
Returns: last.
Throws: Nothing.
constexpr void resize(size_type sz);
Preconditions: T is Cpp17DefaultInsertable into forward_list.
Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz elements from the list.
Otherwise, inserts sz - distance(begin(), end()) default-inserted elements at the end of the list.
constexpr void resize(size_type sz, const value_type& c);
Preconditions: T is Cpp17CopyInsertable into forward_list.
Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz elements from the list.
Otherwise, inserts sz - distance(begin(), end()) copies of c at the end of the list.
constexpr void clear() noexcept;
Effects: Erases all elements in the range [begin(), end()).
Remarks: Does not invalidate past-the-end iterators.

23.3.7.6 Operations [forward.list.ops]

In this subclause, arguments for a template parameter named Predicate or BinaryPredicate shall meet the corresponding requirements in [algorithms.requirements].
The semantics of i + n, where i is an iterator into the list and n is an integer, are the same as those of next(i, n).
The expression i - n, where i is an iterator into the list and n is an integer, means an iterator j such that j + n == i is true.
For merge and sort, the definitions and requirements in [alg.sorting] apply.
constexpr void splice_after(const_iterator position, forward_list& x); constexpr void splice_after(const_iterator position, forward_list&& x);
Preconditions: position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
get_allocator() == x.get_allocator() is true.
addressof(x) != this is true.
Effects: Inserts the contents of x after position, and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity:
constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i);
Preconditions: position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
The iterator following i is a dereferenceable iterator in x.
get_allocator() == x.get_allocator() is true.
Effects: Inserts the element following i into *this, following position, and removes it from x.
The result is unchanged if position == i or position == ++i.
Pointers and references to *++i continue to refer to the same element but as a member of *this.
Iterators to *++i continue to refer to the same element, but now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity:
constexpr void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last);
Preconditions: position is before_begin() or is a dereferenceable iterator in the range [begin(), end()).
(first, last) is a valid range in x, and all iterators in the range (first, last) are dereferenceable.
position is not an iterator in the range (first, last).
get_allocator() == x.get_allocator() is true.
Effects: Inserts elements in the range (first, last) after position and removes the elements from x.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Complexity:
constexpr size_type remove(const T& value); template<class Predicate> constexpr size_type remove_if(Predicate pred);
Effects: Erases all the elements in the list referred to by a list iterator i for which the following conditions hold: *i == value (for remove()), pred(*i) is true (for remove_if()).
Invalidates only the iterators and references to the erased elements.
Returns: The number of elements erased.
Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.
Complexity: Exactly distance(begin(), end()) applications of the corresponding predicate.
Remarks: Stable.
constexpr size_type unique(); template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred);
Let binary_pred be equal_to<>{} for the first overload.
Preconditions: binary_pred is an equivalence relation.
Effects: Erases all but the first element from every consecutive group of equivalent elements.
That is, for a nonempty list, erases all elements referred to by the iterator i in the range [begin() + 1, end()) for which binary_pred(*i, *(i - 1)) is true.
Invalidates only the iterators and references to the erased elements.
Returns: The number of elements erased.
Throws: Nothing unless an exception is thrown by the predicate.
Complexity: If empty() is false, exactly distance(begin(), end()) - 1 applications of the corresponding predicate, otherwise no applications of the predicate.
constexpr void merge(forward_list& x); constexpr void merge(forward_list&& x); template<class Compare> constexpr void merge(forward_list& x, Compare comp); template<class Compare> constexpr void merge(forward_list&& x, Compare comp);
Let comp be less<> for the first two overloads.
Preconditions: *this and x are both sorted with respect to the comparator comp, and get_allocator() == x.get_allocator() is true.
Effects: If addressof(x) == this, there are no effects.
Otherwise, merges the two sorted ranges [begin(), end()) and [x.begin(), x.end()).
The result is a range that is sorted with respect to the comparator comp.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Complexity: At most distance(begin(), end()) + distance(x.begin(), x.end()) - 1 comparisons if addressof(x) != this; otherwise, no comparisons are performed.
Remarks: Stable ([algorithm.stable]).
If addressof(x) != this, x is empty after the merge.
No elements are copied by this operation.
If an exception is thrown other than by a comparison, there are no effects.
constexpr void sort(); template<class Compare> constexpr void sort(Compare comp);
Effects: Sorts the list according to the operator< or the comp function object.
If an exception is thrown, the order of the elements in *this is unspecified.
Does not affect the validity of iterators and references.
Complexity: Approximately comparisons, where N is distance(begin(), end()).
Remarks: Stable.
constexpr void reverse() noexcept;
Effects: Reverses the order of the elements in the list.
Does not affect the validity of iterators and references.
Complexity: Linear time.

23.3.7.7 Erasure [forward.list.erasure]

template<class T, class Allocator, class U = T> constexpr typename forward_list<T, Allocator>::size_type erase(forward_list<T, Allocator>& c, const U& value);
Effects: Equivalent to: return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
template<class T, class Allocator, class Predicate> constexpr typename forward_list<T, Allocator>::size_type erase_if(forward_list<T, Allocator>& c, Predicate pred);
Effects: Equivalent to: return c.remove_if(pred);

23.3.8 Header <hive> synopsis [hive.syn]

#include <initializer_list> // see [initializer.list.syn] #include <compare> // see [compare.syn] namespace std { struct hive_limits { size_t min; size_t max; constexpr hive_limits(size_t minimum, size_t maximum) noexcept : min(minimum), max(maximum) {} }; // [hive], class template hive template<class T, class Allocator = allocator<T>> class hive; template<class T, class Allocator> void swap(hive<T, Allocator>& x, hive<T, Allocator>& y) noexcept(noexcept(x.swap(y))); template<class T, class Allocator, class U = T> typename hive<T, Allocator>::size_type erase(hive<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> typename hive<T, Allocator>::size_type erase_if(hive<T, Allocator>& c, Predicate pred); namespace pmr { template<class T> using hive = std::hive<T, polymorphic_allocator<T>>; } }

23.3.9 Class template hive [hive]

23.3.9.1 Overview [hive.overview]

A hive is a type of sequence container that provides constant-time insertion and erasure operations.
Storage is automatically managed in multiple memory blocks, referred to as element blocks.
Insertion ([hive.modifiers]) position is determined by the container, and insertion may re-use the memory locations of erased elements.
[Note 1: 
Construction and assignment are not considered to involve insertion operations.
— end note]
Element blocks which contain elements are referred to as active blocks, those which do not are referred to as reserved blocks.
Active blocks which become empty of elements are either deallocated or become reserved blocks.
Reserved blocks become active blocks when they are used to store elements.
A user can create additional reserved blocks by calling reserve.
Erasures use unspecified techniques of constant time complexity to identify the memory locations of erased elements, which are subsequently skipped during iteration, as opposed to relocating subsequent elements during erasure.
Active block capacities have an implementation-defined growth factor (which need not be integral), for example a new active block's capacity could be equal to the summed capacities of the pre-existing active blocks.
Limits can be placed on both the minimum and maximum element capacities of element blocks, both by users and implementations.
  • The minimum limit shall be no larger than the maximum limit.
  • When limits are not specified by a user during construction, the implementation's default limits are used.
  • The default limits of an implementation are not guaranteed to be the same as the minimum and maximum possible capacities for an implementation's element blocks.
    [Note 2: 
    To allow latitude for both implementation-specific and user-directed optimization.
    — end note]
    The latter are defined as hard limits.
    The maximum hard limit shall be no larger than std​::​allocator_traits<Allocator>​::​max_size().
  • If user-specified limits passed to a hive constructor or reshape are not within hard limits, or if the specified minimum limit is greater than the specified maximum limit, the behavior is erroneous and the effects are implementation-defined.
    [Note 3: 
    This condition can be checked using is_within_hard_limits.
    — end note]
  • An element block is said to be within the bounds of a pair of minimum/maximum limits when its capacity is greater-or-equal-to the minimum limit and less-than-or-equal-to the maximum limit.
A hive conforms to the requirements for containers ([container.reqmts]), with the exception of operators == and !=.
A hive also meets the requirements of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and some of the requirements of a sequence container ([sequence.reqmts]).
Descriptions are provided here only for operations on hive that are not described in that table or for operations where there is additional semantic information.
The iterators of hive meet the Cpp17BidirectionalIterator requirements but also model three_way_comparable<strong_ordering>.
namespace std { template<class T, class Allocator = allocator<T>> class hive { public: // types using value_type = T; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; // see [container.requirements] using const_reverse_iterator = std::reverse_iterator<const_iterator>; // see [container.requirements] // [hive.cons], construct/copy/destroy constexpr hive() noexcept(noexcept(Allocator())) : hive(Allocator()) {} constexpr explicit hive(const Allocator&) noexcept; constexpr explicit hive(hive_limits block_limits) : hive(block_limits, Allocator()) {} constexpr hive(hive_limits block_limits, const Allocator&); explicit hive(size_type n, const Allocator& = Allocator()); hive(size_type n, hive_limits block_limits, const Allocator& = Allocator()); hive(size_type n, const T& value, const Allocator& = Allocator()); hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator()); template<class InputIterator> hive(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<class InputIterator> hive(InputIterator first, InputIterator last, hive_limits block_limits, const Allocator& = Allocator()); template<container-compatible-range<T> R> hive(from_range_t, R&& rg, const Allocator& = Allocator()); template<container-compatible-range<T> R> hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator()); hive(const hive& x); hive(hive&&) noexcept; hive(const hive& x, const type_identity_t<Allocator>& alloc); hive(hive&&, const type_identity_t<Allocator>& alloc); hive(initializer_list<T> il, const Allocator& = Allocator()); hive(initializer_list<T> il, hive_limits block_limits, const Allocator& = Allocator()); ~hive(); hive& operator=(const hive& x); hive& operator=(hive&& x) noexcept(see below); hive& operator=(initializer_list<T>); template<class InputIterator> void assign(InputIterator first, InputIterator last); template<container-compatible-range<T> R> void assign_range(R&& rg); void assign(size_type n, const T& t); void assign(initializer_list<T>); allocator_type get_allocator() const noexcept; // iterators iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_iterator end() const noexcept; reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; // [hive.capacity], capacity bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; size_type capacity() const noexcept; void reserve(size_type n); void shrink_to_fit(); void trim_capacity() noexcept; void trim_capacity(size_type n) noexcept; constexpr hive_limits block_capacity_limits() const noexcept; static constexpr hive_limits block_capacity_default_limits() noexcept; static constexpr hive_limits block_capacity_hard_limits() noexcept; static constexpr bool is_within_hard_limits(hive_limits) noexcept; void reshape(hive_limits block_limits); // [hive.modifiers], modifiers template<class... Args> iterator emplace(Args&&... args); template<class... Args> iterator emplace_hint(const_iterator hint, Args&&... args); iterator insert(const T& x); iterator insert(T&& x); iterator insert(const_iterator hint, const T& x); iterator insert(const_iterator hint, T&& x); void insert(initializer_list<T> il); template<container-compatible-range<T> R> void insert_range(R&& rg); template<class InputIterator> void insert(InputIterator first, InputIterator last); void insert(size_type n, const T& x); iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void swap(hive&) noexcept(see below); void clear() noexcept; // [hive.operations], hive operations void splice(hive& x); void splice(hive&& x); template<class BinaryPredicate = equal_to<T>> size_type unique(BinaryPredicate binary_pred = BinaryPredicate()); template<class Compare = less<T>> void sort(Compare comp = Compare()); iterator get_iterator(const_pointer p) noexcept; const_iterator get_iterator(const_pointer p) const noexcept; private: hive_limits current-limits = implementation-defined; // exposition only }; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> hive(InputIterator, InputIterator, Allocator = Allocator()) -> hive<iter-value-type<InputIterator>, Allocator>; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> hive(InputIterator, InputIterator, hive_limits, Allocator = Allocator()) -> hive<iter-value-type<InputIterator>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> hive(from_range_t, R&&, Allocator = Allocator()) -> hive<ranges::range_value_t<R>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> hive(from_range_t, R&&, hive_limits, Allocator = Allocator()) -> hive<ranges::range_value_t<R>, Allocator>; }

23.3.9.2 Constructors, copy, and assignment [hive.cons]

constexpr explicit hive(const Allocator&) noexcept;
Effects: Constructs an empty hive, using the specified allocator.
Complexity: Constant.
constexpr hive(hive_limits block_limits, const Allocator&);
Effects: Constructs an empty hive, using the specified allocator.
Initializes current-limits with block_limits.
Complexity: Constant.
explicit hive(size_type n, const Allocator& = Allocator()); hive(size_type n, hive_limits block_limits, const Allocator& = Allocator());
Preconditions: T is Cpp17DefaultInsertable into hive.
Effects: Constructs a hive with n default-inserted elements, using the specified allocator.
If the second overload is called, also initializes current-limits with block_limits.
Complexity: Linear in n.
hive(size_type n, const T& value, const Allocator& = Allocator()); hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into hive.
Effects: Constructs a hive with n copies of value, using the specified allocator.
If the second overload is called, also initializes current-limits with block_limits.
Complexity: Linear in n.
template<class InputIterator> hive(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<class InputIterator> hive(InputIterator first, InputIterator last, hive_limits block_limits, const Allocator& = Allocator());
Effects: Constructs a hive equal to the range [first, last), using the specified allocator.
If the second overload is called, also initializes current-limits with block_limits.
Complexity: Linear in distance(first, last).
template<container-compatible-range<T> R> hive(from_range_t, R&& rg, const Allocator& = Allocator()); template<container-compatible-range<T> R> hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator());
Effects: Constructs a hive object equal to the range rg, using the specified allocator.
If the second overload is called, also initializes current-limits with block_limits.
Complexity: Linear in ranges​::​distance(rg).
hive(const hive& x); hive(const hive& x, const type_identity_t<Allocator>& alloc);
Preconditions: T is Cpp17CopyInsertable into hive.
Effects: Constructs a hive object equal to x.
If the second overload is called, uses alloc.
Initializes current-limits with x.current-limits.
Complexity: Linear in x.size().
hive(hive&& x) noexcept; hive(hive&& x, const type_identity_t<Allocator>& alloc);
Preconditions: For the second overload, when allocator_traits<Allocator>​::​is_always_equal​::​value is false, T meets the Cpp17MoveInsertable requirements.
Effects: When the first overload is called, or the second overload is called and alloc == x.get_allocator() is true, current-limits is set to x.current-limits and each element block is moved from x into *this.
Pointers and references to the elements of x now refer to those same elements but as members of *this.
Iterators referring to the elements of x will continue to refer to their elements, but they now behave as iterators into *this.
If the second overload is called and alloc == x.get_allocator() is false, each element in x is moved into *this.
References, pointers and iterators referring to the elements of x, as well as the past-the-end iterator of x, are invalidated.
Postconditions: x.empty() is true.
The relative order of the elements of *this is the same as that of the elements of x prior to the call.
Complexity: If the second overload is called and alloc == x.get_allocator() is false, linear in x.size().
Otherwise constant.
hive(initializer_list<T> il, const Allocator& = Allocator()); hive(initializer_list<T> il, hive_limits block_limits, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into hive.
Effects: Constructs a hive object equal to il, using the specified allocator.
If the second overload is called, also initializes current-limits with block_limits.
Complexity: Linear in il.size().
hive& operator=(const hive& x);
Preconditions: T is Cpp17CopyInsertable into hive and Cpp17CopyAssignable.
Effects: All elements in *this are either copy-assigned to, or destroyed.
All elements in x are copied into *this, maintaining their relative order.
[Note 1: 
current-limits is unchanged.
— end note]
Complexity: Linear in size() + x.size().
hive& operator=(hive&& x) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Preconditions: When (allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value) is false, T is Cpp17MoveInsertable into hive and Cpp17MoveAssignable.
Effects: Each element in *this is either move-assigned to, or destroyed.
When (allocator_traits<Allocator>::propagate_on_container_move_assignment::value || get_allocator() == x.get_allocator()) is true, current-limits is set to x.current-limits and each element block is moved from x into *this.
Pointers and references to the elements of x now refer to those same elements but as members of *this.
Iterators referring to the elements of x will continue to refer to their elements, but they now behave as iterators into *this, not into x.
When (allocator_traits<Allocator>::propagate_on_container_move_assignment::value || get_allocator() == x.get_allocator()) is false, each element in x is moved into *this.
References, pointers and iterators referring to the elements of x, as well as the past-the-end iterator of x, are invalidated.
Postconditions: x.empty() is true.
The relative order of the elements of *this is the same as that of the elements of x prior to this call.
Complexity: Linear in size().
If (allocator_traits<Allocator>::propagate_on_container_move_assignment::value || get_allocator() == x.get_allocator()) is false, also linear in x.size().

23.3.9.3 Capacity [hive.capacity]

size_type capacity() const noexcept;
Returns: The total number of elements that *this can hold without requiring allocation of more element blocks.
Complexity: Constant.
void reserve(size_type n);
Effects: If n <= capacity() is true, there are no effects.
Otherwise increases capacity() by allocating reserved blocks.
Postconditions: capacity() >= n is true.
Throws: length_error if satisfying the postcondition would cause capacity() to exceed max_size(), as well as any exceptions thrown by the allocator.
Complexity: Linear in the number of reserved blocks allocated.
Remarks: All references, pointers, and iterators referring to elements in *this, as well as the past-the-end iterator, remain valid.
void shrink_to_fit();
Preconditions: T is Cpp17MoveInsertable into hive.
Effects: shrink_to_fit is a non-binding request to reduce capacity() to be closer to size().
[Note 1: 
The request is non-binding to allow latitude for implementation-specific optimizations.
— end note]
It does not increase capacity(), but may reduce capacity().
It may reallocate elements.
If capacity() is already equal to size(), there are no effects.
If an exception is thrown during allocation of a new element block, capacity() may be reduced and reallocation may occur.
Otherwise if an exception is thrown, the effects are unspecified.
Complexity: If reallocation happens, linear in the size of the sequence.
Remarks: If reallocation happens, the order of the elements in *this may change and all references, pointers, and iterators referring to the elements in *this, as well as the past-the-end iterator, are invalidated.
void trim_capacity() noexcept; void trim_capacity(size_type n) noexcept;
Effects: For the first overload, all reserved blocks are deallocated, and capacity() is reduced accordingly.
For the second overload, if n >= capacity() is true, there are no effects; otherwise, capacity() is reduced to no less than n.
Complexity: Linear in the number of reserved blocks deallocated.
Remarks: All references, pointers, and iterators referring to elements in *this, as well as the past-the-end iterator, remain valid.
constexpr hive_limits block_capacity_limits() const noexcept;
Returns: current-limits.
Complexity: Constant.
static constexpr hive_limits block_capacity_default_limits() noexcept;
Returns: A hive_limits struct with the min and max members set to the implementation's default limits.
Complexity: Constant.
static constexpr hive_limits block_capacity_hard_limits() noexcept;
Returns: A hive_limits struct with the min and max members set to the implementation's hard limits.
Complexity: Constant.
static constexpr bool is_within_hard_limits(hive_limits lim) noexcept;
Let hl be block_capacity_hard_limits().
Returns: hl.min <= lim.min && lim.min <= lim.max && lim.max <= hl.max.
void reshape(hive_limits block_limits);
Preconditions: T is Cpp17MoveInsertable into hive.
Effects: For any active blocks not within the bounds of block_limits, the elements within those active blocks are reallocated to new or existing element blocks which are within the bounds.
Any element blocks not within the bounds of block_limits are deallocated.
If an exception is thrown during allocation of a new element block, capacity() may be reduced, reallocation may occur, and current-limits may be assigned a value other than block_limits.
Otherwise block_limits is assigned to current-limits.
If any other exception is thrown the effects are unspecified.
Postconditions: size() is unchanged.
Complexity: Linear in the number of element blocks in *this.
If reallocation happens, also linear in the number of elements reallocated.
Remarks: This operation may change capacity().
If reallocation happens, the order of the elements in *this may change.
Reallocation invalidates all references, pointers, and iterators referring to the elements in *this, as well as the past-the-end iterator.
[Note 2: 
If no reallocation happens, they remain valid.
— end note]

23.3.9.4 Modifiers [hive.modifiers]

template<class... Args> iterator emplace(Args&&... args); template<class... Args> iterator emplace_hint(const_iterator hint, Args&&... args);
Preconditions: T is Cpp17EmplaceConstructible into hive from args.
Effects: Inserts an object of type T constructed with std​::​forward<Args>(args)....
The hint parameter is ignored.
If an exception is thrown, there are no effects.
[Note 1: 
args can directly or indirectly refer to a value in *this.
— end note]
Returns: An iterator that points to the new element.
Complexity: Constant.
Exactly one object of type T is constructed.
Remarks: Invalidates the past-the-end iterator.
iterator insert(const T& x); iterator insert(const_iterator hint, const T& x); iterator insert(T&& x); iterator insert(const_iterator hint, T&& x);
Effects: Equivalent to: return emplace(std​::​forward<decltype(x)>(x));
[Note 2: 
The hint parameter is ignored.
— end note]
void insert(initializer_list<T> rg); template<container-compatible-range<T> R> void insert_range(R&& rg);
Preconditions: T is Cpp17EmplaceInsertable into hive from *ranges​::​begin(rg).
rg and *this do not overlap.
Effects: Inserts copies of elements in rg.
Each iterator in the range rg is dereferenced exactly once.
Complexity: Linear in the number of elements inserted.
Exactly one object of type T is constructed for each element inserted.
Remarks: If an element is inserted, invalidates the past-the-end iterator.
void insert(size_type n, const T& x);
Preconditions: T is Cpp17CopyInsertable into hive.
Effects: Inserts n copies of x.
Complexity: Linear in n.
Exactly one object of type T is constructed for each element inserted.
Remarks: If an element is inserted, invalidates the past-the-end iterator.
template<class InputIterator> void insert(InputIterator first, InputIterator last);
Effects: Equivalent to insert_range(ranges​::​subrange(first, last)).
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last);
Complexity: Linear in the number of elements erased.
Additionally, if any active blocks become empty of elements as a result of the function call, at worst linear in the number of element blocks.
Remarks: Invalidates references, pointers and iterators referring to the erased elements.
An erase operation that erases the last element in *this also invalidates the past-the-end iterator.
void swap(hive& x) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Exchanges the contents, capacity(), and current-limits of *this with that of x.
Complexity: Constant.

23.3.9.5 Operations [hive.operations]

In this subclause, arguments for a template parameter named Predicate or BinaryPredicate shall meet the corresponding requirements in [algorithms.requirements].
The semantics of i + n and i - n, where i is an iterator into the hive and n is an integer, are the same as those of next(i, n) and prev(i, n), respectively.
For sort, the definitions and requirements in [alg.sorting] apply.
void splice(hive& x); void splice(hive&& x);
Preconditions: get_allocator() == x.get_allocator() is true.
Effects: If addressof(x) == this is true, the behavior is erroneous and there are no effects.
If an exception is thrown, there are no effects.
Otherwise, inserts the contents of x into *this and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: length_error if any of x's active blocks are not within the bounds of current-limits, as well as any exceptions thrown by the allocator.
Complexity: Linear in the sum of all element blocks in x plus all element blocks in *this.
Remarks: Reserved blocks in x are not transferred into *this.
If addressof(x) == this is false, invalidates the past-the-end iterator for both x and *this.
template<class BinaryPredicate = equal_to<T>> size_type unique(BinaryPredicate binary_pred = BinaryPredicate());
Preconditions: binary_pred is an equivalence relation.
Effects: Erases all but the first element from every consecutive group of equivalent elements.
That is, for a nonempty hive, erases all elements referred to by the iterator i in the range [begin() + 1, end()) for which binary_pred(*i, *(i - 1)) is true.
Returns: The number of elements erased.
Throws: Nothing unless an exception is thrown by the predicate.
Complexity: If empty() is false, exactly size() - 1 applications of the corresponding predicate, otherwise no applications of the predicate.
Remarks: Invalidates references, pointers, and iterators referring to the erased elements.
If the last element in *this is erased, also invalidates the past-the-end iterator.
template<class Compare = less<T>> void sort(Compare comp = Compare());
Preconditions: T is Cpp17MoveInsertable into hive, Cpp17MoveAssignable, and Cpp17Swappable.
Effects: Sorts *this according to the comp function object.
If an exception is thrown, the order of the elements in *this is unspecified.
Complexity: comparisons, where N is size().
Remarks: May allocate.
References, pointers, and iterators referring to elements in *this, as well as the past-the-end iterator, may be invalidated.
[Note 1: 
Not required to be stable ([algorithm.stable]).
— end note]
iterator get_iterator(const_pointer p) noexcept; const_iterator get_iterator(const_pointer p) const noexcept;
Preconditions: p points to an element in *this.
Returns: An iterator or const_iterator pointing to the same element as p.
Complexity: Linear in the number of active blocks in *this.

23.3.9.6 Erasure [hive.erasure]

template<class T, class Allocator, class U = T> typename hive<T, Allocator>::size_type erase(hive<T, Allocator>& c, const U& value);
Effects: Equivalent to: return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
template<class T, class Allocator, class Predicate> typename hive<T, Allocator>::size_type erase_if(hive<T, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto original_size = c.size(); for (auto i = c.begin(); i != c.end(); ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size();

23.3.10 Header <list> synopsis [list.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [list], class template list template<class T, class Allocator = allocator<T>> class list; template<class T, class Allocator> constexpr bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y); template<class T, class Allocator> constexpr synth-three-way-result<T> operator<=>(const list<T, Allocator>& x, const list<T, Allocator>& y); template<class T, class Allocator> constexpr void swap(list<T, Allocator>& x, list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // [list.erasure], erasure template<class T, class Allocator, class U = T> constexpr typename list<T, Allocator>::size_type erase(list<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> constexpr typename list<T, Allocator>::size_type erase_if(list<T, Allocator>& c, Predicate pred); namespace pmr { template<class T> using list = std::list<T, polymorphic_allocator<T>>; } }

23.3.11 Class template list [list]

23.3.11.1 Overview [list.overview]

A list is a sequence container that supports bidirectional iterators and allows constant time insert and erase operations anywhere within the sequence, with storage management handled automatically.
Unlike vectors and deques, fast random access to list elements is not supported, but many algorithms only need sequential access anyway.
A list meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of a sequence container, including most of the optional sequence container requirements ([sequence.reqmts]).
The exceptions are the operator[] and at member functions, which are not provided.¹⁷⁴
Descriptions are provided here only for operations on list that are not described in one of these tables or for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class T, class Allocator = allocator<T>> class list { public: // types using value_type = T; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // [list.cons], construct/copy/destroy constexpr list() : list(Allocator()) { } constexpr explicit list(const Allocator&); constexpr explicit list(size_type n, const Allocator& = Allocator()); constexpr list(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<container-compatible-range<T> R> constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr list(const list& x); constexpr list(list&& x); constexpr list(const list&, const type_identity_t<Allocator>&); constexpr list(list&&, const type_identity_t<Allocator>&); constexpr list(initializer_list<T>, const Allocator& = Allocator()); constexpr ~list(); constexpr list& operator=(const list& x); constexpr list& operator=(list&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr list& operator=(initializer_list<T>); template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const T& t); constexpr void assign(initializer_list<T>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // [list.capacity], capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; constexpr void resize(size_type sz); constexpr void resize(size_type sz, const T& c); // element access constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; // [list.modifiers], modifiers template<class... Args> constexpr reference emplace_front(Args&&... args); template<class... Args> constexpr reference emplace_back(Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg); constexpr void pop_front(); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg); constexpr void pop_back(); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T> il); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator position, const_iterator last); constexpr void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value); constexpr void clear() noexcept; // [list.ops], list operations constexpr void splice(const_iterator position, list& x); constexpr void splice(const_iterator position, list&& x); constexpr void splice(const_iterator position, list& x, const_iterator i); constexpr void splice(const_iterator position, list&& x, const_iterator i); constexpr void splice(const_iterator position, list& x, const_iterator first, const_iterator last); constexpr void splice(const_iterator position, list&& x, const_iterator first, const_iterator last); constexpr size_type remove(const T& value); template<class Predicate> constexpr size_type remove_if(Predicate pred); constexpr size_type unique(); template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred); constexpr void merge(list& x); constexpr void merge(list&& x); template<class Compare> constexpr void merge(list& x, Compare comp); template<class Compare> constexpr void merge(list&& x, Compare comp); constexpr void sort(); template<class Compare> constexpr void sort(Compare comp); constexpr void reverse() noexcept; }; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> list(InputIterator, InputIterator, Allocator = Allocator()) -> list<iter-value-type<InputIterator>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> list(from_range_t, R&&, Allocator = Allocator()) -> list<ranges::range_value_t<R>, Allocator>; }
An incomplete type T may be used when instantiating list if the allocator meets the allocator completeness requirements.
T shall be complete before any member of the resulting specialization of list is referenced.
174)174)
These member functions are only provided by containers whose iterators are random access iterators.

23.3.11.2 Constructors, copy, and assignment [list.cons]

constexpr explicit list(const Allocator&);
Effects: Constructs an empty list, using the specified allocator.
Complexity: Constant.
constexpr explicit list(size_type n, const Allocator& = Allocator());
Preconditions: T is Cpp17DefaultInsertable into list.
Effects: Constructs a list with n default-inserted elements using the specified allocator.
Complexity: Linear in n.
constexpr list(size_type n, const T& value, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into list.
Effects: Constructs a list with n copies of value, using the specified allocator.
Complexity: Linear in n.
template<class InputIterator> constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a list equal to the range [first, last).
Complexity: Linear in distance(first, last).
template<container-compatible-range<T> R> constexpr list(from_range_t, R&& rg, const Allocator& = Allocator());
Effects: Constructs a list object with the elements of the range rg.
Complexity: Linear in ranges​::​distance(rg).

23.3.11.3 Capacity [list.capacity]

constexpr void resize(size_type sz);
Preconditions: T is Cpp17DefaultInsertable into list.
Effects: If size() < sz, appends sz - size() default-inserted elements to the sequence.
If sz <= size(), equivalent to: list<T>::iterator it = begin(); advance(it, sz); erase(it, end());
constexpr void resize(size_type sz, const T& c);
Preconditions: T is Cpp17CopyInsertable into list.
Effects: As if by: if (sz > size()) insert(end(), sz-size(), c); else if (sz < size()) { iterator i = begin(); advance(i, sz); erase(i, end()); } else ; // do nothing

23.3.11.4 Modifiers [list.modifiers]

constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T>); template<class... Args> constexpr reference emplace_front(Args&&... args); template<class... Args> constexpr reference emplace_back(Args&&... args); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr void push_front(const T& x); constexpr void push_front(T&& x); template<container-compatible-range<T> R> constexpr void prepend_range(R&& rg); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg);
Complexity: Insertion of a single element into a list takes constant time and exactly one call to a constructor of T.
Insertion of multiple elements into a list is linear in the number of elements inserted, and the number of calls to the copy constructor or move constructor of T is exactly equal to the number of elements inserted.
Remarks: Does not affect the validity of iterators and references.
If an exception is thrown, there are no effects.
constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_front(); constexpr void pop_back(); constexpr void clear() noexcept;
Effects: Invalidates only the iterators and references to the erased elements.
Throws: Nothing.
Complexity: Erasing a single element is a constant time operation with a single call to the destructor of T.
Erasing a range in a list is linear time in the size of the range and the number of calls to the destructor of type T is exactly equal to the size of the range.

23.3.11.5 Operations [list.ops]

Since lists allow fast insertion and erasing from the middle of a list, certain operations are provided specifically for them.¹⁷⁵
In this subclause, arguments for a template parameter named Predicate or BinaryPredicate shall meet the corresponding requirements in [algorithms.requirements].
The semantics of i + n and i - n, where i is an iterator into the list and n is an integer, are the same as those of next(i, n) and prev(i, n), respectively.
For merge and sort, the definitions and requirements in [alg.sorting] apply.
list provides three splice operations that destructively move elements from one list to another.
The behavior of splice operations is undefined if get_allocator() != x.get_allocator().
constexpr void splice(const_iterator position, list& x); constexpr void splice(const_iterator position, list&& x);
Preconditions: addressof(x) != this is true.
Effects: Inserts the contents of x before position and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time.
constexpr void splice(const_iterator position, list& x, const_iterator i); constexpr void splice(const_iterator position, list&& x, const_iterator i);
Preconditions: i is a valid dereferenceable iterator of x.
Effects: Inserts an element pointed to by i from list x before position and removes the element from x.
The result is unchanged if position == i or position == ++i.
Pointers and references to *i continue to refer to this same element but as a member of *this.
Iterators to *i (including i itself) continue to refer to the same element, but now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time.
constexpr void splice(const_iterator position, list& x, const_iterator first, const_iterator last); constexpr void splice(const_iterator position, list&& x, const_iterator first, const_iterator last);
Preconditions: [first, last) is a valid range in x.
position is not an iterator in the range [first, last).
Effects: Inserts elements in the range [first, last) before position and removes the elements from x.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time if addressof(x) == this; otherwise, linear time.
constexpr size_type remove(const T& value); template<class Predicate> constexpr size_type remove_if(Predicate pred);
Effects: Erases all the elements in the list referred to by a list iterator i for which the following conditions hold: *i == value, pred(*i) != false.
Invalidates only the iterators and references to the erased elements.
Returns: The number of elements erased.
Throws: Nothing unless an exception is thrown by *i == value or pred(*i) != false.
Complexity: Exactly size() applications of the corresponding predicate.
Remarks: Stable.
constexpr size_type unique(); template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred);
Let binary_pred be equal_to<>{} for the first overload.
Preconditions: binary_pred is an equivalence relation.
Effects: Erases all but the first element from every consecutive group of equivalent elements.
That is, for a nonempty list, erases all elements referred to by the iterator i in the range [begin() + 1, end()) for which binary_pred(*i, *(i - 1)) is true.
Invalidates only the iterators and references to the erased elements.
Returns: The number of elements erased.
Throws: Nothing unless an exception is thrown by the predicate.
Complexity: If empty() is false, exactly size() - 1 applications of the corresponding predicate, otherwise no applications of the predicate.
constexpr void merge(list& x); constexpr void merge(list&& x); template<class Compare> constexpr void merge(list& x, Compare comp); template<class Compare> constexpr void merge(list&& x, Compare comp);
Let comp be less<> for the first two overloads.
Preconditions: *this and x are both sorted with respect to the comparator comp, and get_allocator() == x.get_allocator() is true.
Effects: If addressof(x) == this, there are no effects.
Otherwise, merges the two sorted ranges [begin(), end()) and [x.begin(), x.end()).
The result is a range that is sorted with respect to the comparator comp.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Complexity: At most size() + x.size() - 1 comparisons if addressof(x) != this; otherwise, no comparisons are performed.
Remarks: Stable ([algorithm.stable]).
If addressof(x) != this, x is empty after the merge.
No elements are copied by this operation.
If an exception is thrown other than by a comparison, there are no effects.
constexpr void reverse() noexcept;
Effects: Reverses the order of the elements in the list.
Does not affect the validity of iterators and references.
Complexity: Linear time.
void sort(); template<class Compare> void sort(Compare comp);
Effects: Sorts the list according to the operator< or a Compare function object.
If an exception is thrown, the order of the elements in *this is unspecified.
Does not affect the validity of iterators and references.
Complexity: Approximately comparisons, where N is size().
Remarks: Stable.
175)175)
As specified in [allocator.requirements], the requirements in this Clause apply only to lists whose allocators compare equal.

23.3.11.6 Erasure [list.erasure]

template<class T, class Allocator, class U = T> typename list<T, Allocator>::size_type constexpr erase(list<T, Allocator>& c, const U& value);
Effects: Equivalent to: return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
template<class T, class Allocator, class Predicate> typename list<T, Allocator>::size_type constexpr erase_if(list<T, Allocator>& c, Predicate pred);
Effects: Equivalent to: return c.remove_if(pred);

23.3.12 Header <vector> synopsis [vector.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [vector], class template vector template<class T, class Allocator = allocator<T>> class vector; template<class T, class Allocator> constexpr bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y); template<class T, class Allocator> constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x, const vector<T, Allocator>& y); template<class T, class Allocator> constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // [vector.erasure], erasure template<class T, class Allocator, class U = T> constexpr typename vector<T, Allocator>::size_type erase(vector<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> constexpr typename vector<T, Allocator>::size_type erase_if(vector<T, Allocator>& c, Predicate pred); namespace pmr { template<class T> using vector = std::vector<T, polymorphic_allocator<T>>; } // [vector.bool], specialization of vector for bool // [vector.bool.pspc], partial class template specialization vector<bool, Allocator> template<class Allocator> class vector<bool, Allocator>; template<class T> constexpr bool is-vector-bool-reference = see below; // exposition only // hash support template<class T> struct hash; template<class Allocator> struct hash<vector<bool, Allocator>>; // [vector.bool.fmt], formatter specialization for vector<bool> template<class T, class charT> requires is-vector-bool-reference<T> struct formatter<T, charT>; }

23.3.13 Class template vector [vector]

23.3.13.1 Overview [vector.overview]

A vector is a sequence container that supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time.
Storage management is handled automatically, though hints can be given to improve efficiency.
A vector meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), of a sequence container, including most of the optional sequence container requirements ([sequence.reqmts]), and, for an element type other than bool, of a contiguous container.
The exceptions are the push_front, prepend_range, pop_front, and emplace_front member functions, which are not provided.
Descriptions are provided here only for operations on vector that are not described in one of these tables or for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class T, class Allocator = allocator<T>> class vector { public: // types using value_type = T; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // [vector.cons], construct/copy/destroy constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } constexpr explicit vector(const Allocator&) noexcept; constexpr explicit vector(size_type n, const Allocator& = Allocator()); constexpr vector(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<container-compatible-range<T> R> constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr vector(const vector& x); constexpr vector(vector&&) noexcept; constexpr vector(const vector&, const type_identity_t<Allocator>&); constexpr vector(vector&&, const type_identity_t<Allocator>&); constexpr vector(initializer_list<T>, const Allocator& = Allocator()); constexpr ~vector(); constexpr vector& operator=(const vector& x); constexpr vector& operator=(vector&& x) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); constexpr vector& operator=(initializer_list<T>); template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const T& u); constexpr void assign(initializer_list<T>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // [vector.capacity], capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; constexpr size_type capacity() const noexcept; constexpr void resize(size_type sz); constexpr void resize(size_type sz, const T& c); constexpr void reserve(size_type n); constexpr void shrink_to_fit(); // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); constexpr const_reference at(size_type n) const; constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; // [vector.data], data access constexpr T* data() noexcept; constexpr const T* data() const noexcept; // [vector.modifiers], modifiers template<class... Args> constexpr reference emplace_back(Args&&... args); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg); constexpr void pop_back(); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T> il); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(vector&) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); constexpr void clear() noexcept; }; template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>> vector(InputIterator, InputIterator, Allocator = Allocator()) -> vector<iter-value-type<InputIterator>, Allocator>; template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> vector(from_range_t, R&&, Allocator = Allocator()) -> vector<ranges::range_value_t<R>, Allocator>; }
An incomplete type T may be used when instantiating vector if the allocator meets the allocator completeness requirements.
T shall be complete before any member of the resulting specialization of vector is referenced.

23.3.13.2 Constructors [vector.cons]

constexpr explicit vector(const Allocator&) noexcept;
Effects: Constructs an empty vector, using the specified allocator.
Complexity: Constant.
constexpr explicit vector(size_type n, const Allocator& = Allocator());
Preconditions: T is Cpp17DefaultInsertable into vector.
Effects: Constructs a vector with n default-inserted elements using the specified allocator.
Complexity: Linear in n.
constexpr vector(size_type n, const T& value, const Allocator& = Allocator());
Preconditions: T is Cpp17CopyInsertable into vector.
Effects: Constructs a vector with n copies of value, using the specified allocator.
Complexity: Linear in n.
template<class InputIterator> constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a vector equal to the range [first, last), using the specified allocator.
Complexity: Makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if InputIterator meets the Cpp17ForwardIterator requirements.
It makes order N calls to the copy constructor of T and order reallocations if they are just input iterators.
template<container-compatible-range<T> R> constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
Effects: Constructs a vector object with the elements of the range rg, using the specified allocator.
Complexity: Initializes exactly N elements from the results of dereferencing successive iterators of rg, where N is ranges​::​distance(rg).
Performs no reallocations if:
Otherwise, performs order reallocations and order N calls to the copy or move constructor of T.

23.3.13.3 Capacity [vector.capacity]

constexpr size_type capacity() const noexcept;
Returns: The total number of elements that the vector can hold without requiring reallocation.
Complexity: Constant time.
constexpr void reserve(size_type n);
Preconditions: T is Cpp17MoveInsertable into vector.
Effects: After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise.
Reallocation happens at this point if and only if the current capacity is less than the argument of reserve().
If an exception is thrown other than by the move constructor of a non-Cpp17CopyInsertable type, there are no effects.
Throws: length_error if n > max_size().¹⁷⁶
Complexity: Linear in the size of the sequence.
Remarks: The size of the sequence is not changed.
Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end iterator.
[Note 1: 
If no reallocation happens, they remain valid.
— end note]
No reallocation shall take place during insertions that happen after a call to reserve() until an insertion would make the size of the vector greater than the value of capacity().
constexpr void shrink_to_fit();
Preconditions: T is Cpp17MoveInsertable into vector.
Effects: shrink_to_fit is a non-binding request to reduce capacity() to size().
[Note 2: 
The request is non-binding to allow latitude for implementation-specific optimizations.
— end note]
It does not increase capacity(), but may reduce capacity() by causing reallocation.
If an exception is thrown other than by the move constructor of a non-Cpp17CopyInsertable T, there are no effects.
Complexity: If reallocation happens, linear in the size of the sequence.
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator.
[Note 3: 
If no reallocation happens, they remain valid.
— end note]
constexpr void swap(vector& x) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Exchanges the contents and capacity() of *this with that of x.
Complexity: Constant time.
constexpr void resize(size_type sz);
Preconditions: T is Cpp17MoveInsertable and Cpp17DefaultInsertable into vector.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() default-inserted elements to the sequence.
Remarks: If an exception is thrown other than by the move constructor of a non-Cpp17CopyInsertable T, there are no effects.
constexpr void resize(size_type sz, const T& c);
Preconditions: T is Cpp17CopyInsertable into vector.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() copies of c to the sequence.
Remarks: If an exception is thrown, there are no effects.
176)176)
reserve() uses Allocator​::​allocate() which can throw an appropriate exception.

23.3.13.4 Data [vector.data]

constexpr T* data() noexcept; constexpr const T* data() const noexcept;
Returns: A pointer such that [data(), data() + size()) is a valid range.
For a non-empty vector, data() == addressof(front()) is true.
Complexity: Constant time.

23.3.13.5 Modifiers [vector.modifiers]

constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T>); template<class... Args> constexpr reference emplace_back(Args&&... args); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr void push_back(const T& x); constexpr void push_back(T&& x); template<container-compatible-range<T> R> constexpr void append_range(R&& rg);
Complexity: If reallocation happens, linear in the number of elements of the resulting vector; otherwise, linear in the number of elements inserted plus the distance to the end of the vector.
Remarks: Causes reallocation if the new size is greater than the old capacity.
Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end iterator.
If no reallocation happens, then references, pointers, and iterators before the insertion point remain valid but those at or after the insertion point, including the past-the-end iterator, are invalidated.
If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation, there are no effects.
If an exception is thrown while inserting a single element at the end and T is Cpp17CopyInsertable or is_nothrow_move_constructible_v<T> is true, there are no effects.
Otherwise, if an exception is thrown by the move constructor of a non-Cpp17CopyInsertable T, the effects are unspecified.
For the declarations taking a range R, performs at most one reallocation if:
For the declarations taking a pair of InputIterator, performs at most one reallocation if InputIterator meets the Cpp17ForwardIterator requirements.
constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_back();
Effects: Invalidates iterators and references at or after the point of the erase.
Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.
Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.

23.3.13.6 Erasure [vector.erasure]

template<class T, class Allocator, class U = T> constexpr typename vector<T, Allocator>::size_type erase(vector<T, Allocator>& c, const U& value);
Effects: Equivalent to: auto it = remove(c.begin(), c.end(), value); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;
template<class T, class Allocator, class Predicate> constexpr typename vector<T, Allocator>::size_type erase_if(vector<T, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto it = remove_if(c.begin(), c.end(), pred); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;

23.3.14 Specialization of vector for bool [vector.bool]

23.3.14.1 Partial class template specialization vector<bool, Allocator> [vector.bool.pspc]

To optimize space allocation, a partial specialization of vector for bool elements is provided: namespace std { template<class Allocator> class vector<bool, Allocator> { public: // types using value_type = bool; using allocator_type = Allocator; using pointer = implementation-defined; using const_pointer = implementation-defined; using const_reference = bool; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // bit reference class reference { public: constexpr reference(const reference& x) noexcept; constexpr ~reference(); constexpr reference& operator=(bool x) noexcept; constexpr reference& operator=(const reference& x) noexcept; constexpr const reference& operator=(bool x) const noexcept; constexpr operator bool() const noexcept; constexpr void flip() noexcept; // flips the bit friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept; }; // construct/copy/destroy constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } constexpr explicit vector(const Allocator&) noexcept; constexpr explicit vector(size_type n, const Allocator& = Allocator()); constexpr vector(size_type n, const bool& value, const Allocator& = Allocator()); template<class InputIterator> constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<container-compatible-range<bool> R> constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr vector(const vector& x); constexpr vector(vector&& x) noexcept; constexpr vector(const vector&, const type_identity_t<Allocator>&); constexpr vector(vector&&, const type_identity_t<Allocator>&); constexpr vector(initializer_list<bool>, const Allocator& = Allocator()); constexpr ~vector(); constexpr vector& operator=(const vector& x); constexpr vector& operator=(vector&& x) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); constexpr vector& operator=(initializer_list<bool>); template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); template<container-compatible-range<bool> R> constexpr void assign_range(R&& rg); constexpr void assign(size_type n, const bool& t); constexpr void assign(initializer_list<bool>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; constexpr size_type capacity() const noexcept; constexpr void resize(size_type sz, bool c = false); constexpr void reserve(size_type n); constexpr void shrink_to_fit(); // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); constexpr const_reference at(size_type n) const; constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; // modifiers template<class... Args> constexpr reference emplace_back(Args&&... args); constexpr void push_back(const bool& x); template<container-compatible-range<bool> R> constexpr void append_range(R&& rg); constexpr void pop_back(); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); constexpr iterator insert(const_iterator position, const bool& x); constexpr iterator insert(const_iterator position, size_type n, const bool& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<bool> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<bool> il); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(vector&) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); constexpr void flip() noexcept; // flips all bits constexpr void clear() noexcept; }; }
Unless described below, all operations have the same requirements and semantics as the vector primary template, except that operations dealing with the bool value type map to bit values in the container storage and allocator_traits​::​construct is not used to construct these values.
There is no requirement that the data be stored as a contiguous allocation of bool values.
A space-optimized representation of bits is recommended instead.
reference is a class that simulates a reference to a single bit in the sequence.
constexpr reference::reference(const reference& x) noexcept;
Effects: Initializes *this to refer to the same bit as x.
constexpr reference::~reference();
Effects: None.
constexpr reference& reference::operator=(bool x) noexcept; constexpr reference& reference::operator=(const reference& x) noexcept; constexpr const reference& reference::operator=(bool x) const noexcept;
Effects: Sets the bit referred to by *this when bool(x) is true, and clears it otherwise.
Returns: *this.
constexpr reference::operator bool() const noexcept;
Returns: true if the value of the bit referred to by *this is one, false otherwise.
constexpr void reference::flip() noexcept;
Effects: Equivalent to *this = !*this.
constexpr void swap(reference x, reference y) noexcept; constexpr void swap(reference x, bool& y) noexcept; constexpr void swap(bool& x, reference y) noexcept;
Effects: Exchanges the values denoted by x and y as if by:
bool b = x; x = y; y = b;
constexpr void flip() noexcept;
Effects: Replaces each element in the container with its complement.
template<class Allocator> struct hash<vector<bool, Allocator>>;
The specialization is enabled ([unord.hash]).
template<class T> constexpr bool is-vector-bool-reference = see below;
The expression is-vector-bool-reference<T> is true if T denotes the type vector<bool, Alloc>​::​reference for some type Alloc and vector<bool, Alloc> is not a program-defined specialization.

23.3.14.2 Formatter specialization for vector<bool> [vector.bool.fmt]

namespace std { template<class T, class charT> requires is-vector-bool-reference<T> struct formatter<T, charT> { private: formatter<bool, charT> underlying_; // exposition only public: template<class ParseContext> constexpr typename ParseContext::iterator parse(ParseContext& ctx); template<class FormatContext> constexpr typename FormatContext::iterator format(const T& ref, FormatContext& ctx) const; }; }
template<class ParseContext> constexpr typename ParseContext::iterator parse(ParseContext& ctx);
Equivalent to: return underlying_.parse(ctx);
template<class FormatContext> constexpr typename FormatContext::iterator format(const T& ref, FormatContext& ctx) const;
Equivalent to: return underlying_.format(ref, ctx);

23.3.15 Header <inplace_vector> synopsis [inplace.vector.syn]

// mostly freestanding #include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [inplace.vector], class template inplace_vector template<class T, size_t N> class inplace_vector; // partially freestanding // [inplace.vector.erasure], erasure template<class T, size_t N, class U = T> constexpr typename inplace_vector<T, N>::size_type erase(inplace_vector<T, N>& c, const U& value); template<class T, size_t N, class Predicate> constexpr typename inplace_vector<T, N>::size_type erase_if(inplace_vector<T, N>& c, Predicate pred); }

23.3.16 Class template inplace_vector [inplace.vector]

23.3.16.1 Overview [inplace.vector.overview]

An inplace_vector is a contiguous container.
Its capacity is fixed and its elements are stored within the inplace_vector object itself.
An inplace_vector meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of a contiguous container, and of a sequence container, including most of the optional sequence container requirements ([sequence.reqmts]).
The exceptions are the push_front, prepend_range, pop_front, and emplace_front member functions, which are not provided.
Descriptions are provided here only for operations on inplace_vector that are not described in one of these tables or for operations where there is additional semantic information.
For any N, inplace_vector<T, N>​::​iterator and inplace_vector<T, N>​::​const_iterator meet the constexpr iterator requirements.
Any member function of inplace_vector<T, N> that would cause the size to exceed N throws an exception of type bad_alloc.
Let IV denote a specialization of inplace_vector<T, N>.
If N is zero, then IV is trivially copyable and empty, and std​::​is_trivially_default_constructible_v<IV> is true.
Otherwise:
  • If is_trivially_copy_constructible_v<T> is true, then IV has a trivial copy constructor.
  • If is_trivially_move_constructible_v<T> is true, then IV has a trivial move constructor.
  • If is_trivially_destructible_v<T> is true, then:
    • IV has a trivial destructor.
    • If is_trivially_copy_constructible_v<T> && is_trivially_copy_assignable_v<T> is true, then IV has a trivial copy assignment operator.
    • If is_trivially_move_constructible_v<T> && is_trivially_move_assignable_v<T> is true, then IV has a trivial move assignment operator.
namespace std { template<class T, size_t N> class inplace_vector { public: // types: using value_type = T; using pointer = T*; using const_pointer = const T*; using reference = value_type&; using const_reference = const value_type&; using size_type = size_t; using difference_type = ptrdiff_t; using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; // [inplace.vector.cons], construct/copy/destroy constexpr inplace_vector() noexcept; constexpr explicit inplace_vector(size_type n); // freestanding-deleted constexpr inplace_vector(size_type n, const T& value); // freestanding-deleted template<class InputIterator> constexpr inplace_vector(InputIterator first, InputIterator last); // freestanding-deleted template<container-compatible-range<T> R> constexpr inplace_vector(from_range_t, R&& rg); // freestanding-deleted constexpr inplace_vector(const inplace_vector&); constexpr inplace_vector(inplace_vector&&) noexcept(N == 0 || is_nothrow_move_constructible_v<T>); constexpr inplace_vector(initializer_list<T> il); // freestanding-deleted constexpr ~inplace_vector(); constexpr inplace_vector& operator=(const inplace_vector& other); constexpr inplace_vector& operator=(inplace_vector&& other) noexcept(N == 0 || (is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>)); constexpr inplace_vector& operator=(initializer_list<T>); // freestanding-deleted template<class InputIterator> constexpr void assign(InputIterator first, InputIterator last); // freestanding-deleted template<container-compatible-range<T> R> constexpr void assign_range(R&& rg); // freestanding-deleted constexpr void assign(size_type n, const T& u); // freestanding-deleted constexpr void assign(initializer_list<T> il); // freestanding-deleted // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // [inplace.vector.capacity], capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; static constexpr size_type max_size() noexcept; static constexpr size_type capacity() noexcept; constexpr void resize(size_type sz); // freestanding-deleted constexpr void resize(size_type sz, const T& c); // freestanding-deleted static constexpr void reserve(size_type n); // freestanding-deleted static constexpr void shrink_to_fit() noexcept; // element access constexpr reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; constexpr reference at(size_type n); // freestanding-deleted constexpr const_reference at(size_type n) const; // freestanding-deleted constexpr reference front(); constexpr const_reference front() const; constexpr reference back(); constexpr const_reference back() const; // [inplace.vector.data], data access constexpr T* data() noexcept; constexpr const T* data() const noexcept; // [inplace.vector.modifiers], modifiers template<class... Args> constexpr reference emplace_back(Args&&... args); // freestanding-deleted constexpr reference push_back(const T& x); // freestanding-deleted constexpr reference push_back(T&& x); // freestanding-deleted template<container-compatible-range<T> R> constexpr void append_range(R&& rg); // freestanding-deleted constexpr void pop_back(); template<class... Args> constexpr optional<reference> try_emplace_back(Args&&... args); constexpr optional<reference> try_push_back(const T& x); constexpr optional<reference> try_push_back(T&& x); template<class... Args> constexpr reference unchecked_emplace_back(Args&&... args); constexpr reference unchecked_push_back(const T& x); constexpr reference unchecked_push_back(T&& x); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); // freestanding-deleted constexpr iterator insert(const_iterator position, const T& x); // freestanding-deleted constexpr iterator insert(const_iterator position, T&& x); // freestanding-deleted constexpr iterator insert(const_iterator position, size_type n, // freestanding-deleted const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, // freestanding-deleted InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); // freestanding-deleted constexpr iterator insert(const_iterator position, // freestanding-deleted initializer_list<T> il); constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(inplace_vector& x) noexcept(N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>)); constexpr void clear() noexcept; friend constexpr bool operator==(const inplace_vector& x, const inplace_vector& y); friend constexpr auto operator<=>(const inplace_vector& x, const inplace_vector& y) requires requires (const T t) { synth-three-way(t, t); } { return lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end(), synth-three-way); } friend constexpr void swap(inplace_vector& x, inplace_vector& y) noexcept(N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>)) { x.swap(y); } }; }

23.3.16.2 Constructors [inplace.vector.cons]

constexpr explicit inplace_vector(size_type n);
Preconditions: T is Cpp17DefaultInsertable into inplace_vector.
Effects: Constructs an inplace_vector with n default-inserted elements.
Complexity: Linear in n.
constexpr inplace_vector(size_type n, const T& value);
Preconditions: T is Cpp17CopyInsertable into inplace_vector.
Effects: Constructs an inplace_vector with n copies of value.
Complexity: Linear in n.
template<class InputIterator> constexpr inplace_vector(InputIterator first, InputIterator last);
Effects: Constructs an inplace_vector equal to the range [first, last).
Complexity: Linear in distance(first, last).
template<container-compatible-range<T> R> constexpr inplace_vector(from_range_t, R&& rg);
Mandates: If ranges​::​size(rg) is a constant expression, then ranges​::​size(rg)  ≤ N.
Effects: Constructs an inplace_vector with the elements of the range rg.
Complexity: Linear in ranges​::​distance(rg).

23.3.16.3 Capacity [inplace.vector.capacity]

static constexpr size_type capacity() noexcept; static constexpr size_type max_size() noexcept;
Returns: N.
constexpr void resize(size_type sz);
Preconditions: T is Cpp17DefaultInsertable into inplace_vector.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() default-inserted elements to the sequence.
Remarks: If an exception is thrown, there are no effects on *this.
constexpr void resize(size_type sz, const T& c);
Preconditions: T is Cpp17CopyInsertable into inplace_vector.
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() copies of c to the sequence.
Remarks: If an exception is thrown, there are no effects on *this.
static constexpr void reserve(size_type n);
Effects: None.
Throws: bad_alloc if n > capacity() is true.
static constexpr void shrink_to_fit() noexcept;
Effects: None.

23.3.16.4 Data [inplace.vector.data]

constexpr T* data() noexcept; constexpr const T* data() const noexcept;
Returns: A pointer such that [data(), data() + size()) is a valid range.
For a non-empty inplace_vector, data() == addressof(front()) is true.
Complexity: Constant time.

23.3.16.5 Modifiers [inplace.vector.modifiers]

constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last); template<container-compatible-range<T> R> constexpr iterator insert_range(const_iterator position, R&& rg); constexpr iterator insert(const_iterator position, initializer_list<T> il); template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); template<container-compatible-range<T> R> constexpr void append_range(R&& rg);
Let n be the value of size() before this call for the append_range overload, and distance(begin, position) otherwise.
Complexity: Linear in the number of elements inserted plus the distance to the end of the vector.
Remarks: If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation, there are no effects.
Otherwise, if an exception is thrown, then size()  ≥ n and elements in the range begin() + [0, n) are not modified.
constexpr reference push_back(const T& x); constexpr reference push_back(T&& x); template<class... Args> constexpr reference emplace_back(Args&&... args);
Returns: back().
Throws: bad_alloc or any exception thrown by the initialization of the inserted element.
Complexity: Constant.
Remarks: If an exception is thrown, there are no effects on *this.
template<class... Args> constexpr optional<reference> try_emplace_back(Args&&... args); constexpr optional<reference> try_push_back(const T& x); constexpr optional<reference> try_push_back(T&& x);
Let vals denote a pack:
  • std​::​forward<Args>(args)... for the first overload,
  • x for the second overload,
  • std​::​move(x) for the third overload.
Preconditions: value_type is Cpp17EmplaceConstructible into inplace_vector from vals....
Effects: If size() < capacity() is true, appends an object of type T direct-non-list-initialized with vals....
Otherwise, there are no effects.
Returns: nullopt if size() == capacity() is true, otherwise optional<reference>(in_place, back()).
Throws: Nothing unless an exception is thrown by the initialization of the inserted element.
Complexity: Constant.
Remarks: If an exception is thrown, there are no effects on *this.
template<class... Args> constexpr reference unchecked_emplace_back(Args&&... args);
Preconditions: size() < capacity() is true.
Effects: Equivalent to: return *try_emplace_back(std​::​forward<Args>(args)...);
constexpr reference unchecked_push_back(const T& x); constexpr reference unchecked_push_back(T&& x);
Preconditions: size() < capacity() is true.
Effects: Equivalent to: return *try_push_back(std​::​forward<decltype(x)>(x));
constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_back();
Effects: Invalidates iterators and references at or after the point of the erase.
Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.
Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the assignment operator of T is called the number of times equal to the number of elements after the erased elements.
constexpr void swap(inplace_vector& x) noexcept( N == 0 || (is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<T>));
Preconditions: T meets the Cpp17MoveConstructible requirements.
Let M be min(size(), x.size()).
For each non-negative integer , (*this)[n] is swappable with x[n] ([swappable.requirements]).
Effects: Exchanges the contents of *this and x.

23.3.16.6 Erasure [inplace.vector.erasure]

template<class T, size_t N, class U = T> constexpr size_t erase(inplace_vector<T, N>& c, const U& value);
Effects: Equivalent to: auto it = remove(c.begin(), c.end(), value); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;
template<class T, size_t N, class Predicate> constexpr size_t erase_if(inplace_vector<T, N>& c, Predicate pred);
Effects: Equivalent to: auto it = remove_if(c.begin(), c.end(), pred); auto r = distance(it, c.end()); c.erase(it, c.end()); return r;

23.4 Associative containers [associative]

23.4.1 General [associative.general]

The header <map> defines the class templates map and multimap; the header <set> defines the class templates set and multiset.
The following exposition-only alias templates may appear in deduction guides for associative containers: template<class InputIterator> using iter-value-type = iterator_traits<InputIterator>::value_type; // exposition only template<class InputIterator> using iter-key-type = remove_cvref_t< tuple_element_t<0, iter-value-type<InputIterator>>>; // exposition only template<class InputIterator> using iter-mapped-type = remove_cvref_t< tuple_element_t<1, iter-value-type<InputIterator>>>; // exposition only template<class InputIterator> using iter-to-alloc-type = pair< const iter-key-type<InputIterator>, iter-mapped-type<InputIterator>>; // exposition only template<ranges::input_range Range> using range-key-type = remove_cvref_t<tuple_element_t<0, ranges::range_value_t<Range>>>; // exposition only template<ranges::input_range Range> using range-mapped-type = remove_cvref_t<tuple_element_t<1, ranges::range_value_t<Range>>>; // exposition only template<ranges::input_range Range> using range-to-alloc-type = pair<const range-key-type<Range>, range-mapped-type<Range>>; // exposition only

23.4.2 Header <map> synopsis [associative.map.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [map], class template map template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class map; template<class Key, class T, class Compare, class Allocator> constexpr bool operator==(const map<Key, T, Compare, Allocator>& x, const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> constexpr synth-three-way-result<pair<const Key, T>> operator<=>(const map<Key, T, Compare, Allocator>& x, const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> constexpr void swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // [map.erasure], erasure for map template<class Key, class T, class Compare, class Allocator, class Predicate> constexpr typename map<Key, T, Compare, Allocator>::size_type erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // [multimap], class template multimap template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class multimap; template<class Key, class T, class Compare, class Allocator> constexpr bool operator==(const multimap<Key, T, Compare, Allocator>& x, const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> constexpr synth-three-way-result<pair<const Key, T>> operator<=>(const multimap<Key, T, Compare, Allocator>& x, const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> constexpr void swap(multimap<Key, T, Compare, Allocator>& x, multimap<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // [multimap.erasure], erasure for multimap template<class Key, class T, class Compare, class Allocator, class Predicate> constexpr typename multimap<Key, T, Compare, Allocator>::size_type erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); namespace pmr { template<class Key, class T, class Compare = less<Key>> using map = std::map<Key, T, Compare, polymorphic_allocator<pair<const Key, T>>>; template<class Key, class T, class Compare = less<Key>> using multimap = std::multimap<Key, T, Compare, polymorphic_allocator<pair<const Key, T>>>; } }

23.4.3 Class template map [map]

23.4.3.1 Overview [map.overview]

A map is an associative container that supports unique keys (i.e., contains at most one of each key value) and provides for fast retrieval of values of another type T based on the keys.
The map class supports bidirectional iterators.
A map meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of an associative container ([associative.reqmts]).
A map also provides most operations described in [associative.reqmts] for unique keys.
This means that a map supports the a_uniq operations in [associative.reqmts] but not the a_eq operations.
For a map<Key,T> the key_type is Key and the value_type is pair<const Key,T>.
Descriptions are provided here only for operations on map that are not described in one of those tables or for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class map { public: // types using key_type = Key; using mapped_type = T; using value_type = pair<const Key, T>; using key_compare = Compare; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = unspecified; using insert_return_type = insert-return-type<iterator, node_type>; class value_compare { protected: Compare comp; constexpr value_compare(Compare c) : comp(c) {} public: constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // [map.cons], construct/copy/destroy constexpr map() : map(Compare()) { } constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> constexpr map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<container-compatible-range<value_type> R> constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr map(const map& x); constexpr map(map&& x); constexpr explicit map(const Allocator&); constexpr map(const map&, const type_identity_t<Allocator>&); constexpr map(map&&, const type_identity_t<Allocator>&); constexpr map(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator> constexpr map(InputIterator first, InputIterator last, const Allocator& a) : map(first, last, Compare(), a) { } template<container-compatible-range<value_type> R> constexpr map(from_range_t, R&& rg, const Allocator& a) : map(from_range, std::forward<R>(rg), Compare(), a) { } constexpr map(initializer_list<value_type> il, const Allocator& a) : map(il, Compare(), a) { } constexpr ~map(); constexpr map& operator=(const map& x); constexpr map& operator=(map&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr map& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [map.access], element access constexpr mapped_type& operator[](const key_type& x); constexpr mapped_type& operator[](key_type&& x); template<class K> constexpr mapped_type& operator[](K&& x); constexpr mapped_type& at(const key_type& x); constexpr const mapped_type& at(const key_type& x) const; template<class K> constexpr mapped_type& at(const K& x); template<class K> constexpr const mapped_type& at(const K& x) const; constexpr optional<mapped_type&> lookup(const key_type& x); constexpr optional<const mapped_type&> lookup(const key_type& x) const; template<class K> constexpr optional<mapped_type&> lookup(const K& x); template<class K> constexpr optional<const mapped_type&> lookup(const K& x) const; // [map.modifiers], modifiers template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args> constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair<iterator, bool> insert(const value_type& x); constexpr pair<iterator, bool> insert(value_type&& x); template<class P> constexpr pair<iterator, bool> insert(P&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class P> constexpr iterator insert(const_iterator position, P&&); template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<container-compatible-range<value_type> R> constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); template<class... Args> constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class K, class... Args> constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template<class K, class... Args> constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template<class M> constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class K, class M> constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template<class K, class M> constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); constexpr iterator erase(iterator position); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(map&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2> constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2> constexpr void merge(map<Key, T, C2, Allocator>&& source); template<class C2> constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2> constexpr void merge(multimap<Key, T, C2, Allocator>&& source); // observers constexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // map operations constexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K> constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>, class Allocator = allocator<iter-to-alloc-type<InputIterator>>> map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare, Allocator>; template<ranges::input_range R, class Compare = less<range-key-type<R>>, class Allocator = allocator<range-to-alloc-type<R>>> map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> map(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator()) -> map<Key, T, Compare, Allocator>; template<class InputIterator, class Allocator> map(InputIterator, InputIterator, Allocator) -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, less<iter-key-type<InputIterator>>, Allocator>; template<ranges::input_range R, class Allocator> map(from_range_t, R&&, Allocator) -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; template<class Key, class T, class Allocator> map(initializer_list<pair<Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; }

23.4.3.2 Constructors, copy, and assignment [map.cons]

constexpr explicit map(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty map using the specified comparison object and allocator.
Complexity: Constant.
template<class InputIterator> constexpr map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty map using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted with respect to comp and otherwise , where N is last - first.
template<container-compatible-range<value_type> R> constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty map using the specified comparison object and allocator, and inserts elements from the range rg.
Complexity: Linear in N if rg is already sorted with respect to comp and otherwise , where N is ranges​::​distance(rg).

23.4.3.3 Element access [map.access]

constexpr mapped_type& operator[](const key_type& x);
Effects: Equivalent to: return try_emplace(x).first->second;
constexpr mapped_type& operator[](key_type&& x);
Effects: Equivalent to: return try_emplace(std​::​move(x)).first->second;
template<class K> constexpr mapped_type& operator[](K&& x);
Constraints: The qualified-id Compare​::​is_transparent is valid and denotes a type.
Effects: Equivalent to: return try_emplace(std​::​forward<K>(x)).first->second;
constexpr mapped_type& at(const key_type& x); constexpr const mapped_type& at(const key_type& x) const;
Returns: A reference to the mapped_type corresponding to x in *this.
Throws: An exception object of type out_of_range if no such element is present.
Complexity: Logarithmic.
template<class K> constexpr mapped_type& at(const K& x); template<class K> constexpr const mapped_type& at(const K& x) const;
Constraints: The qualified-id Compare​::​is_transparent is valid and denotes a type.
Preconditions: The expression find(x) is well-formed and has well-defined behavior.
Returns: A reference to find(x)->second.
Throws: An exception object of type out_of_range if find(x) == end() is true.
Complexity: Logarithmic.
constexpr optional<mapped_type&> lookup(const key_type& x); constexpr optional<const mapped_type&> lookup(const key_type& x) const; template<class K> constexpr optional<mapped_type&> lookup(const K& x); template<class K> constexpr optional<const mapped_type&> lookup(const K& x) const;
Constraints: For the third and fourth overloads, the qualified-id Compare​::​is_transparent is valid and denotes a type.
Preconditions: The expression find(x) is well-formed and has well-defined behavior.
Returns: find(x)->second if contains(x) is true, otherwise nullopt.
Complexity: Logarithmic.

23.4.3.4 Modifiers [map.modifiers]

template<class P> constexpr pair<iterator, bool> insert(P&& x); template<class P> constexpr iterator insert(const_iterator position, P&& x);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects: The first form is equivalent to return emplace(std​::​forward<P>(x)).
The second form is equivalent to return emplace_hint(position, std​::​forward<P>(x)).
template<class... Args> constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
Preconditions: value_type is Cpp17EmplaceConstructible into map from piecewise_construct, forward_as_tuple(k), forward_as_tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k), forward_as_tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.
template<class... Args> constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
Preconditions: value_type is Cpp17EmplaceConstructible into map from piecewise_construct, forward_as_tuple(std​::​move(k)), forward_as_tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(std​::​move(k)), forward_as_tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.
template<class K, class... Args> constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class K, class... Args> constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
Constraints: The qualified-id Compare​::​is_transparent is valid and denotes a type.
For the first overload, is_convertible_v<K&&, const_iterator> and is_convertible_v<K&&, iterator> are both false.
Preconditions: value_type is Cpp17EmplaceConstructible into map from piecewise_construct, forward_as_tuple(std​::​forward<K>(k)), forward_as_tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise, let r be equal_range(k).
Constructs an object u of type value_type with piecewise_construct, forward_as_tuple(std​::​forward<K>(k)), forward_as_tuple(std​::​forward<Args>(args)...).
If equal_range(u.first) == r is false, the behavior is undefined.
Inserts u into *this.
Returns: For the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.
template<class M> constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
Mandates: is_assignable_v<mapped_type&, M&&> is true.
Preconditions: value_type is Cpp17EmplaceConstructible into map from k, std​::​forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_type constructed with k, std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.
template<class M> constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
Mandates: is_assignable_v<mapped_type&, M&&> is true.
Preconditions: value_type is Cpp17EmplaceConstructible into map from std​::​move(k), std​::​forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_type constructed with std​::​​move(k), std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.
template<class K, class M> constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class K, class M> constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
Constraints: The qualified-id Compare​::​is_transparent is valid and denotes a type.
Mandates: is_assignable_v<mapped_type&, M&&> is true.
Preconditions: value_type is Cpp17EmplaceConstructible into map from std​::​forward<K>(k), std​::​
forward<M>(obj)
.
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>
(obj)
to e.second.
Otherwise, let r be equal_range(k).
Constructs an object u of type value_type with std​::​forward<K>(k), std​::​forward<M>(obj).
If equal_range(u.first) == r is false, the behavior is undefined.
Inserts u into *this.
Returns: For the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_hint, respectively.

23.4.3.5 Erasure [map.erasure]

template<class Key, class T, class Compare, class Allocator, class Predicate> typename map<Key, T, Compare, Allocator>::size_type constexpr erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size();

23.4.4 Class template multimap [multimap]

23.4.4.1 Overview [multimap.overview]

A multimap is an associative container that supports equivalent keys (i.e., possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type T based on the keys.
The multimap class supports bidirectional iterators.
A multimap meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of an associative container ([associative.reqmts]).
A multimap also provides most operations described in [associative.reqmts] for equal keys.
This means that a multimap supports the a_eq operations in [associative.reqmts] but not the a_uniq operations.
For a multimap<Key,T> the key_type is Key and the value_type is pair<const Key,T>.
Descriptions are provided here only for operations on multimap that are not described in one of those tables or for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class multimap { public: // types using key_type = Key; using mapped_type = T; using value_type = pair<const Key, T>; using key_compare = Compare; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = unspecified; class value_compare { protected: Compare comp; constexpr value_compare(Compare c) : comp(c) { } public: constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // [multimap.cons], construct/copy/destroy constexpr multimap() : multimap(Compare()) { } constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> constexpr multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<container-compatible-range<value_type> R> constexpr multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr multimap(const multimap& x); constexpr multimap(multimap&& x); constexpr explicit multimap(const Allocator&); constexpr multimap(const multimap&, const type_identity_t<Allocator>&); constexpr multimap(multimap&&, const type_identity_t<Allocator>&); constexpr multimap(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator> constexpr multimap(InputIterator first, InputIterator last, const Allocator& a) : multimap(first, last, Compare(), a) { } template<container-compatible-range<value_type> R> constexpr multimap(from_range_t, R&& rg, const Allocator& a) : multimap(from_range, std::forward<R>(rg), Compare(), a) { } constexpr multimap(initializer_list<value_type> il, const Allocator& a) : multimap(il, Compare(), a) { } constexpr ~multimap(); constexpr multimap& operator=(const multimap& x); constexpr multimap& operator=(multimap&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr multimap& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [multimap.modifiers], modifiers template<class... Args> constexpr iterator emplace(Args&&... args); template<class... Args> constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr iterator insert(const value_type& x); constexpr iterator insert(value_type&& x); template<class P> constexpr iterator insert(P&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class P> constexpr iterator insert(const_iterator position, P&& x); template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<container-compatible-range<value_type> R> constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> node_type extract(K&& x); constexpr iterator insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(multimap&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2> constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2> constexpr void merge(multimap<Key, T, C2, Allocator>&& source); template<class C2> constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2> constexpr void merge(map<Key, T, C2, Allocator>&& source); // observers constexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // map operations constexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K> constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>, class Allocator = allocator<iter-to-alloc-type<InputIterator>>> multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare, Allocator>; template<ranges::input_range R, class Compare = less<range-key-type<R>>, class Allocator = allocator<range-to-alloc-type<R>>> multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> multimap(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator()) -> multimap<Key, T, Compare, Allocator>; template<class InputIterator, class Allocator> multimap(InputIterator, InputIterator, Allocator) -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, less<iter-key-type<InputIterator>>, Allocator>; template<ranges::input_range R, class Allocator> multimap(from_range_t, R&&, Allocator) -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; template<class Key, class T, class Allocator> multimap(initializer_list<pair<Key, T>>, Allocator) -> multimap<Key, T, less<Key>, Allocator>; }

23.4.4.2 Constructors [multimap.cons]

constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty multimap using the specified comparison object and allocator.
Complexity: Constant.
template<class InputIterator> constexpr multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty multimap using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted with respect to comp and otherwise , where N is last - first.
template<container-compatible-range<value_type> R> constexpr multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty multimap using the specified comparison object and allocator, and inserts elements from the range rg.
Complexity: Linear in N if rg is already sorted with respect to comp and otherwise , where N is ranges​::​distance(rg).

23.4.4.3 Modifiers [multimap.modifiers]

template<class P> constexpr iterator insert(P&& x); template<class P> constexpr iterator insert(const_iterator position, P&& x);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects: The first form is equivalent to return emplace(std​::​forward<P>(x)).
The second form is equivalent to return emplace_hint(position, std​::​forward<P>(x)).

23.4.4.4 Erasure [multimap.erasure]

template<class Key, class T, class Compare, class Allocator, class Predicate> typename multimap<Key, T, Compare, Allocator>::size_type constexpr erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size();

23.4.5 Header <set> synopsis [associative.set.syn]

#include <compare> // see [compare.syn] #include <initializer_list> // see [initializer.list.syn] namespace std { // [set], class template set template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class set; template<class Key, class Compare, class Allocator> constexpr bool operator==(const set<Key, Compare, Allocator>& x, const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> constexpr synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x, const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> constexpr void swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // [set.erasure], erasure for set template<class Key, class Compare, class Allocator, class Predicate> constexpr typename set<Key, Compare, Allocator>::size_type erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // [multiset], class template multiset template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class multiset; template<class Key, class Compare, class Allocator> constexpr bool operator==(const multiset<Key, Compare, Allocator>& x, const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> constexpr synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x, const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> constexpr void swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // [multiset.erasure], erasure for multiset template<class Key, class Compare, class Allocator, class Predicate> constexpr typename multiset<Key, Compare, Allocator>::size_type erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); namespace pmr { template<class Key, class Compare = less<Key>> using set = std::set<Key, Compare, polymorphic_allocator<Key>>; template<class Key, class Compare = less<Key>> using multiset = std::multiset<Key, Compare, polymorphic_allocator<Key>>; } }

23.4.6 Class template set [set]

23.4.6.1 Overview [set.overview]

A set is an associative container that supports unique keys (i.e., contains at most one of each key value) and provides for fast retrieval of the keys themselves.
The set class supports bidirectional iterators.
A set meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of an associative container ([associative.reqmts]).
A set also provides most operations described in [associative.reqmts] for unique keys.
This means that a set supports the a_uniq operations in [associative.reqmts] but not the a_eq operations.
For a set<Key> both the key_type and value_type are Key.
Descriptions are provided here only for operations on set that are not described in one of these tables and for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class set { public: // types using key_type = Key; using key_compare = Compare; using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = unspecified; using insert_return_type = insert-return-type<iterator, node_type>; // [set.cons], construct/copy/destroy constexpr set() : set(Compare()) { } constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> constexpr set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<container-compatible-range<value_type> R> constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr set(const set& x); constexpr set(set&& x); constexpr explicit set(const Allocator&); constexpr set(const set&, const type_identity_t<Allocator>&); constexpr set(set&&, const type_identity_t<Allocator>&); constexpr set(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator> constexpr set(InputIterator first, InputIterator last, const Allocator& a) : set(first, last, Compare(), a) { } template<container-compatible-range<value_type> R> constexpr set(from_range_t, R&& rg, const Allocator& a) : set(from_range, std::forward<R>(rg), Compare(), a) { } constexpr set(initializer_list<value_type> il, const Allocator& a) : set(il, Compare(), a) { } constexpr ~set(); constexpr set& operator=(const set& x); constexpr set& operator=(set&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr set& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iterators constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacity constexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [set.modifiers], modifiers template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args> constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair<iterator,bool> insert(const value_type& x); constexpr pair<iterator,bool> insert(value_type&& x); template<class K> constexpr pair<iterator, bool> insert(K&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class K> constexpr iterator insert(const_iterator position, K&& x); template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<container-compatible-range<value_type> R> constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position) requires (!same_as<iterator, const_iterator>); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(set&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2> constexpr void merge(set<Key, C2, Allocator>& source); template<class C2> constexpr void merge(set<Key, C2, Allocator>&& source); template<class C2> constexpr void merge(multiset<Key, C2, Allocator>& source); template<class C2> constexpr void merge(multiset<Key, C2, Allocator>&& source); // observers constexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // set operations constexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K> constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>, class Allocator = allocator<iter-value-type<InputIterator>>> set(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) -> set<iter-value-type<InputIterator>, Compare, Allocator>; template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>, class Allocator = allocator<ranges::range_value_t<R>>> set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) -> set<ranges::range_value_t<R>, Compare, Allocator>; template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator()) -> set<Key, Compare, Allocator>; template<class InputIterator, class Allocator> set(InputIterator, InputIterator, Allocator) -> set<iter-value-type<InputIterator>, less<iter-value-type<InputIterator>>, Allocator>; template<ranges::input_range R, class Allocator> set(from_range_t, R&&, Allocator) -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; template<class Key, class Allocator> set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; }

23.4.6.2 Constructors, copy, and assignment [set.cons]

constexpr explicit set(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty set using the specified comparison object and allocator.
Complexity: Constant.
template<class InputIterator> constexpr set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty set using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted with respect to comp and otherwise , where N is last - first.
template<container-compatible-range<value_type> R> constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty set using the specified comparison object and allocator, and inserts elements from the range rg.
Complexity: Linear in N if rg is already sorted with respect to comp and otherwise , where N is ranges​::​distance(rg).

23.4.6.3 Erasure [set.erasure]

template<class Key, class Compare, class Allocator, class Predicate> constexpr typename set<Key, Compare, Allocator>::size_type erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
Effects: Equivalent to: auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size();

23.4.6.4 Modifiers [set.modifiers]

template<class K> constexpr pair<iterator, bool> insert(K&& x); template<class K> constexpr iterator insert(const_iterator hint, K&& x);
Constraints: The qualified-id Compare​::​is_transparent is valid and denotes a type.
For the second overload, is_convertible_v<K&&, const_iterator> and is_convertible_v<K&&, iterator> are both false.
Preconditions: value_type is Cpp17EmplaceConstructible into set from std​::​forward<K>(x).
Effects: If the set already contains an element that is equivalent to x, there is no effect.
Otherwise, let r be equal_range(x).
Constructs an object u of type value_type with std​::​forward<K>(x).
If equal_range(u) == r is false, the behavior is undefined.
Inserts u into *this.
Returns: For the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the set element that is equivalent to x.
Complexity: Logarithmic.

23.4.7 Class template multiset [multiset]

23.4.7.1 Overview [multiset.overview]

A multiset is an associative container that supports equivalent keys (i.e., possibly contains multiple copies of the same key value) and provides for fast retrieval of the keys themselves.
The multiset class supports bidirectional iterators.
A multiset meets all of the requirements of a container ([container.reqmts]), of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of an associative container ([associative.reqmts]).
multiset also provides most operations described in [associative.reqmts] for duplicate keys.
This means that a multiset supports the a_eq operations in [associative.reqmts] but not the a_uniq operations.
For a multiset<Key> both the key_type and value_type are Key.
Descriptions are provided here only for operations on multiset that are not described in one of these tables and for operations where there is additional semantic information.
The types iterator and const_iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std { template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class multiset { public: // types using key_type = Key; using key_compare = Compare; using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; using pointer = allocator_traits<Allocator>::pointer; using const_pointer = allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = implementation-defined; // see [container.requirements] using difference_type = implementation-defined; // see [container.requirements] using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements] using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator&