From Jason Turner

[containers]

Large diff (469.0 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp6zoy__18/{from.md → to.md} +8500 -731
tmp/tmp6zoy__18/{from.md → to.md} RENAMED
@@ -15,17 +15,17 @@ for sequence containers and associative containers, as summarized in
15
  | -------------------------- | -------------------------------- | ------------------------------------------------------------ |
16
  | [[container.requirements]] | Requirements | |
17
  | [[sequences]] | Sequence containers | `<array>`, `<deque>`, `<forward_list>`, `<list>`, `<vector>` |
18
  | [[associative]] | Associative containers | `<map>`, `<set>` |
19
  | [[unord]] | Unordered associative containers | `<unordered_map>`, `<unordered_set>` |
20
- | [[container.adaptors]] | Container adaptors | `<queue>`, `<stack>` |
21
- | [[views]] | Views | `<span>` |
22
 
23
 
24
- ## Container requirements <a id="container.requirements">[[container.requirements]]</a>
25
 
26
- ### General container requirements <a id="container.requirements.general">[[container.requirements.general]]</a>
27
 
28
  Containers are objects that store other objects. They control allocation
29
  and deallocation of these objects through constructors, destructors,
30
  insert and erase operations.
31
 
@@ -34,47 +34,299 @@ terms of the number of operations on the contained objects.
34
 
35
  [*Example 1*: The copy constructor of type `vector<vector<int>>` has
36
  linear complexity, even though the complexity of copying each contained
37
  `vector<int>` is itself linear. — *end example*]
38
 
39
- For the components affected by this subclause that declare an
40
- `allocator_type`, objects stored in these components shall be
41
- constructed using the function
42
  `allocator_traits<allocator_type>::rebind_traits<U>::{}construct` and
43
- destroyed using the function
44
  `allocator_traits<allocator_type>::rebind_traits<U>::{}destroy`
45
  [[allocator.traits.members]], where `U` is either
46
  `allocator_type::value_type` or an internal type used by the container.
47
  These functions are called only for the container’s element type, not
48
  for internal types used by the container.
49
 
50
- [*Note 1*: This means, for example, that a node-based container might
51
  need to construct nodes containing aligned buffers and call `construct`
52
  to place the element into the buffer. — *end note*]
53
 
54
- In Tables  [[tab:container.req]], [[tab:container.rev.req]], and
55
- [[tab:container.opt]] `X` denotes a container class containing objects
56
- of type `T`, `a` and `b` denote values of type `X`, `i` and `j` denote
57
- values of type (possibly const) `X::iterator`, `u` denotes an
58
- identifier, `r` denotes a non-const value of type `X`, and `rv` denotes
59
- a non-const rvalue of type `X`.
60
 
61
- Those entries marked “(Note A)” or “(Note B)” have linear complexity for
62
- `array` and have constant complexity for all other standard containers.
63
 
64
- [*Note 2*: The algorithm `equal()` is defined in
65
- [[algorithms]]. — *end note*]
66
 
67
- The member function `size()` returns the number of elements in the
68
- container. The number of elements is defined by the rules of
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  constructors, inserts, and erases.
70
 
71
- `begin()`
 
 
72
 
73
- returns an iterator referring to the first element in the container.
74
- `end()` returns an iterator which is the past-the-end value for the
75
- container. If the container is empty, then `begin() == end()`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  In the expressions
78
 
79
  ``` cpp
80
  i == j
@@ -90,14 +342,14 @@ i - j
90
  where `i` and `j` denote objects of a container’s `iterator` type,
91
  either or both may be replaced by an object of the container’s
92
  `const_iterator` type referring to the same element with no change in
93
  semantics.
94
 
95
- Unless otherwise specified, all containers defined in this clause obtain
96
  memory using an allocator (see  [[allocator.requirements]]).
97
 
98
- [*Note 3*: In particular, containers and iterators do not store
99
  references to allocated elements other than through the allocator’s
100
  pointer type, i.e., as objects of type `P` or
101
  `pointer_traits<P>::template rebind<unspecified>`, where `P` is
102
  `allocator_traits<allocator_type>::pointer`. — *end note*]
103
 
@@ -108,72 +360,69 @@ on the allocator belonging to the container being copied. Move
108
  constructors obtain an allocator by move construction from the allocator
109
  belonging to the container being moved. Such move construction of the
110
  allocator shall not exit via an exception. All other constructors for
111
  these container types take a `const allocator_type&` argument.
112
 
113
- [*Note 4*: If an invocation of a constructor uses the default value of
114
  an optional allocator argument, then the allocator type must support
115
  value-initialization. — *end note*]
116
 
117
  A copy of this allocator is used for any memory allocation and element
118
  construction performed, by these constructors and by all member
119
  functions, during the lifetime of each container object or until the
120
  allocator is replaced. The allocator may be replaced only via assignment
121
  or `swap()`. Allocator replacement is performed by copy assignment, move
122
  assignment, or swapping of the allocator only if
123
- `allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value`,
124
- `allocator_traits<allocator_type>::propagate_on_container_move_assignment::value`,
 
125
  or
126
- `allocator_traits<allocator_type>::propagate_on_container_swap::value`
 
127
  is `true` within the implementation of the corresponding container
128
  operation. In all container types defined in this Clause, the member
129
  `get_allocator()` returns a copy of the allocator used to construct the
130
  container or, if that allocator has been replaced, a copy of the most
131
  recent replacement.
132
 
133
  The expression `a.swap(b)`, for containers `a` and `b` of a standard
134
  container type other than `array`, shall exchange the values of `a` and
135
  `b` without invoking any move, copy, or swap operations on the
136
- individual container elements. Lvalues of any `Compare`, `Pred`, or
137
- `Hash` types belonging to `a` and `b` shall be swappable and shall be
138
- exchanged by calling `swap` as described in  [[swappable.requirements]].
139
- If
140
  `allocator_traits<allocator_type>::propagate_on_container_swap::value`
141
- is `true`, then lvalues of type `allocator_type` shall be swappable and
142
- the allocators of `a` and `b` shall also be exchanged by calling `swap`
143
- as described in  [[swappable.requirements]]. Otherwise, the allocators
144
- shall not be swapped, and the behavior is undefined unless
145
- `a.get_allocator() == b.get_allocator()`. Every iterator referring to an
146
- element in one container before the swap shall refer to the same element
147
- in the other container after the swap. It is unspecified whether an
148
- iterator with value `a.end()` before the swap will have value `b.end()`
149
- after the swap.
150
-
151
- If the iterator type of a container belongs to the bidirectional or
152
- random access iterator categories [[iterator.requirements]], the
153
- container is called *reversible* and meets the additional requirements
154
- in [[container.rev.req]].
155
 
156
  Unless otherwise specified (see  [[associative.reqmts.except]],
157
  [[unord.req.except]], [[deque.modifiers]], and [[vector.modifiers]]) all
158
  container types defined in this Clause meet the following additional
159
  requirements:
160
 
161
- - if an exception is thrown by an `insert()` or `emplace()` function
162
  while inserting a single element, that function has no effects.
163
- - if an exception is thrown by a `push_back()`, `push_front()`,
164
  `emplace_back()`, or `emplace_front()` function, that function has no
165
  effects.
166
- - no `erase()`, `clear()`, `pop_back()` or `pop_front()` function throws
167
  an exception.
168
- - no copy constructor or assignment operator of a returned iterator
169
  throws an exception.
170
- - no `swap()` function throws an exception.
171
- - no `swap()` function invalidates any references, pointers, or
172
  iterators referring to the elements of the containers being swapped.
173
- \[*Note 5*: The `end()` iterator does not refer to any element, so it
174
- may be invalidated. — *end note*]
175
 
176
  Unless otherwise specified (either explicitly or by defining a function
177
  in terms of other functions), invoking a container member function or
178
  passing a container as an argument to a library function shall not
179
  invalidate iterators to, or change the values of, objects within that
@@ -182,33 +431,129 @@ container.
182
  A *contiguous container* is a container whose member types `iterator`
183
  and `const_iterator` meet the *Cpp17RandomAccessIterator* requirements
184
  [[random.access.iterators]] and model `contiguous_iterator`
185
  [[iterator.concept.contiguous]].
186
 
187
- [[container.opt]] lists operations that are provided for some types of
188
- containers but not others. Those containers for which the listed
189
- operations are provided shall implement the semantics described in
190
- [[container.opt]] unless otherwise stated. If the iterators passed to
191
- `lexicographical_compare_three_way` meet the constexpr iterator
192
- requirements [[iterator.requirements.general]] then the operations
193
- described in [[container.opt]] are implemented by constexpr functions.
194
-
195
- [*Note 6*: The algorithm `lexicographical_compare_three_way` is defined
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  in [[algorithms]]. — *end note*]
197
 
198
- All of the containers defined in this Clause and in  [[basic.string]]
199
- except `array` meet the additional requirements of an allocator-aware
200
- container, as described in [[container.alloc.req]].
 
 
 
 
201
 
202
  Given an allocator type `A` and given a container type `X` having a
203
  `value_type` identical to `T` and an `allocator_type` identical to
204
  `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
205
- `A`, a pointer `p` of type `T*`, an expression `v` of type (possibly
206
- `const`) `T`, and an rvalue `rv` of type `T`, the following terms are
207
- defined. If `X` is not allocator-aware, the terms below are defined as
208
- if `A` were `allocator<T>` no allocator object needs to be created and
209
- user specializations of `allocator<T>` are not instantiated:
 
210
 
211
  - `T` is **Cpp17DefaultInsertable* into `X`* means that the following
212
  expression is well-formed:
213
  ``` cpp
214
  allocator_traits<A>::construct(m, p)
@@ -228,11 +573,11 @@ user specializations of `allocator<T>` are not instantiated:
228
  ```
229
 
230
  and its evaluation causes the following postcondition to hold: The
231
  value of `*p` is equivalent to the value of `rv` before the
232
  evaluation.
233
- \[*Note 7*: `rv` remains a valid object. Its state is
234
  unspecified — *end note*]
235
  - `T` is **Cpp17CopyInsertable* into `X`* means that, in addition to `T`
236
  being *Cpp17MoveInsertable* into `X`, the following expression is
237
  well-formed:
238
  ``` cpp
@@ -251,35 +596,138 @@ user specializations of `allocator<T>` are not instantiated:
251
  is well-formed:
252
  ``` cpp
253
  allocator_traits<A>::destroy(m, p)
254
  ```
255
 
256
- [*Note 8*: A container calls
257
  `allocator_traits<A>::construct(m, p, args)` to construct an element at
258
  `p` using `args`, with `m == get_allocator()`. The default `construct`
259
  in `allocator` will call `::new((void*)p) T(args)`, but specialized
260
- allocators may choose a different definition. — *end note*]
261
-
262
- In [[container.alloc.req]], `X` denotes an allocator-aware container
263
- class with a `value_type` of `T` using allocator of type `A`, `u`
264
- denotes a variable, `a` and `b` denote non-const lvalues of type `X`,
265
- `t` denotes an lvalue or a const rvalue of type `X`, `rv` denotes a
266
- non-const rvalue of type `X`, and `m` is a value of type `A`.
267
-
268
- The behavior of certain container member functions and deduction guides
269
- depends on whether types qualify as input iterators or allocators. The
270
- extent to which an implementation determines that a type cannot be an
271
- input iterator is unspecified, except that as a minimum integral types
272
- shall not qualify as input iterators. Likewise, the extent to which an
273
- implementation determines that a type cannot be an allocator is
274
- unspecified, except that as a minimum a type `A` shall not qualify as an
275
- allocator unless it meets both of the following conditions:
276
-
277
- - The *qualified-id* `A::value_type` is valid and denotes a type
278
- [[temp.deduct]].
279
- - The expression `declval<A&>().allocate(size_t{})` is well-formed when
280
- treated as an unevaluated operand.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
282
  ### Container data races <a id="container.requirements.dataraces">[[container.requirements.dataraces]]</a>
283
 
284
  For purposes of avoiding data races [[res.on.data.races]],
285
  implementations shall consider the following functions to be `const`:
@@ -293,84 +741,324 @@ elements in the same container, excepting `vector<bool>`, are modified
293
  concurrently.
294
 
295
  [*Note 1*: For a `vector<int> x` with a size greater than one,
296
  `x[1] = 5` and `*x.begin() = 10` can be executed concurrently without a
297
  data race, but `x[0] = 5` and `*x.begin() = 10` executed concurrently
298
- may result in a data race. As an exception to the general rule, for a
299
- `vector<bool> y`, `y[0] = true` may race with
300
  `y[1] = true`. — *end note*]
301
 
302
  ### Sequence containers <a id="sequence.reqmts">[[sequence.reqmts]]</a>
303
 
304
  A sequence container organizes a finite set of objects, all of the same
305
  type, into a strictly linear arrangement. The library provides four
306
  basic kinds of sequence containers: `vector`, `forward_list`, `list`,
307
  and `deque`. In addition, `array` is provided as a sequence container
308
  which provides limited sequence operations because it has a fixed number
309
  of elements. The library also provides container adaptors that make it
310
- easy to construct abstract data types, such as `stack`s or `queue`s, out
311
- of the basic sequence container kinds (or out of other kinds of sequence
312
- containers that the user might define).
 
313
 
314
  [*Note 1*: The sequence containers offer the programmer different
315
- complexity trade-offs and should be used accordingly. `vector` is the
316
- type of sequence container that should be used by default. `array`
317
- should be used when the container has a fixed size known during
318
- translation. `list` or `forward_list` should be used when there are
319
- frequent insertions and deletions from the middle of the sequence.
320
- `deque` is the data structure of choice when most insertions and
321
- deletions take place at the beginning or at the end of the sequence.
322
- When choosing a container, remember `vector` is best; leave a comment to
323
  explain if you choose from the rest! — *end note*]
324
 
325
- In Tables  [[tab:container.seq.req]] and [[tab:container.seq.opt]], `X`
326
- denotes a sequence container class, `a` denotes a value of type `X`
327
- containing elements of type `T`, `u` denotes the name of a variable
328
- being declared, `A` denotes `X::allocator_type` if the *qualified-id*
 
 
329
  `X::allocator_type` is valid and denotes a type [[temp.deduct]] and
330
- `allocator<T>` if it doesn’t, `i` and `j` denote iterators that meet the
331
- *Cpp17InputIterator* requirements and refer to elements implicitly
332
- convertible to `value_type`, `[i, j)` denotes a valid range, `il`
333
- designates an object of type `initializer_list<value_type>`, `n` denotes
334
- a value of type `X::size_type`, `p` denotes a valid constant iterator to
335
- `a`, `q` denotes a valid dereferenceable constant iterator to `a`,
336
- `[q1, q2)` denotes a valid range of constant iterators in `a`, `t`
337
- denotes an lvalue or a const rvalue of `X::value_type`, and `rv` denotes
338
- a non-const rvalue of `X::value_type`. `Args` denotes a template
339
- parameter pack; `args` denotes a function parameter pack with the
340
- pattern `Args&&`.
 
 
 
 
 
341
 
342
  The complexities of the expressions are sequence dependent.
343
 
344
- [*Note 2*: `args` may directly or indirectly refer to a value in
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  `a`. — *end note*]
346
 
347
- The iterator returned from `a.insert(p, t)` points to the copy of `t`
348
- inserted into `a`.
349
 
350
- The iterator returned from `a.insert(p, rv)` points to the copy of `rv`
351
- inserted into `a`.
 
352
 
353
- The iterator returned from `a.insert(p, n, t)` points to the copy of the
354
- first element inserted into `a`, or `p` if `n == 0`.
355
 
356
- The iterator returned from `a.insert(p, i, j)` points to the copy of the
357
- first element inserted into `a`, or `p` if `i == j`.
358
 
359
- The iterator returned from `a.insert(p, il)` points to the copy of the
360
- first element inserted into `a`, or `p` if `il` is empty.
361
 
362
- The iterator returned from `a.emplace(p, args)` points to the new
363
- element constructed from `args` into `a`.
364
 
365
- The iterator returned from `a.erase(q)` points to the element
366
- immediately following `q` prior to the element being erased. If no such
367
- element exists, `a.end()` is returned.
368
 
369
- The iterator returned by `a.erase(q1, q2)` points to the element pointed
370
- to by `q2` prior to any elements being erased. If no such element
371
- exists, `a.end()` is returned.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
 
373
  For every sequence container defined in this Clause and in [[strings]]:
374
 
375
  - If the constructor
376
  ``` cpp
@@ -404,17 +1092,202 @@ For every sequence container defined in this Clause and in [[strings]]:
404
  and a type that does not qualify as an input iterator is deduced for
405
  that parameter, or if it has an `Allocator` template parameter and a
406
  type that does not qualify as an allocator is deduced for that
407
  parameter.
408
 
409
- [[container.seq.opt]] lists operations that are provided for some types
410
- of sequence containers but not others. An implementation shall provide
411
- these operations for all container types shown in the “container”
412
- column, and shall implement them so as to take amortized constant time.
413
 
414
- The member function `at()` provides bounds-checked access to container
415
- elements. `at()` throws `out_of_range` if `n >= a.size()`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
  ### Node handles <a id="container.node">[[container.node]]</a>
418
 
419
  #### Overview <a id="container.node.overview">[[container.node.overview]]</a>
420
 
@@ -453,22 +1326,23 @@ operations involving node handles is undefined.
453
 
454
  ``` cpp
455
  template<unspecified>
456
  class node-handle {
457
  public:
458
- // These type declarations are described in Tables [tab:container.assoc.req] and [tab:container.hash.req].
459
  using value_type = see below; // not present for map containers
460
  using key_type = see below; // not present for set containers
461
  using mapped_type = see below; // not present for set containers
462
  using allocator_type = see below;
463
 
464
  private:
465
- using container_node_type = unspecified;
466
- using ator_traits = allocator_traits<allocator_type>;
467
 
468
- typename ator_traits::template rebind_traits<container_node_type>::pointer ptr_;
469
- optional<allocator_type> alloc_;
 
470
 
471
  public:
472
  // [container.node.cons], constructors, copy, and assignment
473
  constexpr node-handle() noexcept : ptr_(), alloc_() {}
474
  node-handle(node-handle&&) noexcept;
@@ -641,13 +1515,19 @@ The name *`insert-return-type`* is exposition only.
641
  special members specified above. It has no base classes or members other
642
  than those specified.
643
 
644
  ### Associative containers <a id="associative.reqmts">[[associative.reqmts]]</a>
645
 
 
 
646
  Associative containers provide fast retrieval of data based on keys. The
647
  library provides four basic kinds of associative containers: `set`,
648
- `multiset`, `map` and `multimap`.
 
 
 
 
649
 
650
  Each associative container is parameterized on `Key` and an ordering
651
  relation `Compare` that induces a strict weak ordering [[alg.sorting]]
652
  on elements of `Key`. In addition, `map` and `multimap` associate an
653
  arbitrary *mapped type* `T` with the `Key`. The object of type `Compare`
@@ -685,50 +1565,729 @@ type.
685
  [*Note 2*: `iterator` and `const_iterator` have identical semantics in
686
  this case, and `iterator` is convertible to `const_iterator`. Users can
687
  avoid violating the one-definition rule by always using `const_iterator`
688
  in their function parameter lists. — *end note*]
689
 
690
- The associative containers meet all the requirements of Allocator-aware
691
- containers [[container.requirements.general]], except that for `map` and
692
- `multimap`, the requirements placed on `value_type` in
693
- [[container.alloc.req]] apply instead to `key_type` and `mapped_type`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
 
695
  [*Note 3*: For example, in some cases `key_type` and `mapped_type` are
696
  required to be *Cpp17CopyAssignable* even though the associated
697
  `value_type`, `pair<const key_type, mapped_type>`, is not
698
  *Cpp17CopyAssignable*. — *end note*]
699
 
700
- In [[container.assoc.req]], `X` denotes an associative container class,
701
- `a` denotes a value of type `X`, `a2` denotes a value of a type with
702
- nodes compatible with type `X` ([[container.node.compat]]), `b` denotes
703
- a possibly `const` value of type `X`, `u` denotes the name of a variable
704
- being declared, `a_uniq` denotes a value of type `X` when `X` supports
705
- unique keys, `a_eq` denotes a value of type `X` when `X` supports
706
- multiple keys, `a_tran` denotes a possibly `const` value of type `X`
707
- when the *qualified-id* `X::key_compare::is_transparent` is valid and
708
- denotes a type [[temp.deduct]], `i` and `j` meet the
709
- *Cpp17InputIterator* requirements and refer to elements implicitly
710
- convertible to `value_type`, \[`i`, `j`) denotes a valid range, `p`
711
- denotes a valid constant iterator to `a`, `q` denotes a valid
712
- dereferenceable constant iterator to `a`, `r` denotes a valid
713
- dereferenceable iterator to `a`, `[q1, q2)` denotes a valid range of
714
- constant iterators in `a`, `il` designates an object of type
715
- `initializer_list<value_type>`, `t` denotes a value of type
716
- `X::value_type`, `k` denotes a value of type `X::key_type` and `c`
717
- denotes a possibly `const` value of type `X::key_compare`; `kl` is a
718
- value such that `a` is partitioned [[alg.sorting]] with respect to
719
- `c(r, kl)`, with `r` the key value of `e` and `e` in `a`; `ku` is a
720
- value such that `a` is partitioned with respect to `!c(ku, r)`; `ke` is
721
- a value such that `a` is partitioned with respect to `c(r, ke)` and
722
- `!c(ke, r)`, with `c(r, ke)` implying `!c(ke, r)`. `A` denotes the
723
- storage allocator used by `X`, if any, or `allocator<X::value_type>`
724
- otherwise, `m` denotes an allocator of a type convertible to `A`, and
725
- `nh` denotes a non-const rvalue of type `X::node_type`.
726
-
727
- The `insert` and `emplace` members shall not affect the validity of
728
- iterators and references to the container, and the `erase` members shall
729
- invalidate only iterators and references to the erased elements.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
730
 
731
  The `extract` members invalidate only iterators to the removed element;
732
  pointers and references to the removed element remain valid. However,
733
  accessing the element through such pointers and references while the
734
  element is owned by a `node_type` is undefined behavior. References and
@@ -760,13 +2319,18 @@ associative container is copied, through either a copy constructor or an
760
  assignment operator, the target container shall then use the comparison
761
  object from the container being copied, as if that comparison object had
762
  been passed to the target container in its constructor.
763
 
764
  The member function templates `find`, `count`, `contains`,
765
- `lower_bound`, `upper_bound`, and `equal_range` shall not participate in
766
- overload resolution unless the *qualified-id* `Compare::is_transparent`
767
- is valid and denotes a type [[temp.deduct]].
 
 
 
 
 
768
 
769
  A deduction guide for an associative container shall not participate in
770
  overload resolution if any of the following are true:
771
 
772
  - It has an `InputIterator` template parameter and a type that does not
@@ -790,10 +2354,12 @@ For associative containers, no `swap` function throws an exception
790
  unless that exception is thrown by the swap of the container’s `Compare`
791
  object (if any).
792
 
793
  ### Unordered associative containers <a id="unord.req">[[unord.req]]</a>
794
 
 
 
795
  Unordered associative containers provide an ability for fast retrieval
796
  of data based on keys. The worst-case complexity for most operations is
797
  linear, but the average case is much faster. The library provides four
798
  unordered associative containers: `unordered_set`, `unordered_map`,
799
  `unordered_multiset`, and `unordered_multimap`.
@@ -865,54 +2431,956 @@ per bucket is kept below a bound. Rehashing invalidates iterators,
865
  changes ordering between elements, and changes which buckets elements
866
  appear in, but does not invalidate pointers or references to elements.
867
  For `unordered_multiset` and `unordered_multimap`, rehashing preserves
868
  the relative ordering of equivalent elements.
869
 
870
- The unordered associative containers meet all the requirements of
871
- Allocator-aware containers [[container.requirements.general]], except
872
- that for `unordered_map` and `unordered_multimap`, the requirements
873
- placed on `value_type` in [[container.alloc.req]] apply instead to
874
- `key_type` and `mapped_type`.
875
-
876
- [*Note 3*: For example, `key_type` and `mapped_type` are sometimes
877
- required to be *Cpp17CopyAssignable* even though the associated
878
- `value_type`, `pair<const key_type, mapped_type>`, is not
879
- *Cpp17CopyAssignable*. — *end note*]
880
-
881
- In [[container.hash.req]]:
882
 
883
  - `X` denotes an unordered associative container class,
884
  - `a` denotes a value of type `X`,
885
  - `a2` denotes a value of a type with nodes compatible with type `X` (
886
  [[container.node.compat]]),
887
- - `b` denotes a possibly const value of type `X`,
888
  - `a_uniq` denotes a value of type `X` when `X` supports unique keys,
889
  - `a_eq` denotes a value of type `X` when `X` supports equivalent keys,
890
- - `a_tran` denotes a possibly const value of type `X` when the
891
  *qualified-id*s `X::key_equal::is_transparent` and
892
  `X::hasher::is_transparent` are both valid and denote types
893
  [[temp.deduct]],
894
  - `i` and `j` denote input iterators that refer to `value_type`,
895
  - `[i, j)` denotes a valid range,
 
 
896
  - `p` and `q2` denote valid constant iterators to `a`,
897
  - `q` and `q1` denote valid dereferenceable constant iterators to `a`,
898
  - `r` denotes a valid dereferenceable iterator to `a`,
899
  - `[q1, q2)` denotes a valid range in `a`,
900
  - `il` denotes a value of type `initializer_list<value_type>`,
901
  - `t` denotes a value of type `X::value_type`,
902
  - `k` denotes a value of type `key_type`,
903
- - `hf` denotes a possibly const value of type `hasher`,
904
- - `eq` denotes a possibly const value of type `key_equal`,
905
  - `ke` is a value such that
906
- - `eq(r1, ke) == eq(ke, r1)`
907
  - `hf(r1) == hf(ke)` if `eq(r1, ke)` is `true`, and
908
- - `(eq(r1, ke) && eq(r1, r2)) == eq(r2, ke)`
 
 
 
 
 
 
 
 
 
909
 
910
  where `r1` and `r2` are keys of elements in `a_tran`,
911
  - `n` denotes a value of type `size_type`,
912
  - `z` denotes a value of type `float`, and
913
- - `nh` denotes a non-const rvalue of type `X::node_type`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
914
 
915
  Two unordered containers `a` and `b` compare equal if
916
  `a.size() == b.size()` and, for every equivalent-key group \[`Ea1`,
917
  `Ea2`) obtained from `a.equal_range(Ea1)`, there exists an
918
  equivalent-key group \[`Eb1`, `Eb2`) obtained from `b.equal_range(Ea1)`,
@@ -932,42 +3400,48 @@ same container), then the average-case complexity for
932
  `unordered_multiset` and `unordered_multimap` becomes proportional to N
933
  (but worst-case complexity remains 𝑂(N^2), e.g., for a pathologically
934
  bad hash function). The behavior of a program that uses `operator==` or
935
  `operator!=` on unordered containers is undefined unless the `Pred`
936
  function object has the same behavior for both containers and the
937
- equality comparison function for `Key` is a refinement[^1] of the
938
- partition into equivalent-key groups produced by `Pred`.
 
939
 
940
  The iterator types `iterator` and `const_iterator` of an unordered
941
  associative container are of at least the forward iterator category. For
942
  unordered associative containers where the key type and value type are
943
  the same, both `iterator` and `const_iterator` are constant iterators.
944
 
945
- The `insert` and `emplace` members shall not affect the validity of
946
- references to container elements, but may invalidate all iterators to
947
- the container. The `erase` members shall invalidate only iterators and
948
- references to the erased elements, and preserve the relative order of
949
- the elements that are not erased.
950
 
951
- The `insert` and `emplace` members shall not affect the validity of
952
- iterators if `(N+n) <= z * B`, where `N` is the number of elements in
953
- the container prior to the insert operation, `n` is the number of
954
- elements inserted, `B` is the container’s bucket count, and `z` is the
955
- container’s maximum load factor.
956
 
957
  The `extract` members invalidate only iterators to the removed element,
958
  and preserve the relative order of the elements that are not erased;
959
  pointers and references to the removed element remain valid. However,
960
  accessing the element through such pointers and references while the
961
  element is owned by a `node_type` is undefined behavior. References and
962
  pointers to an element obtained while it is owned by a `node_type` are
963
  invalidated if the element is successfully inserted.
964
 
965
- The member function templates `find`, `count`, `equal_range`, and
966
- `contains` shall not participate in overload resolution unless the
967
- *qualified-id*s `Pred::is_transparent` and `Hash::is_transparent` are
968
- both valid and denote types [[temp.deduct]].
 
 
 
 
 
969
 
970
  A deduction guide for an unordered associative container shall not
971
  participate in overload resolution if any of the following are true:
972
 
973
  - It has an `InputIterator` template parameter and a type that does not
@@ -1076,10 +3550,11 @@ namespace std {
1076
 
1077
  template<class T, class Allocator>
1078
  void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
1079
  noexcept(noexcept(x.swap(y)));
1080
 
 
1081
  template<class T, class Allocator, class U>
1082
  typename deque<T, Allocator>::size_type
1083
  erase(deque<T, Allocator>& c, const U& value);
1084
  template<class T, class Allocator, class Predicate>
1085
  typename deque<T, Allocator>::size_type
@@ -1097,11 +3572,11 @@ namespace std {
1097
  ``` cpp
1098
  #include <compare> // see [compare.syn]
1099
  #include <initializer_list> // see [initializer.list.syn]
1100
 
1101
  namespace std {
1102
- // [forwardlist], class template forward_list
1103
  template<class T, class Allocator = allocator<T>> class forward_list;
1104
 
1105
  template<class T, class Allocator>
1106
  bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1107
  template<class T, class Allocator>
@@ -1110,10 +3585,11 @@ namespace std {
1110
 
1111
  template<class T, class Allocator>
1112
  void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
1113
  noexcept(noexcept(x.swap(y)));
1114
 
 
1115
  template<class T, class Allocator, class U>
1116
  typename forward_list<T, Allocator>::size_type
1117
  erase(forward_list<T, Allocator>& c, const U& value);
1118
  template<class T, class Allocator, class Predicate>
1119
  typename forward_list<T, Allocator>::size_type
@@ -1144,10 +3620,11 @@ namespace std {
1144
 
1145
  template<class T, class Allocator>
1146
  void swap(list<T, Allocator>& x, list<T, Allocator>& y)
1147
  noexcept(noexcept(x.swap(y)));
1148
 
 
1149
  template<class T, class Allocator, class U>
1150
  typename list<T, Allocator>::size_type
1151
  erase(list<T, Allocator>& c, const U& value);
1152
  template<class T, class Allocator, class Predicate>
1153
  typename list<T, Allocator>::size_type
@@ -1178,52 +3655,62 @@ namespace std {
1178
 
1179
  template<class T, class Allocator>
1180
  constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
1181
  noexcept(noexcept(x.swap(y)));
1182
 
 
1183
  template<class T, class Allocator, class U>
1184
  constexpr typename vector<T, Allocator>::size_type
1185
  erase(vector<T, Allocator>& c, const U& value);
1186
  template<class T, class Allocator, class Predicate>
1187
  constexpr typename vector<T, Allocator>::size_type
1188
  erase_if(vector<T, Allocator>& c, Predicate pred);
1189
 
1190
- // [vector.bool], class vector<bool>
1191
- template<class Allocator> class vector<bool, Allocator>;
 
 
 
 
 
 
 
 
 
 
1192
 
1193
  // hash support
1194
  template<class T> struct hash;
1195
  template<class Allocator> struct hash<vector<bool, Allocator>>;
1196
 
1197
- namespace pmr {
1198
- template<class T>
1199
- using vector = std::vector<T, polymorphic_allocator<T>>;
1200
- }
1201
  }
1202
  ```
1203
 
1204
  ### Class template `array` <a id="array">[[array]]</a>
1205
 
1206
  #### Overview <a id="array.overview">[[array.overview]]</a>
1207
 
1208
  The header `<array>` defines a class template for storing fixed-size
1209
  sequences of objects. An `array` is a contiguous container
1210
- [[container.requirements.general]]. An instance of `array<T, N>` stores
1211
- `N` elements of type `T`, so that `size() == N` is an invariant.
1212
 
1213
  An `array` is an aggregate [[dcl.init.aggr]] that can be
1214
  list-initialized with up to `N` elements whose types are convertible to
1215
  `T`.
1216
 
1217
- An `array` meets all of the requirements of a container and of a
1218
- reversible container [[container.requirements]], except that a default
1219
- constructed `array` object is not empty and that `swap` does not have
1220
- constant complexity. An `array` meets some of the requirements of a
1221
- sequence container [[sequence.reqmts]]. Descriptions are provided here
1222
- only for operations on `array` that are not described in one of these
1223
- tables and for operations where there is additional semantic
1224
- information.
1225
 
1226
  `array<T, N>` is a structural type [[temp.param]] if `T` is a structural
1227
  type. Two values `a1` and `a2` of type `array<T, N>` are
1228
  template-argument-equivalent [[temp.type]] if and only if each pair of
1229
  corresponding elements in `a1` and `a2` are
@@ -1295,17 +3782,17 @@ namespace std {
1295
  ```
1296
 
1297
  #### Constructors, copy, and assignment <a id="array.cons">[[array.cons]]</a>
1298
 
1299
  The conditions for an aggregate [[dcl.init.aggr]] shall be met. Class
1300
- `array` relies on the implicitly-declared special member functions (
1301
- [[class.default.ctor]], [[class.dtor]], and [[class.copy.ctor]]) to
1302
- conform to the container requirements table in 
1303
- [[container.requirements]]. In addition to the requirements specified in
1304
- the container requirements table, the implicit move constructor and move
1305
- assignment operator for `array` require that `T` be
1306
- *Cpp17MoveConstructible* or *Cpp17MoveAssignable*, respectively.
1307
 
1308
  ``` cpp
1309
  template<class T, class... U>
1310
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
1311
  ```
@@ -1339,11 +3826,11 @@ constexpr void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
1339
  ```
1340
 
1341
  *Effects:* Equivalent to `swap_ranges(begin(), end(), y.begin())`.
1342
 
1343
  [*Note 1*: Unlike the `swap` function for other containers,
1344
- `array::swap` takes linear time, may exit via an exception, and does not
1345
  cause iterators to become associated with the other
1346
  container. — *end note*]
1347
 
1348
  #### Specialized algorithms <a id="array.special">[[array.special]]</a>
1349
 
@@ -1438,17 +3925,18 @@ A `deque` is a sequence container that supports random access iterators
1438
  insert and erase operations at the beginning or the end; insert and
1439
  erase in the middle take linear time. That is, a deque is especially
1440
  optimized for pushing and popping elements at the beginning and end.
1441
  Storage management is handled automatically.
1442
 
1443
- A `deque` meets all of the requirements of a container, of a reversible
1444
- container (given in tables in  [[container.requirements]]), of a
1445
- sequence container, including the optional sequence container
1446
- requirements [[sequence.reqmts]], and of an allocator-aware container (
1447
- [[container.alloc.req]]). Descriptions are provided here only for
1448
- operations on `deque` that are not described in one of these tables or
1449
- for operations where there is additional semantic information.
 
1450
 
1451
  ``` cpp
1452
  namespace std {
1453
  template<class T, class Allocator = allocator<T>>
1454
  class deque {
@@ -1458,12 +3946,12 @@ namespace std {
1458
  using allocator_type = Allocator;
1459
  using pointer = typename allocator_traits<Allocator>::pointer;
1460
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
1461
  using reference = value_type&;
1462
  using const_reference = const value_type&;
1463
- using size_type = implementation-defined; // see [container.requirements]
1464
- using difference_type = implementation-defined; // see [container.requirements]
1465
  using iterator = implementation-defined // type of deque::iterator; // see [container.requirements]
1466
  using const_iterator = implementation-defined // type of deque::const_iterator; // see [container.requirements]
1467
  using reverse_iterator = std::reverse_iterator<iterator>;
1468
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1469
 
@@ -1472,23 +3960,27 @@ namespace std {
1472
  explicit deque(const Allocator&);
1473
  explicit deque(size_type n, const Allocator& = Allocator());
1474
  deque(size_type n, const T& value, const Allocator& = Allocator());
1475
  template<class InputIterator>
1476
  deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
 
1477
  deque(const deque& x);
1478
  deque(deque&&);
1479
- deque(const deque&, const Allocator&);
1480
- deque(deque&&, const Allocator&);
1481
  deque(initializer_list<T>, const Allocator& = Allocator());
1482
 
1483
  ~deque();
1484
  deque& operator=(const deque& x);
1485
  deque& operator=(deque&& x)
1486
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
1487
  deque& operator=(initializer_list<T>);
1488
  template<class InputIterator>
1489
  void assign(InputIterator first, InputIterator last);
 
 
1490
  void assign(size_type n, const T& t);
1491
  void assign(initializer_list<T>);
1492
  allocator_type get_allocator() const noexcept;
1493
 
1494
  // iterators
@@ -1529,18 +4021,24 @@ namespace std {
1529
  template<class... Args> reference emplace_back(Args&&... args);
1530
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
1531
 
1532
  void push_front(const T& x);
1533
  void push_front(T&& x);
 
 
1534
  void push_back(const T& x);
1535
  void push_back(T&& x);
 
 
1536
 
1537
  iterator insert(const_iterator position, const T& x);
1538
  iterator insert(const_iterator position, T&& x);
1539
  iterator insert(const_iterator position, size_type n, const T& x);
1540
  template<class InputIterator>
1541
  iterator insert(const_iterator position, InputIterator first, InputIterator last);
 
 
1542
  iterator insert(const_iterator position, initializer_list<T>);
1543
 
1544
  void pop_front();
1545
  void pop_back();
1546
 
@@ -1553,14 +4051,13 @@ namespace std {
1553
 
1554
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
1555
  deque(InputIterator, InputIterator, Allocator = Allocator())
1556
  -> deque<iter-value-type<InputIterator>, Allocator>;
1557
 
1558
- // swap
1559
- template<class T, class Allocator>
1560
- void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
1561
- noexcept(noexcept(x.swap(y)));
1562
  }
1563
  ```
1564
 
1565
  #### Constructors, copy, and assignment <a id="deque.cons">[[deque.cons]]</a>
1566
 
@@ -1574,26 +4071,26 @@ explicit deque(const Allocator&);
1574
 
1575
  ``` cpp
1576
  explicit deque(size_type n, const Allocator& = Allocator());
1577
  ```
1578
 
 
 
1579
  *Effects:* Constructs a `deque` with `n` default-inserted elements using
1580
  the specified allocator.
1581
 
1582
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
1583
-
1584
  *Complexity:* Linear in `n`.
1585
 
1586
  ``` cpp
1587
  deque(size_type n, const T& value, const Allocator& = Allocator());
1588
  ```
1589
 
 
 
1590
  *Effects:* Constructs a `deque` with `n` copies of `value`, using the
1591
  specified allocator.
1592
 
1593
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
1594
-
1595
  *Complexity:* Linear in `n`.
1596
 
1597
  ``` cpp
1598
  template<class InputIterator>
1599
  deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
@@ -1602,10 +4099,20 @@ template<class InputIterator>
1602
  *Effects:* Constructs a `deque` equal to the range \[`first`, `last`),
1603
  using the specified allocator.
1604
 
1605
  *Complexity:* Linear in `distance(first, last)`.
1606
 
 
 
 
 
 
 
 
 
 
 
1607
  #### Capacity <a id="deque.capacity">[[deque.capacity]]</a>
1608
 
1609
  ``` cpp
1610
  void resize(size_type sz);
1611
  ```
@@ -1657,39 +4164,45 @@ iterator insert(const_iterator position, const T& x);
1657
  iterator insert(const_iterator position, T&& x);
1658
  iterator insert(const_iterator position, size_type n, const T& x);
1659
  template<class InputIterator>
1660
  iterator insert(const_iterator position,
1661
  InputIterator first, InputIterator last);
 
 
1662
  iterator insert(const_iterator position, initializer_list<T>);
1663
 
1664
  template<class... Args> reference emplace_front(Args&&... args);
1665
  template<class... Args> reference emplace_back(Args&&... args);
1666
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
1667
  void push_front(const T& x);
1668
  void push_front(T&& x);
 
 
1669
  void push_back(const T& x);
1670
  void push_back(T&& x);
 
 
1671
  ```
1672
 
1673
  *Effects:* An insertion in the middle of the deque invalidates all the
1674
  iterators and references to elements of the deque. An insertion at
1675
  either end of the deque invalidates all the iterators to the deque, but
1676
  has no effect on the validity of references to elements of the deque.
1677
 
 
 
 
 
 
 
1678
  *Remarks:* If an exception is thrown other than by the copy constructor,
1679
  move constructor, assignment operator, or move assignment operator of
1680
  `T` there are no effects. If an exception is thrown while inserting a
1681
  single element at either end, there are no effects. Otherwise, if an
1682
  exception is thrown by the move constructor of a
1683
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
1684
 
1685
- *Complexity:* The complexity is linear in the number of elements
1686
- inserted plus the lesser of the distances to the beginning and end of
1687
- the deque. Inserting a single element at either the beginning or end of
1688
- a deque always takes constant time and causes a single call to a
1689
- constructor of `T`.
1690
-
1691
  ``` cpp
1692
  iterator erase(const_iterator position);
1693
  iterator erase(const_iterator first, const_iterator last);
1694
  void pop_front();
1695
  void pop_back();
@@ -1705,19 +4218,19 @@ invalidates the past-the-end iterator and all iterators and references
1705
  to all the elements of the deque.
1706
 
1707
  [*Note 1*: `pop_front` and `pop_back` are erase
1708
  operations. — *end note*]
1709
 
 
 
 
1710
  *Complexity:* The number of calls to the destructor of `T` is the same
1711
  as the number of elements erased, but the number of calls to the
1712
  assignment operator of `T` is no more than the lesser of the number of
1713
  elements before the erased elements and the number of elements after the
1714
  erased elements.
1715
 
1716
- *Throws:* Nothing unless an exception is thrown by the assignment
1717
- operator of `T`.
1718
-
1719
  #### Erasure <a id="deque.erasure">[[deque.erasure]]</a>
1720
 
1721
  ``` cpp
1722
  template<class T, class Allocator, class U>
1723
  typename deque<T, Allocator>::size_type
@@ -1746,39 +4259,38 @@ auto it = remove_if(c.begin(), c.end(), pred);
1746
  auto r = distance(it, c.end());
1747
  c.erase(it, c.end());
1748
  return r;
1749
  ```
1750
 
1751
- ### Class template `forward_list` <a id="forwardlist">[[forwardlist]]</a>
1752
 
1753
- #### Overview <a id="forwardlist.overview">[[forwardlist.overview]]</a>
1754
 
1755
  A `forward_list` is a container that supports forward iterators and
1756
  allows constant time insert and erase operations anywhere within the
1757
  sequence, with storage management handled automatically. Fast random
1758
  access to list elements is not supported.
1759
 
1760
  [*Note 1*: It is intended that `forward_list` have zero space or time
1761
  overhead relative to a hand-written C-style singly linked list. Features
1762
  that would conflict with that goal have been omitted. — *end note*]
1763
 
1764
- A `forward_list` meets all of the requirements of a container (
1765
- [[container.req]]), except that the `size()` member function is not
1766
- provided and `operator==` has linear complexity. A `forward_list` also
1767
- meets all of the requirements for an allocator-aware container (
1768
- [[container.alloc.req]]). In addition, a `forward_list` provides the
1769
- `assign` member functions ([[container.seq.req]]) and several of the
1770
- optional container requirements ([[container.seq.opt]]). Descriptions
1771
- are provided here only for operations on `forward_list` that are not
1772
- described in that table or for operations where there is additional
1773
- semantic information.
1774
 
1775
  [*Note 2*: Modifying any list requires access to the element preceding
1776
  the first element of interest, but in a `forward_list` there is no
1777
- constant-time way to access a preceding element. For this reason, ranges
1778
- that are modified, such as those supplied to `erase` and `splice`, must
1779
- be open at the beginning. — *end note*]
1780
 
1781
  ``` cpp
1782
  namespace std {
1783
  template<class T, class Allocator = allocator<T>>
1784
  class forward_list {
@@ -1788,39 +4300,43 @@ namespace std {
1788
  using allocator_type = Allocator;
1789
  using pointer = typename allocator_traits<Allocator>::pointer;
1790
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
1791
  using reference = value_type&;
1792
  using const_reference = const value_type&;
1793
- using size_type = implementation-defined; // see [container.requirements]
1794
- using difference_type = implementation-defined; // see [container.requirements]
1795
  using iterator = implementation-defined // type of forward_list::iterator; // see [container.requirements]
1796
  using const_iterator = implementation-defined // type of forward_list::const_iterator; // see [container.requirements]
1797
 
1798
- // [forwardlist.cons], construct/copy/destroy
1799
  forward_list() : forward_list(Allocator()) { }
1800
  explicit forward_list(const Allocator&);
1801
  explicit forward_list(size_type n, const Allocator& = Allocator());
1802
  forward_list(size_type n, const T& value, const Allocator& = Allocator());
1803
  template<class InputIterator>
1804
  forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
 
1805
  forward_list(const forward_list& x);
1806
  forward_list(forward_list&& x);
1807
- forward_list(const forward_list& x, const Allocator&);
1808
- forward_list(forward_list&& x, const Allocator&);
1809
  forward_list(initializer_list<T>, const Allocator& = Allocator());
1810
  ~forward_list();
1811
  forward_list& operator=(const forward_list& x);
1812
  forward_list& operator=(forward_list&& x)
1813
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
1814
  forward_list& operator=(initializer_list<T>);
1815
  template<class InputIterator>
1816
  void assign(InputIterator first, InputIterator last);
 
 
1817
  void assign(size_type n, const T& t);
1818
  void assign(initializer_list<T>);
1819
  allocator_type get_allocator() const noexcept;
1820
 
1821
- // [forwardlist.iter], iterators
1822
  iterator before_begin() noexcept;
1823
  const_iterator before_begin() const noexcept;
1824
  iterator begin() noexcept;
1825
  const_iterator begin() const noexcept;
1826
  iterator end() noexcept;
@@ -1832,39 +4348,43 @@ namespace std {
1832
 
1833
  // capacity
1834
  [[nodiscard]] bool empty() const noexcept;
1835
  size_type max_size() const noexcept;
1836
 
1837
- // [forwardlist.access], element access
1838
  reference front();
1839
  const_reference front() const;
1840
 
1841
- // [forwardlist.modifiers], modifiers
1842
  template<class... Args> reference emplace_front(Args&&... args);
1843
  void push_front(const T& x);
1844
  void push_front(T&& x);
 
 
1845
  void pop_front();
1846
 
1847
  template<class... Args> iterator emplace_after(const_iterator position, Args&&... args);
1848
  iterator insert_after(const_iterator position, const T& x);
1849
  iterator insert_after(const_iterator position, T&& x);
1850
 
1851
  iterator insert_after(const_iterator position, size_type n, const T& x);
1852
  template<class InputIterator>
1853
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
1854
  iterator insert_after(const_iterator position, initializer_list<T> il);
 
 
1855
 
1856
  iterator erase_after(const_iterator position);
1857
  iterator erase_after(const_iterator position, const_iterator last);
1858
  void swap(forward_list&)
1859
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
1860
 
1861
  void resize(size_type sz);
1862
  void resize(size_type sz, const value_type& c);
1863
  void clear() noexcept;
1864
 
1865
- // [forwardlist.ops], forward_list operations
1866
  void splice_after(const_iterator position, forward_list& x);
1867
  void splice_after(const_iterator position, forward_list&& x);
1868
  void splice_after(const_iterator position, forward_list& x, const_iterator i);
1869
  void splice_after(const_iterator position, forward_list&& x, const_iterator i);
1870
  void splice_after(const_iterator position, forward_list& x,
@@ -1891,24 +4411,23 @@ namespace std {
1891
 
1892
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
1893
  forward_list(InputIterator, InputIterator, Allocator = Allocator())
1894
  -> forward_list<iter-value-type<InputIterator>, Allocator>;
1895
 
1896
- // swap
1897
- template<class T, class Allocator>
1898
- void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
1899
- noexcept(noexcept(x.swap(y)));
1900
  }
1901
  ```
1902
 
1903
  An incomplete type `T` may be used when instantiating `forward_list` if
1904
  the allocator meets the allocator completeness requirements
1905
  [[allocator.requirements.completeness]]. `T` shall be complete before
1906
  any member of the resulting specialization of `forward_list` is
1907
  referenced.
1908
 
1909
- #### Constructors, copy, and assignment <a id="forwardlist.cons">[[forwardlist.cons]]</a>
1910
 
1911
  ``` cpp
1912
  explicit forward_list(const Allocator&);
1913
  ```
1914
 
@@ -1947,36 +4466,46 @@ template<class InputIterator>
1947
  *Effects:* Constructs a `forward_list` object equal to the range
1948
  \[`first`, `last`).
1949
 
1950
  *Complexity:* Linear in `distance(first, last)`.
1951
 
1952
- #### Iterators <a id="forwardlist.iter">[[forwardlist.iter]]</a>
 
 
 
 
 
 
 
 
 
 
1953
 
1954
  ``` cpp
1955
  iterator before_begin() noexcept;
1956
  const_iterator before_begin() const noexcept;
1957
  const_iterator cbefore_begin() const noexcept;
1958
  ```
1959
 
1960
- *Returns:* A non-dereferenceable iterator that, when incremented, is
1961
- equal to the iterator returned by `begin()`.
1962
-
1963
  *Effects:* `cbefore_begin()` is equivalent to
1964
  `const_cast<forward_list const&>(*this).before_begin()`.
1965
 
 
 
 
1966
  *Remarks:* `before_begin() == end()` shall equal `false`.
1967
 
1968
- #### Element access <a id="forwardlist.access">[[forwardlist.access]]</a>
1969
 
1970
  ``` cpp
1971
  reference front();
1972
  const_reference front() const;
1973
  ```
1974
 
1975
  *Returns:* `*begin()`
1976
 
1977
- #### Modifiers <a id="forwardlist.modifiers">[[forwardlist.modifiers]]</a>
1978
 
1979
  None of the overloads of `insert_after` shall affect the validity of
1980
  iterators and references, and `erase_after` shall invalidate only
1981
  iterators and references to the erased elements. If an exception is
1982
  thrown during `insert_after` there shall be no effect. Inserting `n`
@@ -1997,74 +4526,114 @@ void push_front(const T& x);
1997
  void push_front(T&& x);
1998
  ```
1999
 
2000
  *Effects:* Inserts a copy of `x` at the beginning of the list.
2001
 
 
 
 
 
 
 
 
 
 
 
2002
  ``` cpp
2003
  void pop_front();
2004
  ```
2005
 
2006
  *Effects:* As if by `erase_after(before_begin())`.
2007
 
2008
  ``` cpp
2009
  iterator insert_after(const_iterator position, const T& x);
 
 
 
 
 
 
 
 
 
 
 
2010
  iterator insert_after(const_iterator position, T&& x);
2011
  ```
2012
 
2013
- *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2014
- iterator in the range \[`begin()`, `end()`).
 
2015
 
2016
  *Effects:* Inserts a copy of `x` after `position`.
2017
 
2018
  *Returns:* An iterator pointing to the copy of `x`.
2019
 
2020
  ``` cpp
2021
  iterator insert_after(const_iterator position, size_type n, const T& x);
2022
  ```
2023
 
2024
- *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2025
- iterator in the range \[`begin()`, `end()`).
 
2026
 
2027
  *Effects:* Inserts `n` copies of `x` after `position`.
2028
 
2029
- *Returns:* An iterator pointing to the last inserted copy of `x` or
2030
- `position` if `n == 0`.
2031
 
2032
  ``` cpp
2033
  template<class InputIterator>
2034
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
2035
  ```
2036
 
2037
- *Preconditions:* `position` is `before_begin()` or is a dereferenceable
 
2038
  iterator in the range \[`begin()`, `end()`). Neither `first` nor `last`
2039
  are iterators in `*this`.
2040
 
2041
  *Effects:* Inserts copies of elements in \[`first`, `last`) after
2042
  `position`.
2043
 
2044
- *Returns:* An iterator pointing to the last inserted element or
2045
- `position` if `first == last`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2046
 
2047
  ``` cpp
2048
  iterator insert_after(const_iterator position, initializer_list<T> il);
2049
  ```
2050
 
2051
- *Effects:* `insert_after(p, il.begin(), il.end())`.
2052
-
2053
- *Returns:* An iterator pointing to the last inserted element or
2054
- `position` if `il` is empty.
2055
 
2056
  ``` cpp
2057
  template<class... Args>
2058
  iterator emplace_after(const_iterator position, Args&&... args);
2059
  ```
2060
 
2061
- *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2062
- iterator in the range \[`begin()`, `end()`).
 
2063
 
2064
- *Effects:* Inserts an object of type `value_type` constructed with
2065
- `value_type(std::forward<Args>(args)...)` after `position`.
 
2066
 
2067
  *Returns:* An iterator pointing to the new object.
2068
 
2069
  ``` cpp
2070
  iterator erase_after(const_iterator position);
@@ -2121,16 +4690,20 @@ void clear() noexcept;
2121
 
2122
  *Effects:* Erases all elements in the range \[`begin()`, `end()`).
2123
 
2124
  *Remarks:* Does not invalidate past-the-end iterators.
2125
 
2126
- #### Operations <a id="forwardlist.ops">[[forwardlist.ops]]</a>
2127
 
2128
  In this subclause, arguments for a template parameter named `Predicate`
2129
  or `BinaryPredicate` shall meet the corresponding requirements in
2130
- [[algorithms.requirements]]. For `merge` and `sort`, the definitions and
2131
- requirements in [[alg.sorting]] apply.
 
 
 
 
2132
 
2133
  ``` cpp
2134
  void splice_after(const_iterator position, forward_list& x);
2135
  void splice_after(const_iterator position, forward_list&& x);
2136
  ```
@@ -2206,61 +4779,66 @@ the iterators and references to the erased elements.
2206
  *Returns:* The number of elements erased.
2207
 
2208
  *Throws:* Nothing unless an exception is thrown by the equality
2209
  comparison or the predicate.
2210
 
2211
- *Remarks:* Stable [[algorithm.stable]].
2212
-
2213
  *Complexity:* Exactly `distance(begin(), end())` applications of the
2214
  corresponding predicate.
2215
 
 
 
2216
  ``` cpp
2217
  size_type unique();
2218
- template<class BinaryPredicate> size_type unique(BinaryPredicate pred);
2219
  ```
2220
 
 
 
 
 
2221
  *Effects:* Erases all but the first element from every consecutive group
2222
- of equal elements referred to by the iterator `i` in the range
2223
- \[`first + 1`, `last`) for which `*i == *(i-1)` (for the version with no
2224
- arguments) or `pred(*i, *(i - 1))` (for the version with a predicate
2225
- argument) holds. Invalidates only the iterators and references to the
2226
- erased elements.
2227
 
2228
  *Returns:* The number of elements erased.
2229
 
2230
- *Throws:* Nothing unless an exception is thrown by the equality
2231
- comparison or the predicate.
2232
 
2233
- *Complexity:* If the range \[`first`, `last`) is not empty, exactly
2234
- `(last - first) - 1` applications of the corresponding predicate,
2235
- otherwise no applications of the predicate.
2236
 
2237
  ``` cpp
2238
  void merge(forward_list& x);
2239
  void merge(forward_list&& x);
2240
  template<class Compare> void merge(forward_list& x, Compare comp);
2241
  template<class Compare> void merge(forward_list&& x, Compare comp);
2242
  ```
2243
 
 
 
2244
  *Preconditions:* `*this` and `x` are both sorted with respect to the
2245
- comparator `operator<` (for the first two overloads) or `comp` (for the
2246
- last two overloads), and `get_allocator() == x.get_allocator()` is
2247
- `true`.
2248
 
2249
- *Effects:* Merges the two sorted ranges `[begin(), end())` and
2250
- `[x.begin(), x.end())`. `x` is empty after the merge. If an exception is
2251
- thrown other than by a comparison there are no effects. Pointers and
2252
- references to the moved elements of `x` now refer to those same elements
2253
- but as members of `*this`. Iterators referring to the moved elements
2254
- will continue to refer to their elements, but they now behave as
2255
- iterators into `*this`, not into `x`.
2256
-
2257
- *Remarks:* Stable [[algorithm.stable]].
2258
 
2259
  *Complexity:* At most
2260
  `distance(begin(), end()) + distance(x.begin(), x.end()) - 1`
2261
- comparisons.
 
 
 
 
 
2262
 
2263
  ``` cpp
2264
  void sort();
2265
  template<class Compare> void sort(Compare comp);
2266
  ```
@@ -2268,15 +4846,15 @@ template<class Compare> void sort(Compare comp);
2268
  *Effects:* Sorts the list according to the `operator<` or the `comp`
2269
  function object. If an exception is thrown, the order of the elements in
2270
  `*this` is unspecified. Does not affect the validity of iterators and
2271
  references.
2272
 
2273
- *Remarks:* Stable [[algorithm.stable]].
2274
-
2275
  *Complexity:* Approximately N log N comparisons, where N is
2276
  `distance(begin(), end())`.
2277
 
 
 
2278
  ``` cpp
2279
  void reverse() noexcept;
2280
  ```
2281
 
2282
  *Effects:* Reverses the order of the elements in the list. Does not
@@ -2311,19 +4889,21 @@ A `list` is a sequence container that supports bidirectional iterators
2311
  and allows constant time insert and erase operations anywhere within the
2312
  sequence, with storage management handled automatically. Unlike vectors
2313
  [[vector]] and deques [[deque]], fast random access to list elements is
2314
  not supported, but many algorithms only need sequential access anyway.
2315
 
2316
- A `list` meets all of the requirements of a container, of a reversible
2317
- container (given in two tables in [[container.requirements]]), of a
2318
- sequence container, including most of the optional sequence container
2319
- requirements [[sequence.reqmts]], and of an allocator-aware container (
2320
- [[container.alloc.req]]). The exceptions are the `operator[]` and `at`
2321
- member functions, which are not provided.[^2] Descriptions are provided
2322
- here only for operations on `list` that are not described in one of
2323
- these tables or for operations where there is additional semantic
2324
- information.
 
 
2325
 
2326
  ``` cpp
2327
  namespace std {
2328
  template<class T, class Allocator = allocator<T>>
2329
  class list {
@@ -2333,12 +4913,12 @@ namespace std {
2333
  using allocator_type = Allocator;
2334
  using pointer = typename allocator_traits<Allocator>::pointer;
2335
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
2336
  using reference = value_type&;
2337
  using const_reference = const value_type&;
2338
- using size_type = implementation-defined; // see [container.requirements]
2339
- using difference_type = implementation-defined; // see [container.requirements]
2340
  using iterator = implementation-defined // type of list::iterator; // see [container.requirements]
2341
  using const_iterator = implementation-defined // type of list::const_iterator; // see [container.requirements]
2342
  using reverse_iterator = std::reverse_iterator<iterator>;
2343
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2344
 
@@ -2347,22 +4927,26 @@ namespace std {
2347
  explicit list(const Allocator&);
2348
  explicit list(size_type n, const Allocator& = Allocator());
2349
  list(size_type n, const T& value, const Allocator& = Allocator());
2350
  template<class InputIterator>
2351
  list(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
 
2352
  list(const list& x);
2353
  list(list&& x);
2354
- list(const list&, const Allocator&);
2355
- list(list&&, const Allocator&);
2356
  list(initializer_list<T>, const Allocator& = Allocator());
2357
  ~list();
2358
  list& operator=(const list& x);
2359
  list& operator=(list&& x)
2360
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
2361
  list& operator=(initializer_list<T>);
2362
  template<class InputIterator>
2363
  void assign(InputIterator first, InputIterator last);
 
 
2364
  void assign(size_type n, const T& t);
2365
  void assign(initializer_list<T>);
2366
  allocator_type get_allocator() const noexcept;
2367
 
2368
  // iterators
@@ -2396,21 +4980,27 @@ namespace std {
2396
  // [list.modifiers], modifiers
2397
  template<class... Args> reference emplace_front(Args&&... args);
2398
  template<class... Args> reference emplace_back(Args&&... args);
2399
  void push_front(const T& x);
2400
  void push_front(T&& x);
 
 
2401
  void pop_front();
2402
  void push_back(const T& x);
2403
  void push_back(T&& x);
 
 
2404
  void pop_back();
2405
 
2406
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
2407
  iterator insert(const_iterator position, const T& x);
2408
  iterator insert(const_iterator position, T&& x);
2409
  iterator insert(const_iterator position, size_type n, const T& x);
2410
  template<class InputIterator>
2411
  iterator insert(const_iterator position, InputIterator first, InputIterator last);
 
 
2412
  iterator insert(const_iterator position, initializer_list<T> il);
2413
 
2414
  iterator erase(const_iterator position);
2415
  iterator erase(const_iterator position, const_iterator last);
2416
  void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value);
@@ -2444,14 +5034,13 @@ namespace std {
2444
 
2445
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
2446
  list(InputIterator, InputIterator, Allocator = Allocator())
2447
  -> list<iter-value-type<InputIterator>, Allocator>;
2448
 
2449
- // swap
2450
- template<class T, class Allocator>
2451
- void swap(list<T, Allocator>& x, list<T, Allocator>& y)
2452
- noexcept(noexcept(x.swap(y)));
2453
  }
2454
  ```
2455
 
2456
  An incomplete type `T` may be used when instantiating `list` if the
2457
  allocator meets the allocator completeness requirements
@@ -2497,10 +5086,20 @@ template<class InputIterator>
2497
 
2498
  *Effects:* Constructs a `list` equal to the range \[`first`, `last`).
2499
 
2500
  *Complexity:* Linear in `distance(first, last)`.
2501
 
 
 
 
 
 
 
 
 
 
 
2502
  #### Capacity <a id="list.capacity">[[list.capacity]]</a>
2503
 
2504
  ``` cpp
2505
  void resize(size_type sz);
2506
  ```
@@ -2543,30 +5142,36 @@ iterator insert(const_iterator position, const T& x);
2543
  iterator insert(const_iterator position, T&& x);
2544
  iterator insert(const_iterator position, size_type n, const T& x);
2545
  template<class InputIterator>
2546
  iterator insert(const_iterator position, InputIterator first,
2547
  InputIterator last);
 
 
2548
  iterator insert(const_iterator position, initializer_list<T>);
2549
 
2550
  template<class... Args> reference emplace_front(Args&&... args);
2551
  template<class... Args> reference emplace_back(Args&&... args);
2552
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
2553
  void push_front(const T& x);
2554
  void push_front(T&& x);
 
 
2555
  void push_back(const T& x);
2556
  void push_back(T&& x);
 
 
2557
  ```
2558
 
2559
- *Remarks:* Does not affect the validity of iterators and references. If
2560
- an exception is thrown there are no effects.
2561
-
2562
  *Complexity:* Insertion of a single element into a list takes constant
2563
  time and exactly one call to a constructor of `T`. Insertion of multiple
2564
  elements into a list is linear in the number of elements inserted, and
2565
  the number of calls to the copy constructor or move constructor of `T`
2566
  is exactly equal to the number of elements inserted.
2567
 
 
 
 
2568
  ``` cpp
2569
  iterator erase(const_iterator position);
2570
  iterator erase(const_iterator first, const_iterator last);
2571
 
2572
  void pop_front();
@@ -2585,15 +5190,18 @@ linear time in the size of the range and the number of calls to the
2585
  destructor of type `T` is exactly equal to the size of the range.
2586
 
2587
  #### Operations <a id="list.ops">[[list.ops]]</a>
2588
 
2589
  Since lists allow fast insertion and erasing from the middle of a list,
2590
- certain operations are provided specifically for them.[^3] In this
2591
- subclause, arguments for a template parameter named `Predicate` or
2592
- `BinaryPredicate` shall meet the corresponding requirements in
2593
- [[algorithms.requirements]]. For `merge` and `sort`, the definitions and
2594
- requirements in [[alg.sorting]] apply.
 
 
 
2595
 
2596
  `list` provides three splice operations that destructively move elements
2597
  from one list to another. The behavior of splice operations is undefined
2598
  if `get_allocator() !=
2599
  x.get_allocator()`.
@@ -2668,67 +5276,64 @@ the erased elements.
2668
  *Returns:* The number of elements erased.
2669
 
2670
  *Throws:* Nothing unless an exception is thrown by `*i == value` or
2671
  `pred(*i) != false`.
2672
 
2673
- *Remarks:* Stable [[algorithm.stable]].
2674
-
2675
  *Complexity:* Exactly `size()` applications of the corresponding
2676
  predicate.
2677
 
 
 
2678
  ``` cpp
2679
  size_type unique();
2680
  template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
2681
  ```
2682
 
 
 
 
 
2683
  *Effects:* Erases all but the first element from every consecutive group
2684
- of equal elements referred to by the iterator `i` in the range
2685
- \[`first + 1`, `last`) for which `*i == *(i-1)` (for the version of
2686
- `unique` with no arguments) or `pred(*i, *(i - 1))` (for the version of
2687
- `unique` with a predicate argument) holds. Invalidates only the
2688
- iterators and references to the erased elements.
2689
 
2690
  *Returns:* The number of elements erased.
2691
 
2692
- *Throws:* Nothing unless an exception is thrown by `*i == *(i-1)` or
2693
- `pred(*i, *(i - 1))`
2694
 
2695
- *Complexity:* If the range `[first, last)` is not empty, exactly
2696
- `(last - first) - 1` applications of the corresponding predicate,
2697
- otherwise no applications of the predicate.
2698
 
2699
  ``` cpp
2700
  void merge(list& x);
2701
  void merge(list&& x);
2702
  template<class Compare> void merge(list& x, Compare comp);
2703
  template<class Compare> void merge(list&& x, Compare comp);
2704
  ```
2705
 
2706
- *Preconditions:* Both the list and the argument list shall be sorted
2707
- with respect to the comparator `operator<` (for the first two overloads)
2708
- or `comp` (for the last two overloads), and
2709
- `get_allocator() == x.get_allocator()` is `true`.
2710
 
2711
- *Effects:* If `addressof(x) == this`, does nothing; otherwise, merges
2712
- the two sorted ranges `[begin(), end())` and `[x.begin(), x.end())`. The
2713
- result is a range in which the elements will be sorted in non-decreasing
2714
- order according to the ordering defined by `comp`; that is, for every
2715
- iterator `i`, in the range other than the first, the condition
2716
- `comp(*i, *(i - 1))` will be `false`. Pointers and references to the
2717
- moved elements of `x` now refer to those same elements but as members of
2718
- `*this`. Iterators referring to the moved elements will continue to
2719
- refer to their elements, but they now behave as iterators into `*this`,
2720
- not into `x`.
2721
 
2722
- *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, the
2723
- range `[x.begin(), x.end())` is empty after the merge. No elements are
2724
- copied by this operation.
 
 
 
 
2725
 
2726
- *Complexity:* At most `size() + x.size() - 1` applications of `comp` if
2727
- `addressof(x) != this`; otherwise, no applications of `comp` are
2728
- performed. If an exception is thrown other than by a comparison there
2729
- are no effects.
 
 
2730
 
2731
  ``` cpp
2732
  void reverse() noexcept;
2733
  ```
2734
 
@@ -2745,14 +5350,14 @@ template<class Compare> void sort(Compare comp);
2745
  *Effects:* Sorts the list according to the `operator<` or a `Compare`
2746
  function object. If an exception is thrown, the order of the elements in
2747
  `*this` is unspecified. Does not affect the validity of iterators and
2748
  references.
2749
 
2750
- *Remarks:* Stable [[algorithm.stable]].
2751
-
2752
  *Complexity:* Approximately N log N comparisons, where `N == size()`.
2753
 
 
 
2754
  #### Erasure <a id="list.erasure">[[list.erasure]]</a>
2755
 
2756
  ``` cpp
2757
  template<class T, class Allocator, class U>
2758
  typename list<T, Allocator>::size_type
@@ -2777,21 +5382,21 @@ template<class T, class Allocator, class Predicate>
2777
  A `vector` is a sequence container that supports (amortized) constant
2778
  time insert and erase operations at the end; insert and erase in the
2779
  middle take linear time. Storage management is handled automatically,
2780
  though hints can be given to improve efficiency.
2781
 
2782
- A `vector` meets all of the requirements of a container and of a
2783
- reversible container (given in two tables in 
2784
- [[container.requirements]]), of a sequence container, including most of
2785
- the optional sequence container requirements [[sequence.reqmts]], of an
2786
- allocator-aware container ([[container.alloc.req]]), and, for an
2787
- element type other than `bool`, of a contiguous container
2788
- [[container.requirements.general]]. The exceptions are the `push_front`,
2789
- `pop_front`, and `emplace_front` member functions, which are not
2790
- provided. Descriptions are provided here only for operations on `vector`
2791
- that are not described in one of these tables or for operations where
2792
- there is additional semantic information.
2793
 
2794
  The types `iterator` and `const_iterator` meet the constexpr iterator
2795
  requirements [[iterator.requirements.general]].
2796
 
2797
  ``` cpp
@@ -2804,12 +5409,12 @@ namespace std {
2804
  using allocator_type = Allocator;
2805
  using pointer = typename allocator_traits<Allocator>::pointer;
2806
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
2807
  using reference = value_type&;
2808
  using const_reference = const value_type&;
2809
- using size_type = implementation-defined; // see [container.requirements]
2810
- using difference_type = implementation-defined; // see [container.requirements]
2811
  using iterator = implementation-defined // type of vector::iterator; // see [container.requirements]
2812
  using const_iterator = implementation-defined // type of vector::const_iterator; // see [container.requirements]
2813
  using reverse_iterator = std::reverse_iterator<iterator>;
2814
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2815
 
@@ -2818,23 +5423,27 @@ namespace std {
2818
  constexpr explicit vector(const Allocator&) noexcept;
2819
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
2820
  constexpr vector(size_type n, const T& value, const Allocator& = Allocator());
2821
  template<class InputIterator>
2822
  constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
 
2823
  constexpr vector(const vector& x);
2824
  constexpr vector(vector&&) noexcept;
2825
- constexpr vector(const vector&, const Allocator&);
2826
- constexpr vector(vector&&, const Allocator&);
2827
  constexpr vector(initializer_list<T>, const Allocator& = Allocator());
2828
  constexpr ~vector();
2829
  constexpr vector& operator=(const vector& x);
2830
  constexpr vector& operator=(vector&& x)
2831
  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
2832
  allocator_traits<Allocator>::is_always_equal::value);
2833
  constexpr vector& operator=(initializer_list<T>);
2834
  template<class InputIterator>
2835
  constexpr void assign(InputIterator first, InputIterator last);
 
 
2836
  constexpr void assign(size_type n, const T& u);
2837
  constexpr void assign(initializer_list<T>);
2838
  constexpr allocator_type get_allocator() const noexcept;
2839
 
2840
  // iterators
@@ -2878,19 +5487,23 @@ namespace std {
2878
 
2879
  // [vector.modifiers], modifiers
2880
  template<class... Args> constexpr reference emplace_back(Args&&... args);
2881
  constexpr void push_back(const T& x);
2882
  constexpr void push_back(T&& x);
 
 
2883
  constexpr void pop_back();
2884
 
2885
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
2886
  constexpr iterator insert(const_iterator position, const T& x);
2887
  constexpr iterator insert(const_iterator position, T&& x);
2888
  constexpr iterator insert(const_iterator position, size_type n, const T& x);
2889
  template<class InputIterator>
2890
  constexpr iterator insert(const_iterator position,
2891
  InputIterator first, InputIterator last);
 
 
2892
  constexpr iterator insert(const_iterator position, initializer_list<T> il);
2893
  constexpr iterator erase(const_iterator position);
2894
  constexpr iterator erase(const_iterator first, const_iterator last);
2895
  constexpr void swap(vector&)
2896
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
@@ -2900,23 +5513,22 @@ namespace std {
2900
 
2901
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
2902
  vector(InputIterator, InputIterator, Allocator = Allocator())
2903
  -> vector<iter-value-type<InputIterator>, Allocator>;
2904
 
2905
- // swap
2906
- template<class T, class Allocator>
2907
- constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
2908
- noexcept(noexcept(x.swap(y)));
2909
  }
2910
  ```
2911
 
2912
  An incomplete type `T` may be used when instantiating `vector` if the
2913
  allocator meets the allocator completeness requirements
2914
  [[allocator.requirements.completeness]]. `T` shall be complete before
2915
  any member of the resulting specialization of `vector` is referenced.
2916
 
2917
- #### Constructors, copy, and assignment <a id="vector.cons">[[vector.cons]]</a>
2918
 
2919
  ``` cpp
2920
  constexpr explicit vector(const Allocator&) noexcept;
2921
  ```
2922
 
@@ -2957,12 +5569,27 @@ template<class InputIterator>
2957
  using the specified allocator.
2958
 
2959
  *Complexity:* Makes only N calls to the copy constructor of `T` (where N
2960
  is the distance between `first` and `last`) and no reallocations if
2961
  iterators `first` and `last` are of forward, bidirectional, or random
2962
- access categories. It makes order `N` calls to the copy constructor of
2963
- `T` and order log N reallocations if they are just input iterators.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2964
 
2965
  #### Capacity <a id="vector.capacity">[[vector.capacity]]</a>
2966
 
2967
  ``` cpp
2968
  constexpr size_type capacity() const noexcept;
@@ -2986,15 +5613,15 @@ size, so that it can manage the storage allocation accordingly. After
2986
  `capacity()` otherwise. Reallocation happens at this point if and only
2987
  if the current capacity is less than the argument of `reserve()`. If an
2988
  exception is thrown other than by the move constructor of a
2989
  non-*Cpp17CopyInsertable* type, there are no effects.
2990
 
 
 
2991
  *Complexity:* It does not change the size of the sequence and takes at
2992
  most linear time in the size of the sequence.
2993
 
2994
- *Throws:* `length_error` if `n > max_size()`.[^4]
2995
-
2996
  *Remarks:* Reallocation invalidates all the references, pointers, and
2997
  iterators referring to the elements in the sequence, as well as the
2998
  past-the-end iterator.
2999
 
3000
  [*Note 1*: If no reallocation happens, they remain
@@ -3085,18 +5712,26 @@ range. For a non-empty vector, `data()` `==` `addressof(front())`.
3085
  constexpr iterator insert(const_iterator position, const T& x);
3086
  constexpr iterator insert(const_iterator position, T&& x);
3087
  constexpr iterator insert(const_iterator position, size_type n, const T& x);
3088
  template<class InputIterator>
3089
  constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last);
 
 
3090
  constexpr iterator insert(const_iterator position, initializer_list<T>);
3091
 
3092
  template<class... Args> constexpr reference emplace_back(Args&&... args);
3093
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
3094
  constexpr void push_back(const T& x);
3095
  constexpr void push_back(T&& x);
 
 
3096
  ```
3097
 
 
 
 
 
3098
  *Remarks:* Causes reallocation if the new size is greater than the old
3099
  capacity. Reallocation invalidates all the references, pointers, and
3100
  iterators referring to the elements in the sequence, as well as the
3101
  past-the-end iterator. If no reallocation happens, then references,
3102
  pointers, and iterators before the insertion point remain valid but
@@ -3108,31 +5743,27 @@ no effects. If an exception is thrown while inserting a single element
3108
  at the end and `T` is *Cpp17CopyInsertable* or
3109
  `is_nothrow_move_constructible_v<T>` is `true`, there are no effects.
3110
  Otherwise, if an exception is thrown by the move constructor of a
3111
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
3112
 
3113
- *Complexity:* If reallocation happens, linear in the number of elements
3114
- of the resulting vector; otherwise, linear in the number of elements
3115
- inserted plus the distance to the end of the vector.
3116
-
3117
  ``` cpp
3118
  constexpr iterator erase(const_iterator position);
3119
  constexpr iterator erase(const_iterator first, const_iterator last);
3120
  constexpr void pop_back();
3121
  ```
3122
 
3123
  *Effects:* Invalidates iterators and references at or after the point of
3124
  the erase.
3125
 
 
 
 
3126
  *Complexity:* The destructor of `T` is called the number of times equal
3127
  to the number of the elements erased, but the assignment operator of `T`
3128
  is called the number of times equal to the number of elements in the
3129
  vector after the erased elements.
3130
 
3131
- *Throws:* Nothing unless an exception is thrown by the assignment
3132
- operator or move assignment operator of `T`.
3133
-
3134
  #### Erasure <a id="vector.erasure">[[vector.erasure]]</a>
3135
 
3136
  ``` cpp
3137
  template<class T, class Allocator, class U>
3138
  constexpr typename vector<T, Allocator>::size_type
@@ -3161,64 +5792,74 @@ auto it = remove_if(c.begin(), c.end(), pred);
3161
  auto r = distance(it, c.end());
3162
  c.erase(it, c.end());
3163
  return r;
3164
  ```
3165
 
3166
- ### Class `vector<bool>` <a id="vector.bool">[[vector.bool]]</a>
3167
 
3168
- To optimize space allocation, a specialization of vector for `bool`
3169
- elements is provided:
 
 
3170
 
3171
  ``` cpp
3172
  namespace std {
3173
  template<class Allocator>
3174
  class vector<bool, Allocator> {
3175
  public:
3176
  // types
3177
  using value_type = bool;
3178
  using allocator_type = Allocator;
3179
- using pointer = implementation-defined;
3180
- using const_pointer = implementation-defined;
3181
  using const_reference = bool;
3182
- using size_type = implementation-defined; // see [container.requirements]
3183
- using difference_type = implementation-defined; // see [container.requirements]
3184
  using iterator = implementation-defined // type of vector<bool>::iterator; // see [container.requirements]
3185
  using const_iterator = implementation-defined // type of vector<bool>::const_iterator; // see [container.requirements]
3186
  using reverse_iterator = std::reverse_iterator<iterator>;
3187
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3188
 
3189
  // bit reference
3190
  class reference {
3191
  friend class vector;
3192
  constexpr reference() noexcept;
 
3193
  public:
3194
  constexpr reference(const reference&) = default;
3195
  constexpr ~reference();
3196
  constexpr operator bool() const noexcept;
3197
- constexpr reference& operator=(const bool x) noexcept;
3198
  constexpr reference& operator=(const reference& x) noexcept;
 
3199
  constexpr void flip() noexcept; // flips the bit
3200
  };
3201
 
3202
  // construct/copy/destroy
3203
- constexpr vector() : vector(Allocator()) { }
3204
- constexpr explicit vector(const Allocator&);
3205
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
3206
  constexpr vector(size_type n, const bool& value, const Allocator& = Allocator());
3207
  template<class InputIterator>
3208
  constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
 
3209
  constexpr vector(const vector& x);
3210
- constexpr vector(vector&& x);
3211
- constexpr vector(const vector&, const Allocator&);
3212
- constexpr vector(vector&&, const Allocator&);
3213
- constexpr vector(initializer_list<bool>, const Allocator& = Allocator()));
3214
  constexpr ~vector();
3215
  constexpr vector& operator=(const vector& x);
3216
- constexpr vector& operator=(vector&& x);
 
 
3217
  constexpr vector& operator=(initializer_list<bool>);
3218
  template<class InputIterator>
3219
  constexpr void assign(InputIterator first, InputIterator last);
 
 
3220
  constexpr void assign(size_type n, const bool& t);
3221
  constexpr void assign(initializer_list<bool>);
3222
  constexpr allocator_type get_allocator() const noexcept;
3223
 
3224
  // iterators
@@ -3256,23 +5897,29 @@ namespace std {
3256
  constexpr const_reference back() const;
3257
 
3258
  // modifiers
3259
  template<class... Args> constexpr reference emplace_back(Args&&... args);
3260
  constexpr void push_back(const bool& x);
 
 
3261
  constexpr void pop_back();
3262
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
3263
  constexpr iterator insert(const_iterator position, const bool& x);
3264
  constexpr iterator insert(const_iterator position, size_type n, const bool& x);
3265
  template<class InputIterator>
3266
  constexpr iterator insert(const_iterator position,
3267
  InputIterator first, InputIterator last);
 
 
3268
  constexpr iterator insert(const_iterator position, initializer_list<bool> il);
3269
 
3270
  constexpr iterator erase(const_iterator position);
3271
  constexpr iterator erase(const_iterator first, const_iterator last);
3272
- constexpr void swap(vector&);
3273
- constexpr static void swap(reference x, reference y) noexcept;
 
 
3274
  constexpr void flip() noexcept; // flips all bits
3275
  constexpr void clear() noexcept;
3276
  };
3277
  }
3278
  ```
@@ -3289,22 +5936,22 @@ recommended instead.
3289
 
3290
  `reference`
3291
 
3292
  is a class that simulates the behavior of references of a single bit in
3293
  `vector<bool>`. The conversion function returns `true` when the bit is
3294
- set, and `false` otherwise. The assignment operator sets the bit when
3295
- the argument is (convertible to) `true` and clears it otherwise. `flip`
3296
  reverses the state of the bit.
3297
 
3298
  ``` cpp
3299
  constexpr void flip() noexcept;
3300
  ```
3301
 
3302
  *Effects:* Replaces each element in the container with its complement.
3303
 
3304
  ``` cpp
3305
- constexpr static void swap(reference x, reference y) noexcept;
3306
  ```
3307
 
3308
  *Effects:* Exchanges the contents of `x` and `y` as if by:
3309
 
3310
  ``` cpp
@@ -3317,10 +5964,57 @@ y = b;
3317
  template<class Allocator> struct hash<vector<bool, Allocator>>;
3318
  ```
3319
 
3320
  The specialization is enabled [[unord.hash]].
3321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3322
  ## Associative containers <a id="associative">[[associative]]</a>
3323
 
3324
  ### In general <a id="associative.general">[[associative.general]]</a>
3325
 
3326
  The header `<map>` defines the class templates `map` and `multimap`; the
@@ -3333,18 +6027,27 @@ guides for associative containers:
3333
  template<class InputIterator>
3334
  using iter-value-type =
3335
  typename iterator_traits<InputIterator>::value_type; // exposition only
3336
  template<class InputIterator>
3337
  using iter-key-type = remove_const_t<
3338
- typename iterator_traits<InputIterator>::value_type::first_type>; // exposition only
3339
  template<class InputIterator>
3340
  using iter-mapped-type =
3341
- typename iterator_traits<InputIterator>::value_type::second_type; // exposition only
3342
  template<class InputIterator>
3343
  using iter-to-alloc-type = pair<
3344
- add_const_t<typename iterator_traits<InputIterator>::value_type::first_type>,
3345
- typename iterator_traits<InputIterator>::value_type::second_type>; // exposition only
 
 
 
 
 
 
 
 
 
3346
  ```
3347
 
3348
  ### Header `<map>` synopsis <a id="associative.map.syn">[[associative.map.syn]]</a>
3349
 
3350
  ``` cpp
@@ -3368,10 +6071,11 @@ namespace std {
3368
  template<class Key, class T, class Compare, class Allocator>
3369
  void swap(map<Key, T, Compare, Allocator>& x,
3370
  map<Key, T, Compare, Allocator>& y)
3371
  noexcept(noexcept(x.swap(y)));
3372
 
 
3373
  template<class Key, class T, class Compare, class Allocator, class Predicate>
3374
  typename map<Key, T, Compare, Allocator>::size_type
3375
  erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
3376
 
3377
  // [multimap], class template multimap
@@ -3390,10 +6094,11 @@ namespace std {
3390
  template<class Key, class T, class Compare, class Allocator>
3391
  void swap(multimap<Key, T, Compare, Allocator>& x,
3392
  multimap<Key, T, Compare, Allocator>& y)
3393
  noexcept(noexcept(x.swap(y)));
3394
 
 
3395
  template<class Key, class T, class Compare, class Allocator, class Predicate>
3396
  typename multimap<Key, T, Compare, Allocator>::size_type
3397
  erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
3398
 
3399
  namespace pmr {
@@ -3429,10 +6134,11 @@ namespace std {
3429
  template<class Key, class Compare, class Allocator>
3430
  void swap(set<Key, Compare, Allocator>& x,
3431
  set<Key, Compare, Allocator>& y)
3432
  noexcept(noexcept(x.swap(y)));
3433
 
 
3434
  template<class Key, class Compare, class Allocator, class Predicate>
3435
  typename set<Key, Compare, Allocator>::size_type
3436
  erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
3437
 
3438
  // [multiset], class template multiset
@@ -3449,10 +6155,11 @@ namespace std {
3449
  template<class Key, class Compare, class Allocator>
3450
  void swap(multiset<Key, Compare, Allocator>& x,
3451
  multiset<Key, Compare, Allocator>& y)
3452
  noexcept(noexcept(x.swap(y)));
3453
 
 
3454
  template<class Key, class Compare, class Allocator, class Predicate>
3455
  typename multiset<Key, Compare, Allocator>::size_type
3456
  erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
3457
 
3458
  namespace pmr {
@@ -3467,25 +6174,26 @@ namespace std {
3467
 
3468
  ### Class template `map` <a id="map">[[map]]</a>
3469
 
3470
  #### Overview <a id="map.overview">[[map.overview]]</a>
3471
 
3472
- A `map` is an associative container that supports unique keys (contains
3473
- at most one of each key value) and provides for fast retrieval of values
3474
- of another type `T` based on the keys. The `map` class supports
3475
- bidirectional iterators.
3476
 
3477
- A `map` meets all of the requirements of a container, of a reversible
3478
- container [[container.requirements]], of an associative container
3479
- [[associative.reqmts]], and of an allocator-aware container (
3480
- [[container.alloc.req]]). A `map` also provides most operations
3481
- described in  [[associative.reqmts]] for unique keys. This means that a
3482
- `map` supports the `a_uniq` operations in  [[associative.reqmts]] but
3483
- not the `a_eq` operations. For a `map<Key,T>` the `key_type` is `Key`
3484
- and the `value_type` is `pair<const Key,T>`. Descriptions are provided
3485
- here only for operations on `map` that are not described in one of those
3486
- tables or for operations where there is additional semantic information.
 
3487
 
3488
  ``` cpp
3489
  namespace std {
3490
  template<class Key, class T, class Compare = less<Key>,
3491
  class Allocator = allocator<pair<const Key, T>>>
@@ -3499,12 +6207,12 @@ namespace std {
3499
  using allocator_type = Allocator;
3500
  using pointer = typename allocator_traits<Allocator>::pointer;
3501
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
3502
  using reference = value_type&;
3503
  using const_reference = const value_type&;
3504
- using size_type = implementation-defined; // see [container.requirements]
3505
- using difference_type = implementation-defined; // see [container.requirements]
3506
  using iterator = implementation-defined // type of map::iterator; // see [container.requirements]
3507
  using const_iterator = implementation-defined // type of map::const_iterator; // see [container.requirements]
3508
  using reverse_iterator = std::reverse_iterator<iterator>;
3509
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3510
  using node_type = unspecified;
@@ -3513,10 +6221,11 @@ namespace std {
3513
  class value_compare {
3514
  friend class map;
3515
  protected:
3516
  Compare comp;
3517
  value_compare(Compare c) : comp(c) {}
 
3518
  public:
3519
  bool operator()(const value_type& x, const value_type& y) const {
3520
  return comp(x.first, y.first);
3521
  }
3522
  };
@@ -3525,21 +6234,26 @@ namespace std {
3525
  map() : map(Compare()) { }
3526
  explicit map(const Compare& comp, const Allocator& = Allocator());
3527
  template<class InputIterator>
3528
  map(InputIterator first, InputIterator last,
3529
  const Compare& comp = Compare(), const Allocator& = Allocator());
 
 
3530
  map(const map& x);
3531
  map(map&& x);
3532
  explicit map(const Allocator&);
3533
- map(const map&, const Allocator&);
3534
- map(map&&, const Allocator&);
3535
  map(initializer_list<value_type>,
3536
  const Compare& = Compare(),
3537
  const Allocator& = Allocator());
3538
  template<class InputIterator>
3539
  map(InputIterator first, InputIterator last, const Allocator& a)
3540
  : map(first, last, Compare(), a) { }
 
 
 
3541
  map(initializer_list<value_type> il, const Allocator& a)
3542
  : map(il, Compare(), a) { }
3543
  ~map();
3544
  map& operator=(const map& x);
3545
  map& operator=(map&& x)
@@ -3585,14 +6299,17 @@ namespace std {
3585
  iterator insert(const_iterator position, value_type&& x);
3586
  template<class P>
3587
  iterator insert(const_iterator position, P&&);
3588
  template<class InputIterator>
3589
  void insert(InputIterator first, InputIterator last);
 
 
3590
  void insert(initializer_list<value_type>);
3591
 
3592
  node_type extract(const_iterator position);
3593
  node_type extract(const key_type& x);
 
3594
  insert_return_type insert(node_type&& nh);
3595
  iterator insert(const_iterator hint, node_type&& nh);
3596
 
3597
  template<class... Args>
3598
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
@@ -3612,10 +6329,11 @@ namespace std {
3612
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
3613
 
3614
  iterator erase(iterator position);
3615
  iterator erase(const_iterator position);
3616
  size_type erase(const key_type& x);
 
3617
  iterator erase(const_iterator first, const_iterator last);
3618
  void swap(map&)
3619
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
3620
  is_nothrow_swappable_v<Compare>);
3621
  void clear() noexcept;
@@ -3666,28 +6384,31 @@ namespace std {
3666
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
3667
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
3668
  map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
3669
  -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare, Allocator>;
3670
 
 
 
 
 
 
3671
  template<class Key, class T, class Compare = less<Key>,
3672
  class Allocator = allocator<pair<const Key, T>>>
3673
  map(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())
3674
  -> map<Key, T, Compare, Allocator>;
3675
 
3676
  template<class InputIterator, class Allocator>
3677
  map(InputIterator, InputIterator, Allocator)
3678
  -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
3679
  less<iter-key-type<InputIterator>>, Allocator>;
3680
 
 
 
 
 
3681
  template<class Key, class T, class Allocator>
3682
  map(initializer_list<pair<Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;
3683
-
3684
- // swap
3685
- template<class Key, class T, class Compare, class Allocator>
3686
- void swap(map<Key, T, Compare, Allocator>& x,
3687
- map<Key, T, Compare, Allocator>& y)
3688
- noexcept(noexcept(x.swap(y)));
3689
  }
3690
  ```
3691
 
3692
  #### Constructors, copy, and assignment <a id="map.cons">[[map.cons]]</a>
3693
 
@@ -3709,11 +6430,23 @@ template<class InputIterator>
3709
  *Effects:* Constructs an empty `map` using the specified comparison
3710
  object and allocator, and inserts elements from the range \[`first`,
3711
  `last`).
3712
 
3713
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
3714
- sorted using `comp` and otherwise N log N, where N is `last - first`.
 
 
 
 
 
 
 
 
 
 
 
 
3715
 
3716
  #### Element access <a id="map.access">[[map.access]]</a>
3717
 
3718
  ``` cpp
3719
  mapped_type& operator[](const key_type& x);
@@ -3723,11 +6456,12 @@ mapped_type& operator[](const key_type& x);
3723
 
3724
  ``` cpp
3725
  mapped_type& operator[](key_type&& x);
3726
  ```
3727
 
3728
- *Effects:* Equivalent to: `return try_emplace(move(x)).first->second;`
 
3729
 
3730
  ``` cpp
3731
  mapped_type& at(const key_type& x);
3732
  const mapped_type& at(const key_type& x) const;
3733
  ```
@@ -3808,11 +6542,11 @@ template<class M>
3808
  ```
3809
 
3810
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
3811
 
3812
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
3813
- from `k`, `forward<M>(obj)`.
3814
 
3815
  *Effects:* If the map already contains an element `e` whose key is
3816
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
3817
  Otherwise inserts an object of type `value_type` constructed with `k`,
3818
  `std::forward<M>(obj)`.
@@ -3831,11 +6565,11 @@ template<class M>
3831
  ```
3832
 
3833
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
3834
 
3835
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
3836
- from `move(k)`, `forward<M>(obj)`.
3837
 
3838
  *Effects:* If the map already contains an element `e` whose key is
3839
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
3840
  Otherwise inserts an object of type `value_type` constructed with
3841
  `std::move(k)`, `std::forward<M>(obj)`.
@@ -3871,18 +6605,19 @@ return original_size - c.size();
3871
  ### Class template `multimap` <a id="multimap">[[multimap]]</a>
3872
 
3873
  #### Overview <a id="multimap.overview">[[multimap.overview]]</a>
3874
 
3875
  A `multimap` is an associative container that supports equivalent keys
3876
- (possibly containing multiple copies of the same key value) and provides
3877
- for fast retrieval of values of another type `T` based on the keys. The
3878
- `multimap` class supports bidirectional iterators.
3879
 
3880
- A `multimap` meets all of the requirements of a container and of a
3881
- reversible container [[container.requirements]], of an associative
3882
- container [[associative.reqmts]], and of an allocator-aware container (
3883
- [[container.alloc.req]]). A `multimap` also provides most operations
 
3884
  described in  [[associative.reqmts]] for equal keys. This means that a
3885
  `multimap` supports the `a_eq` operations in  [[associative.reqmts]] but
3886
  not the `a_uniq` operations. For a `multimap<Key,T>` the `key_type` is
3887
  `Key` and the `value_type` is `pair<const Key,T>`. Descriptions are
3888
  provided here only for operations on `multimap` that are not described
@@ -3903,12 +6638,12 @@ namespace std {
3903
  using allocator_type = Allocator;
3904
  using pointer = typename allocator_traits<Allocator>::pointer;
3905
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
3906
  using reference = value_type&;
3907
  using const_reference = const value_type&;
3908
- using size_type = implementation-defined; // see [container.requirements]
3909
- using difference_type = implementation-defined; // see [container.requirements]
3910
  using iterator = implementation-defined // type of multimap::iterator; // see [container.requirements]
3911
  using const_iterator = implementation-defined // type of multimap::const_iterator; // see [container.requirements]
3912
  using reverse_iterator = std::reverse_iterator<iterator>;
3913
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3914
  using node_type = unspecified;
@@ -3916,10 +6651,11 @@ namespace std {
3916
  class value_compare {
3917
  friend class multimap;
3918
  protected:
3919
  Compare comp;
3920
  value_compare(Compare c) : comp(c) { }
 
3921
  public:
3922
  bool operator()(const value_type& x, const value_type& y) const {
3923
  return comp(x.first, y.first);
3924
  }
3925
  };
@@ -3929,21 +6665,27 @@ namespace std {
3929
  explicit multimap(const Compare& comp, const Allocator& = Allocator());
3930
  template<class InputIterator>
3931
  multimap(InputIterator first, InputIterator last,
3932
  const Compare& comp = Compare(),
3933
  const Allocator& = Allocator());
 
 
 
3934
  multimap(const multimap& x);
3935
  multimap(multimap&& x);
3936
  explicit multimap(const Allocator&);
3937
- multimap(const multimap&, const Allocator&);
3938
- multimap(multimap&&, const Allocator&);
3939
  multimap(initializer_list<value_type>,
3940
  const Compare& = Compare(),
3941
  const Allocator& = Allocator());
3942
  template<class InputIterator>
3943
  multimap(InputIterator first, InputIterator last, const Allocator& a)
3944
  : multimap(first, last, Compare(), a) { }
 
 
 
3945
  multimap(initializer_list<value_type> il, const Allocator& a)
3946
  : multimap(il, Compare(), a) { }
3947
  ~multimap();
3948
  multimap& operator=(const multimap& x);
3949
  multimap& operator=(multimap&& x)
@@ -3982,20 +6724,24 @@ namespace std {
3982
  iterator insert(const_iterator position, const value_type& x);
3983
  iterator insert(const_iterator position, value_type&& x);
3984
  template<class P> iterator insert(const_iterator position, P&& x);
3985
  template<class InputIterator>
3986
  void insert(InputIterator first, InputIterator last);
 
 
3987
  void insert(initializer_list<value_type>);
3988
 
3989
  node_type extract(const_iterator position);
3990
  node_type extract(const key_type& x);
 
3991
  iterator insert(node_type&& nh);
3992
  iterator insert(const_iterator hint, node_type&& nh);
3993
 
3994
  iterator erase(iterator position);
3995
  iterator erase(const_iterator position);
3996
  size_type erase(const key_type& x);
 
3997
  iterator erase(const_iterator first, const_iterator last);
3998
  void swap(multimap&)
3999
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4000
  is_nothrow_swappable_v<Compare>);
4001
  void clear() noexcept;
@@ -4047,29 +6793,32 @@ namespace std {
4047
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
4048
  multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
4049
  -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
4050
  Compare, Allocator>;
4051
 
 
 
 
 
 
4052
  template<class Key, class T, class Compare = less<Key>,
4053
  class Allocator = allocator<pair<const Key, T>>>
4054
  multimap(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())
4055
  -> multimap<Key, T, Compare, Allocator>;
4056
 
4057
  template<class InputIterator, class Allocator>
4058
  multimap(InputIterator, InputIterator, Allocator)
4059
  -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
4060
  less<iter-key-type<InputIterator>>, Allocator>;
4061
 
 
 
 
 
4062
  template<class Key, class T, class Allocator>
4063
  multimap(initializer_list<pair<Key, T>>, Allocator)
4064
  -> multimap<Key, T, less<Key>, Allocator>;
4065
-
4066
- // swap
4067
- template<class Key, class T, class Compare, class Allocator>
4068
- void swap(multimap<Key, T, Compare, Allocator>& x,
4069
- multimap<Key, T, Compare, Allocator>& y)
4070
- noexcept(noexcept(x.swap(y)));
4071
  }
4072
  ```
4073
 
4074
  #### Constructors <a id="multimap.cons">[[multimap.cons]]</a>
4075
 
@@ -4092,11 +6841,23 @@ template<class InputIterator>
4092
  *Effects:* Constructs an empty `multimap` using the specified comparison
4093
  object and allocator, and inserts elements from the range \[`first`,
4094
  `last`).
4095
 
4096
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4097
- sorted using `comp` and otherwise N log N, where N is `last - first`.
 
 
 
 
 
 
 
 
 
 
 
 
4098
 
4099
  #### Modifiers <a id="multimap.modifiers">[[multimap.modifiers]]</a>
4100
 
4101
  ``` cpp
4102
  template<class P> iterator insert(P&& x);
@@ -4133,24 +6894,26 @@ return original_size - c.size();
4133
 
4134
  ### Class template `set` <a id="set">[[set]]</a>
4135
 
4136
  #### Overview <a id="set.overview">[[set.overview]]</a>
4137
 
4138
- A `set` is an associative container that supports unique keys (contains
4139
- at most one of each key value) and provides for fast retrieval of the
4140
- keys themselves. The `set` class supports bidirectional iterators.
 
4141
 
4142
- A `set` meets all of the requirements of a container, of a reversible
4143
- container [[container.requirements]], of an associative container
4144
- [[associative.reqmts]], and of an allocator-aware container (
4145
- [[container.alloc.req]]). A `set` also provides most operations
4146
- described in  [[associative.reqmts]] for unique keys. This means that a
4147
- `set` supports the `a_uniq` operations in  [[associative.reqmts]] but
4148
- not the `a_eq` operations. For a `set<Key>` both the `key_type` and
4149
- `value_type` are `Key`. Descriptions are provided here only for
4150
- operations on `set` that are not described in one of these tables and
4151
- for operations where there is additional semantic information.
 
4152
 
4153
  ``` cpp
4154
  namespace std {
4155
  template<class Key, class Compare = less<Key>,
4156
  class Allocator = allocator<Key>>
@@ -4164,12 +6927,12 @@ namespace std {
4164
  using allocator_type = Allocator;
4165
  using pointer = typename allocator_traits<Allocator>::pointer;
4166
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4167
  using reference = value_type&;
4168
  using const_reference = const value_type&;
4169
- using size_type = implementation-defined; // see [container.requirements]
4170
- using difference_type = implementation-defined; // see [container.requirements]
4171
  using iterator = implementation-defined // type of set::iterator; // see [container.requirements]
4172
  using const_iterator = implementation-defined // type of set::const_iterator; // see [container.requirements]
4173
  using reverse_iterator = std::reverse_iterator<iterator>;
4174
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
4175
  using node_type = unspecified;
@@ -4179,20 +6942,25 @@ namespace std {
4179
  set() : set(Compare()) { }
4180
  explicit set(const Compare& comp, const Allocator& = Allocator());
4181
  template<class InputIterator>
4182
  set(InputIterator first, InputIterator last,
4183
  const Compare& comp = Compare(), const Allocator& = Allocator());
 
 
4184
  set(const set& x);
4185
  set(set&& x);
4186
  explicit set(const Allocator&);
4187
- set(const set&, const Allocator&);
4188
- set(set&&, const Allocator&);
4189
  set(initializer_list<value_type>, const Compare& = Compare(),
4190
  const Allocator& = Allocator());
4191
  template<class InputIterator>
4192
  set(InputIterator first, InputIterator last, const Allocator& a)
4193
  : set(first, last, Compare(), a) { }
 
 
 
4194
  set(initializer_list<value_type> il, const Allocator& a)
4195
  : set(il, Compare(), a) { }
4196
  ~set();
4197
  set& operator=(const set& x);
4198
  set& operator=(set&& x)
@@ -4229,20 +6997,25 @@ namespace std {
4229
  pair<iterator,bool> insert(value_type&& x);
4230
  iterator insert(const_iterator position, const value_type& x);
4231
  iterator insert(const_iterator position, value_type&& x);
4232
  template<class InputIterator>
4233
  void insert(InputIterator first, InputIterator last);
 
 
4234
  void insert(initializer_list<value_type>);
4235
 
4236
  node_type extract(const_iterator position);
4237
  node_type extract(const key_type& x);
 
4238
  insert_return_type insert(node_type&& nh);
4239
  iterator insert(const_iterator hint, node_type&& nh);
4240
 
4241
- iterator erase(iterator position);
 
4242
  iterator erase(const_iterator position);
4243
  size_type erase(const key_type& x);
 
4244
  iterator erase(const_iterator first, const_iterator last);
4245
  void swap(set&)
4246
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4247
  is_nothrow_swappable_v<Compare>);
4248
  void clear() noexcept;
@@ -4295,38 +7068,41 @@ namespace std {
4295
  class Allocator = allocator<iter-value-type<InputIterator>>>
4296
  set(InputIterator, InputIterator,
4297
  Compare = Compare(), Allocator = Allocator())
4298
  -> set<iter-value-type<InputIterator>, Compare, Allocator>;
4299
 
 
 
 
 
 
4300
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
4301
  set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
4302
  -> set<Key, Compare, Allocator>;
4303
 
4304
  template<class InputIterator, class Allocator>
4305
  set(InputIterator, InputIterator, Allocator)
4306
  -> set<iter-value-type<InputIterator>,
4307
  less<iter-value-type<InputIterator>>, Allocator>;
4308
 
 
 
 
 
4309
  template<class Key, class Allocator>
4310
  set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>;
4311
-
4312
- // swap
4313
- template<class Key, class Compare, class Allocator>
4314
- void swap(set<Key, Compare, Allocator>& x,
4315
- set<Key, Compare, Allocator>& y)
4316
- noexcept(noexcept(x.swap(y)));
4317
  }
4318
  ```
4319
 
4320
  #### Constructors, copy, and assignment <a id="set.cons">[[set.cons]]</a>
4321
 
4322
  ``` cpp
4323
  explicit set(const Compare& comp, const Allocator& = Allocator());
4324
  ```
4325
 
4326
  *Effects:* Constructs an empty `set` using the specified comparison
4327
- objects and allocator.
4328
 
4329
  *Complexity:* Constant.
4330
 
4331
  ``` cpp
4332
  template<class InputIterator>
@@ -4337,11 +7113,23 @@ template<class InputIterator>
4337
  *Effects:* Constructs an empty `set` using the specified comparison
4338
  object and allocator, and inserts elements from the range \[`first`,
4339
  `last`).
4340
 
4341
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4342
- sorted using `comp` and otherwise N log N, where N is `last - first`.
 
 
 
 
 
 
 
 
 
 
 
 
4343
 
4344
  #### Erasure <a id="set.erasure">[[set.erasure]]</a>
4345
 
4346
  ``` cpp
4347
  template<class Key, class Compare, class Allocator, class Predicate>
@@ -4366,18 +7154,19 @@ return original_size - c.size();
4366
  ### Class template `multiset` <a id="multiset">[[multiset]]</a>
4367
 
4368
  #### Overview <a id="multiset.overview">[[multiset.overview]]</a>
4369
 
4370
  A `multiset` is an associative container that supports equivalent keys
4371
- (possibly contains multiple copies of the same key value) and provides
4372
- for fast retrieval of the keys themselves. The `multiset` class supports
4373
- bidirectional iterators.
4374
 
4375
- A `multiset` meets all of the requirements of a container, of a
4376
- reversible container [[container.requirements]], of an associative
4377
- container [[associative.reqmts]], and of an allocator-aware container (
4378
- [[container.alloc.req]]). `multiset` also provides most operations
 
4379
  described in  [[associative.reqmts]] for duplicate keys. This means that
4380
  a `multiset` supports the `a_eq` operations in  [[associative.reqmts]]
4381
  but not the `a_uniq` operations. For a `multiset<Key>` both the
4382
  `key_type` and `value_type` are `Key`. Descriptions are provided here
4383
  only for operations on `multiset` that are not described in one of these
@@ -4398,12 +7187,12 @@ namespace std {
4398
  using allocator_type = Allocator;
4399
  using pointer = typename allocator_traits<Allocator>::pointer;
4400
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4401
  using reference = value_type&;
4402
  using const_reference = const value_type&;
4403
- using size_type = implementation-defined; // see [container.requirements]
4404
- using difference_type = implementation-defined; // see [container.requirements]
4405
  using iterator = implementation-defined // type of multiset::iterator; // see [container.requirements]
4406
  using const_iterator = implementation-defined // type of multiset::const_iterator; // see [container.requirements]
4407
  using reverse_iterator = std::reverse_iterator<iterator>;
4408
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
4409
  using node_type = unspecified;
@@ -4412,20 +7201,26 @@ namespace std {
4412
  multiset() : multiset(Compare()) { }
4413
  explicit multiset(const Compare& comp, const Allocator& = Allocator());
4414
  template<class InputIterator>
4415
  multiset(InputIterator first, InputIterator last,
4416
  const Compare& comp = Compare(), const Allocator& = Allocator());
 
 
 
4417
  multiset(const multiset& x);
4418
  multiset(multiset&& x);
4419
  explicit multiset(const Allocator&);
4420
- multiset(const multiset&, const Allocator&);
4421
- multiset(multiset&&, const Allocator&);
4422
  multiset(initializer_list<value_type>, const Compare& = Compare(),
4423
  const Allocator& = Allocator());
4424
  template<class InputIterator>
4425
  multiset(InputIterator first, InputIterator last, const Allocator& a)
4426
  : multiset(first, last, Compare(), a) { }
 
 
 
4427
  multiset(initializer_list<value_type> il, const Allocator& a)
4428
  : multiset(il, Compare(), a) { }
4429
  ~multiset();
4430
  multiset& operator=(const multiset& x);
4431
  multiset& operator=(multiset&& x)
@@ -4462,20 +7257,25 @@ namespace std {
4462
  iterator insert(value_type&& x);
4463
  iterator insert(const_iterator position, const value_type& x);
4464
  iterator insert(const_iterator position, value_type&& x);
4465
  template<class InputIterator>
4466
  void insert(InputIterator first, InputIterator last);
 
 
4467
  void insert(initializer_list<value_type>);
4468
 
4469
  node_type extract(const_iterator position);
4470
  node_type extract(const key_type& x);
 
4471
  iterator insert(node_type&& nh);
4472
  iterator insert(const_iterator hint, node_type&& nh);
4473
 
4474
- iterator erase(iterator position);
 
4475
  iterator erase(const_iterator position);
4476
  size_type erase(const key_type& x);
 
4477
  iterator erase(const_iterator first, const_iterator last);
4478
  void swap(multiset&)
4479
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4480
  is_nothrow_swappable_v<Compare>);
4481
  void clear() noexcept;
@@ -4528,27 +7328,30 @@ namespace std {
4528
  class Allocator = allocator<iter-value-type<InputIterator>>>
4529
  multiset(InputIterator, InputIterator,
4530
  Compare = Compare(), Allocator = Allocator())
4531
  -> multiset<iter-value-type<InputIterator>, Compare, Allocator>;
4532
 
 
 
 
 
 
4533
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
4534
  multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
4535
  -> multiset<Key, Compare, Allocator>;
4536
 
4537
  template<class InputIterator, class Allocator>
4538
  multiset(InputIterator, InputIterator, Allocator)
4539
  -> multiset<iter-value-type<InputIterator>,
4540
  less<iter-value-type<InputIterator>>, Allocator>;
4541
 
 
 
 
 
4542
  template<class Key, class Allocator>
4543
  multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>;
4544
-
4545
- // swap
4546
- template<class Key, class Compare, class Allocator>
4547
- void swap(multiset<Key, Compare, Allocator>& x,
4548
- multiset<Key, Compare, Allocator>& y)
4549
- noexcept(noexcept(x.swap(y)));
4550
  }
4551
  ```
4552
 
4553
  #### Constructors <a id="multiset.cons">[[multiset.cons]]</a>
4554
 
@@ -4570,11 +7373,23 @@ template<class InputIterator>
4570
  *Effects:* Constructs an empty `multiset` using the specified comparison
4571
  object and allocator, and inserts elements from the range \[`first`,
4572
  `last`).
4573
 
4574
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4575
- sorted using `comp` and otherwise N log N, where N is `last - first`.
 
 
 
 
 
 
 
 
 
 
 
 
4576
 
4577
  #### Erasure <a id="multiset.erasure">[[multiset.erasure]]</a>
4578
 
4579
  ``` cpp
4580
  template<class Key, class Compare, class Allocator, class Predicate>
@@ -4603,11 +7418,12 @@ return original_size - c.size();
4603
  The header `<unordered_map>` defines the class templates `unordered_map`
4604
  and `unordered_multimap`; the header `<unordered_set>` defines the class
4605
  templates `unordered_set` and `unordered_multiset`.
4606
 
4607
  The exposition-only alias templates *`iter-value-type`*,
4608
- *`iter-key-type`*, *`iter-mapped-type`*, and *`iter-to-alloc-type`*
 
4609
  defined in [[associative.general]] may appear in deduction guides for
4610
  unordered containers.
4611
 
4612
  ### Header `<unordered_map>` synopsis <a id="unord.map.syn">[[unord.map.syn]]</a>
4613
 
@@ -4648,14 +7464,16 @@ namespace std {
4648
  template<class Key, class T, class Hash, class Pred, class Alloc>
4649
  void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
4650
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
4651
  noexcept(noexcept(x.swap(y)));
4652
 
 
4653
  template<class K, class T, class H, class P, class A, class Predicate>
4654
  typename unordered_map<K, T, H, P, A>::size_type
4655
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
4656
 
 
4657
  template<class K, class T, class H, class P, class A, class Predicate>
4658
  typename unordered_multimap<K, T, H, P, A>::size_type
4659
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
4660
 
4661
  namespace pmr {
@@ -4715,14 +7533,16 @@ namespace std {
4715
  template<class Key, class Hash, class Pred, class Alloc>
4716
  void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
4717
  unordered_multiset<Key, Hash, Pred, Alloc>& y)
4718
  noexcept(noexcept(x.swap(y)));
4719
 
 
4720
  template<class K, class H, class P, class A, class Predicate>
4721
  typename unordered_set<K, H, P, A>::size_type
4722
  erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
4723
 
 
4724
  template<class K, class H, class P, class A, class Predicate>
4725
  typename unordered_multiset<K, H, P, A>::size_type
4726
  erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
4727
 
4728
  namespace pmr {
@@ -4748,18 +7568,18 @@ namespace std {
4748
  An `unordered_map` is an unordered associative container that supports
4749
  unique keys (an `unordered_map` contains at most one of each key value)
4750
  and that associates values of another type `mapped_type` with the keys.
4751
  The `unordered_map` class supports forward iterators.
4752
 
4753
- An `unordered_map` meets all of the requirements of a container, of an
4754
- unordered associative container, and of an allocator-aware container (
4755
- [[container.alloc.req]]). It provides the operations described in the
4756
- preceding requirements table for unique keys; that is, an
4757
- `unordered_map` supports the `a_uniq` operations in that table, not the
4758
- `a_eq` operations. For an `unordered_map<Key, T>` the `key type` is
4759
- `Key`, the mapped type is `T`, and the value type is
4760
- `pair<const Key, T>`.
4761
 
4762
  Subclause  [[unord.map]] only describes operations on `unordered_map`
4763
  that are not described in one of the requirement tables, or for which
4764
  there is additional semantic information.
4765
 
@@ -4781,12 +7601,12 @@ namespace std {
4781
  using allocator_type = Allocator;
4782
  using pointer = typename allocator_traits<Allocator>::pointer;
4783
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4784
  using reference = value_type&;
4785
  using const_reference = const value_type&;
4786
- using size_type = implementation-defined; // see [container.requirements]
4787
- using difference_type = implementation-defined; // see [container.requirements]
4788
 
4789
  using iterator = implementation-defined // type of unordered_map::iterator; // see [container.requirements]
4790
  using const_iterator = implementation-defined // type of unordered_map::const_iterator; // see [container.requirements]
4791
  using local_iterator = implementation-defined // type of unordered_map::local_iterator; // see [container.requirements]
4792
  using const_local_iterator = implementation-defined // type of unordered_map::const_local_iterator; // see [container.requirements]
@@ -4803,15 +7623,20 @@ namespace std {
4803
  unordered_map(InputIterator f, InputIterator l,
4804
  size_type n = see below,
4805
  const hasher& hf = hasher(),
4806
  const key_equal& eql = key_equal(),
4807
  const allocator_type& a = allocator_type());
 
 
 
 
 
4808
  unordered_map(const unordered_map&);
4809
  unordered_map(unordered_map&&);
4810
  explicit unordered_map(const Allocator&);
4811
- unordered_map(const unordered_map&, const Allocator&);
4812
- unordered_map(unordered_map&&, const Allocator&);
4813
  unordered_map(initializer_list<value_type> il,
4814
  size_type n = see below,
4815
  const hasher& hf = hasher(),
4816
  const key_equal& eql = key_equal(),
4817
  const allocator_type& a = allocator_type());
@@ -4824,10 +7649,16 @@ namespace std {
4824
  : unordered_map(f, l, n, hasher(), key_equal(), a) { }
4825
  template<class InputIterator>
4826
  unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
4827
  const allocator_type& a)
4828
  : unordered_map(f, l, n, hf, key_equal(), a) { }
 
 
 
 
 
 
4829
  unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
4830
  : unordered_map(il, n, hasher(), key_equal(), a) { }
4831
  unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
4832
  const allocator_type& a)
4833
  : unordered_map(il, n, hf, key_equal(), a) { }
@@ -4861,14 +7692,17 @@ namespace std {
4861
  template<class P> pair<iterator, bool> insert(P&& obj);
4862
  iterator insert(const_iterator hint, const value_type& obj);
4863
  iterator insert(const_iterator hint, value_type&& obj);
4864
  template<class P> iterator insert(const_iterator hint, P&& obj);
4865
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
 
4866
  void insert(initializer_list<value_type>);
4867
 
4868
  node_type extract(const_iterator position);
4869
  node_type extract(const key_type& x);
 
4870
  insert_return_type insert(node_type&& nh);
4871
  iterator insert(const_iterator hint, node_type&& nh);
4872
 
4873
  template<class... Args>
4874
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
@@ -4888,10 +7722,11 @@ namespace std {
4888
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
4889
 
4890
  iterator erase(iterator position);
4891
  iterator erase(const_iterator position);
4892
  size_type erase(const key_type& k);
 
4893
  iterator erase(const_iterator first, const_iterator last);
4894
  void swap(unordered_map&)
4895
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4896
  is_nothrow_swappable_v<Hash> &&
4897
  is_nothrow_swappable_v<Pred>);
@@ -4915,11 +7750,10 @@ namespace std {
4915
  const_iterator find(const key_type& k) const;
4916
  template<class K>
4917
  iterator find(const K& k);
4918
  template<class K>
4919
  const_iterator find(const K& k) const;
4920
- template<class K>
4921
  size_type count(const key_type& k) const;
4922
  template<class K>
4923
  size_type count(const K& k) const;
4924
  bool contains(const key_type& k) const;
4925
  template<class K>
@@ -4964,10 +7798,17 @@ namespace std {
4964
  unordered_map(InputIterator, InputIterator, typename see below::size_type = see below,
4965
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
4966
  -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred,
4967
  Allocator>;
4968
 
 
 
 
 
 
 
 
4969
  template<class Key, class T, class Hash = hash<Key>,
4970
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
4971
  unordered_map(initializer_list<pair<Key, T>>,
4972
  typename see below::size_type = see below, Hash = Hash(),
4973
  Pred = Pred(), Allocator = Allocator())
@@ -4988,10 +7829,25 @@ namespace std {
4988
  template<class InputIterator, class Hash, class Allocator>
4989
  unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator)
4990
  -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash,
4991
  equal_to<iter-key-type<InputIterator>>, Allocator>;
4992
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4993
  template<class Key, class T, class Allocator>
4994
  unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type,
4995
  Allocator)
4996
  -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
4997
 
@@ -5001,16 +7857,10 @@ namespace std {
5001
 
5002
  template<class Key, class T, class Hash, class Allocator>
5003
  unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash,
5004
  Allocator)
5005
  -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;
5006
-
5007
- // swap
5008
- template<class Key, class T, class Hash, class Pred, class Alloc>
5009
- void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
5010
- unordered_map<Key, T, Hash, Pred, Alloc>& y)
5011
- noexcept(noexcept(x.swap(y)));
5012
  }
5013
  ```
5014
 
5015
  A `size_type` parameter type in an `unordered_map` deduction guide
5016
  refers to the `size_type` member type of the type deduced by the
@@ -5038,10 +7888,16 @@ template<class InputIterator>
5038
  unordered_map(InputIterator f, InputIterator l,
5039
  size_type n = see below,
5040
  const hasher& hf = hasher(),
5041
  const key_equal& eql = key_equal(),
5042
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5043
  unordered_map(initializer_list<value_type> il,
5044
  size_type n = see below,
5045
  const hasher& hf = hasher(),
5046
  const key_equal& eql = key_equal(),
5047
  const allocator_type& a = allocator_type());
@@ -5049,12 +7905,11 @@ unordered_map(initializer_list<value_type> il,
5049
 
5050
  *Effects:* Constructs an empty `unordered_map` using the specified hash
5051
  function, key equality predicate, and allocator, and using at least `n`
5052
  buckets. If `n` is not provided, the number of buckets is
5053
  *implementation-defined*. Then inserts elements from the range \[`f`,
5054
- `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
5055
- for the second form. `max_load_factor()` returns `1.0`.
5056
 
5057
  *Complexity:* Average case linear, worst case quadratic.
5058
 
5059
  #### Element access <a id="unord.map.elem">[[unord.map.elem]]</a>
5060
 
@@ -5066,11 +7921,12 @@ mapped_type& operator[](const key_type& k);
5066
 
5067
  ``` cpp
5068
  mapped_type& operator[](key_type&& k);
5069
  ```
5070
 
5071
- *Effects:* Equivalent to: `return try_emplace(move(k)).first->second;`
 
5072
 
5073
  ``` cpp
5074
  mapped_type& at(const key_type& k);
5075
  const mapped_type& at(const key_type& k) const;
5076
  ```
@@ -5224,18 +8080,18 @@ An `unordered_multimap` is an unordered associative container that
5224
  supports equivalent keys (an instance of `unordered_multimap` may
5225
  contain multiple copies of each key value) and that associates values of
5226
  another type `mapped_type` with the keys. The `unordered_multimap` class
5227
  supports forward iterators.
5228
 
5229
- An `unordered_multimap` meets all of the requirements of a container, of
5230
- an unordered associative container, and of an allocator-aware container
5231
- ([[container.alloc.req]]). It provides the operations described in the
5232
- preceding requirements table for equivalent keys; that is, an
5233
- `unordered_multimap` supports the `a_eq` operations in that table, not
5234
- the `a_uniq` operations. For an `unordered_multimap<Key, T>` the
5235
- `key type` is `Key`, the mapped type is `T`, and the value type is
5236
- `pair<const Key, T>`.
5237
 
5238
  Subclause  [[unord.multimap]] only describes operations on
5239
  `unordered_multimap` that are not described in one of the requirement
5240
  tables, or for which there is additional semantic information.
5241
 
@@ -5257,12 +8113,12 @@ namespace std {
5257
  using allocator_type = Allocator;
5258
  using pointer = typename allocator_traits<Allocator>::pointer;
5259
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
5260
  using reference = value_type&;
5261
  using const_reference = const value_type&;
5262
- using size_type = implementation-defined; // see [container.requirements]
5263
- using difference_type = implementation-defined; // see [container.requirements]
5264
 
5265
  using iterator = implementation-defined // type of unordered_multimap::iterator; // see [container.requirements]
5266
  using const_iterator = implementation-defined // type of unordered_multimap::const_iterator; // see [container.requirements]
5267
  using local_iterator = implementation-defined // type of unordered_multimap::local_iterator; // see [container.requirements]
5268
  using const_local_iterator = implementation-defined // type of unordered_multimap::const_local_iterator; // see [container.requirements]
@@ -5278,15 +8134,21 @@ namespace std {
5278
  unordered_multimap(InputIterator f, InputIterator l,
5279
  size_type n = see below,
5280
  const hasher& hf = hasher(),
5281
  const key_equal& eql = key_equal(),
5282
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5283
  unordered_multimap(const unordered_multimap&);
5284
  unordered_multimap(unordered_multimap&&);
5285
  explicit unordered_multimap(const Allocator&);
5286
- unordered_multimap(const unordered_multimap&, const Allocator&);
5287
- unordered_multimap(unordered_multimap&&, const Allocator&);
5288
  unordered_multimap(initializer_list<value_type> il,
5289
  size_type n = see below,
5290
  const hasher& hf = hasher(),
5291
  const key_equal& eql = key_equal(),
5292
  const allocator_type& a = allocator_type());
@@ -5299,10 +8161,18 @@ namespace std {
5299
  : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
5300
  template<class InputIterator>
5301
  unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
5302
  const allocator_type& a)
5303
  : unordered_multimap(f, l, n, hf, key_equal(), a) { }
 
 
 
 
 
 
 
 
5304
  unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
5305
  : unordered_multimap(il, n, hasher(), key_equal(), a) { }
5306
  unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
5307
  const allocator_type& a)
5308
  : unordered_multimap(il, n, hf, key_equal(), a) { }
@@ -5336,20 +8206,24 @@ namespace std {
5336
  template<class P> iterator insert(P&& obj);
5337
  iterator insert(const_iterator hint, const value_type& obj);
5338
  iterator insert(const_iterator hint, value_type&& obj);
5339
  template<class P> iterator insert(const_iterator hint, P&& obj);
5340
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
 
5341
  void insert(initializer_list<value_type>);
5342
 
5343
  node_type extract(const_iterator position);
5344
  node_type extract(const key_type& x);
 
5345
  iterator insert(node_type&& nh);
5346
  iterator insert(const_iterator hint, node_type&& nh);
5347
 
5348
  iterator erase(iterator position);
5349
  iterator erase(const_iterator position);
5350
  size_type erase(const key_type& k);
 
5351
  iterator erase(const_iterator first, const_iterator last);
5352
  void swap(unordered_multimap&)
5353
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
5354
  is_nothrow_swappable_v<Hash> &&
5355
  is_nothrow_swappable_v<Pred>);
@@ -5416,10 +8290,18 @@ namespace std {
5416
  typename see below::size_type = see below,
5417
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5418
  -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
5419
  Hash, Pred, Allocator>;
5420
 
 
 
 
 
 
 
 
 
5421
  template<class Key, class T, class Hash = hash<Key>,
5422
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
5423
  unordered_multimap(initializer_list<pair<Key, T>>,
5424
  typename see below::size_type = see below,
5425
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
@@ -5441,10 +8323,25 @@ namespace std {
5441
  unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash,
5442
  Allocator)
5443
  -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash,
5444
  equal_to<iter-key-type<InputIterator>>, Allocator>;
5445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5446
  template<class Key, class T, class Allocator>
5447
  unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type,
5448
  Allocator)
5449
  -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
5450
 
@@ -5454,16 +8351,10 @@ namespace std {
5454
 
5455
  template<class Key, class T, class Hash, class Allocator>
5456
  unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type,
5457
  Hash, Allocator)
5458
  -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;
5459
-
5460
- // swap
5461
- template<class Key, class T, class Hash, class Pred, class Alloc>
5462
- void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
5463
- unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
5464
- noexcept(noexcept(x.swap(y)));
5465
  }
5466
  ```
5467
 
5468
  A `size_type` parameter type in an `unordered_multimap` deduction guide
5469
  refers to the `size_type` member type of the type deduced by the
@@ -5491,10 +8382,16 @@ template<class InputIterator>
5491
  unordered_multimap(InputIterator f, InputIterator l,
5492
  size_type n = see below,
5493
  const hasher& hf = hasher(),
5494
  const key_equal& eql = key_equal(),
5495
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5496
  unordered_multimap(initializer_list<value_type> il,
5497
  size_type n = see below,
5498
  const hasher& hf = hasher(),
5499
  const key_equal& eql = key_equal(),
5500
  const allocator_type& a = allocator_type());
@@ -5502,12 +8399,11 @@ unordered_multimap(initializer_list<value_type> il,
5502
 
5503
  *Effects:* Constructs an empty `unordered_multimap` using the specified
5504
  hash function, key equality predicate, and allocator, and using at least
5505
  `n` buckets. If `n` is not provided, the number of buckets is
5506
  *implementation-defined*. Then inserts elements from the range \[`f`,
5507
- `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
5508
- for the second form. `max_load_factor()` returns `1.0`.
5509
 
5510
  *Complexity:* Average case linear, worst case quadratic.
5511
 
5512
  #### Modifiers <a id="unord.multimap.modifiers">[[unord.multimap.modifiers]]</a>
5513
 
@@ -5559,19 +8455,19 @@ return original_size - c.size();
5559
  An `unordered_set` is an unordered associative container that supports
5560
  unique keys (an `unordered_set` contains at most one of each key value)
5561
  and in which the elements’ keys are the elements themselves. The
5562
  `unordered_set` class supports forward iterators.
5563
 
5564
- An `unordered_set` meets all of the requirements of a container, of an
5565
- unordered associative container, and of an allocator-aware container (
5566
- [[container.alloc.req]]). It provides the operations described in the
5567
- preceding requirements table for unique keys; that is, an
5568
- `unordered_set` supports the `a_uniq` operations in that table, not the
5569
- `a_eq` operations. For an `unordered_set<Key>` the `key type` and the
5570
- value type are both `Key`. The `iterator` and `const_iterator` types are
5571
- both constant iterator types. It is unspecified whether they are the
5572
- same type.
5573
 
5574
  Subclause  [[unord.set]] only describes operations on `unordered_set`
5575
  that are not described in one of the requirement tables, or for which
5576
  there is additional semantic information.
5577
 
@@ -5591,12 +8487,12 @@ namespace std {
5591
  using allocator_type = Allocator;
5592
  using pointer = typename allocator_traits<Allocator>::pointer;
5593
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
5594
  using reference = value_type&;
5595
  using const_reference = const value_type&;
5596
- using size_type = implementation-defined; // see [container.requirements]
5597
- using difference_type = implementation-defined; // see [container.requirements]
5598
 
5599
  using iterator = implementation-defined // type of unordered_set::iterator; // see [container.requirements]
5600
  using const_iterator = implementation-defined // type of unordered_set::const_iterator; // see [container.requirements]
5601
  using local_iterator = implementation-defined // type of unordered_set::local_iterator; // see [container.requirements]
5602
  using const_local_iterator = implementation-defined // type of unordered_set::const_local_iterator; // see [container.requirements]
@@ -5613,15 +8509,21 @@ namespace std {
5613
  unordered_set(InputIterator f, InputIterator l,
5614
  size_type n = see below,
5615
  const hasher& hf = hasher(),
5616
  const key_equal& eql = key_equal(),
5617
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5618
  unordered_set(const unordered_set&);
5619
  unordered_set(unordered_set&&);
5620
  explicit unordered_set(const Allocator&);
5621
- unordered_set(const unordered_set&, const Allocator&);
5622
- unordered_set(unordered_set&&, const Allocator&);
5623
  unordered_set(initializer_list<value_type> il,
5624
  size_type n = see below,
5625
  const hasher& hf = hasher(),
5626
  const key_equal& eql = key_equal(),
5627
  const allocator_type& a = allocator_type());
@@ -5636,10 +8538,16 @@ namespace std {
5636
  unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
5637
  const allocator_type& a)
5638
  : unordered_set(f, l, n, hf, key_equal(), a) { }
5639
  unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
5640
  : unordered_set(il, n, hasher(), key_equal(), a) { }
 
 
 
 
 
 
5641
  unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
5642
  const allocator_type& a)
5643
  : unordered_set(il, n, hf, key_equal(), a) { }
5644
  ~unordered_set();
5645
  unordered_set& operator=(const unordered_set&);
@@ -5669,20 +8577,25 @@ namespace std {
5669
  pair<iterator, bool> insert(const value_type& obj);
5670
  pair<iterator, bool> insert(value_type&& obj);
5671
  iterator insert(const_iterator hint, const value_type& obj);
5672
  iterator insert(const_iterator hint, value_type&& obj);
5673
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
 
5674
  void insert(initializer_list<value_type>);
5675
 
5676
  node_type extract(const_iterator position);
5677
  node_type extract(const key_type& x);
 
5678
  insert_return_type insert(node_type&& nh);
5679
  iterator insert(const_iterator hint, node_type&& nh);
5680
 
5681
- iterator erase(iterator position);
 
5682
  iterator erase(const_iterator position);
5683
  size_type erase(const key_type& k);
 
5684
  iterator erase(const_iterator first, const_iterator last);
5685
  void swap(unordered_set&)
5686
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
5687
  is_nothrow_swappable_v<Hash> &&
5688
  is_nothrow_swappable_v<Pred>);
@@ -5748,10 +8661,18 @@ namespace std {
5748
  unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
5749
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5750
  -> unordered_set<iter-value-type<InputIterator>,
5751
  Hash, Pred, Allocator>;
5752
 
 
 
 
 
 
 
 
 
5753
  template<class T, class Hash = hash<T>,
5754
  class Pred = equal_to<T>, class Allocator = allocator<T>>
5755
  unordered_set(initializer_list<T>, typename see below::size_type = see below,
5756
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5757
  -> unordered_set<T, Hash, Pred, Allocator>;
@@ -5768,23 +8689,32 @@ namespace std {
5768
  Hash, Allocator)
5769
  -> unordered_set<iter-value-type<InputIterator>, Hash,
5770
  equal_to<iter-value-type<InputIterator>>,
5771
  Allocator>;
5772
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5773
  template<class T, class Allocator>
5774
  unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
5775
  -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;
5776
 
5777
  template<class T, class Hash, class Allocator>
5778
  unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
5779
  -> unordered_set<T, Hash, equal_to<T>, Allocator>;
5780
-
5781
- // swap
5782
- template<class Key, class Hash, class Pred, class Alloc>
5783
- void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
5784
- unordered_set<Key, Hash, Pred, Alloc>& y)
5785
- noexcept(noexcept(x.swap(y)));
5786
  }
5787
  ```
5788
 
5789
  A `size_type` parameter type in an `unordered_set` deduction guide
5790
  refers to the `size_type` member type of the type deduced by the
@@ -5812,10 +8742,16 @@ template<class InputIterator>
5812
  unordered_set(InputIterator f, InputIterator l,
5813
  size_type n = see below,
5814
  const hasher& hf = hasher(),
5815
  const key_equal& eql = key_equal(),
5816
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5817
  unordered_set(initializer_list<value_type> il,
5818
  size_type n = see below,
5819
  const hasher& hf = hasher(),
5820
  const key_equal& eql = key_equal(),
5821
  const allocator_type& a = allocator_type());
@@ -5823,12 +8759,11 @@ unordered_set(initializer_list<value_type> il,
5823
 
5824
  *Effects:* Constructs an empty `unordered_set` using the specified hash
5825
  function, key equality predicate, and allocator, and using at least `n`
5826
  buckets. If `n` is not provided, the number of buckets is
5827
  *implementation-defined*. Then inserts elements from the range \[`f`,
5828
- `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
5829
- for the second form. `max_load_factor()` returns `1.0`.
5830
 
5831
  *Complexity:* Average case linear, worst case quadratic.
5832
 
5833
  #### Erasure <a id="unord.set.erasure">[[unord.set.erasure]]</a>
5834
 
@@ -5860,19 +8795,20 @@ An `unordered_multiset` is an unordered associative container that
5860
  supports equivalent keys (an instance of `unordered_multiset` may
5861
  contain multiple copies of the same key value) and in which each
5862
  element’s key is the element itself. The `unordered_multiset` class
5863
  supports forward iterators.
5864
 
5865
- An `unordered_multiset` meets all of the requirements of a container, of
5866
- an unordered associative container, and of an allocator-aware container
5867
- ([[container.alloc.req]]). It provides the operations described in the
5868
- preceding requirements table for equivalent keys; that is, an
5869
- `unordered_multiset` supports the `a_eq` operations in that table, not
5870
- the `a_uniq` operations. For an `unordered_multiset<Key>` the `key type`
5871
- and the value type are both `Key`. The `iterator` and `const_iterator`
5872
- types are both constant iterator types. It is unspecified whether they
5873
- are the same type.
 
5874
 
5875
  Subclause  [[unord.multiset]] only describes operations on
5876
  `unordered_multiset` that are not described in one of the requirement
5877
  tables, or for which there is additional semantic information.
5878
 
@@ -5892,12 +8828,12 @@ namespace std {
5892
  using allocator_type = Allocator;
5893
  using pointer = typename allocator_traits<Allocator>::pointer;
5894
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
5895
  using reference = value_type&;
5896
  using const_reference = const value_type&;
5897
- using size_type = implementation-defined; // see [container.requirements]
5898
- using difference_type = implementation-defined; // see [container.requirements]
5899
 
5900
  using iterator = implementation-defined // type of unordered_multiset::iterator; // see [container.requirements]
5901
  using const_iterator = implementation-defined // type of unordered_multiset::const_iterator; // see [container.requirements]
5902
  using local_iterator = implementation-defined // type of unordered_multiset::local_iterator; // see [container.requirements]
5903
  using const_local_iterator = implementation-defined // type of unordered_multiset::const_local_iterator; // see [container.requirements]
@@ -5913,15 +8849,21 @@ namespace std {
5913
  unordered_multiset(InputIterator f, InputIterator l,
5914
  size_type n = see below,
5915
  const hasher& hf = hasher(),
5916
  const key_equal& eql = key_equal(),
5917
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
5918
  unordered_multiset(const unordered_multiset&);
5919
  unordered_multiset(unordered_multiset&&);
5920
  explicit unordered_multiset(const Allocator&);
5921
- unordered_multiset(const unordered_multiset&, const Allocator&);
5922
- unordered_multiset(unordered_multiset&&, const Allocator&);
5923
  unordered_multiset(initializer_list<value_type> il,
5924
  size_type n = see below,
5925
  const hasher& hf = hasher(),
5926
  const key_equal& eql = key_equal(),
5927
  const allocator_type& a = allocator_type());
@@ -5934,10 +8876,18 @@ namespace std {
5934
  : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
5935
  template<class InputIterator>
5936
  unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
5937
  const allocator_type& a)
5938
  : unordered_multiset(f, l, n, hf, key_equal(), a) { }
 
 
 
 
 
 
 
 
5939
  unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
5940
  : unordered_multiset(il, n, hasher(), key_equal(), a) { }
5941
  unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
5942
  const allocator_type& a)
5943
  : unordered_multiset(il, n, hf, key_equal(), a) { }
@@ -5969,20 +8919,25 @@ namespace std {
5969
  iterator insert(const value_type& obj);
5970
  iterator insert(value_type&& obj);
5971
  iterator insert(const_iterator hint, const value_type& obj);
5972
  iterator insert(const_iterator hint, value_type&& obj);
5973
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
 
5974
  void insert(initializer_list<value_type>);
5975
 
5976
  node_type extract(const_iterator position);
5977
  node_type extract(const key_type& x);
 
5978
  iterator insert(node_type&& nh);
5979
  iterator insert(const_iterator hint, node_type&& nh);
5980
 
5981
- iterator erase(iterator position);
 
5982
  iterator erase(const_iterator position);
5983
  size_type erase(const key_type& k);
 
5984
  iterator erase(const_iterator first, const_iterator last);
5985
  void swap(unordered_multiset&)
5986
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
5987
  is_nothrow_swappable_v<Hash> &&
5988
  is_nothrow_swappable_v<Pred>);
@@ -6048,10 +9003,18 @@ namespace std {
6048
  unordered_multiset(InputIterator, InputIterator, see below::size_type = see below,
6049
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
6050
  -> unordered_multiset<iter-value-type<InputIterator>,
6051
  Hash, Pred, Allocator>;
6052
 
 
 
 
 
 
 
 
 
6053
  template<class T, class Hash = hash<T>,
6054
  class Pred = equal_to<T>, class Allocator = allocator<T>>
6055
  unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
6056
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
6057
  -> unordered_multiset<T, Hash, Pred, Allocator>;
@@ -6068,23 +9031,32 @@ namespace std {
6068
  Hash, Allocator)
6069
  -> unordered_multiset<iter-value-type<InputIterator>, Hash,
6070
  equal_to<iter-value-type<InputIterator>>,
6071
  Allocator>;
6072
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6073
  template<class T, class Allocator>
6074
  unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
6075
  -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;
6076
 
6077
  template<class T, class Hash, class Allocator>
6078
  unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
6079
  -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;
6080
-
6081
- // swap
6082
- template<class Key, class Hash, class Pred, class Alloc>
6083
- void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
6084
- unordered_multiset<Key, Hash, Pred, Alloc>& y)
6085
- noexcept(noexcept(x.swap(y)));
6086
  }
6087
  ```
6088
 
6089
  A `size_type` parameter type in an `unordered_multiset` deduction guide
6090
  refers to the `size_type` member type of the type deduced by the
@@ -6112,10 +9084,16 @@ template<class InputIterator>
6112
  unordered_multiset(InputIterator f, InputIterator l,
6113
  size_type n = see below,
6114
  const hasher& hf = hasher(),
6115
  const key_equal& eql = key_equal(),
6116
  const allocator_type& a = allocator_type());
 
 
 
 
 
 
6117
  unordered_multiset(initializer_list<value_type> il,
6118
  size_type n = see below,
6119
  const hasher& hf = hasher(),
6120
  const key_equal& eql = key_equal(),
6121
  const allocator_type& a = allocator_type());
@@ -6123,12 +9101,11 @@ unordered_multiset(initializer_list<value_type> il,
6123
 
6124
  *Effects:* Constructs an empty `unordered_multiset` using the specified
6125
  hash function, key equality predicate, and allocator, and using at least
6126
  `n` buckets. If `n` is not provided, the number of buckets is
6127
  *implementation-defined*. Then inserts elements from the range \[`f`,
6128
- `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
6129
- for the second form. `max_load_factor()` returns `1.0`.
6130
 
6131
  *Complexity:* Average case linear, worst case quadratic.
6132
 
6133
  #### Erasure <a id="unord.multiset.erasure">[[unord.multiset.erasure]]</a>
6134
 
@@ -6154,47 +9131,95 @@ return original_size - c.size();
6154
 
6155
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
6156
 
6157
  ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
6158
 
6159
- The headers `<queue>` and `<stack>` define the container adaptors
6160
- `queue`, `priority_queue`, and `stack`.
 
6161
 
6162
- The container adaptors each take a `Container` template parameter, and
6163
- each constructor takes a `Container` reference argument. This container
6164
- is copied into the `Container` member of each adaptor. If the container
6165
- takes an allocator, then a compatible allocator may be passed in to the
6166
- adaptor’s constructor. Otherwise, normal copy or move construction is
6167
- used for the container argument. The first template parameter `T` of the
6168
- container adaptors shall denote the same type as
6169
- `Container::value_type`.
 
 
 
 
6170
 
6171
  For container adaptors, no `swap` function throws an exception unless
6172
- that exception is thrown by the swap of the adaptor’s `Container` or
6173
- `Compare` object (if any).
 
 
 
 
 
 
 
 
 
 
 
 
 
6174
 
6175
  A deduction guide for a container adaptor shall not participate in
6176
  overload resolution if any of the following are true:
6177
 
6178
  - It has an `InputIterator` template parameter and a type that does not
6179
  qualify as an input iterator is deduced for that parameter.
6180
  - It has a `Compare` template parameter and a type that qualifies as an
6181
  allocator is deduced for that parameter.
6182
- - It has a `Container` template parameter and a type that qualifies as
6183
- an allocator is deduced for that parameter.
6184
- - It has an `Allocator` template parameter and a type that does not
6185
- qualify as an allocator is deduced for that parameter.
 
 
6186
  - It has both `Container` and `Allocator` template parameters, and
6187
  `uses_allocator_v<Container, Allocator>` is `false`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6188
 
6189
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
6190
 
6191
  ``` cpp
6192
  #include <compare> // see [compare.syn]
6193
  #include <initializer_list> // see [initializer.list.syn]
6194
 
6195
  namespace std {
 
6196
  template<class T, class Container = deque<T>> class queue;
6197
 
6198
  template<class T, class Container>
6199
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
6200
  template<class T, class Container>
@@ -6214,10 +9239,11 @@ namespace std {
6214
  template<class T, class Container>
6215
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
6216
  template<class T, class Container, class Alloc>
6217
  struct uses_allocator<queue<T, Container>, Alloc>;
6218
 
 
6219
  template<class T, class Container = vector<T>,
6220
  class Compare = less<typename Container::value_type>>
6221
  class priority_queue;
6222
 
6223
  template<class T, class Container, class Compare>
@@ -6233,10 +9259,11 @@ namespace std {
6233
  ``` cpp
6234
  #include <compare> // see [compare.syn]
6235
  #include <initializer_list> // see [initializer.list.syn]
6236
 
6237
  namespace std {
 
6238
  template<class T, class Container = deque<T>> class stack;
6239
 
6240
  template<class T, class Container>
6241
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
6242
  template<class T, class Container>
@@ -6258,10 +9285,96 @@ namespace std {
6258
  template<class T, class Container, class Alloc>
6259
  struct uses_allocator<stack<T, Container>, Alloc>;
6260
  }
6261
  ```
6262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6263
  ### Class template `queue` <a id="queue">[[queue]]</a>
6264
 
6265
  #### Definition <a id="queue.defn">[[queue.defn]]</a>
6266
 
6267
  Any sequence container supporting operations `front()`, `back()`,
@@ -6284,24 +9397,31 @@ namespace std {
6284
 
6285
  public:
6286
  queue() : queue(Container()) {}
6287
  explicit queue(const Container&);
6288
  explicit queue(Container&&);
 
 
6289
  template<class Alloc> explicit queue(const Alloc&);
6290
  template<class Alloc> queue(const Container&, const Alloc&);
6291
  template<class Alloc> queue(Container&&, const Alloc&);
6292
  template<class Alloc> queue(const queue&, const Alloc&);
6293
  template<class Alloc> queue(queue&&, const Alloc&);
 
 
 
 
6294
 
6295
  [[nodiscard]] bool empty() const { return c.empty(); }
6296
  size_type size() const { return c.size(); }
6297
  reference front() { return c.front(); }
6298
  const_reference front() const { return c.front(); }
6299
  reference back() { return c.back(); }
6300
  const_reference back() const { return c.back(); }
6301
  void push(const value_type& x) { c.push_back(x); }
6302
  void push(value_type&& x) { c.push_back(std::move(x)); }
 
6303
  template<class... Args>
6304
  decltype(auto) emplace(Args&&... args)
6305
  { return c.emplace_back(std::forward<Args>(args)...); }
6306
  void pop() { c.pop_front(); }
6307
  void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
@@ -6309,15 +9429,27 @@ namespace std {
6309
  };
6310
 
6311
  template<class Container>
6312
  queue(Container) -> queue<typename Container::value_type, Container>;
6313
 
 
 
 
 
 
 
6314
  template<class Container, class Allocator>
6315
  queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
6316
 
6317
- template<class T, class Container>
6318
- void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
 
 
 
 
 
6319
 
6320
  template<class T, class Container, class Alloc>
6321
  struct uses_allocator<queue<T, Container>, Alloc>
6322
  : uses_allocator<Container, Alloc>::type { };
6323
  }
@@ -6335,10 +9467,26 @@ explicit queue(const Container& cont);
6335
  explicit queue(Container&& cont);
6336
  ```
6337
 
6338
  *Effects:* Initializes `c` with `std::move(cont)`.
6339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6340
  #### Constructors with allocators <a id="queue.cons.alloc">[[queue.cons.alloc]]</a>
6341
 
6342
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6343
  in this subclause shall not participate in overload resolution.
6344
 
@@ -6374,10 +9522,36 @@ template<class Alloc> queue(queue&& q, const Alloc& a);
6374
  ```
6375
 
6376
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
6377
  and `a` as the second argument.
6378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6379
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
6380
 
6381
  ``` cpp
6382
  template<class T, class Container>
6383
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
@@ -6472,28 +9646,47 @@ namespace std {
6472
  public:
6473
  priority_queue() : priority_queue(Compare()) {}
6474
  explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
6475
  priority_queue(const Compare& x, const Container&);
6476
  priority_queue(const Compare& x, Container&&);
 
 
6477
  template<class InputIterator>
6478
  priority_queue(InputIterator first, InputIterator last, const Compare& x,
6479
  const Container&);
6480
  template<class InputIterator>
6481
- priority_queue(InputIterator first, InputIterator last,
6482
- const Compare& x = Compare(), Container&& = Container());
 
 
6483
  template<class Alloc> explicit priority_queue(const Alloc&);
6484
  template<class Alloc> priority_queue(const Compare&, const Alloc&);
6485
  template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
6486
  template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
6487
  template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
6488
  template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
 
 
 
 
 
 
 
 
 
 
 
 
 
6489
 
6490
  [[nodiscard]] bool empty() const { return c.empty(); }
6491
  size_type size() const { return c.size(); }
6492
  const_reference top() const { return c.front(); }
6493
  void push(const value_type& x);
6494
  void push(value_type&& x);
 
 
6495
  template<class... Args> void emplace(Args&&... args);
6496
  void pop();
6497
  void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
6498
  is_nothrow_swappable_v<Compare>)
6499
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
@@ -6502,25 +9695,49 @@ namespace std {
6502
  template<class Compare, class Container>
6503
  priority_queue(Compare, Container)
6504
  -> priority_queue<typename Container::value_type, Container, Compare>;
6505
 
6506
  template<class InputIterator,
6507
- class Compare = less<typename iterator_traits<InputIterator>::value_type>,
6508
- class Container = vector<typename iterator_traits<InputIterator>::value_type>>
6509
  priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
6510
- -> priority_queue<typename iterator_traits<InputIterator>::value_type, Container, Compare>;
 
 
 
 
6511
 
6512
  template<class Compare, class Container, class Allocator>
6513
  priority_queue(Compare, Container, Allocator)
6514
  -> priority_queue<typename Container::value_type, Container, Compare>;
6515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6516
  // no equality is provided
6517
 
6518
- template<class T, class Container, class Compare>
6519
- void swap(priority_queue<T, Container, Compare>& x,
6520
- priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
6521
-
6522
  template<class T, class Container, class Compare, class Alloc>
6523
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
6524
  : uses_allocator<Container, Alloc>::type { };
6525
  }
6526
  ```
@@ -6536,25 +9753,46 @@ priority_queue(const Compare& x, Container&& y);
6536
 
6537
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
6538
  constructing or move constructing as appropriate); calls
6539
  `make_heap(c.begin(), c.end(), comp)`.
6540
 
 
 
 
 
 
 
 
 
 
 
 
6541
  ``` cpp
6542
  template<class InputIterator>
6543
  priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y);
6544
  template<class InputIterator>
6545
- priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(),
6546
- Container&& y = Container());
6547
  ```
6548
 
6549
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
6550
 
6551
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
6552
  constructing or move constructing as appropriate); calls
6553
  `c.insert(c.end(), first, last)`; and finally calls
6554
  `make_heap(c.begin(), c.end(), comp)`.
6555
 
 
 
 
 
 
 
 
 
 
 
 
6556
  #### Constructors with allocators <a id="priqueue.cons.alloc">[[priqueue.cons.alloc]]</a>
6557
 
6558
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6559
  in this subclause shall not participate in overload resolution.
6560
 
@@ -6602,10 +9840,68 @@ template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
6602
 
6603
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
6604
  and `a` as the second argument, and initializes `comp` with
6605
  `std::move(q.comp)`.
6606
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6607
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
6608
 
6609
  ``` cpp
6610
  void push(const value_type& x);
6611
  ```
@@ -6626,10 +9922,22 @@ void push(value_type&& x);
6626
  ``` cpp
6627
  c.push_back(std::move(x));
6628
  push_heap(c.begin(), c.end(), comp);
6629
  ```
6630
 
 
 
 
 
 
 
 
 
 
 
 
 
6631
  ``` cpp
6632
  template<class... Args> void emplace(Args&&... args);
6633
  ```
6634
 
6635
  *Effects:* As if by:
@@ -6663,10 +9971,12 @@ template<class T, class Container, class Compare>
6663
 
6664
  *Effects:* As if by `x.swap(y)`.
6665
 
6666
  ### Class template `stack` <a id="stack">[[stack]]</a>
6667
 
 
 
6668
  Any sequence container supporting operations `back()`, `push_back()` and
6669
  `pop_back()` can be used to instantiate `stack`. In particular, `vector`
6670
  [[vector]], `list` [[list]] and `deque` [[deque]] can be used.
6671
 
6672
  #### Definition <a id="stack.defn">[[stack.defn]]</a>
@@ -6687,22 +9997,30 @@ namespace std {
6687
 
6688
  public:
6689
  stack() : stack(Container()) {}
6690
  explicit stack(const Container&);
6691
  explicit stack(Container&&);
 
 
6692
  template<class Alloc> explicit stack(const Alloc&);
6693
  template<class Alloc> stack(const Container&, const Alloc&);
6694
  template<class Alloc> stack(Container&&, const Alloc&);
6695
  template<class Alloc> stack(const stack&, const Alloc&);
6696
  template<class Alloc> stack(stack&&, const Alloc&);
 
 
 
 
6697
 
6698
  [[nodiscard]] bool empty() const { return c.empty(); }
6699
  size_type size() const { return c.size(); }
6700
  reference top() { return c.back(); }
6701
  const_reference top() const { return c.back(); }
6702
  void push(const value_type& x) { c.push_back(x); }
6703
  void push(value_type&& x) { c.push_back(std::move(x)); }
 
 
6704
  template<class... Args>
6705
  decltype(auto) emplace(Args&&... args)
6706
  { return c.emplace_back(std::forward<Args>(args)...); }
6707
  void pop() { c.pop_back(); }
6708
  void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
@@ -6710,13 +10028,28 @@ namespace std {
6710
  };
6711
 
6712
  template<class Container>
6713
  stack(Container) -> stack<typename Container::value_type, Container>;
6714
 
 
 
 
 
 
 
6715
  template<class Container, class Allocator>
6716
  stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
6717
 
 
 
 
 
 
 
 
 
 
6718
  template<class T, class Container, class Alloc>
6719
  struct uses_allocator<stack<T, Container>, Alloc>
6720
  : uses_allocator<Container, Alloc>::type { };
6721
  }
6722
  ```
@@ -6733,10 +10066,26 @@ explicit stack(const Container& cont);
6733
  explicit stack(Container&& cont);
6734
  ```
6735
 
6736
  *Effects:* Initializes `c` with `std::move(cont)`.
6737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6738
  #### Constructors with allocators <a id="stack.cons.alloc">[[stack.cons.alloc]]</a>
6739
 
6740
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6741
  in this subclause shall not participate in overload resolution.
6742
 
@@ -6772,10 +10121,36 @@ template<class Alloc> stack(stack&& s, const Alloc& a);
6772
  ```
6773
 
6774
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
6775
  and `a` as the second argument.
6776
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6777
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
6778
 
6779
  ``` cpp
6780
  template<class T, class Container>
6781
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
@@ -6835,17 +10210,2565 @@ template<class T, class Container>
6835
 
6836
  *Constraints:* `is_swappable_v<Container>` is `true`.
6837
 
6838
  *Effects:* As if by `x.swap(y)`.
6839
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6840
  ## Views <a id="views">[[views]]</a>
6841
 
6842
  ### General <a id="views.general">[[views.general]]</a>
6843
 
6844
- The header `<span>` defines the view `span`.
 
 
6845
 
6846
- ### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
 
 
6847
 
6848
  ``` cpp
6849
  namespace std {
6850
  // constants
6851
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
@@ -6853,14 +12776,13 @@ namespace std {
6853
  // [views.span], class template span
6854
  template<class ElementType, size_t Extent = dynamic_extent>
6855
  class span;
6856
 
6857
  template<class ElementType, size_t Extent>
6858
- inline constexpr bool ranges::enable_view<span<ElementType, Extent>> =
6859
- Extent == 0 || Extent == dynamic_extent;
6860
  template<class ElementType, size_t Extent>
6861
- inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
6862
 
6863
  // [span.objectrep], views of object representation
6864
  template<class ElementType, size_t Extent>
6865
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
6866
  as_bytes(span<ElementType, Extent> s) noexcept;
@@ -6869,13 +12791,13 @@ namespace std {
6869
  span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
6870
  as_writable_bytes(span<ElementType, Extent> s) noexcept;
6871
  }
6872
  ```
6873
 
6874
- ### Class template `span` <a id="views.span">[[views.span]]</a>
6875
 
6876
- #### Overview <a id="span.overview">[[span.overview]]</a>
6877
 
6878
  A `span` is a view over a contiguous sequence of objects, the storage of
6879
  which is owned by some other object.
6880
 
6881
  All member functions of `span` have constant time complexity.
@@ -6893,11 +12815,13 @@ namespace std {
6893
  using pointer = element_type*;
6894
  using const_pointer = const element_type*;
6895
  using reference = element_type&;
6896
  using const_reference = const element_type&;
6897
  using iterator = implementation-defined // type of span::iterator; // see [span.iterators]
 
6898
  using reverse_iterator = std::reverse_iterator<iterator>;
 
6899
  static constexpr size_type extent = Extent;
6900
 
6901
  // [span.cons], constructors, copy, and assignment
6902
  constexpr span() noexcept;
6903
  template<class It>
@@ -6945,12 +12869,16 @@ namespace std {
6945
  constexpr pointer data() const noexcept;
6946
 
6947
  // [span.iterators], iterator support
6948
  constexpr iterator begin() const noexcept;
6949
  constexpr iterator end() const noexcept;
 
 
6950
  constexpr reverse_iterator rbegin() const noexcept;
6951
  constexpr reverse_iterator rend() const noexcept;
 
 
6952
 
6953
  private:
6954
  pointer data_; // exposition only
6955
  size_type size_; // exposition only
6956
  };
@@ -6966,14 +12894,17 @@ namespace std {
6966
  template<class R>
6967
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
6968
  }
6969
  ```
6970
 
 
 
 
6971
  `ElementType` is required to be a complete object type that is not an
6972
  abstract class type.
6973
 
6974
- #### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
6975
 
6976
  ``` cpp
6977
  constexpr span() noexcept;
6978
  ```
6979
 
@@ -6998,12 +12929,12 @@ template<class It>
6998
  - \[`first`, `first + count`) is a valid range.
6999
  - `It` models `contiguous_iterator`.
7000
  - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
7001
  `extent`.
7002
 
7003
- *Effects:* Initializes `data_` with `to_address(first)` and `size_` with
7004
- `count`.
7005
 
7006
  *Throws:* Nothing.
7007
 
7008
  ``` cpp
7009
  template<class It, class End>
@@ -7025,12 +12956,12 @@ template<class It, class End>
7025
  equal to `extent`.
7026
  - \[`first`, `last`) is a valid range.
7027
  - `It` models `contiguous_iterator`.
7028
  - `End` models `sized_sentinel_for<It>`.
7029
 
7030
- *Effects:* Initializes `data_` with `to_address(first)` and `size_` with
7031
- `last - first`.
7032
 
7033
  *Throws:* When and what `last - first` throws.
7034
 
7035
  ``` cpp
7036
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
@@ -7075,12 +13006,12 @@ template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
7075
  is equal to `extent`.
7076
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
7077
  - If `is_const_v<element_type>` is `false`, `R` models
7078
  `ranges::borrowed_range`.
7079
 
7080
- *Effects:* Initializes `data_` with `ranges::data(r)` and `size_` with
7081
- `ranges::size(r)`.
7082
 
7083
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
7084
 
7085
  ``` cpp
7086
  constexpr span(const span& other) noexcept = default;
@@ -7120,11 +13051,11 @@ extent != dynamic_extent && OtherExtent == dynamic_extent
7120
  constexpr span& operator=(const span& other) noexcept = default;
7121
  ```
7122
 
7123
  *Ensures:* `size() == other.size() && data() == other.data()`.
7124
 
7125
- #### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
7126
 
7127
  ``` cpp
7128
  template<class It, class EndOrSize>
7129
  span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
7130
  ```
@@ -7136,11 +13067,11 @@ template<class R>
7136
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
7137
  ```
7138
 
7139
  *Constraints:* `R` satisfies `ranges::contiguous_range`.
7140
 
7141
- #### Subviews <a id="span.sub">[[span.sub]]</a>
7142
 
7143
  ``` cpp
7144
  template<size_t Count> constexpr span<element_type, Count> first() const;
7145
  ```
7146
 
@@ -7231,17 +13162,17 @@ is `true`.
7231
 
7232
  ``` cpp
7233
  return {data() + offset, count == dynamic_extent ? size() - offset : count};
7234
  ```
7235
 
7236
- #### Observers <a id="span.obs">[[span.obs]]</a>
7237
 
7238
  ``` cpp
7239
  constexpr size_type size() const noexcept;
7240
  ```
7241
 
7242
- *Effects:* Equivalent to: `return size_;`
7243
 
7244
  ``` cpp
7245
  constexpr size_type size_bytes() const noexcept;
7246
  ```
7247
 
@@ -7251,11 +13182,11 @@ constexpr size_type size_bytes() const noexcept;
7251
  [[nodiscard]] constexpr bool empty() const noexcept;
7252
  ```
7253
 
7254
  *Effects:* Equivalent to: `return size() == 0;`
7255
 
7256
- #### Element access <a id="span.elem">[[span.elem]]</a>
7257
 
7258
  ``` cpp
7259
  constexpr reference operator[](size_type idx) const;
7260
  ```
7261
 
@@ -7281,23 +13212,25 @@ constexpr reference back() const;
7281
 
7282
  ``` cpp
7283
  constexpr pointer data() const noexcept;
7284
  ```
7285
 
7286
- *Effects:* Equivalent to: `return data_;`
7287
 
7288
- #### Iterator support <a id="span.iterators">[[span.iterators]]</a>
7289
 
7290
  ``` cpp
7291
  using iterator = implementation-defined // type of span::iterator;
7292
  ```
7293
 
7294
  The type models `contiguous_iterator` [[iterator.concept.contiguous]],
7295
  meets the *Cpp17RandomAccessIterator*
7296
  requirements [[random.access.iterators]], and meets the requirements for
7297
- constexpr iterators [[iterator.requirements.general]]. All requirements
7298
- on container iterators [[container.requirements]] apply to
 
 
7299
  `span::iterator` as well.
7300
 
7301
  ``` cpp
7302
  constexpr iterator begin() const noexcept;
7303
  ```
@@ -7345,18 +13278,1781 @@ template<class ElementType, size_t Extent>
7345
 
7346
  *Effects:* Equivalent to:
7347
  `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};` where `R`
7348
  is the return type.
7349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7350
  <!-- Link reference definitions -->
 
7351
  [alg.sorting]: algorithms.md#alg.sorting
7352
  [algorithm.stable]: library.md#algorithm.stable
7353
  [algorithms]: algorithms.md#algorithms
7354
  [algorithms.requirements]: algorithms.md#algorithms.requirements
7355
  [allocator.requirements]: library.md#allocator.requirements
7356
  [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
7357
- [allocator.traits.members]: utilities.md#allocator.traits.members
 
7358
  [array]: #array
7359
  [array.cons]: #array.cons
7360
  [array.creation]: #array.creation
7361
  [array.members]: #array.members
7362
  [array.overview]: #array.overview
@@ -7367,58 +15063,90 @@ is the return type.
7367
  [associative]: #associative
7368
  [associative.general]: #associative.general
7369
  [associative.map.syn]: #associative.map.syn
7370
  [associative.reqmts]: #associative.reqmts
7371
  [associative.reqmts.except]: #associative.reqmts.except
 
7372
  [associative.set.syn]: #associative.set.syn
 
7373
  [basic.string]: strings.md#basic.string
7374
  [class.copy.ctor]: class.md#class.copy.ctor
7375
  [class.default.ctor]: class.md#class.default.ctor
7376
  [class.dtor]: class.md#class.dtor
7377
  [container.adaptors]: #container.adaptors
 
7378
  [container.adaptors.general]: #container.adaptors.general
7379
- [container.alloc.req]: #container.alloc.req
7380
- [container.assoc.req]: #container.assoc.req
7381
- [container.hash.req]: #container.hash.req
7382
  [container.insert.return]: #container.insert.return
7383
  [container.node]: #container.node
7384
  [container.node.compat]: #container.node.compat
7385
  [container.node.cons]: #container.node.cons
7386
  [container.node.dtor]: #container.node.dtor
7387
  [container.node.modifiers]: #container.node.modifiers
7388
  [container.node.observers]: #container.node.observers
7389
  [container.node.overview]: #container.node.overview
7390
- [container.opt]: #container.opt
7391
- [container.req]: #container.req
7392
  [container.requirements]: #container.requirements
7393
  [container.requirements.dataraces]: #container.requirements.dataraces
7394
  [container.requirements.general]: #container.requirements.general
7395
- [container.rev.req]: #container.rev.req
7396
- [container.seq.opt]: #container.seq.opt
7397
- [container.seq.req]: #container.seq.req
7398
  [containers]: #containers
7399
  [containers.general]: #containers.general
7400
  [containers.summary]: #containers.summary
7401
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
 
7402
  [deque]: #deque
7403
  [deque.capacity]: #deque.capacity
7404
  [deque.cons]: #deque.cons
7405
  [deque.erasure]: #deque.erasure
7406
  [deque.modifiers]: #deque.modifiers
7407
  [deque.overview]: #deque.overview
7408
  [deque.syn]: #deque.syn
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7409
  [forward.list.erasure]: #forward.list.erasure
 
 
 
 
7410
  [forward.list.syn]: #forward.list.syn
7411
- [forwardlist]: #forwardlist
7412
- [forwardlist.access]: #forwardlist.access
7413
- [forwardlist.cons]: #forwardlist.cons
7414
- [forwardlist.iter]: #forwardlist.iter
7415
- [forwardlist.modifiers]: #forwardlist.modifiers
7416
- [forwardlist.ops]: #forwardlist.ops
7417
- [forwardlist.overview]: #forwardlist.overview
7418
  [hash.requirements]: library.md#hash.requirements
7419
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
 
7420
  [iterator.requirements]: iterators.md#iterator.requirements
7421
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
7422
  [list]: #list
7423
  [list.capacity]: #list.capacity
7424
  [list.cons]: #list.cons
@@ -7431,10 +15159,47 @@ is the return type.
7431
  [map.access]: #map.access
7432
  [map.cons]: #map.cons
7433
  [map.erasure]: #map.erasure
7434
  [map.modifiers]: #map.modifiers
7435
  [map.overview]: #map.overview
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7436
  [multimap]: #multimap
7437
  [multimap.cons]: #multimap.cons
7438
  [multimap.erasure]: #multimap.erasure
7439
  [multimap.modifiers]: #multimap.modifiers
7440
  [multimap.overview]: #multimap.overview
@@ -7450,10 +15215,11 @@ is the return type.
7450
  [priqueue.special]: #priqueue.special
7451
  [queue]: #queue
7452
  [queue.cons]: #queue.cons
7453
  [queue.cons.alloc]: #queue.cons.alloc
7454
  [queue.defn]: #queue.defn
 
7455
  [queue.ops]: #queue.ops
7456
  [queue.special]: #queue.special
7457
  [queue.syn]: #queue.syn
7458
  [random.access.iterators]: iterators.md#random.access.iterators
7459
  [res.on.data.races]: library.md#res.on.data.races
@@ -7475,23 +15241,21 @@ is the return type.
7475
  [span.syn]: #span.syn
7476
  [stack]: #stack
7477
  [stack.cons]: #stack.cons
7478
  [stack.cons.alloc]: #stack.cons.alloc
7479
  [stack.defn]: #stack.defn
 
 
7480
  [stack.ops]: #stack.ops
7481
  [stack.special]: #stack.special
7482
  [stack.syn]: #stack.syn
7483
  [strings]: strings.md#strings
7484
  [swappable.requirements]: library.md#swappable.requirements
7485
- [tab:container.opt]: #tab:container.opt
7486
- [tab:container.req]: #tab:container.req
7487
- [tab:container.rev.req]: #tab:container.rev.req
7488
- [tab:container.seq.opt]: #tab:container.seq.opt
7489
- [tab:container.seq.req]: #tab:container.seq.req
7490
  [temp.deduct]: temp.md#temp.deduct
7491
  [temp.param]: temp.md#temp.param
7492
  [temp.type]: temp.md#temp.type
 
7493
  [unord]: #unord
7494
  [unord.general]: #unord.general
7495
  [unord.hash]: utilities.md#unord.hash
7496
  [unord.map]: #unord.map
7497
  [unord.map.cnstr]: #unord.map.cnstr
@@ -7509,26 +15273,31 @@ is the return type.
7509
  [unord.multiset.cnstr]: #unord.multiset.cnstr
7510
  [unord.multiset.erasure]: #unord.multiset.erasure
7511
  [unord.multiset.overview]: #unord.multiset.overview
7512
  [unord.req]: #unord.req
7513
  [unord.req.except]: #unord.req.except
 
7514
  [unord.set]: #unord.set
7515
  [unord.set.cnstr]: #unord.set.cnstr
7516
  [unord.set.erasure]: #unord.set.erasure
7517
  [unord.set.overview]: #unord.set.overview
7518
  [unord.set.syn]: #unord.set.syn
7519
  [vector]: #vector
7520
  [vector.bool]: #vector.bool
 
 
7521
  [vector.capacity]: #vector.capacity
7522
  [vector.cons]: #vector.cons
7523
  [vector.data]: #vector.data
7524
  [vector.erasure]: #vector.erasure
7525
  [vector.modifiers]: #vector.modifiers
7526
  [vector.overview]: #vector.overview
7527
  [vector.syn]: #vector.syn
7528
  [views]: #views
 
7529
  [views.general]: #views.general
 
7530
  [views.span]: #views.span
7531
 
7532
  [^1]: Equality comparison is a refinement of partitioning if no two
7533
  objects that compare equal fall into different partitions.
7534
 
@@ -7536,7 +15305,7 @@ is the return type.
7536
  iterators are random access iterators.
7537
 
7538
  [^3]: As specified in  [[allocator.requirements]], the requirements in
7539
  this Clause apply only to lists whose allocators compare equal.
7540
 
7541
- [^4]: `reserve()` uses `Allocator::allocate()` which may throw an
7542
  appropriate exception.
 
15
  | -------------------------- | -------------------------------- | ------------------------------------------------------------ |
16
  | [[container.requirements]] | Requirements | |
17
  | [[sequences]] | Sequence containers | `<array>`, `<deque>`, `<forward_list>`, `<list>`, `<vector>` |
18
  | [[associative]] | Associative containers | `<map>`, `<set>` |
19
  | [[unord]] | Unordered associative containers | `<unordered_map>`, `<unordered_set>` |
20
+ | [[container.adaptors]] | Container adaptors | `<queue>`, `<stack>`, `<flat_map>`, `<flat_set>` |
21
+ | [[views]] | Views | `<span>`, `<mdspan>` |
22
 
23
 
24
+ ## Requirements <a id="container.requirements">[[container.requirements]]</a>
25
 
26
+ ### Preamble <a id="container.requirements.pre">[[container.requirements.pre]]</a>
27
 
28
  Containers are objects that store other objects. They control allocation
29
  and deallocation of these objects through constructors, destructors,
30
  insert and erase operations.
31
 
 
34
 
35
  [*Example 1*: The copy constructor of type `vector<vector<int>>` has
36
  linear complexity, even though the complexity of copying each contained
37
  `vector<int>` is itself linear. — *end example*]
38
 
39
+ Allocator-aware containers [[container.alloc.reqmts]] other than
40
+ `basic_string` construct elements using the function
 
41
  `allocator_traits<allocator_type>::rebind_traits<U>::{}construct` and
42
+ destroy elements using the function
43
  `allocator_traits<allocator_type>::rebind_traits<U>::{}destroy`
44
  [[allocator.traits.members]], where `U` is either
45
  `allocator_type::value_type` or an internal type used by the container.
46
  These functions are called only for the container’s element type, not
47
  for internal types used by the container.
48
 
49
+ [*Note 1*: This means, for example, that a node-based container would
50
  need to construct nodes containing aligned buffers and call `construct`
51
  to place the element into the buffer. — *end note*]
52
 
53
+ ### General containers <a id="container.gen.reqmts">[[container.gen.reqmts]]</a>
 
 
 
 
 
54
 
55
+ #### General <a id="container.requirements.general">[[container.requirements.general]]</a>
 
56
 
57
+ In subclause [[container.gen.reqmts]],
 
58
 
59
+ - `X` denotes a container class containing objects of type `T`,
60
+ - `a` denotes a value of type `X`,
61
+ - `b` and `c` denote values of type (possibly const) `X`,
62
+ - `i` and `j` denote values of type (possibly const) `X::iterator`,
63
+ - `u` denotes an identifier,
64
+ - `v` denotes an lvalue of type (possibly const) `X` or an rvalue of
65
+ type `const X`,
66
+ - `s` and `t` denote non-const lvalues of type `X`, and
67
+ - `rv` denotes a non-const rvalue of type `X`.
68
+
69
+ The following exposition-only concept is used in the definition of
70
+ containers:
71
+
72
+ ``` cpp
73
+ template<class R, class T>
74
+ concept container-compatible-range = // exposition only
75
+ ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;
76
+ ```
77
+
78
+ #### Containers <a id="container.reqmts">[[container.reqmts]]</a>
79
+
80
+ A type `X` meets the *container* requirements if the following types,
81
+ statements, and expressions are well-formed and have the specified
82
+ semantics.
83
+
84
+ ``` cpp
85
+ typename X::value_type
86
+ ```
87
+
88
+ *Result:* `T`
89
+
90
+ *Preconditions:* `T` is *Cpp17Erasable* from `X`
91
+ (see  [[container.alloc.reqmts]], below).
92
+
93
+ ``` cpp
94
+ typename X::reference
95
+ ```
96
+
97
+ *Result:* `T&`
98
+
99
+ ``` cpp
100
+ typename X::const_reference
101
+ ```
102
+
103
+ *Result:* `const T&`
104
+
105
+ ``` cpp
106
+ typename X::iterator
107
+ ```
108
+
109
+ *Result:* A type that meets the forward iterator
110
+ requirements [[forward.iterators]] with value type `T`. The type
111
+ `X::iterator` is convertible to `X::const_iterator`.
112
+
113
+ ``` cpp
114
+ typename X::const_iterator
115
+ ```
116
+
117
+ *Result:* A type that meets the requirements of a constant iterator and
118
+ those of a forward iterator with value type `T`.
119
+
120
+ ``` cpp
121
+ typename X::difference_type
122
+ ```
123
+
124
+ *Result:* A signed integer type, identical to the difference type of
125
+ `X::iterator` and `X::const_iterator`.
126
+
127
+ ``` cpp
128
+ typename X::size_type
129
+ ```
130
+
131
+ *Result:* An unsigned integer type that can represent any non-negative
132
+ value of `X::difference_type`.
133
+
134
+ ``` cpp
135
+ X u;
136
+ X u = X();
137
+ ```
138
+
139
+ *Ensures:* `u.empty()`
140
+
141
+ *Complexity:* Constant.
142
+
143
+ ``` cpp
144
+ X u(v);
145
+ X u = v;
146
+ ```
147
+
148
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` (see below).
149
+
150
+ *Ensures:* `u == v`.
151
+
152
+ *Complexity:* Linear.
153
+
154
+ ``` cpp
155
+ X u(rv);
156
+ X u = rv;
157
+ ```
158
+
159
+ *Ensures:* `u` is equal to the value that `rv` had before this
160
+ construction.
161
+
162
+ *Complexity:* Linear for `array` and constant for all other standard
163
+ containers.
164
+
165
+ ``` cpp
166
+ t = v;
167
+ ```
168
+
169
+ *Result:* `X&`.
170
+
171
+ *Ensures:* `t == v`.
172
+
173
+ *Complexity:* Linear.
174
+
175
+ ``` cpp
176
+ t = rv
177
+ ```
178
+
179
+ *Result:* `X&`.
180
+
181
+ *Effects:* All existing elements of `t` are either move assigned to or
182
+ destroyed.
183
+
184
+ *Ensures:* If `t` and `rv` do not refer to the same object, `t` is equal
185
+ to the value that `rv` had before this assignment.
186
+
187
+ *Complexity:* Linear.
188
+
189
+ ``` cpp
190
+ a.~X()
191
+ ```
192
+
193
+ *Result:* `void`.
194
+
195
+ *Effects:* Destroys every element of `a`; any memory obtained is
196
+ deallocated.
197
+
198
+ *Complexity:* Linear.
199
+
200
+ ``` cpp
201
+ b.begin()
202
+ ```
203
+
204
+ *Result:* `iterator`; `const_iterator` for constant `b`.
205
+
206
+ *Returns:* An iterator referring to the first element in the container.
207
+
208
+ *Complexity:* Constant.
209
+
210
+ ``` cpp
211
+ b.end()
212
+ ```
213
+
214
+ *Result:* `iterator`; `const_iterator` for constant `b`.
215
+
216
+ *Returns:* An iterator which is the past-the-end value for the
217
+ container.
218
+
219
+ *Complexity:* Constant.
220
+
221
+ ``` cpp
222
+ b.cbegin()
223
+ ```
224
+
225
+ *Result:* `const_iterator`.
226
+
227
+ *Returns:* `const_cast<X const&>(b).begin()`
228
+
229
+ *Complexity:* Constant.
230
+
231
+ ``` cpp
232
+ b.cend()
233
+ ```
234
+
235
+ *Result:* `const_iterator`.
236
+
237
+ *Returns:* `const_cast<X const&>(b).end()`
238
+
239
+ *Complexity:* Constant.
240
+
241
+ ``` cpp
242
+ i <=> j
243
+ ```
244
+
245
+ *Result:* `strong_ordering`.
246
+
247
+ *Constraints:* `X::iterator` meets the random access iterator
248
+ requirements.
249
+
250
+ *Complexity:* Constant.
251
+
252
+ ``` cpp
253
+ c == b
254
+ ```
255
+
256
+ *Preconditions:* `T` meets the *Cpp17EqualityComparable* requirements.
257
+
258
+ *Result:* `bool`.
259
+
260
+ *Returns:* `equal(c.begin(), c.end(), b.begin(), b.end())`
261
+
262
+ [*Note 1*: The algorithm `equal` is defined in
263
+ [[alg.equal]]. — *end note*]
264
+
265
+ *Complexity:* Constant if `c.size() != b.size()`, linear otherwise.
266
+
267
+ *Remarks:* `==` is an equivalence relation.
268
+
269
+ ``` cpp
270
+ c != b
271
+ ```
272
+
273
+ *Effects:* Equivalent to `!(c == b)`.
274
+
275
+ ``` cpp
276
+ t.swap(s)
277
+ ```
278
+
279
+ *Result:* `void`.
280
+
281
+ *Effects:* Exchanges the contents of `t` and `s`.
282
+
283
+ *Complexity:* Linear for `array` and constant for all other standard
284
+ containers.
285
+
286
+ ``` cpp
287
+ swap(t, s)
288
+ ```
289
+
290
+ *Effects:* Equivalent to `t.swap(s)`.
291
+
292
+ ``` cpp
293
+ c.size()
294
+ ```
295
+
296
+ *Result:* `size_type`.
297
+
298
+ *Returns:* `distance(c.begin(), c.end())`, i.e., the number of elements
299
+ in the container.
300
+
301
+ *Complexity:* Constant.
302
+
303
+ *Remarks:* The number of elements is defined by the rules of
304
  constructors, inserts, and erases.
305
 
306
+ ``` cpp
307
+ c.max_size()
308
+ ```
309
 
310
+ *Result:* `size_type`.
311
+
312
+ *Returns:* `distance(begin(), end())` for the largest possible
313
+ container.
314
+
315
+ *Complexity:* Constant.
316
+
317
+ ``` cpp
318
+ c.empty()
319
+ ```
320
+
321
+ *Result:* `bool`.
322
+
323
+ *Returns:* `c.begin() == c.end()`
324
+
325
+ *Complexity:* Constant.
326
+
327
+ *Remarks:* If the container is empty, then `c.empty()` is `true`.
328
 
329
  In the expressions
330
 
331
  ``` cpp
332
  i == j
 
342
  where `i` and `j` denote objects of a container’s `iterator` type,
343
  either or both may be replaced by an object of the container’s
344
  `const_iterator` type referring to the same element with no change in
345
  semantics.
346
 
347
+ Unless otherwise specified, all containers defined in this Clause obtain
348
  memory using an allocator (see  [[allocator.requirements]]).
349
 
350
+ [*Note 1*: In particular, containers and iterators do not store
351
  references to allocated elements other than through the allocator’s
352
  pointer type, i.e., as objects of type `P` or
353
  `pointer_traits<P>::template rebind<unspecified>`, where `P` is
354
  `allocator_traits<allocator_type>::pointer`. — *end note*]
355
 
 
360
  constructors obtain an allocator by move construction from the allocator
361
  belonging to the container being moved. Such move construction of the
362
  allocator shall not exit via an exception. All other constructors for
363
  these container types take a `const allocator_type&` argument.
364
 
365
+ [*Note 2*: If an invocation of a constructor uses the default value of
366
  an optional allocator argument, then the allocator type must support
367
  value-initialization. — *end note*]
368
 
369
  A copy of this allocator is used for any memory allocation and element
370
  construction performed, by these constructors and by all member
371
  functions, during the lifetime of each container object or until the
372
  allocator is replaced. The allocator may be replaced only via assignment
373
  or `swap()`. Allocator replacement is performed by copy assignment, move
374
  assignment, or swapping of the allocator only if
375
+
376
+ - `allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value`,
377
+ - `allocator_traits<allocator_type>::propagate_on_container_move_assignment::value`,
378
  or
379
+ - `allocator_traits<allocator_type>::propagate_on_container_swap::value`
380
+
381
  is `true` within the implementation of the corresponding container
382
  operation. In all container types defined in this Clause, the member
383
  `get_allocator()` returns a copy of the allocator used to construct the
384
  container or, if that allocator has been replaced, a copy of the most
385
  recent replacement.
386
 
387
  The expression `a.swap(b)`, for containers `a` and `b` of a standard
388
  container type other than `array`, shall exchange the values of `a` and
389
  `b` without invoking any move, copy, or swap operations on the
390
+ individual container elements. Any `Compare`, `Pred`, or `Hash` types
391
+ belonging to `a` and `b` shall meet the *Cpp17Swappable* requirements
392
+ and shall be exchanged by calling `swap` as described in 
393
+ [[swappable.requirements]]. If
394
  `allocator_traits<allocator_type>::propagate_on_container_swap::value`
395
+ is `true`, then `allocator_type` shall meet the *Cpp17Swappable*
396
+ requirements and the allocators of `a` and `b` shall also be exchanged
397
+ by calling `swap` as described in  [[swappable.requirements]].
398
+ Otherwise, the allocators shall not be swapped, and the behavior is
399
+ undefined unless `a.get_allocator() == b.get_allocator()`. Every
400
+ iterator referring to an element in one container before the swap shall
401
+ refer to the same element in the other container after the swap. It is
402
+ unspecified whether an iterator with value `a.end()` before the swap
403
+ will have value `b.end()` after the swap.
 
 
 
 
 
404
 
405
  Unless otherwise specified (see  [[associative.reqmts.except]],
406
  [[unord.req.except]], [[deque.modifiers]], and [[vector.modifiers]]) all
407
  container types defined in this Clause meet the following additional
408
  requirements:
409
 
410
+ - If an exception is thrown by an `insert()` or `emplace()` function
411
  while inserting a single element, that function has no effects.
412
+ - If an exception is thrown by a `push_back()`, `push_front()`,
413
  `emplace_back()`, or `emplace_front()` function, that function has no
414
  effects.
415
+ - No `erase()`, `clear()`, `pop_back()` or `pop_front()` function throws
416
  an exception.
417
+ - No copy constructor or assignment operator of a returned iterator
418
  throws an exception.
419
+ - No `swap()` function throws an exception.
420
+ - No `swap()` function invalidates any references, pointers, or
421
  iterators referring to the elements of the containers being swapped.
422
+ \[*Note 3*: The `end()` iterator does not refer to any element, so it
423
+ can be invalidated. — *end note*]
424
 
425
  Unless otherwise specified (either explicitly or by defining a function
426
  in terms of other functions), invoking a container member function or
427
  passing a container as an argument to a library function shall not
428
  invalidate iterators to, or change the values of, objects within that
 
431
  A *contiguous container* is a container whose member types `iterator`
432
  and `const_iterator` meet the *Cpp17RandomAccessIterator* requirements
433
  [[random.access.iterators]] and model `contiguous_iterator`
434
  [[iterator.concept.contiguous]].
435
 
436
+ The behavior of certain container member functions and deduction guides
437
+ depends on whether types qualify as input iterators or allocators. The
438
+ extent to which an implementation determines that a type cannot be an
439
+ input iterator is unspecified, except that as a minimum integral types
440
+ shall not qualify as input iterators. Likewise, the extent to which an
441
+ implementation determines that a type cannot be an allocator is
442
+ unspecified, except that as a minimum a type `A` shall not qualify as an
443
+ allocator unless it meets both of the following conditions:
444
+
445
+ - The *qualified-id* `A::value_type` is valid and denotes a type
446
+ [[temp.deduct]].
447
+ - The expression `declval<A&>().allocate(size_t{})` is well-formed when
448
+ treated as an unevaluated operand.
449
+
450
+ #### Reversible container requirements <a id="container.rev.reqmts">[[container.rev.reqmts]]</a>
451
+
452
+ A type `X` meets the *reversible container* requirements if `X` meets
453
+ the container requirements, the iterator type of `X` belongs to the
454
+ bidirectional or random access iterator categories
455
+ [[iterator.requirements]], and the following types and expressions are
456
+ well-formed and have the specified semantics.
457
+
458
+ ``` cpp
459
+ typename X::reverse_iterator
460
+ ```
461
+
462
+ *Result:* The type `reverse_iterator<X::iterator>`, an iterator type
463
+ whose value type is `T`.
464
+
465
+ ``` cpp
466
+ typename X::const_reverse_iterator
467
+ ```
468
+
469
+ *Result:* The type `reverse_iterator<X::const_iterator>`, a constant
470
+ iterator type whose value type is `T`.
471
+
472
+ ``` cpp
473
+ a.rbegin()
474
+ ```
475
+
476
+ *Result:* `reverse_iterator`; `const_reverse_iterator` for constant `a`.
477
+
478
+ *Returns:* `reverse_iterator(end())`
479
+
480
+ *Complexity:* Constant.
481
+
482
+ ``` cpp
483
+ a.rend()
484
+ ```
485
+
486
+ *Result:* `reverse_iterator`; `const_reverse_iterator` for constant `a`.
487
+
488
+ *Returns:* `reverse_iterator(begin())`
489
+
490
+ *Complexity:* Constant.
491
+
492
+ ``` cpp
493
+ a.crbegin()
494
+ ```
495
+
496
+ *Result:* `const_reverse_iterator`.
497
+
498
+ *Returns:* `const_cast<X const&>(a).rbegin()`
499
+
500
+ *Complexity:* Constant.
501
+
502
+ ``` cpp
503
+ a.crend()
504
+ ```
505
+
506
+ *Result:* `const_reverse_iterator`.
507
+
508
+ *Returns:* `const_cast<X const&>(a).rend()`
509
+
510
+ *Complexity:* Constant.
511
+
512
+ #### Optional container requirements <a id="container.opt.reqmts">[[container.opt.reqmts]]</a>
513
+
514
+ The following operations are provided for some types of containers but
515
+ not others. Those containers for which the listed operations are
516
+ provided shall implement the semantics as described unless otherwise
517
+ stated. If the iterators passed to `lexicographical_compare_three_way`
518
+ meet the constexpr iterator requirements
519
+ [[iterator.requirements.general]] then the operations described below
520
+ are implemented by constexpr functions.
521
+
522
+ ``` cpp
523
+ a <=> b
524
+ ```
525
+
526
+ *Result:* *`synth-three-way-result`*`<X::value_type>`.
527
+
528
+ *Preconditions:* Either `<=>` is defined for values of type (possibly
529
+ const) `T`, or `<` is defined for values of type (possibly const) `T`
530
+ and `<` is a total ordering relationship.
531
+
532
+ *Returns:*
533
+ `lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(), `*`synth-three-way`*`)`
534
+
535
+ [*Note 1*: The algorithm `lexicographical_compare_three_way` is defined
536
  in [[algorithms]]. — *end note*]
537
 
538
+ *Complexity:* Linear.
539
+
540
+ #### Allocator-aware containers <a id="container.alloc.reqmts">[[container.alloc.reqmts]]</a>
541
+
542
+ All of the containers defined in [[containers]] and in  [[basic.string]]
543
+ except `array` meet the additional requirements of an
544
+ *allocator-aware container*, as described below.
545
 
546
  Given an allocator type `A` and given a container type `X` having a
547
  `value_type` identical to `T` and an `allocator_type` identical to
548
  `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
549
+ `A`, a pointer `p` of type `T*`, an expression `v` of type `T` or
550
+ `const T`, and an rvalue `rv` of type `T`, the following terms are
551
+ defined. If `X` is not allocator-aware or is a specialization of
552
+ `basic_string`, the terms below are defined as if `A` were
553
+ `allocator<T>` no allocator object needs to be created and user
554
+ specializations of `allocator<T>` are not instantiated:
555
 
556
  - `T` is **Cpp17DefaultInsertable* into `X`* means that the following
557
  expression is well-formed:
558
  ``` cpp
559
  allocator_traits<A>::construct(m, p)
 
573
  ```
574
 
575
  and its evaluation causes the following postcondition to hold: The
576
  value of `*p` is equivalent to the value of `rv` before the
577
  evaluation.
578
+ \[*Note 1*: `rv` remains a valid object. Its state is
579
  unspecified — *end note*]
580
  - `T` is **Cpp17CopyInsertable* into `X`* means that, in addition to `T`
581
  being *Cpp17MoveInsertable* into `X`, the following expression is
582
  well-formed:
583
  ``` cpp
 
596
  is well-formed:
597
  ``` cpp
598
  allocator_traits<A>::destroy(m, p)
599
  ```
600
 
601
+ [*Note 2*: A container calls
602
  `allocator_traits<A>::construct(m, p, args)` to construct an element at
603
  `p` using `args`, with `m == get_allocator()`. The default `construct`
604
  in `allocator` will call `::new((void*)p) T(args)`, but specialized
605
+ allocators can choose a different definition. — *end note*]
606
+
607
+ In this subclause,
608
+
609
+ - `X` denotes an allocator-aware container class with a `value_type` of
610
+ `T` using an allocator of type `A`,
611
+ - `u` denotes a variable,
612
+ - `a` and `b` denote non-const lvalues of type `X`,
613
+ - `c` denotes an lvalue of type `const X`,
614
+ - `t` denotes an lvalue or a const rvalue of type `X`,
615
+ - `rv` denotes a non-const rvalue of type `X`, and
616
+ - `m` is a value of type `A`.
617
+
618
+ A type `X` meets the allocator-aware container requirements if `X` meets
619
+ the container requirements and the following types, statements, and
620
+ expressions are well-formed and have the specified semantics.
621
+
622
+ ``` cpp
623
+ typename X::allocator_type
624
+ ```
625
+
626
+ *Result:* `A`
627
+
628
+ *Mandates:* `allocator_type::value_type` is the same as `X::value_type`.
629
+
630
+ ``` cpp
631
+ c.get_allocator()
632
+ ```
633
+
634
+ *Result:* `A`
635
+
636
+ *Complexity:* Constant.
637
+
638
+ ``` cpp
639
+ X u;
640
+ X u = X();
641
+ ```
642
+
643
+ *Preconditions:* `A` meets the *Cpp17DefaultConstructible* requirements.
644
+
645
+ *Ensures:* `u.empty()` returns `true`, `u.get_allocator() == A()`.
646
+
647
+ *Complexity:* Constant.
648
+
649
+ ``` cpp
650
+ X u(m);
651
+ ```
652
+
653
+ *Ensures:* `u.empty()` returns `true`, `u.get_allocator() == m`.
654
+
655
+ *Complexity:* Constant.
656
+
657
+ ``` cpp
658
+ X u(t, m);
659
+ ```
660
+
661
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
662
+
663
+ *Ensures:* `u == t`, `u.get_allocator() == m`
664
+
665
+ *Complexity:* Linear.
666
+
667
+ ``` cpp
668
+ X u(rv);
669
+ ```
670
+
671
+ *Ensures:* `u` has the same elements as `rv` had before this
672
+ construction; the value of `u.get_allocator()` is the same as the value
673
+ of `rv.get_allocator()` before this construction.
674
+
675
+ *Complexity:* Constant.
676
+
677
+ ``` cpp
678
+ X u(rv, m);
679
+ ```
680
+
681
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
682
+
683
+ *Ensures:* `u` has the same elements, or copies of the elements, that
684
+ `rv` had before this construction, `u.get_allocator() == m`.
685
+
686
+ *Complexity:* Constant if `m == rv.get_allocator()`, otherwise linear.
687
+
688
+ ``` cpp
689
+ a = t
690
+ ```
691
+
692
+ *Result:* `X&`.
693
+
694
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` and
695
+ *Cpp17CopyAssignable*.
696
+
697
+ *Ensures:* `a == t` is `true`.
698
+
699
+ *Complexity:* Linear.
700
+
701
+ ``` cpp
702
+ a = rv
703
+ ```
704
+
705
+ *Result:* `X&`.
706
+
707
+ *Preconditions:* If
708
+ `allocator_traits<allocator_type>::propagate_on_container_move_assignment::value`
709
+ is `false`, `T` is *Cpp17MoveInsertable* into `X` and
710
+ *Cpp17MoveAssignable*.
711
+
712
+ *Effects:* All existing elements of `a` are either move assigned to or
713
+ destroyed.
714
+
715
+ *Ensures:* If `a` and `rv` do not refer to the same object, `a` is equal
716
+ to the value that `rv` had before this assignment.
717
+
718
+ *Complexity:* Linear.
719
+
720
+ ``` cpp
721
+ a.swap(b)
722
+ ```
723
+
724
+ *Result:* `void`
725
+
726
+ *Effects:* Exchanges the contents of `a` and `b`.
727
+
728
+ *Complexity:* Constant.
729
 
730
  ### Container data races <a id="container.requirements.dataraces">[[container.requirements.dataraces]]</a>
731
 
732
  For purposes of avoiding data races [[res.on.data.races]],
733
  implementations shall consider the following functions to be `const`:
 
741
  concurrently.
742
 
743
  [*Note 1*: For a `vector<int> x` with a size greater than one,
744
  `x[1] = 5` and `*x.begin() = 10` can be executed concurrently without a
745
  data race, but `x[0] = 5` and `*x.begin() = 10` executed concurrently
746
+ can result in a data race. As an exception to the general rule, for a
747
+ `vector<bool> y`, `y[0] = true` can race with
748
  `y[1] = true`. — *end note*]
749
 
750
  ### Sequence containers <a id="sequence.reqmts">[[sequence.reqmts]]</a>
751
 
752
  A sequence container organizes a finite set of objects, all of the same
753
  type, into a strictly linear arrangement. The library provides four
754
  basic kinds of sequence containers: `vector`, `forward_list`, `list`,
755
  and `deque`. In addition, `array` is provided as a sequence container
756
  which provides limited sequence operations because it has a fixed number
757
  of elements. The library also provides container adaptors that make it
758
+ easy to construct abstract data types, such as `stack`s, `queue`s,
759
+ `flat_map`s, `flat_multimap`s, `flat_set`s, or `flat_multiset`s, out of
760
+ the basic sequence container kinds (or out of other program-defined
761
+ sequence containers).
762
 
763
  [*Note 1*: The sequence containers offer the programmer different
764
+ complexity trade-offs. `vector` is appropriate in most circumstances.
765
+ `array` has a fixed size known during translation. `list` or
766
+ `forward_list` support frequent insertions and deletions from the middle
767
+ of the sequence. `deque` supports efficient insertions and deletions
768
+ taking place at the beginning or at the end of the sequence. When
769
+ choosing a container, remember `vector` is best; leave a comment to
 
 
770
  explain if you choose from the rest! — *end note*]
771
 
772
+ In this subclause,
773
+
774
+ - `X` denotes a sequence container class,
775
+ - `a` denotes a value of type `X` containing elements of type `T`,
776
+ - `u` denotes the name of a variable being declared,
777
+ - `A` denotes `X::allocator_type` if the *qualified-id*
778
  `X::allocator_type` is valid and denotes a type [[temp.deduct]] and
779
+ `allocator<T>` if it doesn’t,
780
+ - `i` and `j` denote iterators that meet the *Cpp17InputIterator*
781
+ requirements and refer to elements implicitly convertible to
782
+ `value_type`,
783
+ - `[i, j)` denotes a valid range,
784
+ - `rg` denotes a value of a type `R` that models
785
+ `container-compatible-range<T>`,
786
+ - `il` designates an object of type `initializer_list<value_type>`,
787
+ - `n` denotes a value of type `X::size_type`,
788
+ - `p` denotes a valid constant iterator to `a`,
789
+ - `q` denotes a valid dereferenceable constant iterator to `a`,
790
+ - `[q1, q2)` denotes a valid range of constant iterators in `a`,
791
+ - `t` denotes an lvalue or a const rvalue of `X::value_type`, and
792
+ - `rv` denotes a non-const rvalue of `X::value_type`.
793
+ - `Args` denotes a template parameter pack;
794
+ - `args` denotes a function parameter pack with the pattern `Args&&`.
795
 
796
  The complexities of the expressions are sequence dependent.
797
 
798
+ A type `X` meets the *sequence container* requirements if `X` meets the
799
+ container requirements and the following statements and expressions are
800
+ well-formed and have the specified semantics.
801
+
802
+ ``` cpp
803
+ X u(n, t);
804
+ ```
805
+
806
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
807
+
808
+ *Effects:* Constructs a sequence container with `n` copies of `t`.
809
+
810
+ *Ensures:* `distance(u.begin(), u.end()) == n` is `true`.
811
+
812
+ ``` cpp
813
+ X u(i, j);
814
+ ```
815
+
816
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
817
+ For `vector`, if the iterator does not meet the *Cpp17ForwardIterator*
818
+ requirements [[forward.iterators]], `T` is also *Cpp17MoveInsertable*
819
+ into `X`.
820
+
821
+ *Effects:* Constructs a sequence container equal to the range `[i, j)`.
822
+ Each iterator in the range \[`i`, `j`) is dereferenced exactly once.
823
+
824
+ *Ensures:* `distance(u.begin(), u.end()) == distance(i, j)` is `true`.
825
+
826
+ ``` cpp
827
+ X(from_range, rg)
828
+ ```
829
+
830
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
831
+ `*ranges::begin(rg)`. For `vector`, if `R` models neither
832
+ `ranges::sized_range` nor `ranges::forward_range`, `T` is also
833
+ *Cpp17MoveInsertable* into `X`.
834
+
835
+ *Effects:* Constructs a sequence container equal to the range `rg`. Each
836
+ iterator in the range `rg` is dereferenced exactly once.
837
+
838
+ *Ensures:* `distance(begin(), end()) == ranges::distance(rg)` is `true`.
839
+
840
+ ``` cpp
841
+ X(il)
842
+ ```
843
+
844
+ *Effects:* Equivalent to `X(il.begin(), il.end())`.
845
+
846
+ ``` cpp
847
+ a = il
848
+ ```
849
+
850
+ *Result:* `X&`.
851
+
852
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` and
853
+ *Cpp17CopyAssignable*.
854
+
855
+ *Effects:* Assigns the range \[`il.begin()`, `il.end()`) into `a`. All
856
+ existing elements of `a` are either assigned to or destroyed.
857
+
858
+ *Returns:* `*this`.
859
+
860
+ ``` cpp
861
+ a.emplace(p, args)
862
+ ```
863
+
864
+ *Result:* `iterator`.
865
+
866
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
867
+ `args`. For `vector` and `deque`, `T` is also *Cpp17MoveInsertable* into
868
+ `X` and *Cpp17MoveAssignable*.
869
+
870
+ *Effects:* Inserts an object of type `T` constructed with
871
+ `std::forward<Args>(args)...` before `p`.
872
+
873
+ [*Note 1*: `args` can directly or indirectly refer to a value in
874
  `a`. — *end note*]
875
 
876
+ *Returns:* An iterator that points to the new element constructed from
877
+ `args` into `a`.
878
 
879
+ ``` cpp
880
+ a.insert(p, t)
881
+ ```
882
 
883
+ *Result:* `iterator`.
 
884
 
885
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`. For `vector` and
886
+ `deque`, `T` is also *Cpp17CopyAssignable*.
887
 
888
+ *Effects:* Inserts a copy of `t` before `p`.
 
889
 
890
+ *Returns:* An iterator that points to the copy of `t` inserted into `a`.
 
891
 
892
+ ``` cpp
893
+ a.insert(p, rv)
894
+ ```
895
 
896
+ *Result:* `iterator`.
897
+
898
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`. For `vector` and
899
+ `deque`, `T` is also *Cpp17MoveAssignable*.
900
+
901
+ *Effects:* Inserts a copy of `rv` before `p`.
902
+
903
+ *Returns:* An iterator that points to the copy of `rv` inserted into
904
+ `a`.
905
+
906
+ ``` cpp
907
+ a.insert(p, n, t)
908
+ ```
909
+
910
+ *Result:* `iterator`.
911
+
912
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` and
913
+ *Cpp17CopyAssignable*.
914
+
915
+ *Effects:* Inserts `n` copies of `t` before `p`.
916
+
917
+ *Returns:* An iterator that points to the copy of the first element
918
+ inserted into `a`, or `p` if `n == 0`.
919
+
920
+ ``` cpp
921
+ a.insert(p, i, j)
922
+ ```
923
+
924
+ *Result:* `iterator`.
925
+
926
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
927
+ For `vector` and `deque`, `T` is also *Cpp17MoveInsertable* into `X`,
928
+ and `T` meets the *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
929
+ *Cpp17Swappable*[[swappable.requirements]] requirements. Neither `i` nor
930
+ `j` are iterators into `a`.
931
+
932
+ *Effects:* Inserts copies of elements in `[i, j)` before `p`. Each
933
+ iterator in the range \[`i`, `j`) shall be dereferenced exactly once.
934
+
935
+ *Returns:* An iterator that points to the copy of the first element
936
+ inserted into `a`, or `p` if `i == j`.
937
+
938
+ ``` cpp
939
+ a.insert_range(p, rg)
940
+ ```
941
+
942
+ *Result:* `iterator`.
943
+
944
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
945
+ `*ranges::begin(rg)`. For `vector` and `deque`, `T` is also
946
+ *Cpp17MoveInsertable* into `X`, and `T` meets the
947
+ *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
948
+ *Cpp17Swappable*[[swappable.requirements]] requirements. `rg` and `a` do
949
+ not overlap.
950
+
951
+ *Effects:* Inserts copies of elements in `rg` before `p`. Each iterator
952
+ in the range `rg` is dereferenced exactly once.
953
+
954
+ *Returns:* An iterator that points to the copy of the first element
955
+ inserted into `a`, or `p` if `rg` is empty.
956
+
957
+ ``` cpp
958
+ a.insert(p, il)
959
+ ```
960
+
961
+ *Effects:* Equivalent to `a.insert(p, il.begin(), il.end())`.
962
+
963
+ ``` cpp
964
+ a.erase(q)
965
+ ```
966
+
967
+ *Result:* `iterator`.
968
+
969
+ *Preconditions:* For `vector` and `deque`, `T` is *Cpp17MoveAssignable*.
970
+
971
+ *Effects:* Erases the element pointed to by `q`.
972
+
973
+ *Returns:* An iterator that points to the element immediately following
974
+ `q` prior to the element being erased. If no such element exists,
975
+ `a.end()` is returned.
976
+
977
+ ``` cpp
978
+ a.erase(q1, q2)
979
+ ```
980
+
981
+ *Result:* `iterator`.
982
+
983
+ *Preconditions:* For `vector` and `deque`, `T` is *Cpp17MoveAssignable*.
984
+
985
+ *Effects:* Erases the elements in the range `[q1, q2)`.
986
+
987
+ *Returns:* An iterator that points to the element pointed to by `q2`
988
+ prior to any elements being erased. If no such element exists, `a.end()`
989
+ is returned.
990
+
991
+ ``` cpp
992
+ a.clear()
993
+ ```
994
+
995
+ *Result:* `void`
996
+
997
+ *Effects:* Destroys all elements in `a`. Invalidates all references,
998
+ pointers, and iterators referring to the elements of `a` and may
999
+ invalidate the past-the-end iterator.
1000
+
1001
+ *Ensures:* `a.empty()` is `true`.
1002
+
1003
+ *Complexity:* Linear.
1004
+
1005
+ ``` cpp
1006
+ a.assign(i, j)
1007
+ ```
1008
+
1009
+ *Result:* `void`
1010
+
1011
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`
1012
+ and assignable from `*i`. For `vector`, if the iterator does not meet
1013
+ the forward iterator requirements [[forward.iterators]], `T` is also
1014
+ *Cpp17MoveInsertable* into `X`. Neither `i` nor `j` are iterators into
1015
+ `a`.
1016
+
1017
+ *Effects:* Replaces elements in `a` with a copy of `[i, j)`. Invalidates
1018
+ all references, pointers and iterators referring to the elements of `a`.
1019
+ For `vector` and `deque`, also invalidates the past-the-end iterator.
1020
+ Each iterator in the range \[`i`, `j`) is dereferenced exactly once.
1021
+
1022
+ ``` cpp
1023
+ a.assign_range(rg)
1024
+ ```
1025
+
1026
+ *Result:* `void`
1027
+
1028
+ *Mandates:* `assignable_from<T&, ranges::range_reference_t<R>>` is
1029
+ modeled.
1030
+
1031
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1032
+ `*ranges::begin(rg)`. For `vector`, if `R` models neither
1033
+ `ranges::sized_range` nor `ranges::forward_range`, `T` is also
1034
+ *Cpp17MoveInsertable* into `X`. `rg` and `a` do not overlap.
1035
+
1036
+ *Effects:* Replaces elements in `a` with a copy of each element in `rg`.
1037
+ Invalidates all references, pointers, and iterators referring to the
1038
+ elements of `a`. For `vector` and `deque`, also invalidates the
1039
+ past-the-end iterator. Each iterator in the range `rg` is dereferenced
1040
+ exactly once.
1041
+
1042
+ ``` cpp
1043
+ a.assign(il)
1044
+ ```
1045
+
1046
+ *Effects:* Equivalent to `a.assign(il.begin(), il.end())`.
1047
+
1048
+ ``` cpp
1049
+ a.assign(n, t)
1050
+ ```
1051
+
1052
+ *Result:* `void`
1053
+
1054
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X` and
1055
+ *Cpp17CopyAssignable*. `t` is not a reference into `a`.
1056
+
1057
+ *Effects:* Replaces elements in `a` with `n` copies of `t`. Invalidates
1058
+ all references, pointers and iterators referring to the elements of `a`.
1059
+ For `vector` and `deque`, also invalidates the past-the-end iterator.
1060
 
1061
  For every sequence container defined in this Clause and in [[strings]]:
1062
 
1063
  - If the constructor
1064
  ``` cpp
 
1092
  and a type that does not qualify as an input iterator is deduced for
1093
  that parameter, or if it has an `Allocator` template parameter and a
1094
  type that does not qualify as an allocator is deduced for that
1095
  parameter.
1096
 
1097
+ The following operations are provided for some types of sequence
1098
+ containers but not others. Operations other than `prepend_range` and
1099
+ `append_range` are implemented so as to take amortized constant time.
 
1100
 
1101
+ ``` cpp
1102
+ a.front()
1103
+ ```
1104
+
1105
+ *Result:* `reference; const_reference` for constant `a`.
1106
+
1107
+ *Returns:* `*a.begin()`
1108
+
1109
+ *Remarks:* Required for `basic_string`, `array`, `deque`,
1110
+ `forward_list`, `list`, and `vector`.
1111
+
1112
+ ``` cpp
1113
+ a.back()
1114
+ ```
1115
+
1116
+ *Result:* `reference; const_reference` for constant `a`.
1117
+
1118
+ *Effects:* Equivalent to:
1119
+
1120
+ ``` cpp
1121
+ auto tmp = a.end();
1122
+ --tmp;
1123
+ return *tmp;
1124
+ ```
1125
+
1126
+ *Remarks:* Required for `basic_string`, `array`, `deque`, `list`, and
1127
+ `vector`.
1128
+
1129
+ ``` cpp
1130
+ a.emplace_front(args)
1131
+ ```
1132
+
1133
+ *Result:* `reference`
1134
+
1135
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1136
+ `args`.
1137
+
1138
+ *Effects:* Prepends an object of type `T` constructed with
1139
+ `std::forward<Args>(args)...`.
1140
+
1141
+ *Returns:* `a.front()`.
1142
+
1143
+ *Remarks:* Required for `deque`, `forward_list`, and `list`.
1144
+
1145
+ ``` cpp
1146
+ a.emplace_back(args)
1147
+ ```
1148
+
1149
+ *Result:* `reference`
1150
+
1151
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1152
+ `args`. For `vector`, `T` is also *Cpp17MoveInsertable* into `X`.
1153
+
1154
+ *Effects:* Appends an object of type `T` constructed with
1155
+ `std::forward<Args>(args)...`.
1156
+
1157
+ *Returns:* `a.back()`.
1158
+
1159
+ *Remarks:* Required for `deque`, `list`, and `vector`.
1160
+
1161
+ ``` cpp
1162
+ a.push_front(t)
1163
+ ```
1164
+
1165
+ *Result:* `void`
1166
+
1167
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
1168
+
1169
+ *Effects:* Prepends a copy of `t`.
1170
+
1171
+ *Remarks:* Required for `deque`, `forward_list`, and `list`.
1172
+
1173
+ ``` cpp
1174
+ a.push_front(rv)
1175
+ ```
1176
+
1177
+ *Result:* `void`
1178
+
1179
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
1180
+
1181
+ *Effects:* Prepends a copy of `rv`.
1182
+
1183
+ *Remarks:* Required for `deque`, `forward_list`, and `list`.
1184
+
1185
+ ``` cpp
1186
+ a.prepend_range(rg)
1187
+ ```
1188
+
1189
+ *Result:* `void`
1190
+
1191
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1192
+ `*ranges::begin(rg)`. For `deque`, `T` is also *Cpp17MoveInsertable*
1193
+ into `X`, and `T` meets the *Cpp17MoveConstructible*,
1194
+ *Cpp17MoveAssignable*, and *Cpp17Swappable*[[swappable.requirements]]
1195
+ requirements.
1196
+
1197
+ *Effects:* Inserts copies of elements in `rg` before `begin()`. Each
1198
+ iterator in the range `rg` is dereferenced exactly once.
1199
+
1200
+ [*Note 2*: The order of elements in `rg` is not
1201
+ reversed. — *end note*]
1202
+
1203
+ *Remarks:* Required for `deque`, `forward_list`, and `list`.
1204
+
1205
+ ``` cpp
1206
+ a.push_back(t)
1207
+ ```
1208
+
1209
+ *Result:* `void`
1210
+
1211
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
1212
+
1213
+ *Effects:* Appends a copy of `t`.
1214
+
1215
+ *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
1216
+
1217
+ ``` cpp
1218
+ a.push_back(rv)
1219
+ ```
1220
+
1221
+ *Result:* `void`
1222
+
1223
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
1224
+
1225
+ *Effects:* Appends a copy of `rv`.
1226
+
1227
+ *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
1228
+
1229
+ ``` cpp
1230
+ a.append_range(rg)
1231
+ ```
1232
+
1233
+ *Result:* `void`
1234
+
1235
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1236
+ `*ranges::begin(rg)`. For `vector`, `T` is also *Cpp17MoveInsertable*
1237
+ into `X`.
1238
+
1239
+ *Effects:* Inserts copies of elements in `rg` before `end()`. Each
1240
+ iterator in the range `rg` is dereferenced exactly once.
1241
+
1242
+ *Remarks:* Required for `deque`, `list`, and `vector`.
1243
+
1244
+ ``` cpp
1245
+ a.pop_front()
1246
+ ```
1247
+
1248
+ *Result:* `void`
1249
+
1250
+ *Preconditions:* `a.empty()` is `false`.
1251
+
1252
+ *Effects:* Destroys the first element.
1253
+
1254
+ *Remarks:* Required for `deque`, `forward_list`, and `list`.
1255
+
1256
+ ``` cpp
1257
+ a.pop_back()
1258
+ ```
1259
+
1260
+ *Result:* `void`
1261
+
1262
+ *Preconditions:* `a.empty()` is `false`.
1263
+
1264
+ *Effects:* Destroys the last element.
1265
+
1266
+ *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
1267
+
1268
+ ``` cpp
1269
+ a[n]
1270
+ ```
1271
+
1272
+ *Result:* `reference; const_reference` for constant `a`
1273
+
1274
+ *Returns:* `*(a.begin() + n)`
1275
+
1276
+ *Remarks:* Required for `basic_string`, `array`, `deque`, and `vector`.
1277
+
1278
+ ``` cpp
1279
+ a.at(n)
1280
+ ```
1281
+
1282
+ *Result:* `reference; const_reference` for constant `a`
1283
+
1284
+ *Returns:* `*(a.begin() + n)`
1285
+
1286
+ *Throws:* `out_of_range` if `n >= a.size()`.
1287
+
1288
+ *Remarks:* Required for `basic_string`, `array`, `deque`, and `vector`.
1289
 
1290
  ### Node handles <a id="container.node">[[container.node]]</a>
1291
 
1292
  #### Overview <a id="container.node.overview">[[container.node.overview]]</a>
1293
 
 
1326
 
1327
  ``` cpp
1328
  template<unspecified>
1329
  class node-handle {
1330
  public:
1331
+ // These type declarations are described in [associative.reqmts] and [unord.req].
1332
  using value_type = see below; // not present for map containers
1333
  using key_type = see below; // not present for set containers
1334
  using mapped_type = see below; // not present for set containers
1335
  using allocator_type = see below;
1336
 
1337
  private:
1338
+ using container_node_type = unspecified; // exposition only
1339
+ using ator_traits = allocator_traits<allocator_type>; // exposition only
1340
 
1341
+ typename ator_traits::template
1342
+ rebind_traits<container_node_type>::pointer ptr_; // exposition only
1343
+ optional<allocator_type> alloc_; // exposition only
1344
 
1345
  public:
1346
  // [container.node.cons], constructors, copy, and assignment
1347
  constexpr node-handle() noexcept : ptr_(), alloc_() {}
1348
  node-handle(node-handle&&) noexcept;
 
1515
  special members specified above. It has no base classes or members other
1516
  than those specified.
1517
 
1518
  ### Associative containers <a id="associative.reqmts">[[associative.reqmts]]</a>
1519
 
1520
+ #### General <a id="associative.reqmts.general">[[associative.reqmts.general]]</a>
1521
+
1522
  Associative containers provide fast retrieval of data based on keys. The
1523
  library provides four basic kinds of associative containers: `set`,
1524
+ `multiset`, `map` and `multimap`. The library also provides container
1525
+ adaptors that make it easy to construct abstract data types, such as
1526
+ `flat_map`s, `flat_multimap`s, `flat_set`s, or `flat_multiset`s, out of
1527
+ the basic sequence container kinds (or out of other program-defined
1528
+ sequence containers).
1529
 
1530
  Each associative container is parameterized on `Key` and an ordering
1531
  relation `Compare` that induces a strict weak ordering [[alg.sorting]]
1532
  on elements of `Key`. In addition, `map` and `multimap` associate an
1533
  arbitrary *mapped type* `T` with the `Key`. The object of type `Compare`
 
1565
  [*Note 2*: `iterator` and `const_iterator` have identical semantics in
1566
  this case, and `iterator` is convertible to `const_iterator`. Users can
1567
  avoid violating the one-definition rule by always using `const_iterator`
1568
  in their function parameter lists. — *end note*]
1569
 
1570
+ In this subclause,
1571
+
1572
+ - `X` denotes an associative container class,
1573
+ - `a` denotes a value of type `X`,
1574
+ - `a2` denotes a value of a type with nodes compatible with type `X` (
1575
+ [[container.node.compat]]),
1576
+ - `b` denotes a value or type `X` or `const X`,
1577
+ - `u` denotes the name of a variable being declared,
1578
+ - `a_uniq` denotes a value of type `X` when `X` supports unique keys,
1579
+ - `a_eq` denotes a value of type `X` when `X` supports multiple keys,
1580
+ - `a_tran` denotes a value of type `X` or `const X` when the
1581
+ *qualified-id* `X::key_compare::is_transparent` is valid and denotes a
1582
+ type [[temp.deduct]],
1583
+ - `i` and `j` meet the *Cpp17InputIterator* requirements and refer to
1584
+ elements implicitly convertible to `value_type`,
1585
+ - \[`i`, `j`) denotes a valid range,
1586
+ - `rg` denotes a value of a type `R` that models
1587
+ `container-compatible-range<value_type>`,
1588
+ - `p` denotes a valid constant iterator to `a`,
1589
+ - `q` denotes a valid dereferenceable constant iterator to `a`,
1590
+ - `r` denotes a valid dereferenceable iterator to `a`,
1591
+ - `[q1, q2)` denotes a valid range of constant iterators in `a`,
1592
+ - `il` designates an object of type `initializer_list<value_type>`,
1593
+ - `t` denotes a value of type `X::value_type`,
1594
+ - `k` denotes a value of type `X::key_type`, and
1595
+ - `c` denotes a value of type `X::key_compare` or
1596
+ `const X::key_compare`;
1597
+ - `kl` is a value such that `a` is partitioned [[alg.sorting]] with
1598
+ respect to `c(x, kl)`, with `x` the key value of `e` and `e` in `a`;
1599
+ - `ku` is a value such that `a` is partitioned with respect to
1600
+ `!c(ku, x)`, with `x` the key value of `e` and `e` in `a`;
1601
+ - `ke` is a value such that `a` is partitioned with respect to
1602
+ `c(x, ke)` and `!c(ke, x)`, with `c(x, ke)` implying `!c(ke, x)` and
1603
+ with `x` the key value of `e` and `e` in `a`;
1604
+ - `kx` is a value such that
1605
+ - `a` is partitioned with respect to `c(x, kx)` and `!c(kx, x)`, with
1606
+ `c(x, kx)` implying `!c(kx, x)` and with `x` the key value of `e`
1607
+ and `e` in `a`, and
1608
+ - `kx` is not convertible to either `iterator` or `const_iterator`;
1609
+ and
1610
+ - `A` denotes the storage allocator used by `X`, if any, or
1611
+ `allocator<X::value_type>` otherwise,
1612
+ - `m` denotes an allocator of a type convertible to `A`, and `nh`
1613
+ denotes a non-const rvalue of type `X::node_type`.
1614
+
1615
+ A type `X` meets the *associative container* requirements if `X` meets
1616
+ all the requirements of an allocator-aware container
1617
+ [[container.requirements.general]] and the following types, statements,
1618
+ and expressions are well-formed and have the specified semantics, except
1619
+ that for `map` and `multimap`, the requirements placed on `value_type`
1620
+ in [[container.alloc.reqmts]] apply instead to `key_type` and
1621
+ `mapped_type`.
1622
 
1623
  [*Note 3*: For example, in some cases `key_type` and `mapped_type` are
1624
  required to be *Cpp17CopyAssignable* even though the associated
1625
  `value_type`, `pair<const key_type, mapped_type>`, is not
1626
  *Cpp17CopyAssignable*. — *end note*]
1627
 
1628
+ ``` cpp
1629
+ typename X::key_type
1630
+ ```
1631
+
1632
+ *Result:* `Key`.
1633
+
1634
+ ``` cpp
1635
+ typename X::mapped_type
1636
+ ```
1637
+
1638
+ *Result:* `T`.
1639
+
1640
+ *Remarks:* For `map` and `multimap` only.
1641
+
1642
+ ``` cpp
1643
+ typename X::value_type
1644
+ ```
1645
+
1646
+ *Result:* `Key` for `set` and `multiset` only; `pair<const Key, T>` for
1647
+ `map` and `multimap` only.
1648
+
1649
+ *Preconditions:* `X::value_type` is *Cpp17Erasable* from `X`.
1650
+
1651
+ ``` cpp
1652
+ typename X::key_compare
1653
+ ```
1654
+
1655
+ *Result:* `Compare`.
1656
+
1657
+ *Preconditions:* `key_compare` is *Cpp17CopyConstructible*.
1658
+
1659
+ ``` cpp
1660
+ typename X::value_compare
1661
+ ```
1662
+
1663
+ *Result:* A binary predicate type. It is the same as `key_compare` for
1664
+ `set` and `multiset`; is an ordering relation on pairs induced by the
1665
+ first component (i.e., `Key`) for `map` and `multimap`.
1666
+
1667
+ ``` cpp
1668
+ typename X::node_type
1669
+ ```
1670
+
1671
+ *Result:* A specialization of the *node-handle* class
1672
+ template [[container.node]], such that the public nested types are the
1673
+ same types as the corresponding types in `X`.
1674
+
1675
+ ``` cpp
1676
+ X(c)
1677
+ ```
1678
+
1679
+ *Effects:* Constructs an empty container. Uses a copy of `c` as a
1680
+ comparison object.
1681
+
1682
+ *Complexity:* Constant.
1683
+
1684
+ ``` cpp
1685
+ X u = X();
1686
+ X u;
1687
+ ```
1688
+
1689
+ *Preconditions:* `key_compare` meets the *Cpp17DefaultConstructible*
1690
+ requirements.
1691
+
1692
+ *Effects:* Constructs an empty container. Uses `Compare()` as a
1693
+ comparison object.
1694
+
1695
+ *Complexity:* Constant.
1696
+
1697
+ ``` cpp
1698
+ X(i, j, c)
1699
+ ```
1700
+
1701
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1702
+ from `*i`.
1703
+
1704
+ *Effects:* Constructs an empty container and inserts elements from the
1705
+ range \[`i`, `j`) into it; uses `c` as a comparison object.
1706
+
1707
+ *Complexity:* N log N in general, where N has the value
1708
+ `distance(i, j)`; linear if \[`i`, `j`) is sorted with respect to
1709
+ `value_comp()`.
1710
+
1711
+ ``` cpp
1712
+ X(i, j)
1713
+ ```
1714
+
1715
+ *Preconditions:* `key_compare` meets the *Cpp17DefaultConstructible*
1716
+ requirements. `value_type` is *Cpp17EmplaceConstructible* into `X` from
1717
+ `*i`.
1718
+
1719
+ *Effects:* Constructs an empty container and inserts elements from the
1720
+ range \[`i`, `j`) into it; uses `Compare()` as a comparison object.
1721
+
1722
+ *Complexity:* N log N in general, where N has the value
1723
+ `distance(i, j)`; linear if \[`i`, `j`) is sorted with respect to
1724
+ `value_comp()`.
1725
+
1726
+ ``` cpp
1727
+ X(from_range, rg, c)
1728
+ ```
1729
+
1730
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1731
+ from `*ranges::begin(rg)`.
1732
+
1733
+ *Effects:* Constructs an empty container and inserts each element from
1734
+ `rg` into it. Uses `c` as the comparison object.
1735
+
1736
+ *Complexity:* N log N in general, where N has the value
1737
+ `ranges::distance(rg)`; linear if `rg` is sorted with respect to
1738
+ `value_comp()`.
1739
+
1740
+ ``` cpp
1741
+ X(from_range, rg)
1742
+ ```
1743
+
1744
+ *Preconditions:* `key_compare` meets the *Cpp17DefaultConstructible*
1745
+ requirements. `value_type` is *Cpp17EmplaceConstructible* into `X` from
1746
+ `*ranges::begin(rg)`.
1747
+
1748
+ *Effects:* Constructs an empty container and inserts each element from
1749
+ `rg` into it. Uses `Compare()` as the comparison object.
1750
+
1751
+ *Complexity:* Same as `X(from_range, rg, c)`.
1752
+
1753
+ ``` cpp
1754
+ X(il, c)
1755
+ ```
1756
+
1757
+ *Effects:* Equivalent to `X(il.begin(), il.end(), c)`.
1758
+
1759
+ ``` cpp
1760
+ X(il)
1761
+ ```
1762
+
1763
+ *Effects:* Equivalent to `X(il.begin(), il.end())`.
1764
+
1765
+ ``` cpp
1766
+ a = il
1767
+ ```
1768
+
1769
+ *Result:* `X&`
1770
+
1771
+ *Preconditions:* `value_type` is *Cpp17CopyInsertable* into `X` and
1772
+ *Cpp17CopyAssignable*.
1773
+
1774
+ *Effects:* Assigns the range \[`il.begin()`, `il.end()`) into `a`. All
1775
+ existing elements of `a` are either assigned to or destroyed.
1776
+
1777
+ *Complexity:* N log N in general, where N has the value
1778
+ `il.size() + a.size()`; linear if \[`il.begin()`, `il.end()`) is sorted
1779
+ with respect to `value_comp()`.
1780
+
1781
+ ``` cpp
1782
+ b.key_comp()
1783
+ ```
1784
+
1785
+ *Result:* `X::key_compare`
1786
+
1787
+ *Returns:* The comparison object out of which `b` was constructed.
1788
+
1789
+ *Complexity:* Constant.
1790
+
1791
+ ``` cpp
1792
+ b.value_comp()
1793
+ ```
1794
+
1795
+ *Result:* `X::value_compare`
1796
+
1797
+ *Returns:* An object of `value_compare` constructed out of the
1798
+ comparison object.
1799
+
1800
+ *Complexity:* Constant.
1801
+
1802
+ ``` cpp
1803
+ a_uniq.emplace(args)
1804
+ ```
1805
+
1806
+ *Result:* `pair<iterator, bool>`
1807
+
1808
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1809
+ from `args`.
1810
+
1811
+ *Effects:* Inserts a `value_type` object `t` constructed with
1812
+ `std::forward<Args>(args)...` if and only if there is no element in the
1813
+ container with key equivalent to the key of `t`.
1814
+
1815
+ *Returns:* The `bool` component of the returned pair is `true` if and
1816
+ only if the insertion takes place, and the iterator component of the
1817
+ pair points to the element with key equivalent to the key of `t`.
1818
+
1819
+ *Complexity:* Logarithmic.
1820
+
1821
+ ``` cpp
1822
+ a_eq.emplace(args)
1823
+ ```
1824
+
1825
+ *Result:* `iterator`
1826
+
1827
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1828
+ from `args`.
1829
+
1830
+ *Effects:* Inserts a `value_type` object `t` constructed with
1831
+ `std::forward<Args>(args)...`. If a range containing elements equivalent
1832
+ to `t` exists in `a_eq`, `t` is inserted at the end of that range.
1833
+
1834
+ *Returns:* An iterator pointing to the newly inserted element.
1835
+
1836
+ *Complexity:* Logarithmic.
1837
+
1838
+ ``` cpp
1839
+ a.emplace_hint(p, args)
1840
+ ```
1841
+
1842
+ *Result:* `iterator`
1843
+
1844
+ *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`,
1845
+ except that the element is inserted as close as possible to the position
1846
+ just prior to `p`.
1847
+
1848
+ *Returns:* An iterator pointing to the element with the key equivalent
1849
+ to the newly inserted element.
1850
+
1851
+ *Complexity:* Logarithmic in general, but amortized constant if the
1852
+ element is inserted right before `p`.
1853
+
1854
+ ``` cpp
1855
+ a_uniq.insert(t)
1856
+ ```
1857
+
1858
+ *Result:* `pair<iterator, bool>`
1859
+
1860
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
1861
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
1862
+ *Cpp17CopyInsertable* into `X`.
1863
+
1864
+ *Effects:* Inserts `t` if and only if there is no element in the
1865
+ container with key equivalent to the key of `t`.
1866
+
1867
+ *Returns:* The `bool` component of the returned pair is `true` if and
1868
+ only if the insertion takes place, and the `iterator` component of the
1869
+ pair points to the element with key equivalent to the key of `t`.
1870
+
1871
+ *Complexity:* Logarithmic.
1872
+
1873
+ ``` cpp
1874
+ a_eq.insert(t)
1875
+ ```
1876
+
1877
+ *Result:* `iterator`
1878
+
1879
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
1880
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
1881
+ *Cpp17CopyInsertable* into `X`.
1882
+
1883
+ *Effects:* Inserts `t` and returns the iterator pointing to the newly
1884
+ inserted element. If a range containing elements equivalent to `t`
1885
+ exists in `a_eq`, `t` is inserted at the end of that range.
1886
+
1887
+ *Complexity:* Logarithmic.
1888
+
1889
+ ``` cpp
1890
+ a.insert(p, t)
1891
+ ```
1892
+
1893
+ *Result:* `iterator`
1894
+
1895
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
1896
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
1897
+ *Cpp17CopyInsertable* into `X`.
1898
+
1899
+ *Effects:* Inserts `t` if and only if there is no element with key
1900
+ equivalent to the key of `t` in containers with unique keys; always
1901
+ inserts `t` in containers with equivalent keys. `t` is inserted as close
1902
+ as possible to the position just prior to `p`.
1903
+
1904
+ *Returns:* An iterator pointing to the element with key equivalent to
1905
+ the key of `t`.
1906
+
1907
+ *Complexity:* Logarithmic in general, but amortized constant if `t` is
1908
+ inserted right before `p`.
1909
+
1910
+ ``` cpp
1911
+ a.insert(i, j)
1912
+ ```
1913
+
1914
+ *Result:* `void`
1915
+
1916
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1917
+ from `*i`. Neither `i` nor `j` are iterators into `a`.
1918
+
1919
+ *Effects:* Inserts each element from the range \[`i`, `j`) if and only
1920
+ if there is no element with key equivalent to the key of that element in
1921
+ containers with unique keys; always inserts that element in containers
1922
+ with equivalent keys.
1923
+
1924
+ *Complexity:* N log (`a.size()` + N), where N has the value
1925
+ `distance(i, j)`.
1926
+
1927
+ ``` cpp
1928
+ a.insert_range(rg)
1929
+ ```
1930
+
1931
+ *Result:* `void`
1932
+
1933
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
1934
+ from `*ranges::begin(rg)`. `rg` and `a` do not overlap.
1935
+
1936
+ *Effects:* Inserts each element from `rg` if and only if there is no
1937
+ element with key equivalent to the key of that element in containers
1938
+ with unique keys; always inserts that element in containers with
1939
+ equivalent keys.
1940
+
1941
+ *Complexity:* N log (`a.size()` + N), where N has the value
1942
+ `ranges::distance(rg)`.
1943
+
1944
+ ``` cpp
1945
+ a.insert(il)
1946
+ ```
1947
+
1948
+ *Effects:* Equivalent to `a.insert(il.begin(), il.end())`.
1949
+
1950
+ ``` cpp
1951
+ a_uniq.insert(nh)
1952
+ ```
1953
+
1954
+ *Result:* `insert_return_type`
1955
+
1956
+ *Preconditions:* `nh` is empty or
1957
+ `a_uniq.get_allocator() == nh.get_allocator()` is `true`.
1958
+
1959
+ *Effects:* If `nh` is empty, has no effect. Otherwise, inserts the
1960
+ element owned by `nh` if and only if there is no element in the
1961
+ container with a key equivalent to `nh.key()`.
1962
+
1963
+ *Returns:* If `nh` is empty, `inserted` is `false`, `position` is
1964
+ `end()`, and `node` is empty. Otherwise if the insertion took place,
1965
+ `inserted` is `true`, `position` points to the inserted element, and
1966
+ `node` is empty; if the insertion failed, `inserted` is `false`, `node`
1967
+ has the previous value of `nh`, and `position` points to an element with
1968
+ a key equivalent to `nh.key()`.
1969
+
1970
+ *Complexity:* Logarithmic.
1971
+
1972
+ ``` cpp
1973
+ a_eq.insert(nh)
1974
+ ```
1975
+
1976
+ *Result:* `iterator`
1977
+
1978
+ *Preconditions:* `nh` is empty or
1979
+ `a_eq.get_allocator() == nh.get_allocator()` is `true`.
1980
+
1981
+ *Effects:* If `nh` is empty, has no effect and returns `a_eq.end()`.
1982
+ Otherwise, inserts the element owned by `nh` and returns an iterator
1983
+ pointing to the newly inserted element. If a range containing elements
1984
+ with keys equivalent to `nh.key()` exists in `a_eq`, the element is
1985
+ inserted at the end of that range.
1986
+
1987
+ *Ensures:* `nh` is empty.
1988
+
1989
+ *Complexity:* Logarithmic.
1990
+
1991
+ ``` cpp
1992
+ a.insert(p, nh)
1993
+ ```
1994
+
1995
+ *Result:* `iterator`
1996
+
1997
+ *Preconditions:* `nh` is empty or
1998
+ `a.get_allocator() == nh.get_allocator()` is `true`.
1999
+
2000
+ *Effects:* If `nh` is empty, has no effect and returns `a.end()`.
2001
+ Otherwise, inserts the element owned by `nh` if and only if there is no
2002
+ element with key equivalent to `nh.key()` in containers with unique
2003
+ keys; always inserts the element owned by `nh` in containers with
2004
+ equivalent keys. The element is inserted as close as possible to the
2005
+ position just prior to `p`.
2006
+
2007
+ *Ensures:* `nh` is empty if insertion succeeds, unchanged if insertion
2008
+ fails.
2009
+
2010
+ *Returns:* An iterator pointing to the element with key equivalent to
2011
+ `nh.key()`.
2012
+
2013
+ *Complexity:* Logarithmic in general, but amortized constant if the
2014
+ element is inserted right before `p`.
2015
+
2016
+ ``` cpp
2017
+ a.extract(k)
2018
+ ```
2019
+
2020
+ *Result:* `node_type`
2021
+
2022
+ *Effects:* Removes the first element in the container with key
2023
+ equivalent to `k`.
2024
+
2025
+ *Returns:* A `node_type` owning the element if found, otherwise an empty
2026
+ `node_type`.
2027
+
2028
+ *Complexity:* log (`a.size()`)
2029
+
2030
+ ``` cpp
2031
+ a_tran.extract(kx)
2032
+ ```
2033
+
2034
+ *Result:* `node_type`
2035
+
2036
+ *Effects:* Removes the first element in the container with key `r` such
2037
+ that `!c(r, kx) && !c(kx, r)` is `true`.
2038
+
2039
+ *Returns:* A `node_type` owning the element if found, otherwise an empty
2040
+ `node_type`.
2041
+
2042
+ *Complexity:* log(`a_tran.size()`)
2043
+
2044
+ ``` cpp
2045
+ a.extract(q)
2046
+ ```
2047
+
2048
+ *Result:* `node_type`
2049
+
2050
+ *Effects:* Removes the element pointed to by `q`.
2051
+
2052
+ *Returns:* A `node_type` owning that element.
2053
+
2054
+ *Complexity:* Amortized constant.
2055
+
2056
+ ``` cpp
2057
+ a.merge(a2)
2058
+ ```
2059
+
2060
+ *Result:* `void`
2061
+
2062
+ *Preconditions:* `a.get_allocator() == a2.get_allocator()`.
2063
+
2064
+ *Effects:* Attempts to extract each element in `a2` and insert it into
2065
+ `a` using the comparison object of `a`. In containers with unique keys,
2066
+ if there is an element in `a` with key equivalent to the key of an
2067
+ element from `a2`, then that element is not extracted from `a2`.
2068
+
2069
+ *Ensures:* Pointers and references to the transferred elements of `a2`
2070
+ refer to those same elements but as members of `a`. Iterators referring
2071
+ to the transferred elements will continue to refer to their elements,
2072
+ but they now behave as iterators into `a`, not into `a2`.
2073
+
2074
+ *Throws:* Nothing unless the comparison object throws.
2075
+
2076
+ *Complexity:* N log(`a.size()+` N), where N has the value `a2.size()`.
2077
+
2078
+ ``` cpp
2079
+ a.erase(k)
2080
+ ```
2081
+
2082
+ *Result:* `size_type`
2083
+
2084
+ *Effects:* Erases all elements in the container with key equivalent to
2085
+ `k`.
2086
+
2087
+ *Returns:* The number of erased elements.
2088
+
2089
+ *Complexity:* log (`a.size()`) + `a.count(k)`
2090
+
2091
+ ``` cpp
2092
+ a_tran.erase(kx)
2093
+ ```
2094
+
2095
+ *Result:* `size_type`
2096
+
2097
+ *Effects:* Erases all elements in the container with key `r` such that
2098
+ `!c(r, kx) && !c(kx, r)` is `true`.
2099
+
2100
+ *Returns:* The number of erased elements.
2101
+
2102
+ *Complexity:* log(`a_tran.size())` + `a_tran.count(kx)`
2103
+
2104
+ ``` cpp
2105
+ a.erase(q)
2106
+ ```
2107
+
2108
+ *Result:* `iterator`
2109
+
2110
+ *Effects:* Erases the element pointed to by `q`.
2111
+
2112
+ *Returns:* An iterator pointing to the element immediately following `q`
2113
+ prior to the element being erased. If no such element exists, returns
2114
+ `a.end()`.
2115
+
2116
+ *Complexity:* Amortized constant.
2117
+
2118
+ ``` cpp
2119
+ a.erase(r)
2120
+ ```
2121
+
2122
+ *Result:* `iterator`
2123
+
2124
+ *Effects:* Erases the element pointed to by `r`.
2125
+
2126
+ *Returns:* An iterator pointing to the element immediately following `r`
2127
+ prior to the element being erased. If no such element exists, returns
2128
+ `a.end()`.
2129
+
2130
+ *Complexity:* Amortized constant.
2131
+
2132
+ ``` cpp
2133
+ a.erase(q1, q2)
2134
+ ```
2135
+
2136
+ *Result:* `iterator`
2137
+
2138
+ *Effects:* Erases all the elements in the range \[`q1`, `q2`).
2139
+
2140
+ *Returns:* An iterator pointing to the element pointed to by `q2` prior
2141
+ to any elements being erased. If no such element exists, `a.end()` is
2142
+ returned.
2143
+
2144
+ *Complexity:* log(`a.size()`) + N, where N has the value
2145
+ `distance(q1, q2)`.
2146
+
2147
+ ``` cpp
2148
+ a.clear()
2149
+ ```
2150
+
2151
+ *Effects:* Equivalent to `a.erase(a.begin(), a.end())`.
2152
+
2153
+ *Ensures:* `a.empty()` is `true`.
2154
+
2155
+ *Complexity:* Linear in `a.size()`.
2156
+
2157
+ ``` cpp
2158
+ b.find(k)
2159
+ ```
2160
+
2161
+ *Result:* `iterator`; `const_iterator` for constant `b`.
2162
+
2163
+ *Returns:* An iterator pointing to an element with the key equivalent to
2164
+ `k`, or `b.end()` if such an element is not found.
2165
+
2166
+ *Complexity:* Logarithmic.
2167
+
2168
+ ``` cpp
2169
+ a_tran.find(ke)
2170
+ ```
2171
+
2172
+ *Result:* `iterator`; `const_iterator` for constant `a_tran`.
2173
+
2174
+ *Returns:* An iterator pointing to an element with key `r` such that
2175
+ `!c(r, ke) && !c(ke, r)` is `true`, or `a_tran.end()` if such an element
2176
+ is not found.
2177
+
2178
+ *Complexity:* Logarithmic.
2179
+
2180
+ ``` cpp
2181
+ b.count(k)
2182
+ ```
2183
+
2184
+ *Result:* `size_type`
2185
+
2186
+ *Returns:* The number of elements with key equivalent to `k`.
2187
+
2188
+ *Complexity:* log (`b.size()`) + `b.count(k)`
2189
+
2190
+ ``` cpp
2191
+ a_tran.count(ke)
2192
+ ```
2193
+
2194
+ *Result:* `size_type`
2195
+
2196
+ *Returns:* The number of elements with key `r` such that
2197
+ `!c(r, ke) && !c(ke, r)`.
2198
+
2199
+ *Complexity:* log (`a_tran.size()`) + `a_tran.count(ke)`
2200
+
2201
+ ``` cpp
2202
+ b.contains(k)
2203
+ ```
2204
+
2205
+ *Result:* `bool`
2206
+
2207
+ *Effects:* Equivalent to: `return b.find(k) != b.end();`
2208
+
2209
+ ``` cpp
2210
+ a_tran.contains(ke)
2211
+ ```
2212
+
2213
+ *Result:* `bool`
2214
+
2215
+ *Effects:* Equivalent to: `return a_tran.find(ke) != a_tran.end();`
2216
+
2217
+ ``` cpp
2218
+ b.lower_bound(k)
2219
+ ```
2220
+
2221
+ *Result:* `iterator`; `const_iterator` for constant `b`.
2222
+
2223
+ *Returns:* An iterator pointing to the first element with key not less
2224
+ than `k`, or `b.end()` if such an element is not found.
2225
+
2226
+ *Complexity:* Logarithmic.
2227
+
2228
+ ``` cpp
2229
+ a_tran.lower_bound(kl)
2230
+ ```
2231
+
2232
+ *Result:* `iterator`; `const_iterator` for constant `a_tran`.
2233
+
2234
+ *Returns:* An iterator pointing to the first element with key `r` such
2235
+ that `!c(r, kl)`, or `a_tran.end()` if such an element is not found.
2236
+
2237
+ *Complexity:* Logarithmic.
2238
+
2239
+ ``` cpp
2240
+ b.upper_bound(k)
2241
+ ```
2242
+
2243
+ *Result:* `iterator`; `const_iterator` for constant `b`.
2244
+
2245
+ *Returns:* An iterator pointing to the first element with key greater
2246
+ than `k`, or `b.end()` if such an element is not found.
2247
+
2248
+ *Complexity:* Logarithmic,
2249
+
2250
+ ``` cpp
2251
+ a_tran.upper_bound(ku)
2252
+ ```
2253
+
2254
+ *Result:* `iterator`; `const_iterator` for constant `a_tran`.
2255
+
2256
+ *Returns:* An iterator pointing to the first element with key `r` such
2257
+ that `c(ku, r)`, or `a_tran.end()` if such an element is not found.
2258
+
2259
+ *Complexity:* Logarithmic.
2260
+
2261
+ ``` cpp
2262
+ b.equal_range(k)
2263
+ ```
2264
+
2265
+ *Result:* `pair<iterator, iterator>`;
2266
+ `pair<const_iterator, const_iterator>` for constant `b`.
2267
+
2268
+ *Effects:* Equivalent to:
2269
+ `return make_pair(b.lower_bound(k), b.upper_bound(k));`
2270
+
2271
+ *Complexity:* Logarithmic.
2272
+
2273
+ ``` cpp
2274
+ a_tran.equal_range(ke)
2275
+ ```
2276
+
2277
+ *Result:* `pair<iterator, iterator>`;
2278
+ `pair<const_iterator, const_iterator>` for constant `a_tran`.
2279
+
2280
+ *Effects:* Equivalent to:
2281
+ `return make_pair(a_tran.lower_bound(ke), a_tran.upper_bound(ke));`
2282
+
2283
+ *Complexity:* Logarithmic.
2284
+
2285
+ The `insert`, `insert_range`, and `emplace` members shall not affect the
2286
+ validity of iterators and references to the container, and the `erase`
2287
+ members shall invalidate only iterators and references to the erased
2288
+ elements.
2289
 
2290
  The `extract` members invalidate only iterators to the removed element;
2291
  pointers and references to the removed element remain valid. However,
2292
  accessing the element through such pointers and references while the
2293
  element is owned by a `node_type` is undefined behavior. References and
 
2319
  assignment operator, the target container shall then use the comparison
2320
  object from the container being copied, as if that comparison object had
2321
  been passed to the target container in its constructor.
2322
 
2323
  The member function templates `find`, `count`, `contains`,
2324
+ `lower_bound`, `upper_bound`, `equal_range`, `erase`, and `extract`
2325
+ shall not participate in overload resolution unless the *qualified-id*
2326
+ `Compare::is_transparent` is valid and denotes a type [[temp.deduct]].
2327
+ Additionally, the member function templates `extract` and `erase` shall
2328
+ not participate in overload resolution if
2329
+ `is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator>`
2330
+ is `true`, where `K` is the type substituted as the first template
2331
+ argument.
2332
 
2333
  A deduction guide for an associative container shall not participate in
2334
  overload resolution if any of the following are true:
2335
 
2336
  - It has an `InputIterator` template parameter and a type that does not
 
2354
  unless that exception is thrown by the swap of the container’s `Compare`
2355
  object (if any).
2356
 
2357
  ### Unordered associative containers <a id="unord.req">[[unord.req]]</a>
2358
 
2359
+ #### General <a id="unord.req.general">[[unord.req.general]]</a>
2360
+
2361
  Unordered associative containers provide an ability for fast retrieval
2362
  of data based on keys. The worst-case complexity for most operations is
2363
  linear, but the average case is much faster. The library provides four
2364
  unordered associative containers: `unordered_set`, `unordered_map`,
2365
  `unordered_multiset`, and `unordered_multimap`.
 
2431
  changes ordering between elements, and changes which buckets elements
2432
  appear in, but does not invalidate pointers or references to elements.
2433
  For `unordered_multiset` and `unordered_multimap`, rehashing preserves
2434
  the relative ordering of equivalent elements.
2435
 
2436
+ In this subclause,
 
 
 
 
 
 
 
 
 
 
 
2437
 
2438
  - `X` denotes an unordered associative container class,
2439
  - `a` denotes a value of type `X`,
2440
  - `a2` denotes a value of a type with nodes compatible with type `X` (
2441
  [[container.node.compat]]),
2442
+ - `b` denotes a value of type `X` or `const X`,
2443
  - `a_uniq` denotes a value of type `X` when `X` supports unique keys,
2444
  - `a_eq` denotes a value of type `X` when `X` supports equivalent keys,
2445
+ - `a_tran` denotes a value of type `X` or `const X` when the
2446
  *qualified-id*s `X::key_equal::is_transparent` and
2447
  `X::hasher::is_transparent` are both valid and denote types
2448
  [[temp.deduct]],
2449
  - `i` and `j` denote input iterators that refer to `value_type`,
2450
  - `[i, j)` denotes a valid range,
2451
+ - `rg` denotes a value of a type `R` that models
2452
+ `container-compatible-range<value_type>`,
2453
  - `p` and `q2` denote valid constant iterators to `a`,
2454
  - `q` and `q1` denote valid dereferenceable constant iterators to `a`,
2455
  - `r` denotes a valid dereferenceable iterator to `a`,
2456
  - `[q1, q2)` denotes a valid range in `a`,
2457
  - `il` denotes a value of type `initializer_list<value_type>`,
2458
  - `t` denotes a value of type `X::value_type`,
2459
  - `k` denotes a value of type `key_type`,
2460
+ - `hf` denotes a value of type `hasher` or `const hasher`,
2461
+ - `eq` denotes a value of type `key_equal` or `const key_equal`,
2462
  - `ke` is a value such that
2463
+ - `eq(r1, ke) == eq(ke, r1)`,
2464
  - `hf(r1) == hf(ke)` if `eq(r1, ke)` is `true`, and
2465
+ - if any two of `eq(r1, ke)`, `eq(r2, ke)`, and `eq(r1, r2)` are
2466
+ `true`, then all three are `true`,
2467
+
2468
+ where `r1` and `r2` are keys of elements in `a_tran`,
2469
+ - `kx` is a value such that
2470
+ - `eq(r1, kx) == eq(kx, r1)`,
2471
+ - `hf(r1) == hf(kx)` if `eq(r1, kx)` is `true`,
2472
+ - if any two of `eq(r1, kx)`, `eq(r2, kx)`, and `eq(r1, r2)` are
2473
+ `true`, then all three are `true`, and
2474
+ - `kx` is not convertible to either `iterator` or `const_iterator`,
2475
 
2476
  where `r1` and `r2` are keys of elements in `a_tran`,
2477
  - `n` denotes a value of type `size_type`,
2478
  - `z` denotes a value of type `float`, and
2479
+ - `nh` denotes an rvalue of type `X::node_type`.
2480
+
2481
+ A type `X` meets the *unordered associative container* requirements if
2482
+ `X` meets all the requirements of an allocator-aware container
2483
+ [[container.requirements.general]] and the following types, statements,
2484
+ and expressions are well-formed and have the specified semantics, except
2485
+ that for `unordered_map` and `unordered_multimap`, the requirements
2486
+ placed on `value_type` in [[container.alloc.reqmts]] apply instead to
2487
+ `key_type` and `mapped_type`.
2488
+
2489
+ [*Note 3*: For example, `key_type` and `mapped_type` are sometimes
2490
+ required to be *Cpp17CopyAssignable* even though the associated
2491
+ `value_type`, `pair<const key_type, mapped_type>`, is not
2492
+ *Cpp17CopyAssignable*. — *end note*]
2493
+
2494
+ ``` cpp
2495
+ typename X::key_type
2496
+ ```
2497
+
2498
+ *Result:* `Key`.
2499
+
2500
+ ``` cpp
2501
+ typename X::mapped_type
2502
+ ```
2503
+
2504
+ *Result:* `T`.
2505
+
2506
+ *Remarks:* For `unordered_map` and `unordered_multimap` only.
2507
+
2508
+ ``` cpp
2509
+ typename X::value_type
2510
+ ```
2511
+
2512
+ *Result:* `Key` for `unordered_set` and `unordered_multiset` only;
2513
+ `pair<const Key, T>` for `unordered_map` and `unordered_multimap` only.
2514
+
2515
+ *Preconditions:* `value_type` is *Cpp17Erasable* from `X`.
2516
+
2517
+ ``` cpp
2518
+ typename X::hasher
2519
+ ```
2520
+
2521
+ *Result:* `Hash`.
2522
+
2523
+ *Preconditions:* `Hash` is a unary function object type such that the
2524
+ expression `hf(k)` has type `size_t`.
2525
+
2526
+ ``` cpp
2527
+ typename X::key_equal
2528
+ ```
2529
+
2530
+ *Result:* `Pred`.
2531
+
2532
+ *Preconditions:* `Pred` meets the *Cpp17CopyConstructible* requirements.
2533
+ `Pred` is a binary predicate that takes two arguments of type `Key`.
2534
+ `Pred` is an equivalence relation.
2535
+
2536
+ ``` cpp
2537
+ typename X::local_iterator
2538
+ ```
2539
+
2540
+ *Result:* An iterator type whose category, value type, difference type,
2541
+ and pointer and reference types are the same as `X::iterator`’s.
2542
+
2543
+ [*Note 1*: A `local_iterator` object can be used to iterate through a
2544
+ single bucket, but cannot be used to iterate across
2545
+ buckets. — *end note*]
2546
+
2547
+ ``` cpp
2548
+ typename X::const_local_iterator
2549
+ ```
2550
+
2551
+ *Result:* An iterator type whose category, value type, difference type,
2552
+ and pointer and reference types are the same as `X::const_iterator`’s.
2553
+
2554
+ [*Note 2*: A `const_local_iterator` object can be used to iterate
2555
+ through a single bucket, but cannot be used to iterate across
2556
+ buckets. — *end note*]
2557
+
2558
+ ``` cpp
2559
+ typename X::node_type
2560
+ ```
2561
+
2562
+ *Result:* A specialization of a *node-handle* class
2563
+ template [[container.node]], such that the public nested types are the
2564
+ same types as the corresponding types in `X`.
2565
+
2566
+ ``` cpp
2567
+ X(n, hf, eq)
2568
+ ```
2569
+
2570
+ *Effects:* Constructs an empty container with at least `n` buckets,
2571
+ using `hf` as the hash function and `eq` as the key equality predicate.
2572
+
2573
+ *Complexity:* 𝑂(`n`)
2574
+
2575
+ ``` cpp
2576
+ X(n, hf)
2577
+ ```
2578
+
2579
+ *Preconditions:* `key_equal` meets the *Cpp17DefaultConstructible*
2580
+ requirements.
2581
+
2582
+ *Effects:* Constructs an empty container with at least `n` buckets,
2583
+ using `hf` as the hash function and `key_equal()` as the key equality
2584
+ predicate.
2585
+
2586
+ *Complexity:* 𝑂(`n`)
2587
+
2588
+ ``` cpp
2589
+ X(n)
2590
+ ```
2591
+
2592
+ *Preconditions:* `hasher` and `key_equal` meet the
2593
+ *Cpp17DefaultConstructible* requirements.
2594
+
2595
+ *Effects:* Constructs an empty container with at least `n` buckets,
2596
+ using `hasher()` as the hash function and `key_equal()` as the key
2597
+ equality predicate.
2598
+
2599
+ *Complexity:* 𝑂(`n`)
2600
+
2601
+ ``` cpp
2602
+ X a = X();
2603
+ X a;
2604
+ ```
2605
+
2606
+ *Preconditions:* `hasher` and `key_equal` meet the
2607
+ *Cpp17DefaultConstructible* requirements.
2608
+
2609
+ *Effects:* Constructs an empty container with an unspecified number of
2610
+ buckets, using `hasher()` as the hash function and `key_equal()` as the
2611
+ key equality predicate.
2612
+
2613
+ *Complexity:* Constant.
2614
+
2615
+ ``` cpp
2616
+ X(i, j, n, hf, eq)
2617
+ ```
2618
+
2619
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2620
+ from `*i`.
2621
+
2622
+ *Effects:* Constructs an empty container with at least `n` buckets,
2623
+ using `hf` as the hash function and `eq` as the key equality predicate,
2624
+ and inserts elements from \[`i`, `j`) into it.
2625
+
2626
+ *Complexity:* Average case 𝑂(N) (N is `distance(i, j)`), worst case
2627
+ 𝑂(N^2).
2628
+
2629
+ ``` cpp
2630
+ X(i, j, n, hf)
2631
+ ```
2632
+
2633
+ *Preconditions:* `key_equal` meets the *Cpp17DefaultConstructible*
2634
+ requirements. `value_type` is *Cpp17EmplaceConstructible* into `X` from
2635
+ `*i`.
2636
+
2637
+ *Effects:* Constructs an empty container with at least `n` buckets,
2638
+ using `hf` as the hash function and `key_equal()` as the key equality
2639
+ predicate, and inserts elements from \[`i`, `j`) into it.
2640
+
2641
+ *Complexity:* Average case 𝑂(N) (N is `distance(i, j)`), worst case
2642
+ 𝑂(N^2).
2643
+
2644
+ ``` cpp
2645
+ X(i, j, n)
2646
+ ```
2647
+
2648
+ *Preconditions:* `hasher` and `key_equal` meet the
2649
+ *Cpp17DefaultConstructible* requirements. `value_type` is
2650
+ *Cpp17EmplaceConstructible* into `X` from `*i`.
2651
+
2652
+ *Effects:* Constructs an empty container with at least `n` buckets,
2653
+ using `hasher()` as the hash function and `key_equal()` as the key
2654
+ equality predicate, and inserts elements from \[`i`, `j`) into it.
2655
+
2656
+ *Complexity:* Average case 𝑂(N) (N is `distance(i, j)`), worst case
2657
+ 𝑂(N^2).
2658
+
2659
+ ``` cpp
2660
+ X(i, j)
2661
+ ```
2662
+
2663
+ *Preconditions:* `hasher` and `key_equal` meet the
2664
+ *Cpp17DefaultConstructible* requirements. `value_type` is
2665
+ *Cpp17EmplaceConstructible* into `X` from `*i`.
2666
+
2667
+ *Effects:* Constructs an empty container with an unspecified number of
2668
+ buckets, using `hasher()` as the hash function and `key_equal()` as the
2669
+ key equality predicate, and inserts elements from \[`i`, `j`) into it.
2670
+
2671
+ *Complexity:* Average case 𝑂(N) (N is `distance(i, j)`), worst case
2672
+ 𝑂(N^2).
2673
+
2674
+ ``` cpp
2675
+ X(from_range, rg, n, hf, eq)
2676
+ ```
2677
+
2678
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2679
+ from `*ranges::begin(rg)`.
2680
+
2681
+ *Effects:* Constructs an empty container with at least `n` buckets,
2682
+ using `hf` as the hash function and `eq` as the key equality predicate,
2683
+ and inserts elements from `rg` into it.
2684
+
2685
+ *Complexity:* Average case 𝑂(N) (N is `ranges::distance(rg)`), worst
2686
+ case 𝑂(N^2).
2687
+
2688
+ ``` cpp
2689
+ X(from_range, rg, n, hf)
2690
+ ```
2691
+
2692
+ *Preconditions:* `key_equal` meets the *Cpp17DefaultConstructible*
2693
+ requirements. `value_type` is *Cpp17EmplaceConstructible* into `X` from
2694
+ `*ranges::begin(rg)`.
2695
+
2696
+ *Effects:* Constructs an empty container with at least `n` buckets,
2697
+ using `hf` as the hash function and `key_equal()` as the key equality
2698
+ predicate, and inserts elements from `rg` into it.
2699
+
2700
+ *Complexity:* Average case 𝑂(N) (N is `ranges::distance(rg)`), worst
2701
+ case 𝑂(N^2).
2702
+
2703
+ ``` cpp
2704
+ X(from_range, rg, n)
2705
+ ```
2706
+
2707
+ *Preconditions:* `hasher` and `key_equal` meet the
2708
+ *Cpp17DefaultConstructible* requirements. `value_type` is
2709
+ *Cpp17EmplaceConstructible* into `X` from `*ranges::begin(rg)`.
2710
+
2711
+ *Effects:* Constructs an empty container with at least `n` buckets,
2712
+ using `hasher()` as the hash function and `key_equal()` as the key
2713
+ equality predicate, and inserts elements from `rg` into it.
2714
+
2715
+ *Complexity:* Average case 𝑂(N) (N is `ranges::distance(rg)`), worst
2716
+ case 𝑂(N^2).
2717
+
2718
+ ``` cpp
2719
+ X(from_range, rg)
2720
+ ```
2721
+
2722
+ *Preconditions:* `hasher` and `key_equal` meet the
2723
+ *Cpp17DefaultConstructible* requirements. `value_type` is
2724
+ *Cpp17EmplaceConstructible* into `X` from `*ranges::begin(rg)`.
2725
+
2726
+ *Effects:* Constructs an empty container with an unspecified number of
2727
+ buckets, using `hasher()` as the hash function and `key_equal()` as the
2728
+ key equality predicate, and inserts elements from `rg` into it.
2729
+
2730
+ *Complexity:* Average case 𝑂(N) (N is `ranges::distance(rg)`), worst
2731
+ case 𝑂(N^2).
2732
+
2733
+ ``` cpp
2734
+ X(il)
2735
+ ```
2736
+
2737
+ *Effects:* Equivalent to `X(il.begin(), il.end())`.
2738
+
2739
+ ``` cpp
2740
+ X(il, n)
2741
+ ```
2742
+
2743
+ *Effects:* Equivalent to `X(il.begin(), il.end(), n)`.
2744
+
2745
+ ``` cpp
2746
+ X(il, n, hf)
2747
+ ```
2748
+
2749
+ *Effects:* Equivalent to `X(il.begin(), il.end(), n, hf)`.
2750
+
2751
+ ``` cpp
2752
+ X(il, n, hf, eq)
2753
+ ```
2754
+
2755
+ *Effects:* Equivalent to `X(il.begin(), il.end(), n, hf, eq)`.
2756
+
2757
+ ``` cpp
2758
+ X(b)
2759
+ ```
2760
+
2761
+ *Effects:* In addition to the container
2762
+ requirements [[container.requirements.general]], copies the hash
2763
+ function, predicate, and maximum load factor.
2764
+
2765
+ *Complexity:* Average case linear in `b.size()`, worst case quadratic.
2766
+
2767
+ ``` cpp
2768
+ a = b
2769
+ ```
2770
+
2771
+ *Result:* `X&`
2772
+
2773
+ *Effects:* In addition to the container requirements, copies the hash
2774
+ function, predicate, and maximum load factor.
2775
+
2776
+ *Complexity:* Average case linear in `b.size()`, worst case quadratic.
2777
+
2778
+ ``` cpp
2779
+ a = il
2780
+ ```
2781
+
2782
+ *Result:* `X&`
2783
+
2784
+ *Preconditions:* `value_type` is *Cpp17CopyInsertable* into `X` and
2785
+ *Cpp17CopyAssignable*.
2786
+
2787
+ *Effects:* Assigns the range \[`il.begin()`, `il.end()`) into `a`. All
2788
+ existing elements of `a` are either assigned to or destroyed.
2789
+
2790
+ *Complexity:* Average case linear in `il.size()`, worst case quadratic.
2791
+
2792
+ ``` cpp
2793
+ b.hash_function()
2794
+ ```
2795
+
2796
+ *Result:* `hasher`
2797
+
2798
+ *Returns:* `b`’s hash function.
2799
+
2800
+ *Complexity:* Constant.
2801
+
2802
+ ``` cpp
2803
+ b.key_eq()
2804
+ ```
2805
+
2806
+ *Result:* `key_equal`
2807
+
2808
+ *Returns:* `b`’s key equality predicate.
2809
+
2810
+ *Complexity:* Constant.
2811
+
2812
+ ``` cpp
2813
+ a_uniq.emplace(args)
2814
+ ```
2815
+
2816
+ *Result:* `pair<iterator,` `bool>`
2817
+
2818
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2819
+ from `args`.
2820
+
2821
+ *Effects:* Inserts a `value_type` object `t` constructed with
2822
+ `std::forward<Args>(args)...` if and only if there is no element in the
2823
+ container with key equivalent to the key of `t`.
2824
+
2825
+ *Returns:* The `bool` component of the returned pair is `true` if and
2826
+ only if the insertion takes place, and the iterator component of the
2827
+ pair points to the element with key equivalent to the key of `t`.
2828
+
2829
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_uniq.size()`).
2830
+
2831
+ ``` cpp
2832
+ a_eq.emplace(args)
2833
+ ```
2834
+
2835
+ *Result:* `iterator`
2836
+
2837
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2838
+ from `args`.
2839
+
2840
+ *Effects:* Inserts a `value_type` object `t` constructed with
2841
+ `std::forward<Args>(args)...`.
2842
+
2843
+ *Returns:* An iterator pointing to the newly inserted element.
2844
+
2845
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_eq.size()`).
2846
+
2847
+ ``` cpp
2848
+ a.emplace_hint(p, args)
2849
+ ```
2850
+
2851
+ *Result:* `iterator`
2852
+
2853
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2854
+ from `args`.
2855
+
2856
+ *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`.
2857
+
2858
+ *Returns:* An iterator pointing to the element with the key equivalent
2859
+ to the newly inserted element. The `const_iterator` `p` is a hint
2860
+ pointing to where the search should start. Implementations are permitted
2861
+ to ignore the hint.
2862
+
2863
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
2864
+
2865
+ ``` cpp
2866
+ a_uniq.insert(t)
2867
+ ```
2868
+
2869
+ *Result:* `pair<iterator, bool>`
2870
+
2871
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
2872
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
2873
+ *Cpp17CopyInsertable* into `X`.
2874
+
2875
+ *Effects:* Inserts `t` if and only if there is no element in the
2876
+ container with key equivalent to the key of `t`.
2877
+
2878
+ *Returns:* The `bool` component of the returned pair indicates whether
2879
+ the insertion takes place, and the `iterator` component points to the
2880
+ element with key equivalent to the key of `t`.
2881
+
2882
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_uniq.size()`).
2883
+
2884
+ ``` cpp
2885
+ a_eq.insert(t)
2886
+ ```
2887
+
2888
+ *Result:* `iterator`
2889
+
2890
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
2891
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
2892
+ *Cpp17CopyInsertable* into `X`.
2893
+
2894
+ *Effects:* Inserts `t`.
2895
+
2896
+ *Returns:* An iterator pointing to the newly inserted element.
2897
+
2898
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_eq.size()`).
2899
+
2900
+ ``` cpp
2901
+ a.insert(p, t)
2902
+ ```
2903
+
2904
+ *Result:* `iterator`
2905
+
2906
+ *Preconditions:* If `t` is a non-const rvalue, `value_type` is
2907
+ *Cpp17MoveInsertable* into `X`; otherwise, `value_type` is
2908
+ *Cpp17CopyInsertable* into `X`.
2909
+
2910
+ *Effects:* Equivalent to `a.insert(t)`. The iterator `p` is a hint
2911
+ pointing to where the search should start. Implementations are permitted
2912
+ to ignore the hint.
2913
+
2914
+ *Returns:* An iterator pointing to the element with the key equivalent
2915
+ to that of `t`.
2916
+
2917
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
2918
+
2919
+ ``` cpp
2920
+ a.insert(i, j)
2921
+ ```
2922
+
2923
+ *Result:* `void`
2924
+
2925
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2926
+ from `*i`. Neither `i` nor `j` are iterators into `a`.
2927
+
2928
+ *Effects:* Equivalent to `a.insert(t)` for each element in `[i,j)`.
2929
+
2930
+ *Complexity:* Average case 𝑂(N), where N is `distance(i, j)`, worst case
2931
+ 𝑂(N(`a.size()` + 1)).
2932
+
2933
+ ``` cpp
2934
+ a.insert_range(rg)
2935
+ ```
2936
+
2937
+ *Result:* `void`
2938
+
2939
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2940
+ from `*ranges::begin(rg)`. `rg` and `a` do not overlap.
2941
+
2942
+ *Effects:* Equivalent to `a.insert(t)` for each element `t` in `rg`.
2943
+
2944
+ *Complexity:* Average case 𝑂(N), where N is `ranges::distance(rg)`,
2945
+ worst case 𝑂(N(`a.size()` + 1)).
2946
+
2947
+ ``` cpp
2948
+ a.insert(il)
2949
+ ```
2950
+
2951
+ *Effects:* Equivalent to `a.insert(il.begin(), il.end())`.
2952
+
2953
+ ``` cpp
2954
+ a_uniq.insert(nh)
2955
+ ```
2956
+
2957
+ *Result:* `insert_return_type`
2958
+
2959
+ *Preconditions:* `nh` is empty or
2960
+ `a_uniq.get_allocator() == nh.get_allocator()` is `true`.
2961
+
2962
+ *Effects:* If `nh` is empty, has no effect. Otherwise, inserts the
2963
+ element owned by `nh` if and only if there is no element in the
2964
+ container with a key equivalent to `nh.key()`.
2965
+
2966
+ *Ensures:* If `nh` is empty, `inserted` is `false`, `position` is
2967
+ `end()`, and `node` is empty. Otherwise if the insertion took place,
2968
+ `inserted` is `true`, `position` points to the inserted element, and
2969
+ `node` is empty; if the insertion failed, `inserted` is `false`, `node`
2970
+ has the previous value of `nh`, and `position` points to an element with
2971
+ a key equivalent to `nh.key()`.
2972
+
2973
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_uniq.size()`).
2974
+
2975
+ ``` cpp
2976
+ a_eq.insert(nh)
2977
+ ```
2978
+
2979
+ *Result:* `iterator`
2980
+
2981
+ *Preconditions:* `nh` is empty or
2982
+ `a_eq.get_allocator() == nh.get_allocator()` is `true`.
2983
+
2984
+ *Effects:* If `nh` is empty, has no effect and returns `a_eq.end()`.
2985
+ Otherwise, inserts the element owned by `nh` and returns an iterator
2986
+ pointing to the newly inserted element.
2987
+
2988
+ *Ensures:* `nh` is empty.
2989
+
2990
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_eq.size()`).
2991
+
2992
+ ``` cpp
2993
+ a.insert(q, nh)
2994
+ ```
2995
+
2996
+ *Result:* `iterator`
2997
+
2998
+ *Preconditions:* `nh` is empty or
2999
+ `a.get_allocator() == nh.get_allocator()` is `true`.
3000
+
3001
+ *Effects:* If `nh` is empty, has no effect and returns `a.end()`.
3002
+ Otherwise, inserts the element owned by `nh` if and only if there is no
3003
+ element with key equivalent to `nh.key()` in containers with unique
3004
+ keys; always inserts the element owned by `nh` in containers with
3005
+ equivalent keys. The iterator `q` is a hint pointing to where the search
3006
+ should start. Implementations are permitted to ignore the hint.
3007
+
3008
+ *Ensures:* `nh` is empty if insertion succeeds, unchanged if insertion
3009
+ fails.
3010
+
3011
+ *Returns:* An iterator pointing to the element with key equivalent to
3012
+ `nh.key()`.
3013
+
3014
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
3015
+
3016
+ ``` cpp
3017
+ a.extract(k)
3018
+ ```
3019
+
3020
+ *Result:* `node_type`
3021
+
3022
+ *Effects:* Removes an element in the container with key equivalent to
3023
+ `k`.
3024
+
3025
+ *Returns:* A `node_type` owning the element if found, otherwise an empty
3026
+ `node_type`.
3027
+
3028
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
3029
+
3030
+ ``` cpp
3031
+ a_tran.extract(kx)
3032
+ ```
3033
+
3034
+ *Result:* `node_type`
3035
+
3036
+ *Effects:* Removes an element in the container with key equivalent to
3037
+ `kx`.
3038
+
3039
+ *Returns:* A `node_type` owning the element if found, otherwise an empty
3040
+ `node_type`.
3041
+
3042
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_tran.size()`).
3043
+
3044
+ ``` cpp
3045
+ a.extract(q)
3046
+ ```
3047
+
3048
+ *Result:* `node_type`
3049
+
3050
+ *Effects:* Removes the element pointed to by `q`.
3051
+
3052
+ *Returns:* A `node_type` owning that element.
3053
+
3054
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
3055
+
3056
+ ``` cpp
3057
+ a.merge(a2)
3058
+ ```
3059
+
3060
+ *Result:* `void`
3061
+
3062
+ *Preconditions:* `a.get_allocator() == a2.get_allocator()`.
3063
+
3064
+ *Effects:* Attempts to extract each element in `a2` and insert it into
3065
+ `a` using the hash function and key equality predicate of `a`. In
3066
+ containers with unique keys, if there is an element in `a` with key
3067
+ equivalent to the key of an element from `a2`, then that element is not
3068
+ extracted from `a2`.
3069
+
3070
+ *Ensures:* Pointers and references to the transferred elements of `a2`
3071
+ refer to those same elements but as members of `a`. Iterators referring
3072
+ to the transferred elements and all iterators referring to `a` will be
3073
+ invalidated, but iterators to elements remaining in `a2` will remain
3074
+ valid.
3075
+
3076
+ *Complexity:* Average case 𝑂(N), where N is `a2.size()`, worst case
3077
+ 𝑂(N`*a.size() + N`).
3078
+
3079
+ ``` cpp
3080
+ a.erase(k)
3081
+ ```
3082
+
3083
+ *Result:* `size_type`
3084
+
3085
+ *Effects:* Erases all elements with key equivalent to `k`.
3086
+
3087
+ *Returns:* The number of elements erased.
3088
+
3089
+ *Complexity:* Average case 𝑂(`a.count(k)`), worst case 𝑂(`a.size()`).
3090
+
3091
+ ``` cpp
3092
+ a_tran.erase(kx)
3093
+ ```
3094
+
3095
+ *Result:* `size_type`
3096
+
3097
+ *Effects:* Erases all elements with key equivalent to `kx`.
3098
+
3099
+ *Returns:* The number of elements erased.
3100
+
3101
+ *Complexity:* Average case 𝑂(`a_tran.count(kx)`), worst case
3102
+ 𝑂(`a_tran.size()`).
3103
+
3104
+ ``` cpp
3105
+ a.erase(q)
3106
+ ```
3107
+
3108
+ *Result:* `iterator`
3109
+
3110
+ *Effects:* Erases the element pointed to by `q`.
3111
+
3112
+ *Returns:* The iterator immediately following `q` prior to the erasure.
3113
+
3114
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
3115
+
3116
+ ``` cpp
3117
+ a.erase(r)
3118
+ ```
3119
+
3120
+ *Result:* `iterator`
3121
+
3122
+ *Effects:* Erases the element pointed to by `r`.
3123
+
3124
+ *Returns:* The iterator immediately following `r` prior to the erasure.
3125
+
3126
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
3127
+
3128
+ ``` cpp
3129
+ a.erase(q1, q2)
3130
+ ```
3131
+
3132
+ *Result:* `iterator`
3133
+
3134
+ *Effects:* Erases all elements in the range `[q1, q2)`.
3135
+
3136
+ *Returns:* The iterator immediately following the erased elements prior
3137
+ to the erasure.
3138
+
3139
+ *Complexity:* Average case linear in `distance(q1, q2)`, worst case
3140
+ 𝑂(`a.size()`).
3141
+
3142
+ ``` cpp
3143
+ a.clear()
3144
+ ```
3145
+
3146
+ *Result:* `void`
3147
+
3148
+ *Effects:* Erases all elements in the container.
3149
+
3150
+ *Ensures:* `a.empty()` is `true`.
3151
+
3152
+ *Complexity:* Linear in `a.size()`.
3153
+
3154
+ ``` cpp
3155
+ b.find(k)
3156
+ ```
3157
+
3158
+ *Result:* `iterator`; `const_iterator` for constant `b`.
3159
+
3160
+ *Returns:* An iterator pointing to an element with key equivalent to
3161
+ `k`, or `b.end()` if no such element exists.
3162
+
3163
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`b.size()`).
3164
+
3165
+ ``` cpp
3166
+ a_tran.find(ke)
3167
+ ```
3168
+
3169
+ *Result:* `iterator`; `const_iterator` for constant `a_tran`.
3170
+
3171
+ *Returns:* An iterator pointing to an element with key equivalent to
3172
+ `ke`, or `a_tran.end()` if no such element exists.
3173
+
3174
+ *Complexity:* Average case 𝑂(1), worst case 𝑂(`a_tran.size()`).
3175
+
3176
+ ``` cpp
3177
+ b.count(k)
3178
+ ```
3179
+
3180
+ *Result:* `size_type`
3181
+
3182
+ *Returns:* The number of elements with key equivalent to `k`.
3183
+
3184
+ *Complexity:* Average case 𝑂(`b.count(k)`), worst case 𝑂(`b.size()`).
3185
+
3186
+ ``` cpp
3187
+ a_tran.count(ke)
3188
+ ```
3189
+
3190
+ *Result:* `size_type`
3191
+
3192
+ *Returns:* The number of elements with key equivalent to `ke`.
3193
+
3194
+ *Complexity:* Average case 𝑂(`a_tran.count(ke)`), worst case
3195
+ 𝑂(`a_tran.size()`).
3196
+
3197
+ ``` cpp
3198
+ b.contains(k)
3199
+ ```
3200
+
3201
+ *Effects:* Equivalent to `b.find(k) != b.end()`.
3202
+
3203
+ ``` cpp
3204
+ a_tran.contains(ke)
3205
+ ```
3206
+
3207
+ *Effects:* Equivalent to `a_tran.find(ke) != a_tran.end()`.
3208
+
3209
+ ``` cpp
3210
+ b.equal_range(k)
3211
+ ```
3212
+
3213
+ *Result:* `pair<iterator, iterator>`;
3214
+ `pair<const_iterator, const_iterator>` for constant `b`.
3215
+
3216
+ *Returns:* A range containing all elements with keys equivalent to `k`.
3217
+ Returns `make_pair(b.end(), b.end())` if no such elements exist.
3218
+
3219
+ *Complexity:* Average case 𝑂(`b.count(k)`), worst case 𝑂(`b.size()`).
3220
+
3221
+ ``` cpp
3222
+ a_tran.equal_range(ke)
3223
+ ```
3224
+
3225
+ *Result:* `pair<iterator, iterator>`;
3226
+ `pair<const_iterator, const_iterator>` for constant `a_tran`.
3227
+
3228
+ *Returns:* A range containing all elements with keys equivalent to `ke`.
3229
+ Returns `make_pair(a_tran.end(), a_tran.end())` if no such elements
3230
+ exist.
3231
+
3232
+ *Complexity:* Average case 𝑂(`a_tran.count(ke)`), worst case
3233
+ 𝑂(`a_tran.size()`).
3234
+
3235
+ ``` cpp
3236
+ b.bucket_count()
3237
+ ```
3238
+
3239
+ *Result:* `size_type`
3240
+
3241
+ *Returns:* The number of buckets that `b` contains.
3242
+
3243
+ *Complexity:* Constant.
3244
+
3245
+ ``` cpp
3246
+ b.max_bucket_count()
3247
+ ```
3248
+
3249
+ *Result:* `size_type`
3250
+
3251
+ *Returns:* An upper bound on the number of buckets that `b` can ever
3252
+ contain.
3253
+
3254
+ *Complexity:* Constant.
3255
+
3256
+ ``` cpp
3257
+ b.bucket(k)
3258
+ ```
3259
+
3260
+ *Result:* `size_type`
3261
+
3262
+ *Preconditions:* `b.bucket_count() > 0`.
3263
+
3264
+ *Returns:* The index of the bucket in which elements with keys
3265
+ equivalent to `k` would be found, if any such element existed. The
3266
+ return value is in the range `[0, b.bucket_count())`.
3267
+
3268
+ *Complexity:* Constant.
3269
+
3270
+ ``` cpp
3271
+ b.bucket_size(n)
3272
+ ```
3273
+
3274
+ *Result:* `size_type`
3275
+
3276
+ *Preconditions:* `n` shall be in the range `[0, b.bucket_count())`.
3277
+
3278
+ *Returns:* The number of elements in the `n`ᵗʰ bucket.
3279
+
3280
+ *Complexity:* 𝑂(`b.bucket_size(n)`)
3281
+
3282
+ ``` cpp
3283
+ b.begin(n)
3284
+ ```
3285
+
3286
+ *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3287
+
3288
+ *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3289
+
3290
+ *Returns:* An iterator referring to the first element in the bucket. If
3291
+ the bucket is empty, then `b.begin(n) == b.end(n)`.
3292
+
3293
+ *Complexity:* Constant.
3294
+
3295
+ ``` cpp
3296
+ b.end(n)
3297
+ ```
3298
+
3299
+ *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3300
+
3301
+ *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3302
+
3303
+ *Returns:* An iterator which is the past-the-end value for the bucket.
3304
+
3305
+ *Complexity:* Constant.
3306
+
3307
+ ``` cpp
3308
+ b.cbegin(n)
3309
+ ```
3310
+
3311
+ *Result:* `const_local_iterator`
3312
+
3313
+ *Preconditions:* `n` shall be in the range `[0, b.bucket_count())`.
3314
+
3315
+ *Returns:* An iterator referring to the first element in the bucket. If
3316
+ the bucket is empty, then `b.cbegin(n) == b.cend(n)`.
3317
+
3318
+ *Complexity:* Constant.
3319
+
3320
+ ``` cpp
3321
+ b.cend(n)
3322
+ ```
3323
+
3324
+ *Result:* `const_local_iterator`
3325
+
3326
+ *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3327
+
3328
+ *Returns:* An iterator which is the past-the-end value for the bucket.
3329
+
3330
+ *Complexity:* Constant.
3331
+
3332
+ ``` cpp
3333
+ b.load_factor()
3334
+ ```
3335
+
3336
+ *Result:* `float`
3337
+
3338
+ *Returns:* The average number of elements per bucket.
3339
+
3340
+ *Complexity:* Constant.
3341
+
3342
+ ``` cpp
3343
+ b.max_load_factor()
3344
+ ```
3345
+
3346
+ *Result:* `float`
3347
+
3348
+ *Returns:* A positive number that the container attempts to keep the
3349
+ load factor less than or equal to. The container automatically increases
3350
+ the number of buckets as necessary to keep the load factor below this
3351
+ number.
3352
+
3353
+ *Complexity:* Constant.
3354
+
3355
+ ``` cpp
3356
+ a.max_load_factor(z)
3357
+ ```
3358
+
3359
+ *Result:* `void`
3360
+
3361
+ *Preconditions:* `z` is positive. May change the container’s maximum
3362
+ load factor, using `z` as a hint.
3363
+
3364
+ *Complexity:* Constant.
3365
+
3366
+ ``` cpp
3367
+ a.rehash(n)
3368
+ ```
3369
+
3370
+ *Result:* `void`
3371
+
3372
+ *Ensures:* `a.bucket_count() >= a.size() / a.max_load_factor()` and
3373
+ `a.bucket_count() >= n`.
3374
+
3375
+ *Complexity:* Average case linear in `a.size()`, worst case quadratic.
3376
+
3377
+ ``` cpp
3378
+ a.reserve(n)
3379
+ ```
3380
+
3381
+ *Effects:* Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`.
3382
 
3383
  Two unordered containers `a` and `b` compare equal if
3384
  `a.size() == b.size()` and, for every equivalent-key group \[`Ea1`,
3385
  `Ea2`) obtained from `a.equal_range(Ea1)`, there exists an
3386
  equivalent-key group \[`Eb1`, `Eb2`) obtained from `b.equal_range(Ea1)`,
 
3400
  `unordered_multiset` and `unordered_multimap` becomes proportional to N
3401
  (but worst-case complexity remains 𝑂(N^2), e.g., for a pathologically
3402
  bad hash function). The behavior of a program that uses `operator==` or
3403
  `operator!=` on unordered containers is undefined unless the `Pred`
3404
  function object has the same behavior for both containers and the
3405
+ equality comparison function for `Key` is a refinement[^1]
3406
+
3407
+ of the partition into equivalent-key groups produced by `Pred`.
3408
 
3409
  The iterator types `iterator` and `const_iterator` of an unordered
3410
  associative container are of at least the forward iterator category. For
3411
  unordered associative containers where the key type and value type are
3412
  the same, both `iterator` and `const_iterator` are constant iterators.
3413
 
3414
+ The `insert`, `insert_range`, and `emplace` members shall not affect the
3415
+ validity of references to container elements, but may invalidate all
3416
+ iterators to the container. The `erase` members shall invalidate only
3417
+ iterators and references to the erased elements, and preserve the
3418
+ relative order of the elements that are not erased.
3419
 
3420
+ The `insert`, `insert_range`, and `emplace` members shall not affect the
3421
+ validity of iterators if `(N+n) <= z * B`, where `N` is the number of
3422
+ elements in the container prior to the insert operation, `n` is the
3423
+ number of elements inserted, `B` is the container’s bucket count, and
3424
+ `z` is the container’s maximum load factor.
3425
 
3426
  The `extract` members invalidate only iterators to the removed element,
3427
  and preserve the relative order of the elements that are not erased;
3428
  pointers and references to the removed element remain valid. However,
3429
  accessing the element through such pointers and references while the
3430
  element is owned by a `node_type` is undefined behavior. References and
3431
  pointers to an element obtained while it is owned by a `node_type` are
3432
  invalidated if the element is successfully inserted.
3433
 
3434
+ The member function templates `find`, `count`, `equal_range`,
3435
+ `contains`, `extract`, and `erase` shall not participate in overload
3436
+ resolution unless the *qualified-id*s `Pred::is_transparent` and
3437
+ `Hash::is_transparent` are both valid and denote types [[temp.deduct]].
3438
+ Additionally, the member function templates `extract` and `erase` shall
3439
+ not participate in overload resolution if
3440
+ `is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator>`
3441
+ is `true`, where `K` is the type substituted as the first template
3442
+ argument.
3443
 
3444
  A deduction guide for an unordered associative container shall not
3445
  participate in overload resolution if any of the following are true:
3446
 
3447
  - It has an `InputIterator` template parameter and a type that does not
 
3550
 
3551
  template<class T, class Allocator>
3552
  void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
3553
  noexcept(noexcept(x.swap(y)));
3554
 
3555
+ // [deque.erasure], erasure
3556
  template<class T, class Allocator, class U>
3557
  typename deque<T, Allocator>::size_type
3558
  erase(deque<T, Allocator>& c, const U& value);
3559
  template<class T, class Allocator, class Predicate>
3560
  typename deque<T, Allocator>::size_type
 
3572
  ``` cpp
3573
  #include <compare> // see [compare.syn]
3574
  #include <initializer_list> // see [initializer.list.syn]
3575
 
3576
  namespace std {
3577
+ // [forward.list], class template forward_list
3578
  template<class T, class Allocator = allocator<T>> class forward_list;
3579
 
3580
  template<class T, class Allocator>
3581
  bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
3582
  template<class T, class Allocator>
 
3585
 
3586
  template<class T, class Allocator>
3587
  void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
3588
  noexcept(noexcept(x.swap(y)));
3589
 
3590
+ // [forward.list.erasure], erasure
3591
  template<class T, class Allocator, class U>
3592
  typename forward_list<T, Allocator>::size_type
3593
  erase(forward_list<T, Allocator>& c, const U& value);
3594
  template<class T, class Allocator, class Predicate>
3595
  typename forward_list<T, Allocator>::size_type
 
3620
 
3621
  template<class T, class Allocator>
3622
  void swap(list<T, Allocator>& x, list<T, Allocator>& y)
3623
  noexcept(noexcept(x.swap(y)));
3624
 
3625
+ // [list.erasure], erasure
3626
  template<class T, class Allocator, class U>
3627
  typename list<T, Allocator>::size_type
3628
  erase(list<T, Allocator>& c, const U& value);
3629
  template<class T, class Allocator, class Predicate>
3630
  typename list<T, Allocator>::size_type
 
3655
 
3656
  template<class T, class Allocator>
3657
  constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
3658
  noexcept(noexcept(x.swap(y)));
3659
 
3660
+ // [vector.erasure], erasure
3661
  template<class T, class Allocator, class U>
3662
  constexpr typename vector<T, Allocator>::size_type
3663
  erase(vector<T, Allocator>& c, const U& value);
3664
  template<class T, class Allocator, class Predicate>
3665
  constexpr typename vector<T, Allocator>::size_type
3666
  erase_if(vector<T, Allocator>& c, Predicate pred);
3667
 
3668
+ namespace pmr {
3669
+ template<class T>
3670
+ using vector = std::vector<T, polymorphic_allocator<T>>;
3671
+ }
3672
+
3673
+ // [vector.bool], specialization of vector for bool
3674
+ // [vector.bool.pspc], partial class template specialization vector<bool, Allocator>
3675
+ template<class Allocator>
3676
+ class vector<bool, Allocator>;
3677
+
3678
+ template<class T>
3679
+ constexpr bool is-vector-bool-reference = see below; // exposition only
3680
 
3681
  // hash support
3682
  template<class T> struct hash;
3683
  template<class Allocator> struct hash<vector<bool, Allocator>>;
3684
 
3685
+ // [vector.bool.fmt], formatter specialization for vector<bool>
3686
+ template<class T, class charT> requires is-vector-bool-reference<T>
3687
+ struct formatter<T, charT>;
 
3688
  }
3689
  ```
3690
 
3691
  ### Class template `array` <a id="array">[[array]]</a>
3692
 
3693
  #### Overview <a id="array.overview">[[array.overview]]</a>
3694
 
3695
  The header `<array>` defines a class template for storing fixed-size
3696
  sequences of objects. An `array` is a contiguous container
3697
+ [[container.reqmts]]. An instance of `array<T, N>` stores `N` elements
3698
+ of type `T`, so that `size() == N` is an invariant.
3699
 
3700
  An `array` is an aggregate [[dcl.init.aggr]] that can be
3701
  list-initialized with up to `N` elements whose types are convertible to
3702
  `T`.
3703
 
3704
+ An `array` meets all of the requirements of a container
3705
+ [[container.reqmts]] and of a reversible container
3706
+ [[container.rev.reqmts]], except that a default constructed `array`
3707
+ object is not empty if `N` > 0. An `array` meets some of the
3708
+ requirements of a sequence container [[sequence.reqmts]]. Descriptions
3709
+ are provided here only for operations on `array` that are not described
3710
+ in one of these tables and for operations where there is additional
3711
+ semantic information.
3712
 
3713
  `array<T, N>` is a structural type [[temp.param]] if `T` is a structural
3714
  type. Two values `a1` and `a2` of type `array<T, N>` are
3715
  template-argument-equivalent [[temp.type]] if and only if each pair of
3716
  corresponding elements in `a1` and `a2` are
 
3782
  ```
3783
 
3784
  #### Constructors, copy, and assignment <a id="array.cons">[[array.cons]]</a>
3785
 
3786
  The conditions for an aggregate [[dcl.init.aggr]] shall be met. Class
3787
+ `array` relies on the implicitly-declared special member functions
3788
+ [[class.default.ctor]], [[class.dtor]], [[class.copy.ctor]] to conform
3789
+ to the container requirements table in  [[container.requirements]]. In
3790
+ addition to the requirements specified in the container requirements
3791
+ table, the implicit move constructor and move assignment operator for
3792
+ `array` require that `T` be *Cpp17MoveConstructible* or
3793
+ *Cpp17MoveAssignable*, respectively.
3794
 
3795
  ``` cpp
3796
  template<class T, class... U>
3797
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
3798
  ```
 
3826
  ```
3827
 
3828
  *Effects:* Equivalent to `swap_ranges(begin(), end(), y.begin())`.
3829
 
3830
  [*Note 1*: Unlike the `swap` function for other containers,
3831
+ `array::swap` takes linear time, can exit via an exception, and does not
3832
  cause iterators to become associated with the other
3833
  container. — *end note*]
3834
 
3835
  #### Specialized algorithms <a id="array.special">[[array.special]]</a>
3836
 
 
3925
  insert and erase operations at the beginning or the end; insert and
3926
  erase in the middle take linear time. That is, a deque is especially
3927
  optimized for pushing and popping elements at the beginning and end.
3928
  Storage management is handled automatically.
3929
 
3930
+ A `deque` meets all of the requirements of a container
3931
+ [[container.reqmts]], of a reversible container
3932
+ [[container.rev.reqmts]], of an allocator-aware container
3933
+ [[container.alloc.reqmts]], and of a sequence container, including the
3934
+ optional sequence container requirements [[sequence.reqmts]].
3935
+ Descriptions are provided here only for operations on `deque` that are
3936
+ not described in one of these tables or for operations where there is
3937
+ additional semantic information.
3938
 
3939
  ``` cpp
3940
  namespace std {
3941
  template<class T, class Allocator = allocator<T>>
3942
  class deque {
 
3946
  using allocator_type = Allocator;
3947
  using pointer = typename allocator_traits<Allocator>::pointer;
3948
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
3949
  using reference = value_type&;
3950
  using const_reference = const value_type&;
3951
+ using size_type = implementation-defined // type of deque::size_type; // see [container.requirements]
3952
+ using difference_type = implementation-defined // type of deque::difference_type; // see [container.requirements]
3953
  using iterator = implementation-defined // type of deque::iterator; // see [container.requirements]
3954
  using const_iterator = implementation-defined // type of deque::const_iterator; // see [container.requirements]
3955
  using reverse_iterator = std::reverse_iterator<iterator>;
3956
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3957
 
 
3960
  explicit deque(const Allocator&);
3961
  explicit deque(size_type n, const Allocator& = Allocator());
3962
  deque(size_type n, const T& value, const Allocator& = Allocator());
3963
  template<class InputIterator>
3964
  deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
3965
+ template<container-compatible-range<T> R>
3966
+ deque(from_range_t, R&& rg, const Allocator& = Allocator());
3967
  deque(const deque& x);
3968
  deque(deque&&);
3969
+ deque(const deque&, const type_identity_t<Allocator>&);
3970
+ deque(deque&&, const type_identity_t<Allocator>&);
3971
  deque(initializer_list<T>, const Allocator& = Allocator());
3972
 
3973
  ~deque();
3974
  deque& operator=(const deque& x);
3975
  deque& operator=(deque&& x)
3976
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
3977
  deque& operator=(initializer_list<T>);
3978
  template<class InputIterator>
3979
  void assign(InputIterator first, InputIterator last);
3980
+ template<container-compatible-range<T> R>
3981
+ void assign_range(R&& rg);
3982
  void assign(size_type n, const T& t);
3983
  void assign(initializer_list<T>);
3984
  allocator_type get_allocator() const noexcept;
3985
 
3986
  // iterators
 
4021
  template<class... Args> reference emplace_back(Args&&... args);
4022
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4023
 
4024
  void push_front(const T& x);
4025
  void push_front(T&& x);
4026
+ template<container-compatible-range<T> R>
4027
+ void prepend_range(R&& rg);
4028
  void push_back(const T& x);
4029
  void push_back(T&& x);
4030
+ template<container-compatible-range<T> R>
4031
+ void append_range(R&& rg);
4032
 
4033
  iterator insert(const_iterator position, const T& x);
4034
  iterator insert(const_iterator position, T&& x);
4035
  iterator insert(const_iterator position, size_type n, const T& x);
4036
  template<class InputIterator>
4037
  iterator insert(const_iterator position, InputIterator first, InputIterator last);
4038
+ template<container-compatible-range<T> R>
4039
+ iterator insert_range(const_iterator position, R&& rg);
4040
  iterator insert(const_iterator position, initializer_list<T>);
4041
 
4042
  void pop_front();
4043
  void pop_back();
4044
 
 
4051
 
4052
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
4053
  deque(InputIterator, InputIterator, Allocator = Allocator())
4054
  -> deque<iter-value-type<InputIterator>, Allocator>;
4055
 
4056
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
4057
+ deque(from_range_t, R&&, Allocator = Allocator())
4058
+ -> deque<ranges::range_value_t<R>, Allocator>;
 
4059
  }
4060
  ```
4061
 
4062
  #### Constructors, copy, and assignment <a id="deque.cons">[[deque.cons]]</a>
4063
 
 
4071
 
4072
  ``` cpp
4073
  explicit deque(size_type n, const Allocator& = Allocator());
4074
  ```
4075
 
4076
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
4077
+
4078
  *Effects:* Constructs a `deque` with `n` default-inserted elements using
4079
  the specified allocator.
4080
 
 
 
4081
  *Complexity:* Linear in `n`.
4082
 
4083
  ``` cpp
4084
  deque(size_type n, const T& value, const Allocator& = Allocator());
4085
  ```
4086
 
4087
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
4088
+
4089
  *Effects:* Constructs a `deque` with `n` copies of `value`, using the
4090
  specified allocator.
4091
 
 
 
4092
  *Complexity:* Linear in `n`.
4093
 
4094
  ``` cpp
4095
  template<class InputIterator>
4096
  deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
4099
  *Effects:* Constructs a `deque` equal to the range \[`first`, `last`),
4100
  using the specified allocator.
4101
 
4102
  *Complexity:* Linear in `distance(first, last)`.
4103
 
4104
+ ``` cpp
4105
+ template<container-compatible-range<T> R>
4106
+ deque(from_range_t, R&& rg, const Allocator& = Allocator());
4107
+ ```
4108
+
4109
+ *Effects:* Constructs a `deque` with the elements of the range `rg`,
4110
+ using the specified allocator.
4111
+
4112
+ *Complexity:* Linear in `ranges::distance(rg)`.
4113
+
4114
  #### Capacity <a id="deque.capacity">[[deque.capacity]]</a>
4115
 
4116
  ``` cpp
4117
  void resize(size_type sz);
4118
  ```
 
4164
  iterator insert(const_iterator position, T&& x);
4165
  iterator insert(const_iterator position, size_type n, const T& x);
4166
  template<class InputIterator>
4167
  iterator insert(const_iterator position,
4168
  InputIterator first, InputIterator last);
4169
+ template<container-compatible-range<T> R>
4170
+ iterator insert_range(const_iterator position, R&& rg);
4171
  iterator insert(const_iterator position, initializer_list<T>);
4172
 
4173
  template<class... Args> reference emplace_front(Args&&... args);
4174
  template<class... Args> reference emplace_back(Args&&... args);
4175
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4176
  void push_front(const T& x);
4177
  void push_front(T&& x);
4178
+ template<container-compatible-range<T> R>
4179
+ void prepend_range(R&& rg);
4180
  void push_back(const T& x);
4181
  void push_back(T&& x);
4182
+ template<container-compatible-range<T> R>
4183
+ void append_range(R&& rg);
4184
  ```
4185
 
4186
  *Effects:* An insertion in the middle of the deque invalidates all the
4187
  iterators and references to elements of the deque. An insertion at
4188
  either end of the deque invalidates all the iterators to the deque, but
4189
  has no effect on the validity of references to elements of the deque.
4190
 
4191
+ *Complexity:* The complexity is linear in the number of elements
4192
+ inserted plus the lesser of the distances to the beginning and end of
4193
+ the deque. Inserting a single element at either the beginning or end of
4194
+ a deque always takes constant time and causes a single call to a
4195
+ constructor of `T`.
4196
+
4197
  *Remarks:* If an exception is thrown other than by the copy constructor,
4198
  move constructor, assignment operator, or move assignment operator of
4199
  `T` there are no effects. If an exception is thrown while inserting a
4200
  single element at either end, there are no effects. Otherwise, if an
4201
  exception is thrown by the move constructor of a
4202
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
4203
 
 
 
 
 
 
 
4204
  ``` cpp
4205
  iterator erase(const_iterator position);
4206
  iterator erase(const_iterator first, const_iterator last);
4207
  void pop_front();
4208
  void pop_back();
 
4218
  to all the elements of the deque.
4219
 
4220
  [*Note 1*: `pop_front` and `pop_back` are erase
4221
  operations. — *end note*]
4222
 
4223
+ *Throws:* Nothing unless an exception is thrown by the assignment
4224
+ operator of `T`.
4225
+
4226
  *Complexity:* The number of calls to the destructor of `T` is the same
4227
  as the number of elements erased, but the number of calls to the
4228
  assignment operator of `T` is no more than the lesser of the number of
4229
  elements before the erased elements and the number of elements after the
4230
  erased elements.
4231
 
 
 
 
4232
  #### Erasure <a id="deque.erasure">[[deque.erasure]]</a>
4233
 
4234
  ``` cpp
4235
  template<class T, class Allocator, class U>
4236
  typename deque<T, Allocator>::size_type
 
4259
  auto r = distance(it, c.end());
4260
  c.erase(it, c.end());
4261
  return r;
4262
  ```
4263
 
4264
+ ### Class template `forward_list` <a id="forward.list">[[forward.list]]</a>
4265
 
4266
+ #### Overview <a id="forward.list.overview">[[forward.list.overview]]</a>
4267
 
4268
  A `forward_list` is a container that supports forward iterators and
4269
  allows constant time insert and erase operations anywhere within the
4270
  sequence, with storage management handled automatically. Fast random
4271
  access to list elements is not supported.
4272
 
4273
  [*Note 1*: It is intended that `forward_list` have zero space or time
4274
  overhead relative to a hand-written C-style singly linked list. Features
4275
  that would conflict with that goal have been omitted. — *end note*]
4276
 
4277
+ A `forward_list` meets all of the requirements of a container
4278
+ [[container.reqmts]], except that the `size()` member function is not
4279
+ provided and `operator==` has linear complexity, A `forward_list` also
4280
+ meets all of the requirements for an allocator-aware container
4281
+ [[container.alloc.reqmts]]. In addition, a `forward_list` provides the
4282
+ `assign` member functions and several of the optional sequence container
4283
+ requirements [[sequence.reqmts]]. Descriptions are provided here only
4284
+ for operations on `forward_list` that are not described in that table or
4285
+ for operations where there is additional semantic information.
 
4286
 
4287
  [*Note 2*: Modifying any list requires access to the element preceding
4288
  the first element of interest, but in a `forward_list` there is no
4289
+ constant-time way to access a preceding element. For this reason,
4290
+ `erase_after` and `splice_after` take fully-open ranges, not semi-open
4291
+ ranges. — *end note*]
4292
 
4293
  ``` cpp
4294
  namespace std {
4295
  template<class T, class Allocator = allocator<T>>
4296
  class forward_list {
 
4300
  using allocator_type = Allocator;
4301
  using pointer = typename allocator_traits<Allocator>::pointer;
4302
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4303
  using reference = value_type&;
4304
  using const_reference = const value_type&;
4305
+ using size_type = implementation-defined // type of forward_list::size_type; // see [container.requirements]
4306
+ using difference_type = implementation-defined // type of forward_list::difference_type; // see [container.requirements]
4307
  using iterator = implementation-defined // type of forward_list::iterator; // see [container.requirements]
4308
  using const_iterator = implementation-defined // type of forward_list::const_iterator; // see [container.requirements]
4309
 
4310
+ // [forward.list.cons], construct/copy/destroy
4311
  forward_list() : forward_list(Allocator()) { }
4312
  explicit forward_list(const Allocator&);
4313
  explicit forward_list(size_type n, const Allocator& = Allocator());
4314
  forward_list(size_type n, const T& value, const Allocator& = Allocator());
4315
  template<class InputIterator>
4316
  forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
4317
+ template<container-compatible-range<T> R>
4318
+ forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4319
  forward_list(const forward_list& x);
4320
  forward_list(forward_list&& x);
4321
+ forward_list(const forward_list& x, const type_identity_t<Allocator>&);
4322
+ forward_list(forward_list&& x, const type_identity_t<Allocator>&);
4323
  forward_list(initializer_list<T>, const Allocator& = Allocator());
4324
  ~forward_list();
4325
  forward_list& operator=(const forward_list& x);
4326
  forward_list& operator=(forward_list&& x)
4327
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4328
  forward_list& operator=(initializer_list<T>);
4329
  template<class InputIterator>
4330
  void assign(InputIterator first, InputIterator last);
4331
+ template<container-compatible-range<T> R>
4332
+ void assign_range(R&& rg);
4333
  void assign(size_type n, const T& t);
4334
  void assign(initializer_list<T>);
4335
  allocator_type get_allocator() const noexcept;
4336
 
4337
+ // [forward.list.iter], iterators
4338
  iterator before_begin() noexcept;
4339
  const_iterator before_begin() const noexcept;
4340
  iterator begin() noexcept;
4341
  const_iterator begin() const noexcept;
4342
  iterator end() noexcept;
 
4348
 
4349
  // capacity
4350
  [[nodiscard]] bool empty() const noexcept;
4351
  size_type max_size() const noexcept;
4352
 
4353
+ // [forward.list.access], element access
4354
  reference front();
4355
  const_reference front() const;
4356
 
4357
+ // [forward.list.modifiers], modifiers
4358
  template<class... Args> reference emplace_front(Args&&... args);
4359
  void push_front(const T& x);
4360
  void push_front(T&& x);
4361
+ template<container-compatible-range<T> R>
4362
+ void prepend_range(R&& rg);
4363
  void pop_front();
4364
 
4365
  template<class... Args> iterator emplace_after(const_iterator position, Args&&... args);
4366
  iterator insert_after(const_iterator position, const T& x);
4367
  iterator insert_after(const_iterator position, T&& x);
4368
 
4369
  iterator insert_after(const_iterator position, size_type n, const T& x);
4370
  template<class InputIterator>
4371
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
4372
  iterator insert_after(const_iterator position, initializer_list<T> il);
4373
+ template<container-compatible-range<T> R>
4374
+ iterator insert_range_after(const_iterator position, R&& rg);
4375
 
4376
  iterator erase_after(const_iterator position);
4377
  iterator erase_after(const_iterator position, const_iterator last);
4378
  void swap(forward_list&)
4379
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4380
 
4381
  void resize(size_type sz);
4382
  void resize(size_type sz, const value_type& c);
4383
  void clear() noexcept;
4384
 
4385
+ // [forward.list.ops], forward_list operations
4386
  void splice_after(const_iterator position, forward_list& x);
4387
  void splice_after(const_iterator position, forward_list&& x);
4388
  void splice_after(const_iterator position, forward_list& x, const_iterator i);
4389
  void splice_after(const_iterator position, forward_list&& x, const_iterator i);
4390
  void splice_after(const_iterator position, forward_list& x,
 
4411
 
4412
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
4413
  forward_list(InputIterator, InputIterator, Allocator = Allocator())
4414
  -> forward_list<iter-value-type<InputIterator>, Allocator>;
4415
 
4416
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
4417
+ forward_list(from_range_t, R&&, Allocator = Allocator())
4418
+ -> forward_list<ranges::range_value_t<R>, Allocator>;
 
4419
  }
4420
  ```
4421
 
4422
  An incomplete type `T` may be used when instantiating `forward_list` if
4423
  the allocator meets the allocator completeness requirements
4424
  [[allocator.requirements.completeness]]. `T` shall be complete before
4425
  any member of the resulting specialization of `forward_list` is
4426
  referenced.
4427
 
4428
+ #### Constructors, copy, and assignment <a id="forward.list.cons">[[forward.list.cons]]</a>
4429
 
4430
  ``` cpp
4431
  explicit forward_list(const Allocator&);
4432
  ```
4433
 
 
4466
  *Effects:* Constructs a `forward_list` object equal to the range
4467
  \[`first`, `last`).
4468
 
4469
  *Complexity:* Linear in `distance(first, last)`.
4470
 
4471
+ ``` cpp
4472
+ template<container-compatible-range<T> R>
4473
+ forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4474
+ ```
4475
+
4476
+ *Effects:* Constructs a `forward_list` object with the elements of the
4477
+ range `rg`.
4478
+
4479
+ *Complexity:* Linear in `ranges::distance(rg)`.
4480
+
4481
+ #### Iterators <a id="forward.list.iter">[[forward.list.iter]]</a>
4482
 
4483
  ``` cpp
4484
  iterator before_begin() noexcept;
4485
  const_iterator before_begin() const noexcept;
4486
  const_iterator cbefore_begin() const noexcept;
4487
  ```
4488
 
 
 
 
4489
  *Effects:* `cbefore_begin()` is equivalent to
4490
  `const_cast<forward_list const&>(*this).before_begin()`.
4491
 
4492
+ *Returns:* A non-dereferenceable iterator that, when incremented, is
4493
+ equal to the iterator returned by `begin()`.
4494
+
4495
  *Remarks:* `before_begin() == end()` shall equal `false`.
4496
 
4497
+ #### Element access <a id="forward.list.access">[[forward.list.access]]</a>
4498
 
4499
  ``` cpp
4500
  reference front();
4501
  const_reference front() const;
4502
  ```
4503
 
4504
  *Returns:* `*begin()`
4505
 
4506
+ #### Modifiers <a id="forward.list.modifiers">[[forward.list.modifiers]]</a>
4507
 
4508
  None of the overloads of `insert_after` shall affect the validity of
4509
  iterators and references, and `erase_after` shall invalidate only
4510
  iterators and references to the erased elements. If an exception is
4511
  thrown during `insert_after` there shall be no effect. Inserting `n`
 
4526
  void push_front(T&& x);
4527
  ```
4528
 
4529
  *Effects:* Inserts a copy of `x` at the beginning of the list.
4530
 
4531
+ ``` cpp
4532
+ template<container-compatible-range<T> R>
4533
+ void prepend_range(R&& rg);
4534
+ ```
4535
+
4536
+ *Effects:* Inserts a copy of each element of `rg` at the beginning of
4537
+ the list.
4538
+
4539
+ [*Note 1*: The order of elements is not reversed. — *end note*]
4540
+
4541
  ``` cpp
4542
  void pop_front();
4543
  ```
4544
 
4545
  *Effects:* As if by `erase_after(before_begin())`.
4546
 
4547
  ``` cpp
4548
  iterator insert_after(const_iterator position, const T& x);
4549
+ ```
4550
+
4551
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4552
+ `position` is `before_begin()` or is a dereferenceable iterator in the
4553
+ range \[`begin()`, `end()`).
4554
+
4555
+ *Effects:* Inserts a copy of `x` after `position`.
4556
+
4557
+ *Returns:* An iterator pointing to the copy of `x`.
4558
+
4559
+ ``` cpp
4560
  iterator insert_after(const_iterator position, T&& x);
4561
  ```
4562
 
4563
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `forward_list`.
4564
+ `position` is `before_begin()` or is a dereferenceable iterator in the
4565
+ range \[`begin()`, `end()`).
4566
 
4567
  *Effects:* Inserts a copy of `x` after `position`.
4568
 
4569
  *Returns:* An iterator pointing to the copy of `x`.
4570
 
4571
  ``` cpp
4572
  iterator insert_after(const_iterator position, size_type n, const T& x);
4573
  ```
4574
 
4575
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4576
+ `position` is `before_begin()` or is a dereferenceable iterator in the
4577
+ range \[`begin()`, `end()`).
4578
 
4579
  *Effects:* Inserts `n` copies of `x` after `position`.
4580
 
4581
+ *Returns:* An iterator pointing to the last inserted copy of `x`, or
4582
+ `position` if `n == 0` is `true`.
4583
 
4584
  ``` cpp
4585
  template<class InputIterator>
4586
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
4587
  ```
4588
 
4589
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4590
+ from `*first`. `position` is `before_begin()` or is a dereferenceable
4591
  iterator in the range \[`begin()`, `end()`). Neither `first` nor `last`
4592
  are iterators in `*this`.
4593
 
4594
  *Effects:* Inserts copies of elements in \[`first`, `last`) after
4595
  `position`.
4596
 
4597
+ *Returns:* An iterator pointing to the last inserted element, or
4598
+ `position` if `first == last` is `true`.
4599
+
4600
+ ``` cpp
4601
+ template<container-compatible-range<T> R>
4602
+ iterator insert_range_after(const_iterator position, R&& rg);
4603
+ ```
4604
+
4605
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4606
+ from `*ranges::begin(rg)`. `position` is `before_begin()` or is a
4607
+ dereferenceable iterator in the range \[`begin()`, `end()`). `rg` and
4608
+ `*this` do not overlap.
4609
+
4610
+ *Effects:* Inserts copies of elements in the range `rg` after
4611
+ `position`.
4612
+
4613
+ *Returns:* An iterator pointing to the last inserted element, or
4614
+ `position` if `rg` is empty.
4615
 
4616
  ``` cpp
4617
  iterator insert_after(const_iterator position, initializer_list<T> il);
4618
  ```
4619
 
4620
+ *Effects:* Equivalent to:
4621
+ `return insert_after(position, il.begin(), il.end());`
 
 
4622
 
4623
  ``` cpp
4624
  template<class... Args>
4625
  iterator emplace_after(const_iterator position, Args&&... args);
4626
  ```
4627
 
4628
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4629
+ from `std::forward<Args>(args)...`. `position` is `before_begin()` or is
4630
+ a dereferenceable iterator in the range \[`begin()`, `end()`).
4631
 
4632
+ *Effects:* Inserts an object of type `value_type`
4633
+ direct-non-list-initialized with `std::forward<Args>(args)...` after
4634
+ `position`.
4635
 
4636
  *Returns:* An iterator pointing to the new object.
4637
 
4638
  ``` cpp
4639
  iterator erase_after(const_iterator position);
 
4690
 
4691
  *Effects:* Erases all elements in the range \[`begin()`, `end()`).
4692
 
4693
  *Remarks:* Does not invalidate past-the-end iterators.
4694
 
4695
+ #### Operations <a id="forward.list.ops">[[forward.list.ops]]</a>
4696
 
4697
  In this subclause, arguments for a template parameter named `Predicate`
4698
  or `BinaryPredicate` shall meet the corresponding requirements in
4699
+ [[algorithms.requirements]]. The semantics of `i + n`, where `i` is an
4700
+ iterator into the list and `n` is an integer, are the same as those of
4701
+ `next(i, n)`. The expression `i - n`, where `i` is an iterator into the
4702
+ list and `n` is an integer, means an iterator `j` such that `j + n == i`
4703
+ is `true`. For `merge` and `sort`, the definitions and requirements in
4704
+ [[alg.sorting]] apply.
4705
 
4706
  ``` cpp
4707
  void splice_after(const_iterator position, forward_list& x);
4708
  void splice_after(const_iterator position, forward_list&& x);
4709
  ```
 
4779
  *Returns:* The number of elements erased.
4780
 
4781
  *Throws:* Nothing unless an exception is thrown by the equality
4782
  comparison or the predicate.
4783
 
 
 
4784
  *Complexity:* Exactly `distance(begin(), end())` applications of the
4785
  corresponding predicate.
4786
 
4787
+ *Remarks:* Stable [[algorithm.stable]].
4788
+
4789
  ``` cpp
4790
  size_type unique();
4791
+ template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
4792
  ```
4793
 
4794
+ Let `binary_pred` be `equal_to<>{}` for the first overload.
4795
+
4796
+ *Preconditions:* `binary_pred` is an equivalence relation.
4797
+
4798
  *Effects:* Erases all but the first element from every consecutive group
4799
+ of equivalent elements. That is, for a nonempty list, erases all
4800
+ elements referred to by the iterator `i` in the range \[`begin() + 1`,
4801
+ `end()`) for which `binary_pred(*i, *(i - 1))` is `true`. Invalidates
4802
+ only the iterators and references to the erased elements.
 
4803
 
4804
  *Returns:* The number of elements erased.
4805
 
4806
+ *Throws:* Nothing unless an exception is thrown by the predicate.
 
4807
 
4808
+ *Complexity:* If `empty()` is `false`, exactly
4809
+ `distance(begin(), end()) - 1` applications of the corresponding
4810
+ predicate, otherwise no applications of the predicate.
4811
 
4812
  ``` cpp
4813
  void merge(forward_list& x);
4814
  void merge(forward_list&& x);
4815
  template<class Compare> void merge(forward_list& x, Compare comp);
4816
  template<class Compare> void merge(forward_list&& x, Compare comp);
4817
  ```
4818
 
4819
+ Let `comp` be `less<>` for the first two overloads.
4820
+
4821
  *Preconditions:* `*this` and `x` are both sorted with respect to the
4822
+ comparator `comp`, and `get_allocator() == x.get_allocator()` is `true`.
 
 
4823
 
4824
+ *Effects:* If `addressof(x) == this`, there are no effects. Otherwise,
4825
+ merges the two sorted ranges \[`begin()`, `end()`) and \[`x.begin()`,
4826
+ `x.end()`). The result is a range that is sorted with respect to the
4827
+ comparator `comp`. Pointers and references to the moved elements of `x`
4828
+ now refer to those same elements but as members of `*this`. Iterators
4829
+ referring to the moved elements will continue to refer to their
4830
+ elements, but they now behave as iterators into `*this`, not into `x`.
 
 
4831
 
4832
  *Complexity:* At most
4833
  `distance(begin(), end()) + distance(x.begin(), x.end()) - 1`
4834
+ comparisons if `addressof(x) != this`; otherwise, no comparisons are
4835
+ performed.
4836
+
4837
+ *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
4838
+ is empty after the merge. No elements are copied by this operation. If
4839
+ an exception is thrown other than by a comparison, there are no effects.
4840
 
4841
  ``` cpp
4842
  void sort();
4843
  template<class Compare> void sort(Compare comp);
4844
  ```
 
4846
  *Effects:* Sorts the list according to the `operator<` or the `comp`
4847
  function object. If an exception is thrown, the order of the elements in
4848
  `*this` is unspecified. Does not affect the validity of iterators and
4849
  references.
4850
 
 
 
4851
  *Complexity:* Approximately N log N comparisons, where N is
4852
  `distance(begin(), end())`.
4853
 
4854
+ *Remarks:* Stable [[algorithm.stable]].
4855
+
4856
  ``` cpp
4857
  void reverse() noexcept;
4858
  ```
4859
 
4860
  *Effects:* Reverses the order of the elements in the list. Does not
 
4889
  and allows constant time insert and erase operations anywhere within the
4890
  sequence, with storage management handled automatically. Unlike vectors
4891
  [[vector]] and deques [[deque]], fast random access to list elements is
4892
  not supported, but many algorithms only need sequential access anyway.
4893
 
4894
+ A `list` meets all of the requirements of a container
4895
+ [[container.reqmts]], of a reversible container
4896
+ [[container.rev.reqmts]], of an allocator-aware container
4897
+ [[container.alloc.reqmts]], and of a sequence container, including most
4898
+ of the optional sequence container requirements [[sequence.reqmts]]. The
4899
+ exceptions are the `operator[]` and `at` member functions, which are not
4900
+ provided.[^2]
4901
+
4902
+ Descriptions are provided here only for operations on `list` that are
4903
+ not described in one of these tables or for operations where there is
4904
+ additional semantic information.
4905
 
4906
  ``` cpp
4907
  namespace std {
4908
  template<class T, class Allocator = allocator<T>>
4909
  class list {
 
4913
  using allocator_type = Allocator;
4914
  using pointer = typename allocator_traits<Allocator>::pointer;
4915
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4916
  using reference = value_type&;
4917
  using const_reference = const value_type&;
4918
+ using size_type = implementation-defined // type of list::size_type; // see [container.requirements]
4919
+ using difference_type = implementation-defined // type of list::difference_type; // see [container.requirements]
4920
  using iterator = implementation-defined // type of list::iterator; // see [container.requirements]
4921
  using const_iterator = implementation-defined // type of list::const_iterator; // see [container.requirements]
4922
  using reverse_iterator = std::reverse_iterator<iterator>;
4923
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
4924
 
 
4927
  explicit list(const Allocator&);
4928
  explicit list(size_type n, const Allocator& = Allocator());
4929
  list(size_type n, const T& value, const Allocator& = Allocator());
4930
  template<class InputIterator>
4931
  list(InputIterator first, InputIterator last, const Allocator& = Allocator());
4932
+ template<container-compatible-range<T> R>
4933
+ list(from_range_t, R&& rg, const Allocator& = Allocator());
4934
  list(const list& x);
4935
  list(list&& x);
4936
+ list(const list&, const type_identity_t<Allocator>&);
4937
+ list(list&&, const type_identity_t<Allocator>&);
4938
  list(initializer_list<T>, const Allocator& = Allocator());
4939
  ~list();
4940
  list& operator=(const list& x);
4941
  list& operator=(list&& x)
4942
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4943
  list& operator=(initializer_list<T>);
4944
  template<class InputIterator>
4945
  void assign(InputIterator first, InputIterator last);
4946
+ template<container-compatible-range<T> R>
4947
+ void assign_range(R&& rg);
4948
  void assign(size_type n, const T& t);
4949
  void assign(initializer_list<T>);
4950
  allocator_type get_allocator() const noexcept;
4951
 
4952
  // iterators
 
4980
  // [list.modifiers], modifiers
4981
  template<class... Args> reference emplace_front(Args&&... args);
4982
  template<class... Args> reference emplace_back(Args&&... args);
4983
  void push_front(const T& x);
4984
  void push_front(T&& x);
4985
+ template<container-compatible-range<T> R>
4986
+ void prepend_range(R&& rg);
4987
  void pop_front();
4988
  void push_back(const T& x);
4989
  void push_back(T&& x);
4990
+ template<container-compatible-range<T> R>
4991
+ void append_range(R&& rg);
4992
  void pop_back();
4993
 
4994
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4995
  iterator insert(const_iterator position, const T& x);
4996
  iterator insert(const_iterator position, T&& x);
4997
  iterator insert(const_iterator position, size_type n, const T& x);
4998
  template<class InputIterator>
4999
  iterator insert(const_iterator position, InputIterator first, InputIterator last);
5000
+ template<container-compatible-range<T> R>
5001
+ iterator insert_range(const_iterator position, R&& rg);
5002
  iterator insert(const_iterator position, initializer_list<T> il);
5003
 
5004
  iterator erase(const_iterator position);
5005
  iterator erase(const_iterator position, const_iterator last);
5006
  void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value);
 
5034
 
5035
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5036
  list(InputIterator, InputIterator, Allocator = Allocator())
5037
  -> list<iter-value-type<InputIterator>, Allocator>;
5038
 
5039
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
5040
+ list(from_range_t, R&&, Allocator = Allocator())
5041
+ -> list<ranges::range_value_t<R>, Allocator>;
 
5042
  }
5043
  ```
5044
 
5045
  An incomplete type `T` may be used when instantiating `list` if the
5046
  allocator meets the allocator completeness requirements
 
5086
 
5087
  *Effects:* Constructs a `list` equal to the range \[`first`, `last`).
5088
 
5089
  *Complexity:* Linear in `distance(first, last)`.
5090
 
5091
+ ``` cpp
5092
+ template<container-compatible-range<T> R>
5093
+ list(from_range_t, R&& rg, const Allocator& = Allocator());
5094
+ ```
5095
+
5096
+ *Effects:* Constructs a `list` object with the elements of the range
5097
+ `rg`.
5098
+
5099
+ *Complexity:* Linear in `ranges::distance(rg)`.
5100
+
5101
  #### Capacity <a id="list.capacity">[[list.capacity]]</a>
5102
 
5103
  ``` cpp
5104
  void resize(size_type sz);
5105
  ```
 
5142
  iterator insert(const_iterator position, T&& x);
5143
  iterator insert(const_iterator position, size_type n, const T& x);
5144
  template<class InputIterator>
5145
  iterator insert(const_iterator position, InputIterator first,
5146
  InputIterator last);
5147
+ template<container-compatible-range<T> R>
5148
+ iterator insert_range(const_iterator position, R&& rg);
5149
  iterator insert(const_iterator position, initializer_list<T>);
5150
 
5151
  template<class... Args> reference emplace_front(Args&&... args);
5152
  template<class... Args> reference emplace_back(Args&&... args);
5153
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
5154
  void push_front(const T& x);
5155
  void push_front(T&& x);
5156
+ template<container-compatible-range<T> R>
5157
+ void prepend_range(R&& rg);
5158
  void push_back(const T& x);
5159
  void push_back(T&& x);
5160
+ template<container-compatible-range<T> R>
5161
+ void append_range(R&& rg);
5162
  ```
5163
 
 
 
 
5164
  *Complexity:* Insertion of a single element into a list takes constant
5165
  time and exactly one call to a constructor of `T`. Insertion of multiple
5166
  elements into a list is linear in the number of elements inserted, and
5167
  the number of calls to the copy constructor or move constructor of `T`
5168
  is exactly equal to the number of elements inserted.
5169
 
5170
+ *Remarks:* Does not affect the validity of iterators and references. If
5171
+ an exception is thrown there are no effects.
5172
+
5173
  ``` cpp
5174
  iterator erase(const_iterator position);
5175
  iterator erase(const_iterator first, const_iterator last);
5176
 
5177
  void pop_front();
 
5190
  destructor of type `T` is exactly equal to the size of the range.
5191
 
5192
  #### Operations <a id="list.ops">[[list.ops]]</a>
5193
 
5194
  Since lists allow fast insertion and erasing from the middle of a list,
5195
+ certain operations are provided specifically for them.[^3]
5196
+
5197
+ In this subclause, arguments for a template parameter named `Predicate`
5198
+ or `BinaryPredicate` shall meet the corresponding requirements in
5199
+ [[algorithms.requirements]]. The semantics of `i + n` and `i - n`, where
5200
+ `i` is an iterator into the list and `n` is an integer, are the same as
5201
+ those of `next(i, n)` and `prev(i, n)`, respectively. For `merge` and
5202
+ `sort`, the definitions and requirements in [[alg.sorting]] apply.
5203
 
5204
  `list` provides three splice operations that destructively move elements
5205
  from one list to another. The behavior of splice operations is undefined
5206
  if `get_allocator() !=
5207
  x.get_allocator()`.
 
5276
  *Returns:* The number of elements erased.
5277
 
5278
  *Throws:* Nothing unless an exception is thrown by `*i == value` or
5279
  `pred(*i) != false`.
5280
 
 
 
5281
  *Complexity:* Exactly `size()` applications of the corresponding
5282
  predicate.
5283
 
5284
+ *Remarks:* Stable [[algorithm.stable]].
5285
+
5286
  ``` cpp
5287
  size_type unique();
5288
  template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
5289
  ```
5290
 
5291
+ Let `binary_pred` be `equal_to<>{}` for the first overload.
5292
+
5293
+ *Preconditions:* `binary_pred` is an equivalence relation.
5294
+
5295
  *Effects:* Erases all but the first element from every consecutive group
5296
+ of equivalent elements. That is, for a nonempty list, erases all
5297
+ elements referred to by the iterator `i` in the range \[`begin() + 1`,
5298
+ `end()`) for which `binary_pred(*i, *(i - 1))` is `true`. Invalidates
5299
+ only the iterators and references to the erased elements.
 
5300
 
5301
  *Returns:* The number of elements erased.
5302
 
5303
+ *Throws:* Nothing unless an exception is thrown by the predicate.
 
5304
 
5305
+ *Complexity:* If `empty()` is `false`, exactly `size() - 1` applications
5306
+ of the corresponding predicate, otherwise no applications of the
5307
+ predicate.
5308
 
5309
  ``` cpp
5310
  void merge(list& x);
5311
  void merge(list&& x);
5312
  template<class Compare> void merge(list& x, Compare comp);
5313
  template<class Compare> void merge(list&& x, Compare comp);
5314
  ```
5315
 
5316
+ Let `comp` be `less<>` for the first two overloads.
 
 
 
5317
 
5318
+ *Preconditions:* `*this` and `x` are both sorted with respect to the
5319
+ comparator `comp`, and `get_allocator() == x.get_allocator()` is `true`.
 
 
 
 
 
 
 
 
5320
 
5321
+ *Effects:* If `addressof(x) == this`, there are no effects. Otherwise,
5322
+ merges the two sorted ranges \[`begin()`, `end()`) and \[`x.begin()`,
5323
+ `x.end()`). The result is a range that is sorted with respect to the
5324
+ comparator `comp`. Pointers and references to the moved elements of `x`
5325
+ now refer to those same elements but as members of `*this`. Iterators
5326
+ referring to the moved elements will continue to refer to their
5327
+ elements, but they now behave as iterators into `*this`, not into `x`.
5328
 
5329
+ *Complexity:* At most `size() + x.size() - 1` comparisons if
5330
+ `addressof(x) != this`; otherwise, no comparisons are performed.
5331
+
5332
+ *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
5333
+ is empty after the merge. No elements are copied by this operation. If
5334
+ an exception is thrown other than by a comparison there are no effects.
5335
 
5336
  ``` cpp
5337
  void reverse() noexcept;
5338
  ```
5339
 
 
5350
  *Effects:* Sorts the list according to the `operator<` or a `Compare`
5351
  function object. If an exception is thrown, the order of the elements in
5352
  `*this` is unspecified. Does not affect the validity of iterators and
5353
  references.
5354
 
 
 
5355
  *Complexity:* Approximately N log N comparisons, where `N == size()`.
5356
 
5357
+ *Remarks:* Stable [[algorithm.stable]].
5358
+
5359
  #### Erasure <a id="list.erasure">[[list.erasure]]</a>
5360
 
5361
  ``` cpp
5362
  template<class T, class Allocator, class U>
5363
  typename list<T, Allocator>::size_type
 
5382
  A `vector` is a sequence container that supports (amortized) constant
5383
  time insert and erase operations at the end; insert and erase in the
5384
  middle take linear time. Storage management is handled automatically,
5385
  though hints can be given to improve efficiency.
5386
 
5387
+ A `vector` meets all of the requirements of a container
5388
+ [[container.reqmts]], of a reversible container
5389
+ [[container.rev.reqmts]], of an allocator-aware container
5390
+ [[container.alloc.reqmts]], of a sequence container, including most of
5391
+ the optional sequence container requirements [[sequence.reqmts]], and,
5392
+ for an element type other than `bool`, of a contiguous container
5393
+ [[container.reqmts]]. The exceptions are the `push_front`,
5394
+ `prepend_range`, `pop_front`, and `emplace_front` member functions,
5395
+ which are not provided. Descriptions are provided here only for
5396
+ operations on `vector` that are not described in one of these tables or
5397
+ for operations where there is additional semantic information.
5398
 
5399
  The types `iterator` and `const_iterator` meet the constexpr iterator
5400
  requirements [[iterator.requirements.general]].
5401
 
5402
  ``` cpp
 
5409
  using allocator_type = Allocator;
5410
  using pointer = typename allocator_traits<Allocator>::pointer;
5411
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
5412
  using reference = value_type&;
5413
  using const_reference = const value_type&;
5414
+ using size_type = implementation-defined // type of vector::size_type; // see [container.requirements]
5415
+ using difference_type = implementation-defined // type of vector::difference_type; // see [container.requirements]
5416
  using iterator = implementation-defined // type of vector::iterator; // see [container.requirements]
5417
  using const_iterator = implementation-defined // type of vector::const_iterator; // see [container.requirements]
5418
  using reverse_iterator = std::reverse_iterator<iterator>;
5419
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
5420
 
 
5423
  constexpr explicit vector(const Allocator&) noexcept;
5424
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
5425
  constexpr vector(size_type n, const T& value, const Allocator& = Allocator());
5426
  template<class InputIterator>
5427
  constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
5428
+ template<container-compatible-range<T> R>
5429
+ constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
5430
  constexpr vector(const vector& x);
5431
  constexpr vector(vector&&) noexcept;
5432
+ constexpr vector(const vector&, const type_identity_t<Allocator>&);
5433
+ constexpr vector(vector&&, const type_identity_t<Allocator>&);
5434
  constexpr vector(initializer_list<T>, const Allocator& = Allocator());
5435
  constexpr ~vector();
5436
  constexpr vector& operator=(const vector& x);
5437
  constexpr vector& operator=(vector&& x)
5438
  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5439
  allocator_traits<Allocator>::is_always_equal::value);
5440
  constexpr vector& operator=(initializer_list<T>);
5441
  template<class InputIterator>
5442
  constexpr void assign(InputIterator first, InputIterator last);
5443
+ template<container-compatible-range<T> R>
5444
+ constexpr void assign_range(R&& rg);
5445
  constexpr void assign(size_type n, const T& u);
5446
  constexpr void assign(initializer_list<T>);
5447
  constexpr allocator_type get_allocator() const noexcept;
5448
 
5449
  // iterators
 
5487
 
5488
  // [vector.modifiers], modifiers
5489
  template<class... Args> constexpr reference emplace_back(Args&&... args);
5490
  constexpr void push_back(const T& x);
5491
  constexpr void push_back(T&& x);
5492
+ template<container-compatible-range<T> R>
5493
+ constexpr void append_range(R&& rg);
5494
  constexpr void pop_back();
5495
 
5496
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
5497
  constexpr iterator insert(const_iterator position, const T& x);
5498
  constexpr iterator insert(const_iterator position, T&& x);
5499
  constexpr iterator insert(const_iterator position, size_type n, const T& x);
5500
  template<class InputIterator>
5501
  constexpr iterator insert(const_iterator position,
5502
  InputIterator first, InputIterator last);
5503
+ template<container-compatible-range<T> R>
5504
+ constexpr iterator insert_range(const_iterator position, R&& rg);
5505
  constexpr iterator insert(const_iterator position, initializer_list<T> il);
5506
  constexpr iterator erase(const_iterator position);
5507
  constexpr iterator erase(const_iterator first, const_iterator last);
5508
  constexpr void swap(vector&)
5509
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
 
5513
 
5514
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5515
  vector(InputIterator, InputIterator, Allocator = Allocator())
5516
  -> vector<iter-value-type<InputIterator>, Allocator>;
5517
 
5518
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
5519
+ vector(from_range_t, R&&, Allocator = Allocator())
5520
+ -> vector<ranges::range_value_t<R>, Allocator>;
 
5521
  }
5522
  ```
5523
 
5524
  An incomplete type `T` may be used when instantiating `vector` if the
5525
  allocator meets the allocator completeness requirements
5526
  [[allocator.requirements.completeness]]. `T` shall be complete before
5527
  any member of the resulting specialization of `vector` is referenced.
5528
 
5529
+ #### Constructors <a id="vector.cons">[[vector.cons]]</a>
5530
 
5531
  ``` cpp
5532
  constexpr explicit vector(const Allocator&) noexcept;
5533
  ```
5534
 
 
5569
  using the specified allocator.
5570
 
5571
  *Complexity:* Makes only N calls to the copy constructor of `T` (where N
5572
  is the distance between `first` and `last`) and no reallocations if
5573
  iterators `first` and `last` are of forward, bidirectional, or random
5574
+ access categories. It makes order N calls to the copy constructor of `T`
5575
+ and order log N reallocations if they are just input iterators.
5576
+
5577
+ ``` cpp
5578
+ template<container-compatible-range<T> R>
5579
+ constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
5580
+ ```
5581
+
5582
+ *Effects:* Constructs a `vector` object with the elements of the range
5583
+ `rg`, using the specified allocator.
5584
+
5585
+ *Complexity:* Initializes exactly N elements from the results of
5586
+ dereferencing successive iterators of `rg`, where N is
5587
+ `ranges::distance(rg)`. Performs no reallocations if `R` models
5588
+ `ranges::forward_range` or `ranges::sized_range`; otherwise, performs
5589
+ order log N reallocations and order N calls to the copy or move
5590
+ constructor of `T`.
5591
 
5592
  #### Capacity <a id="vector.capacity">[[vector.capacity]]</a>
5593
 
5594
  ``` cpp
5595
  constexpr size_type capacity() const noexcept;
 
5613
  `capacity()` otherwise. Reallocation happens at this point if and only
5614
  if the current capacity is less than the argument of `reserve()`. If an
5615
  exception is thrown other than by the move constructor of a
5616
  non-*Cpp17CopyInsertable* type, there are no effects.
5617
 
5618
+ *Throws:* `length_error` if `n > max_size()`.[^4]
5619
+
5620
  *Complexity:* It does not change the size of the sequence and takes at
5621
  most linear time in the size of the sequence.
5622
 
 
 
5623
  *Remarks:* Reallocation invalidates all the references, pointers, and
5624
  iterators referring to the elements in the sequence, as well as the
5625
  past-the-end iterator.
5626
 
5627
  [*Note 1*: If no reallocation happens, they remain
 
5712
  constexpr iterator insert(const_iterator position, const T& x);
5713
  constexpr iterator insert(const_iterator position, T&& x);
5714
  constexpr iterator insert(const_iterator position, size_type n, const T& x);
5715
  template<class InputIterator>
5716
  constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last);
5717
+ template<container-compatible-range<T> R>
5718
+ constexpr iterator insert_range(const_iterator position, R&& rg);
5719
  constexpr iterator insert(const_iterator position, initializer_list<T>);
5720
 
5721
  template<class... Args> constexpr reference emplace_back(Args&&... args);
5722
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
5723
  constexpr void push_back(const T& x);
5724
  constexpr void push_back(T&& x);
5725
+ template<container-compatible-range<T> R>
5726
+ constexpr void append_range(R&& rg);
5727
  ```
5728
 
5729
+ *Complexity:* If reallocation happens, linear in the number of elements
5730
+ of the resulting vector; otherwise, linear in the number of elements
5731
+ inserted plus the distance to the end of the vector.
5732
+
5733
  *Remarks:* Causes reallocation if the new size is greater than the old
5734
  capacity. Reallocation invalidates all the references, pointers, and
5735
  iterators referring to the elements in the sequence, as well as the
5736
  past-the-end iterator. If no reallocation happens, then references,
5737
  pointers, and iterators before the insertion point remain valid but
 
5743
  at the end and `T` is *Cpp17CopyInsertable* or
5744
  `is_nothrow_move_constructible_v<T>` is `true`, there are no effects.
5745
  Otherwise, if an exception is thrown by the move constructor of a
5746
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
5747
 
 
 
 
 
5748
  ``` cpp
5749
  constexpr iterator erase(const_iterator position);
5750
  constexpr iterator erase(const_iterator first, const_iterator last);
5751
  constexpr void pop_back();
5752
  ```
5753
 
5754
  *Effects:* Invalidates iterators and references at or after the point of
5755
  the erase.
5756
 
5757
+ *Throws:* Nothing unless an exception is thrown by the assignment
5758
+ operator or move assignment operator of `T`.
5759
+
5760
  *Complexity:* The destructor of `T` is called the number of times equal
5761
  to the number of the elements erased, but the assignment operator of `T`
5762
  is called the number of times equal to the number of elements in the
5763
  vector after the erased elements.
5764
 
 
 
 
5765
  #### Erasure <a id="vector.erasure">[[vector.erasure]]</a>
5766
 
5767
  ``` cpp
5768
  template<class T, class Allocator, class U>
5769
  constexpr typename vector<T, Allocator>::size_type
 
5792
  auto r = distance(it, c.end());
5793
  c.erase(it, c.end());
5794
  return r;
5795
  ```
5796
 
5797
+ ### Specialization of `vector` for `bool` <a id="vector.bool">[[vector.bool]]</a>
5798
 
5799
+ #### Partial class template specialization `vector<bool, Allocator>` <a id="vector.bool.pspc">[[vector.bool.pspc]]</a>
5800
+
5801
+ To optimize space allocation, a partial specialization of `vector` for
5802
+ `bool` elements is provided:
5803
 
5804
  ``` cpp
5805
  namespace std {
5806
  template<class Allocator>
5807
  class vector<bool, Allocator> {
5808
  public:
5809
  // types
5810
  using value_type = bool;
5811
  using allocator_type = Allocator;
5812
+ using pointer = implementation-defined // type of vector<bool>::pointer;
5813
+ using const_pointer = implementation-defined // type of vector<bool>::const_pointer;
5814
  using const_reference = bool;
5815
+ using size_type = implementation-defined // type of vector<bool>::size_type; // see [container.requirements]
5816
+ using difference_type = implementation-defined // type of vector<bool>::difference_type; // see [container.requirements]
5817
  using iterator = implementation-defined // type of vector<bool>::iterator; // see [container.requirements]
5818
  using const_iterator = implementation-defined // type of vector<bool>::const_iterator; // see [container.requirements]
5819
  using reverse_iterator = std::reverse_iterator<iterator>;
5820
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
5821
 
5822
  // bit reference
5823
  class reference {
5824
  friend class vector;
5825
  constexpr reference() noexcept;
5826
+
5827
  public:
5828
  constexpr reference(const reference&) = default;
5829
  constexpr ~reference();
5830
  constexpr operator bool() const noexcept;
5831
+ constexpr reference& operator=(bool x) noexcept;
5832
  constexpr reference& operator=(const reference& x) noexcept;
5833
+ constexpr const reference& operator=(bool x) const noexcept;
5834
  constexpr void flip() noexcept; // flips the bit
5835
  };
5836
 
5837
  // construct/copy/destroy
5838
+ constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
5839
+ constexpr explicit vector(const Allocator&) noexcept;
5840
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
5841
  constexpr vector(size_type n, const bool& value, const Allocator& = Allocator());
5842
  template<class InputIterator>
5843
  constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
5844
+ template<container-compatible-range<bool> R>
5845
+ constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
5846
  constexpr vector(const vector& x);
5847
+ constexpr vector(vector&& x) noexcept;
5848
+ constexpr vector(const vector&, const type_identity_t<Allocator>&);
5849
+ constexpr vector(vector&&, const type_identity_t<Allocator>&);
5850
+ constexpr vector(initializer_list<bool>, const Allocator& = Allocator());
5851
  constexpr ~vector();
5852
  constexpr vector& operator=(const vector& x);
5853
+ constexpr vector& operator=(vector&& x)
5854
+ noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5855
+ allocator_traits<Allocator>::is_always_equal::value);
5856
  constexpr vector& operator=(initializer_list<bool>);
5857
  template<class InputIterator>
5858
  constexpr void assign(InputIterator first, InputIterator last);
5859
+ template<container-compatible-range<bool> R>
5860
+ constexpr void assign_range(R&& rg);
5861
  constexpr void assign(size_type n, const bool& t);
5862
  constexpr void assign(initializer_list<bool>);
5863
  constexpr allocator_type get_allocator() const noexcept;
5864
 
5865
  // iterators
 
5897
  constexpr const_reference back() const;
5898
 
5899
  // modifiers
5900
  template<class... Args> constexpr reference emplace_back(Args&&... args);
5901
  constexpr void push_back(const bool& x);
5902
+ template<container-compatible-range<bool> R>
5903
+ constexpr void append_range(R&& rg);
5904
  constexpr void pop_back();
5905
  template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
5906
  constexpr iterator insert(const_iterator position, const bool& x);
5907
  constexpr iterator insert(const_iterator position, size_type n, const bool& x);
5908
  template<class InputIterator>
5909
  constexpr iterator insert(const_iterator position,
5910
  InputIterator first, InputIterator last);
5911
+ template<container-compatible-range<bool> R>
5912
+ constexpr iterator insert_range(const_iterator position, R&& rg);
5913
  constexpr iterator insert(const_iterator position, initializer_list<bool> il);
5914
 
5915
  constexpr iterator erase(const_iterator position);
5916
  constexpr iterator erase(const_iterator first, const_iterator last);
5917
+ constexpr void swap(vector&)
5918
+ noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
5919
+ allocator_traits<Allocator>::is_always_equal::value);
5920
+ static constexpr void swap(reference x, reference y) noexcept;
5921
  constexpr void flip() noexcept; // flips all bits
5922
  constexpr void clear() noexcept;
5923
  };
5924
  }
5925
  ```
 
5936
 
5937
  `reference`
5938
 
5939
  is a class that simulates the behavior of references of a single bit in
5940
  `vector<bool>`. The conversion function returns `true` when the bit is
5941
+ set, and `false` otherwise. The assignment operators set the bit when
5942
+ the argument is (convertible to) `true` and clear it otherwise. `flip`
5943
  reverses the state of the bit.
5944
 
5945
  ``` cpp
5946
  constexpr void flip() noexcept;
5947
  ```
5948
 
5949
  *Effects:* Replaces each element in the container with its complement.
5950
 
5951
  ``` cpp
5952
+ static constexpr void swap(reference x, reference y) noexcept;
5953
  ```
5954
 
5955
  *Effects:* Exchanges the contents of `x` and `y` as if by:
5956
 
5957
  ``` cpp
 
5964
  template<class Allocator> struct hash<vector<bool, Allocator>>;
5965
  ```
5966
 
5967
  The specialization is enabled [[unord.hash]].
5968
 
5969
+ ``` cpp
5970
+ template<class T>
5971
+ constexpr bool is-vector-bool-reference = see below;
5972
+ ```
5973
+
5974
+ The expression *`is-vector-bool-reference`*`<T>` is `true` if `T`
5975
+ denotes the type `vector<bool, Alloc>::reference` for some type `Alloc`
5976
+ and `vector<bool, Alloc>` is not a program-defined specialization.
5977
+
5978
+ #### Formatter specialization for `vector<bool>` <a id="vector.bool.fmt">[[vector.bool.fmt]]</a>
5979
+
5980
+ ``` cpp
5981
+ namespace std {
5982
+ template<class T, class charT>
5983
+ requires is-vector-bool-reference<T>
5984
+ struct formatter<T, charT> {
5985
+ private:
5986
+ formatter<bool, charT> underlying_; // exposition only
5987
+
5988
+ public:
5989
+ template<class ParseContext>
5990
+ constexpr typename ParseContext::iterator
5991
+ parse(ParseContext& ctx);
5992
+
5993
+ template<class FormatContext>
5994
+ typename FormatContext::iterator
5995
+ format(const T& ref, FormatContext& ctx) const;
5996
+ };
5997
+ }
5998
+ ```
5999
+
6000
+ ``` cpp
6001
+ template<class ParseContext>
6002
+ constexpr typename ParseContext::iterator
6003
+ parse(ParseContext& ctx);
6004
+ ```
6005
+
6006
+ Equivalent to: `return `*`underlying_`*`.parse(ctx);`
6007
+
6008
+ ``` cpp
6009
+ template<class FormatContext>
6010
+ typename FormatContext::iterator
6011
+ format(const T& ref, FormatContext& ctx) const;
6012
+ ```
6013
+
6014
+ Equivalent to: `return `*`underlying_`*`.format(ref, ctx);`
6015
+
6016
  ## Associative containers <a id="associative">[[associative]]</a>
6017
 
6018
  ### In general <a id="associative.general">[[associative.general]]</a>
6019
 
6020
  The header `<map>` defines the class templates `map` and `multimap`; the
 
6027
  template<class InputIterator>
6028
  using iter-value-type =
6029
  typename iterator_traits<InputIterator>::value_type; // exposition only
6030
  template<class InputIterator>
6031
  using iter-key-type = remove_const_t<
6032
+ tuple_element_t<0, iter-value-type<InputIterator>>>; // exposition only
6033
  template<class InputIterator>
6034
  using iter-mapped-type =
6035
+ tuple_element_t<1, iter-value-type<InputIterator>>; // exposition only
6036
  template<class InputIterator>
6037
  using iter-to-alloc-type = pair<
6038
+ add_const_t<tuple_element_t<0, iter-value-type<InputIterator>>>,
6039
+ tuple_element_t<1, iter-value-type<InputIterator>>>; // exposition only
6040
+ template<ranges::input_range Range>
6041
+ using range-key-type =
6042
+ remove_const_t<typename ranges::range_value_t<Range>::first_type>; // exposition only
6043
+ template<ranges::input_range Range>
6044
+ using range-mapped-type = typename ranges::range_value_t<Range>::second_type; // exposition only
6045
+ template<ranges::input_range Range>
6046
+ using range-to-alloc-type =
6047
+ pair<add_const_t<typename ranges::range_value_t<Range>::first_type>,
6048
+ typename ranges::range_value_t<Range>::second_type>; // exposition only
6049
  ```
6050
 
6051
  ### Header `<map>` synopsis <a id="associative.map.syn">[[associative.map.syn]]</a>
6052
 
6053
  ``` cpp
 
6071
  template<class Key, class T, class Compare, class Allocator>
6072
  void swap(map<Key, T, Compare, Allocator>& x,
6073
  map<Key, T, Compare, Allocator>& y)
6074
  noexcept(noexcept(x.swap(y)));
6075
 
6076
+ // [map.erasure], erasure for map
6077
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6078
  typename map<Key, T, Compare, Allocator>::size_type
6079
  erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
6080
 
6081
  // [multimap], class template multimap
 
6094
  template<class Key, class T, class Compare, class Allocator>
6095
  void swap(multimap<Key, T, Compare, Allocator>& x,
6096
  multimap<Key, T, Compare, Allocator>& y)
6097
  noexcept(noexcept(x.swap(y)));
6098
 
6099
+ // [multimap.erasure], erasure for multimap
6100
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6101
  typename multimap<Key, T, Compare, Allocator>::size_type
6102
  erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
6103
 
6104
  namespace pmr {
 
6134
  template<class Key, class Compare, class Allocator>
6135
  void swap(set<Key, Compare, Allocator>& x,
6136
  set<Key, Compare, Allocator>& y)
6137
  noexcept(noexcept(x.swap(y)));
6138
 
6139
+ // [set.erasure], erasure for set
6140
  template<class Key, class Compare, class Allocator, class Predicate>
6141
  typename set<Key, Compare, Allocator>::size_type
6142
  erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
6143
 
6144
  // [multiset], class template multiset
 
6155
  template<class Key, class Compare, class Allocator>
6156
  void swap(multiset<Key, Compare, Allocator>& x,
6157
  multiset<Key, Compare, Allocator>& y)
6158
  noexcept(noexcept(x.swap(y)));
6159
 
6160
+ // [multiset.erasure], erasure for multiset
6161
  template<class Key, class Compare, class Allocator, class Predicate>
6162
  typename multiset<Key, Compare, Allocator>::size_type
6163
  erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
6164
 
6165
  namespace pmr {
 
6174
 
6175
  ### Class template `map` <a id="map">[[map]]</a>
6176
 
6177
  #### Overview <a id="map.overview">[[map.overview]]</a>
6178
 
6179
+ A `map` is an associative container that supports unique keys (i.e.,
6180
+ contains at most one of each key value) and provides for fast retrieval
6181
+ of values of another type `T` based on the keys. The `map` class
6182
+ supports bidirectional iterators.
6183
 
6184
+ A `map` meets all of the requirements of a container
6185
+ [[container.reqmts]], of a reversible container
6186
+ [[container.rev.reqmts]], of an allocator-aware container
6187
+ [[container.alloc.reqmts]]. and of an associative container
6188
+ [[associative.reqmts]]. A `map` also provides most operations described
6189
+ in  [[associative.reqmts]] for unique keys. This means that a `map`
6190
+ supports the `a_uniq` operations in  [[associative.reqmts]] but not the
6191
+ `a_eq` operations. For a `map<Key,T>` the `key_type` is `Key` and the
6192
+ `value_type` is `pair<const Key,T>`. Descriptions are provided here only
6193
+ for operations on `map` that are not described in one of those tables or
6194
+ for operations where there is additional semantic information.
6195
 
6196
  ``` cpp
6197
  namespace std {
6198
  template<class Key, class T, class Compare = less<Key>,
6199
  class Allocator = allocator<pair<const Key, T>>>
 
6207
  using allocator_type = Allocator;
6208
  using pointer = typename allocator_traits<Allocator>::pointer;
6209
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6210
  using reference = value_type&;
6211
  using const_reference = const value_type&;
6212
+ using size_type = implementation-defined // type of map::size_type; // see [container.requirements]
6213
+ using difference_type = implementation-defined // type of map::difference_type; // see [container.requirements]
6214
  using iterator = implementation-defined // type of map::iterator; // see [container.requirements]
6215
  using const_iterator = implementation-defined // type of map::const_iterator; // see [container.requirements]
6216
  using reverse_iterator = std::reverse_iterator<iterator>;
6217
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6218
  using node_type = unspecified;
 
6221
  class value_compare {
6222
  friend class map;
6223
  protected:
6224
  Compare comp;
6225
  value_compare(Compare c) : comp(c) {}
6226
+
6227
  public:
6228
  bool operator()(const value_type& x, const value_type& y) const {
6229
  return comp(x.first, y.first);
6230
  }
6231
  };
 
6234
  map() : map(Compare()) { }
6235
  explicit map(const Compare& comp, const Allocator& = Allocator());
6236
  template<class InputIterator>
6237
  map(InputIterator first, InputIterator last,
6238
  const Compare& comp = Compare(), const Allocator& = Allocator());
6239
+ template<container-compatible-range<value_type> R>
6240
+ map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6241
  map(const map& x);
6242
  map(map&& x);
6243
  explicit map(const Allocator&);
6244
+ map(const map&, const type_identity_t<Allocator>&);
6245
+ map(map&&, const type_identity_t<Allocator>&);
6246
  map(initializer_list<value_type>,
6247
  const Compare& = Compare(),
6248
  const Allocator& = Allocator());
6249
  template<class InputIterator>
6250
  map(InputIterator first, InputIterator last, const Allocator& a)
6251
  : map(first, last, Compare(), a) { }
6252
+ template<container-compatible-range<value_type> R>
6253
+ map(from_range_t, R&& rg, const Allocator& a))
6254
+ : map(from_range, std::forward<R>(rg), Compare(), a) { }
6255
  map(initializer_list<value_type> il, const Allocator& a)
6256
  : map(il, Compare(), a) { }
6257
  ~map();
6258
  map& operator=(const map& x);
6259
  map& operator=(map&& x)
 
6299
  iterator insert(const_iterator position, value_type&& x);
6300
  template<class P>
6301
  iterator insert(const_iterator position, P&&);
6302
  template<class InputIterator>
6303
  void insert(InputIterator first, InputIterator last);
6304
+ template<container-compatible-range<value_type> R>
6305
+ void insert_range(R&& rg);
6306
  void insert(initializer_list<value_type>);
6307
 
6308
  node_type extract(const_iterator position);
6309
  node_type extract(const key_type& x);
6310
+ template<class K> node_type extract(K&& x);
6311
  insert_return_type insert(node_type&& nh);
6312
  iterator insert(const_iterator hint, node_type&& nh);
6313
 
6314
  template<class... Args>
6315
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
 
6329
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
6330
 
6331
  iterator erase(iterator position);
6332
  iterator erase(const_iterator position);
6333
  size_type erase(const key_type& x);
6334
+ template<class K> size_type erase(K&& x);
6335
  iterator erase(const_iterator first, const_iterator last);
6336
  void swap(map&)
6337
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6338
  is_nothrow_swappable_v<Compare>);
6339
  void clear() noexcept;
 
6384
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
6385
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
6386
  map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
6387
  -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare, Allocator>;
6388
 
6389
+ template<ranges::input_range R, class Compare = less<range-key-type<R>,
6390
+ class Allocator = allocator<range-to-alloc-type<R>>>
6391
+ map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
6392
+ -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>;
6393
+
6394
  template<class Key, class T, class Compare = less<Key>,
6395
  class Allocator = allocator<pair<const Key, T>>>
6396
  map(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())
6397
  -> map<Key, T, Compare, Allocator>;
6398
 
6399
  template<class InputIterator, class Allocator>
6400
  map(InputIterator, InputIterator, Allocator)
6401
  -> map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
6402
  less<iter-key-type<InputIterator>>, Allocator>;
6403
 
6404
+ template<ranges::input_range R, class Allocator>
6405
+ map(from_range_t, R&&, Allocator)
6406
+ -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>;
6407
+
6408
  template<class Key, class T, class Allocator>
6409
  map(initializer_list<pair<Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;
 
 
 
 
 
 
6410
  }
6411
  ```
6412
 
6413
  #### Constructors, copy, and assignment <a id="map.cons">[[map.cons]]</a>
6414
 
 
6430
  *Effects:* Constructs an empty `map` using the specified comparison
6431
  object and allocator, and inserts elements from the range \[`first`,
6432
  `last`).
6433
 
6434
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
6435
+ sorted with respect to `comp` and otherwise N log N, where N is
6436
+ `last - first`.
6437
+
6438
+ ``` cpp
6439
+ template<container-compatible-range<value_type> R>
6440
+ map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6441
+ ```
6442
+
6443
+ *Effects:* Constructs an empty `map` using the specified comparison
6444
+ object and allocator, and inserts elements from the range `rg`.
6445
+
6446
+ *Complexity:* Linear in N if `rg` is already sorted with respect to
6447
+ `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
6448
 
6449
  #### Element access <a id="map.access">[[map.access]]</a>
6450
 
6451
  ``` cpp
6452
  mapped_type& operator[](const key_type& x);
 
6456
 
6457
  ``` cpp
6458
  mapped_type& operator[](key_type&& x);
6459
  ```
6460
 
6461
+ *Effects:* Equivalent to:
6462
+ `return try_emplace(std::move(x)).first->second;`
6463
 
6464
  ``` cpp
6465
  mapped_type& at(const key_type& x);
6466
  const mapped_type& at(const key_type& x) const;
6467
  ```
 
6542
  ```
6543
 
6544
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
6545
 
6546
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
6547
+ from `k`, `std::forward<M>(obj)`.
6548
 
6549
  *Effects:* If the map already contains an element `e` whose key is
6550
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
6551
  Otherwise inserts an object of type `value_type` constructed with `k`,
6552
  `std::forward<M>(obj)`.
 
6565
  ```
6566
 
6567
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
6568
 
6569
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
6570
+ from `std::move(k)`, `std::forward<M>(obj)`.
6571
 
6572
  *Effects:* If the map already contains an element `e` whose key is
6573
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
6574
  Otherwise inserts an object of type `value_type` constructed with
6575
  `std::move(k)`, `std::forward<M>(obj)`.
 
6605
  ### Class template `multimap` <a id="multimap">[[multimap]]</a>
6606
 
6607
  #### Overview <a id="multimap.overview">[[multimap.overview]]</a>
6608
 
6609
  A `multimap` is an associative container that supports equivalent keys
6610
+ (i.e., possibly containing multiple copies of the same key value) and
6611
+ provides for fast retrieval of values of another type `T` based on the
6612
+ keys. The `multimap` class supports bidirectional iterators.
6613
 
6614
+ A `multimap` meets all of the requirements of a container
6615
+ [[container.reqmts]], of a reversible container
6616
+ [[container.rev.reqmts]], of an allocator-aware container
6617
+ [[container.alloc.reqmts]], and of an associative container
6618
+ [[associative.reqmts]]. A `multimap` also provides most operations
6619
  described in  [[associative.reqmts]] for equal keys. This means that a
6620
  `multimap` supports the `a_eq` operations in  [[associative.reqmts]] but
6621
  not the `a_uniq` operations. For a `multimap<Key,T>` the `key_type` is
6622
  `Key` and the `value_type` is `pair<const Key,T>`. Descriptions are
6623
  provided here only for operations on `multimap` that are not described
 
6638
  using allocator_type = Allocator;
6639
  using pointer = typename allocator_traits<Allocator>::pointer;
6640
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6641
  using reference = value_type&;
6642
  using const_reference = const value_type&;
6643
+ using size_type = implementation-defined // type of multimap::size_type; // see [container.requirements]
6644
+ using difference_type = implementation-defined // type of multimap::difference_type; // see [container.requirements]
6645
  using iterator = implementation-defined // type of multimap::iterator; // see [container.requirements]
6646
  using const_iterator = implementation-defined // type of multimap::const_iterator; // see [container.requirements]
6647
  using reverse_iterator = std::reverse_iterator<iterator>;
6648
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6649
  using node_type = unspecified;
 
6651
  class value_compare {
6652
  friend class multimap;
6653
  protected:
6654
  Compare comp;
6655
  value_compare(Compare c) : comp(c) { }
6656
+
6657
  public:
6658
  bool operator()(const value_type& x, const value_type& y) const {
6659
  return comp(x.first, y.first);
6660
  }
6661
  };
 
6665
  explicit multimap(const Compare& comp, const Allocator& = Allocator());
6666
  template<class InputIterator>
6667
  multimap(InputIterator first, InputIterator last,
6668
  const Compare& comp = Compare(),
6669
  const Allocator& = Allocator());
6670
+ template<container-compatible-range<value_type> R>
6671
+ multimap(from_range_t, R&& rg,
6672
+ const Compare& comp = Compare(), const Allocator& = Allocator());
6673
  multimap(const multimap& x);
6674
  multimap(multimap&& x);
6675
  explicit multimap(const Allocator&);
6676
+ multimap(const multimap&, const type_identity_t<Allocator>&);
6677
+ multimap(multimap&&, const type_identity_t<Allocator>&);
6678
  multimap(initializer_list<value_type>,
6679
  const Compare& = Compare(),
6680
  const Allocator& = Allocator());
6681
  template<class InputIterator>
6682
  multimap(InputIterator first, InputIterator last, const Allocator& a)
6683
  : multimap(first, last, Compare(), a) { }
6684
+ template<container-compatible-range<value_type> R>
6685
+ multimap(from_range_t, R&& rg, const Allocator& a))
6686
+ : multimap(from_range, std::forward<R>(rg), Compare(), a) { }
6687
  multimap(initializer_list<value_type> il, const Allocator& a)
6688
  : multimap(il, Compare(), a) { }
6689
  ~multimap();
6690
  multimap& operator=(const multimap& x);
6691
  multimap& operator=(multimap&& x)
 
6724
  iterator insert(const_iterator position, const value_type& x);
6725
  iterator insert(const_iterator position, value_type&& x);
6726
  template<class P> iterator insert(const_iterator position, P&& x);
6727
  template<class InputIterator>
6728
  void insert(InputIterator first, InputIterator last);
6729
+ template<container-compatible-range<value_type> R>
6730
+ void insert_range(R&& rg);
6731
  void insert(initializer_list<value_type>);
6732
 
6733
  node_type extract(const_iterator position);
6734
  node_type extract(const key_type& x);
6735
+ template<class K> node_type extract(K&& x);
6736
  iterator insert(node_type&& nh);
6737
  iterator insert(const_iterator hint, node_type&& nh);
6738
 
6739
  iterator erase(iterator position);
6740
  iterator erase(const_iterator position);
6741
  size_type erase(const key_type& x);
6742
+ template<class K> size_type erase(K&& x);
6743
  iterator erase(const_iterator first, const_iterator last);
6744
  void swap(multimap&)
6745
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6746
  is_nothrow_swappable_v<Compare>);
6747
  void clear() noexcept;
 
6793
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
6794
  multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
6795
  -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
6796
  Compare, Allocator>;
6797
 
6798
+ template<ranges::input_range R, class Compare = less<range-key-type<R>>,
6799
+ class Allocator = allocator<range-to-alloc-type<R>>>
6800
+ multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
6801
+ -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>;
6802
+
6803
  template<class Key, class T, class Compare = less<Key>,
6804
  class Allocator = allocator<pair<const Key, T>>>
6805
  multimap(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())
6806
  -> multimap<Key, T, Compare, Allocator>;
6807
 
6808
  template<class InputIterator, class Allocator>
6809
  multimap(InputIterator, InputIterator, Allocator)
6810
  -> multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
6811
  less<iter-key-type<InputIterator>>, Allocator>;
6812
 
6813
+ template<ranges::input_range R, class Allocator>
6814
+ multimap(from_range_t, R&&, Allocator)
6815
+ -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>;
6816
+
6817
  template<class Key, class T, class Allocator>
6818
  multimap(initializer_list<pair<Key, T>>, Allocator)
6819
  -> multimap<Key, T, less<Key>, Allocator>;
 
 
 
 
 
 
6820
  }
6821
  ```
6822
 
6823
  #### Constructors <a id="multimap.cons">[[multimap.cons]]</a>
6824
 
 
6841
  *Effects:* Constructs an empty `multimap` using the specified comparison
6842
  object and allocator, and inserts elements from the range \[`first`,
6843
  `last`).
6844
 
6845
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
6846
+ sorted with respect to `comp` and otherwise N log N, where N is
6847
+ `last - first`.
6848
+
6849
+ ``` cpp
6850
+ template<container-compatible-range<value_type> R>
6851
+ multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6852
+ ```
6853
+
6854
+ *Effects:* Constructs an empty `multimap` using the specified comparison
6855
+ object and allocator, and inserts elements from the range `rg`.
6856
+
6857
+ *Complexity:* Linear in N if `rg` is already sorted with respect to
6858
+ `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
6859
 
6860
  #### Modifiers <a id="multimap.modifiers">[[multimap.modifiers]]</a>
6861
 
6862
  ``` cpp
6863
  template<class P> iterator insert(P&& x);
 
6894
 
6895
  ### Class template `set` <a id="set">[[set]]</a>
6896
 
6897
  #### Overview <a id="set.overview">[[set.overview]]</a>
6898
 
6899
+ A `set` is an associative container that supports unique keys (i.e.,
6900
+ contains at most one of each key value) and provides for fast retrieval
6901
+ of the keys themselves. The `set` class supports bidirectional
6902
+ iterators.
6903
 
6904
+ A `set` meets all of the requirements of a container
6905
+ [[container.reqmts]], of a reversible container
6906
+ [[container.rev.reqmts]], of an allocator-aware container
6907
+ [[container.alloc.reqmts]]. and of an associative container
6908
+ [[associative.reqmts]]. A `set` also provides most operations described
6909
+ in  [[associative.reqmts]] for unique keys. This means that a `set`
6910
+ supports the `a_uniq` operations in  [[associative.reqmts]] but not the
6911
+ `a_eq` operations. For a `set<Key>` both the `key_type` and `value_type`
6912
+ are `Key`. Descriptions are provided here only for operations on `set`
6913
+ that are not described in one of these tables and for operations where
6914
+ there is additional semantic information.
6915
 
6916
  ``` cpp
6917
  namespace std {
6918
  template<class Key, class Compare = less<Key>,
6919
  class Allocator = allocator<Key>>
 
6927
  using allocator_type = Allocator;
6928
  using pointer = typename allocator_traits<Allocator>::pointer;
6929
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6930
  using reference = value_type&;
6931
  using const_reference = const value_type&;
6932
+ using size_type = implementation-defined // type of set::size_type; // see [container.requirements]
6933
+ using difference_type = implementation-defined // type of set::difference_type; // see [container.requirements]
6934
  using iterator = implementation-defined // type of set::iterator; // see [container.requirements]
6935
  using const_iterator = implementation-defined // type of set::const_iterator; // see [container.requirements]
6936
  using reverse_iterator = std::reverse_iterator<iterator>;
6937
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6938
  using node_type = unspecified;
 
6942
  set() : set(Compare()) { }
6943
  explicit set(const Compare& comp, const Allocator& = Allocator());
6944
  template<class InputIterator>
6945
  set(InputIterator first, InputIterator last,
6946
  const Compare& comp = Compare(), const Allocator& = Allocator());
6947
+ template<container-compatible-range<value_type> R>
6948
+ set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6949
  set(const set& x);
6950
  set(set&& x);
6951
  explicit set(const Allocator&);
6952
+ set(const set&, const type_identity_t<Allocator>&);
6953
+ set(set&&, const type_identity_t<Allocator>&);
6954
  set(initializer_list<value_type>, const Compare& = Compare(),
6955
  const Allocator& = Allocator());
6956
  template<class InputIterator>
6957
  set(InputIterator first, InputIterator last, const Allocator& a)
6958
  : set(first, last, Compare(), a) { }
6959
+ template<container-compatible-range<value_type> R>
6960
+ set(from_range_t, R&& rg, const Allocator& a))
6961
+ : set(from_range, std::forward<R>(rg), Compare(), a) { }
6962
  set(initializer_list<value_type> il, const Allocator& a)
6963
  : set(il, Compare(), a) { }
6964
  ~set();
6965
  set& operator=(const set& x);
6966
  set& operator=(set&& x)
 
6997
  pair<iterator,bool> insert(value_type&& x);
6998
  iterator insert(const_iterator position, const value_type& x);
6999
  iterator insert(const_iterator position, value_type&& x);
7000
  template<class InputIterator>
7001
  void insert(InputIterator first, InputIterator last);
7002
+ template<container-compatible-range<value_type> R>
7003
+ void insert_range(R&& rg);
7004
  void insert(initializer_list<value_type>);
7005
 
7006
  node_type extract(const_iterator position);
7007
  node_type extract(const key_type& x);
7008
+ template<class K> node_type extract(K&& x);
7009
  insert_return_type insert(node_type&& nh);
7010
  iterator insert(const_iterator hint, node_type&& nh);
7011
 
7012
+ iterator erase(iterator position)
7013
+ requires (!same_as<iterator, const_iterator>);
7014
  iterator erase(const_iterator position);
7015
  size_type erase(const key_type& x);
7016
+ template<class K> size_type erase(K&& x);
7017
  iterator erase(const_iterator first, const_iterator last);
7018
  void swap(set&)
7019
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7020
  is_nothrow_swappable_v<Compare>);
7021
  void clear() noexcept;
 
7068
  class Allocator = allocator<iter-value-type<InputIterator>>>
7069
  set(InputIterator, InputIterator,
7070
  Compare = Compare(), Allocator = Allocator())
7071
  -> set<iter-value-type<InputIterator>, Compare, Allocator>;
7072
 
7073
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
7074
+ class Allocator = allocator<ranges::range_value_t<R>>>
7075
+ set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
7076
+ -> set<ranges::range_value_t<R>, Compare, Allocator>;
7077
+
7078
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
7079
  set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
7080
  -> set<Key, Compare, Allocator>;
7081
 
7082
  template<class InputIterator, class Allocator>
7083
  set(InputIterator, InputIterator, Allocator)
7084
  -> set<iter-value-type<InputIterator>,
7085
  less<iter-value-type<InputIterator>>, Allocator>;
7086
 
7087
+ template<ranges::input_range R, class Allocator>
7088
+ set(from_range_t, R&&, Allocator)
7089
+ -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
7090
+
7091
  template<class Key, class Allocator>
7092
  set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>;
 
 
 
 
 
 
7093
  }
7094
  ```
7095
 
7096
  #### Constructors, copy, and assignment <a id="set.cons">[[set.cons]]</a>
7097
 
7098
  ``` cpp
7099
  explicit set(const Compare& comp, const Allocator& = Allocator());
7100
  ```
7101
 
7102
  *Effects:* Constructs an empty `set` using the specified comparison
7103
+ object and allocator.
7104
 
7105
  *Complexity:* Constant.
7106
 
7107
  ``` cpp
7108
  template<class InputIterator>
 
7113
  *Effects:* Constructs an empty `set` using the specified comparison
7114
  object and allocator, and inserts elements from the range \[`first`,
7115
  `last`).
7116
 
7117
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
7118
+ sorted with respect to `comp` and otherwise N log N, where N is
7119
+ `last - first`.
7120
+
7121
+ ``` cpp
7122
+ template<container-compatible-range<value_type> R>
7123
+ set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
7124
+ ```
7125
+
7126
+ *Effects:* Constructs an empty `set` using the specified comparison
7127
+ object and allocator, and inserts elements from the range `rg`.
7128
+
7129
+ *Complexity:* Linear in N if `rg` is already sorted with respect to
7130
+ `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
7131
 
7132
  #### Erasure <a id="set.erasure">[[set.erasure]]</a>
7133
 
7134
  ``` cpp
7135
  template<class Key, class Compare, class Allocator, class Predicate>
 
7154
  ### Class template `multiset` <a id="multiset">[[multiset]]</a>
7155
 
7156
  #### Overview <a id="multiset.overview">[[multiset.overview]]</a>
7157
 
7158
  A `multiset` is an associative container that supports equivalent keys
7159
+ (i.e., possibly contains multiple copies of the same key value) and
7160
+ provides for fast retrieval of the keys themselves. The `multiset` class
7161
+ supports bidirectional iterators.
7162
 
7163
+ A `multiset` meets all of the requirements of a container
7164
+ [[container.reqmts]], of a reversible container
7165
+ [[container.rev.reqmts]], of an allocator-aware container
7166
+ [[container.alloc.reqmts]], of an associative container
7167
+ [[associative.reqmts]]. `multiset` also provides most operations
7168
  described in  [[associative.reqmts]] for duplicate keys. This means that
7169
  a `multiset` supports the `a_eq` operations in  [[associative.reqmts]]
7170
  but not the `a_uniq` operations. For a `multiset<Key>` both the
7171
  `key_type` and `value_type` are `Key`. Descriptions are provided here
7172
  only for operations on `multiset` that are not described in one of these
 
7187
  using allocator_type = Allocator;
7188
  using pointer = typename allocator_traits<Allocator>::pointer;
7189
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
7190
  using reference = value_type&;
7191
  using const_reference = const value_type&;
7192
+ using size_type = implementation-defined // type of multiset::size_type; // see [container.requirements]
7193
+ using difference_type = implementation-defined // type of multiset::difference_type; // see [container.requirements]
7194
  using iterator = implementation-defined // type of multiset::iterator; // see [container.requirements]
7195
  using const_iterator = implementation-defined // type of multiset::const_iterator; // see [container.requirements]
7196
  using reverse_iterator = std::reverse_iterator<iterator>;
7197
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
7198
  using node_type = unspecified;
 
7201
  multiset() : multiset(Compare()) { }
7202
  explicit multiset(const Compare& comp, const Allocator& = Allocator());
7203
  template<class InputIterator>
7204
  multiset(InputIterator first, InputIterator last,
7205
  const Compare& comp = Compare(), const Allocator& = Allocator());
7206
+ template<container-compatible-range<value_type> R>
7207
+ multiset(from_range_t, R&& rg,
7208
+ const Compare& comp = Compare(), const Allocator& = Allocator());
7209
  multiset(const multiset& x);
7210
  multiset(multiset&& x);
7211
  explicit multiset(const Allocator&);
7212
+ multiset(const multiset&, const type_identity_t<Allocator>&);
7213
+ multiset(multiset&&, const type_identity_t<Allocator>&);
7214
  multiset(initializer_list<value_type>, const Compare& = Compare(),
7215
  const Allocator& = Allocator());
7216
  template<class InputIterator>
7217
  multiset(InputIterator first, InputIterator last, const Allocator& a)
7218
  : multiset(first, last, Compare(), a) { }
7219
+ template<container-compatible-range<value_type> R>
7220
+ multiset(from_range_t, R&& rg, const Allocator& a))
7221
+ : multiset(from_range, std::forward<R>(rg), Compare(), a) { }
7222
  multiset(initializer_list<value_type> il, const Allocator& a)
7223
  : multiset(il, Compare(), a) { }
7224
  ~multiset();
7225
  multiset& operator=(const multiset& x);
7226
  multiset& operator=(multiset&& x)
 
7257
  iterator insert(value_type&& x);
7258
  iterator insert(const_iterator position, const value_type& x);
7259
  iterator insert(const_iterator position, value_type&& x);
7260
  template<class InputIterator>
7261
  void insert(InputIterator first, InputIterator last);
7262
+ template<container-compatible-range<value_type> R>
7263
+ void insert_range(R&& rg);
7264
  void insert(initializer_list<value_type>);
7265
 
7266
  node_type extract(const_iterator position);
7267
  node_type extract(const key_type& x);
7268
+ template<class K> node_type extract(K&& x);
7269
  iterator insert(node_type&& nh);
7270
  iterator insert(const_iterator hint, node_type&& nh);
7271
 
7272
+ iterator erase(iterator position)
7273
+ requires (!same_as<iterator, const_iterator>);
7274
  iterator erase(const_iterator position);
7275
  size_type erase(const key_type& x);
7276
+ template<class K> size_type erase(K&& x);
7277
  iterator erase(const_iterator first, const_iterator last);
7278
  void swap(multiset&)
7279
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7280
  is_nothrow_swappable_v<Compare>);
7281
  void clear() noexcept;
 
7328
  class Allocator = allocator<iter-value-type<InputIterator>>>
7329
  multiset(InputIterator, InputIterator,
7330
  Compare = Compare(), Allocator = Allocator())
7331
  -> multiset<iter-value-type<InputIterator>, Compare, Allocator>;
7332
 
7333
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
7334
+ class Allocator = allocator<ranges::range_value_t<R>>>
7335
+ multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
7336
+ -> multiset<ranges::range_value_t<R>, Compare, Allocator>;
7337
+
7338
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
7339
  multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
7340
  -> multiset<Key, Compare, Allocator>;
7341
 
7342
  template<class InputIterator, class Allocator>
7343
  multiset(InputIterator, InputIterator, Allocator)
7344
  -> multiset<iter-value-type<InputIterator>,
7345
  less<iter-value-type<InputIterator>>, Allocator>;
7346
 
7347
+ template<ranges::input_range R, class Allocator>
7348
+ multiset(from_range_t, R&&, Allocator)
7349
+ -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>;
7350
+
7351
  template<class Key, class Allocator>
7352
  multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>;
 
 
 
 
 
 
7353
  }
7354
  ```
7355
 
7356
  #### Constructors <a id="multiset.cons">[[multiset.cons]]</a>
7357
 
 
7373
  *Effects:* Constructs an empty `multiset` using the specified comparison
7374
  object and allocator, and inserts elements from the range \[`first`,
7375
  `last`).
7376
 
7377
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
7378
+ sorted with respect to `comp` and otherwise N log N, where N is
7379
+ `last - first`.
7380
+
7381
+ ``` cpp
7382
+ template<container-compatible-range<value_type> R>
7383
+ multiset(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
7384
+ ```
7385
+
7386
+ *Effects:* Constructs an empty `multiset` using the specified comparison
7387
+ object and allocator, and inserts elements from the range `rg`.
7388
+
7389
+ *Complexity:* Linear in N if `rg` is already sorted with respect to
7390
+ `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
7391
 
7392
  #### Erasure <a id="multiset.erasure">[[multiset.erasure]]</a>
7393
 
7394
  ``` cpp
7395
  template<class Key, class Compare, class Allocator, class Predicate>
 
7418
  The header `<unordered_map>` defines the class templates `unordered_map`
7419
  and `unordered_multimap`; the header `<unordered_set>` defines the class
7420
  templates `unordered_set` and `unordered_multiset`.
7421
 
7422
  The exposition-only alias templates *`iter-value-type`*,
7423
+ *`iter-key-type`*, *`iter-mapped-type`*, *`iter-to-alloc-type`*,
7424
+ *`range-key-type`*, *`range-mapped-type`*, and *`range-to-alloc-type`*
7425
  defined in [[associative.general]] may appear in deduction guides for
7426
  unordered containers.
7427
 
7428
  ### Header `<unordered_map>` synopsis <a id="unord.map.syn">[[unord.map.syn]]</a>
7429
 
 
7464
  template<class Key, class T, class Hash, class Pred, class Alloc>
7465
  void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
7466
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
7467
  noexcept(noexcept(x.swap(y)));
7468
 
7469
+ // [unord.map.erasure], erasure for unordered_map
7470
  template<class K, class T, class H, class P, class A, class Predicate>
7471
  typename unordered_map<K, T, H, P, A>::size_type
7472
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
7473
 
7474
+ // [unord.multimap.erasure], erasure for unordered_multimap
7475
  template<class K, class T, class H, class P, class A, class Predicate>
7476
  typename unordered_multimap<K, T, H, P, A>::size_type
7477
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
7478
 
7479
  namespace pmr {
 
7533
  template<class Key, class Hash, class Pred, class Alloc>
7534
  void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
7535
  unordered_multiset<Key, Hash, Pred, Alloc>& y)
7536
  noexcept(noexcept(x.swap(y)));
7537
 
7538
+ // [unord.set.erasure], erasure for unordered_set
7539
  template<class K, class H, class P, class A, class Predicate>
7540
  typename unordered_set<K, H, P, A>::size_type
7541
  erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
7542
 
7543
+ // [unord.multiset.erasure], erasure for unordered_multiset
7544
  template<class K, class H, class P, class A, class Predicate>
7545
  typename unordered_multiset<K, H, P, A>::size_type
7546
  erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
7547
 
7548
  namespace pmr {
 
7568
  An `unordered_map` is an unordered associative container that supports
7569
  unique keys (an `unordered_map` contains at most one of each key value)
7570
  and that associates values of another type `mapped_type` with the keys.
7571
  The `unordered_map` class supports forward iterators.
7572
 
7573
+ An `unordered_map` meets all of the requirements of a container
7574
+ [[container.reqmts]], of an allocator-aware container
7575
+ [[container.alloc.reqmts]], and of an unordered associative container
7576
+ [[unord.req]]. It provides the operations described in the preceding
7577
+ requirements table for unique keys; that is, an `unordered_map` supports
7578
+ the `a_uniq` operations in that table, not the `a_eq` operations. For an
7579
+ `unordered_map<Key, T>` the `key_type` is `Key`, the `mapped_type` is
7580
+ `T`, and the `value_type` is `pair<const Key, T>`.
7581
 
7582
  Subclause  [[unord.map]] only describes operations on `unordered_map`
7583
  that are not described in one of the requirement tables, or for which
7584
  there is additional semantic information.
7585
 
 
7601
  using allocator_type = Allocator;
7602
  using pointer = typename allocator_traits<Allocator>::pointer;
7603
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
7604
  using reference = value_type&;
7605
  using const_reference = const value_type&;
7606
+ using size_type = implementation-defined // type of unordered_map::size_type; // see [container.requirements]
7607
+ using difference_type = implementation-defined // type of unordered_map::difference_type; // see [container.requirements]
7608
 
7609
  using iterator = implementation-defined // type of unordered_map::iterator; // see [container.requirements]
7610
  using const_iterator = implementation-defined // type of unordered_map::const_iterator; // see [container.requirements]
7611
  using local_iterator = implementation-defined // type of unordered_map::local_iterator; // see [container.requirements]
7612
  using const_local_iterator = implementation-defined // type of unordered_map::const_local_iterator; // see [container.requirements]
 
7623
  unordered_map(InputIterator f, InputIterator l,
7624
  size_type n = see below,
7625
  const hasher& hf = hasher(),
7626
  const key_equal& eql = key_equal(),
7627
  const allocator_type& a = allocator_type());
7628
+
7629
+ template<container-compatible-range<value_type> R>
7630
+ unordered_map(from_range_t, R&& rg, size_type n = see below,
7631
+ const hasher& hf = hasher(), const key_equal& eql = key_equal(),
7632
+ const allocator_type& a = allocator_type());
7633
  unordered_map(const unordered_map&);
7634
  unordered_map(unordered_map&&);
7635
  explicit unordered_map(const Allocator&);
7636
+ unordered_map(const unordered_map&, const type_identity_t<Allocator>&);
7637
+ unordered_map(unordered_map&&, const type_identity_t<Allocator>&);
7638
  unordered_map(initializer_list<value_type> il,
7639
  size_type n = see below,
7640
  const hasher& hf = hasher(),
7641
  const key_equal& eql = key_equal(),
7642
  const allocator_type& a = allocator_type());
 
7649
  : unordered_map(f, l, n, hasher(), key_equal(), a) { }
7650
  template<class InputIterator>
7651
  unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
7652
  const allocator_type& a)
7653
  : unordered_map(f, l, n, hf, key_equal(), a) { }
7654
+ template<container-compatible-range<value_type> R>
7655
+ unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a)
7656
+ : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
7657
+ template<container-compatible-range<value_type> R>
7658
+ unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
7659
+ : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
7660
  unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
7661
  : unordered_map(il, n, hasher(), key_equal(), a) { }
7662
  unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
7663
  const allocator_type& a)
7664
  : unordered_map(il, n, hf, key_equal(), a) { }
 
7692
  template<class P> pair<iterator, bool> insert(P&& obj);
7693
  iterator insert(const_iterator hint, const value_type& obj);
7694
  iterator insert(const_iterator hint, value_type&& obj);
7695
  template<class P> iterator insert(const_iterator hint, P&& obj);
7696
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
7697
+ template<container-compatible-range<value_type> R>
7698
+ void insert_range(R&& rg);
7699
  void insert(initializer_list<value_type>);
7700
 
7701
  node_type extract(const_iterator position);
7702
  node_type extract(const key_type& x);
7703
+ template<class K> node_type extract(K&& x);
7704
  insert_return_type insert(node_type&& nh);
7705
  iterator insert(const_iterator hint, node_type&& nh);
7706
 
7707
  template<class... Args>
7708
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
 
7722
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
7723
 
7724
  iterator erase(iterator position);
7725
  iterator erase(const_iterator position);
7726
  size_type erase(const key_type& k);
7727
+ template<class K> size_type erase(K&& x);
7728
  iterator erase(const_iterator first, const_iterator last);
7729
  void swap(unordered_map&)
7730
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7731
  is_nothrow_swappable_v<Hash> &&
7732
  is_nothrow_swappable_v<Pred>);
 
7750
  const_iterator find(const key_type& k) const;
7751
  template<class K>
7752
  iterator find(const K& k);
7753
  template<class K>
7754
  const_iterator find(const K& k) const;
 
7755
  size_type count(const key_type& k) const;
7756
  template<class K>
7757
  size_type count(const K& k) const;
7758
  bool contains(const key_type& k) const;
7759
  template<class K>
 
7798
  unordered_map(InputIterator, InputIterator, typename see below::size_type = see below,
7799
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
7800
  -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash, Pred,
7801
  Allocator>;
7802
 
7803
+ template<ranges::input_range R, class Hash = hash<range-key-type<R>>,
7804
+ class Pred = equal_to<range-key-type<R>>,
7805
+ class Allocator = allocator<range-to-alloc-type<R>>>
7806
+ unordered_map(from_range_t, R&&, typename see below::size_type = see below,
7807
+ Hash = Hash(), Pred = Pred(), Allocator = Allocator())
7808
+ -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>;
7809
+
7810
  template<class Key, class T, class Hash = hash<Key>,
7811
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
7812
  unordered_map(initializer_list<pair<Key, T>>,
7813
  typename see below::size_type = see below, Hash = Hash(),
7814
  Pred = Pred(), Allocator = Allocator())
 
7829
  template<class InputIterator, class Hash, class Allocator>
7830
  unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator)
7831
  -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash,
7832
  equal_to<iter-key-type<InputIterator>>, Allocator>;
7833
 
7834
+ template<ranges::input_range R, class Allocator>
7835
+ unordered_map(from_range_t, R&&, typename see below::size_type, Allocator)
7836
+ -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
7837
+ equal_to<range-key-type<R>>, Allocator>;
7838
+
7839
+ template<ranges::input_range R, class Allocator>
7840
+ unordered_map(from_range_t, R&&, Allocator)
7841
+ -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
7842
+ equal_to<range-key-type<R>>, Allocator>;
7843
+
7844
+ template<ranges::input_range R, class Hash, class Allocator>
7845
+ unordered_map(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
7846
+ -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash,
7847
+ equal_to<range-key-type<R>>, Allocator>;
7848
+
7849
  template<class Key, class T, class Allocator>
7850
  unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type,
7851
  Allocator)
7852
  -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
7853
 
 
7857
 
7858
  template<class Key, class T, class Hash, class Allocator>
7859
  unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash,
7860
  Allocator)
7861
  -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;
 
 
 
 
 
 
7862
  }
7863
  ```
7864
 
7865
  A `size_type` parameter type in an `unordered_map` deduction guide
7866
  refers to the `size_type` member type of the type deduced by the
 
7888
  unordered_map(InputIterator f, InputIterator l,
7889
  size_type n = see below,
7890
  const hasher& hf = hasher(),
7891
  const key_equal& eql = key_equal(),
7892
  const allocator_type& a = allocator_type());
7893
+ template<container-compatible-range<value_type> R>
7894
+ unordered_map(from_range_t, R&& rg,
7895
+ size_type n = see below,
7896
+ const hasher& hf = hasher(),
7897
+ const key_equal& eql = key_equal(),
7898
+ const allocator_type& a = allocator_type());
7899
  unordered_map(initializer_list<value_type> il,
7900
  size_type n = see below,
7901
  const hasher& hf = hasher(),
7902
  const key_equal& eql = key_equal(),
7903
  const allocator_type& a = allocator_type());
 
7905
 
7906
  *Effects:* Constructs an empty `unordered_map` using the specified hash
7907
  function, key equality predicate, and allocator, and using at least `n`
7908
  buckets. If `n` is not provided, the number of buckets is
7909
  *implementation-defined*. Then inserts elements from the range \[`f`,
7910
+ `l`), `rg`, or `il`, respectively. `max_load_factor()` returns `1.0`.
 
7911
 
7912
  *Complexity:* Average case linear, worst case quadratic.
7913
 
7914
  #### Element access <a id="unord.map.elem">[[unord.map.elem]]</a>
7915
 
 
7921
 
7922
  ``` cpp
7923
  mapped_type& operator[](key_type&& k);
7924
  ```
7925
 
7926
+ *Effects:* Equivalent to:
7927
+ `return try_emplace(std::move(k)).first->second;`
7928
 
7929
  ``` cpp
7930
  mapped_type& at(const key_type& k);
7931
  const mapped_type& at(const key_type& k) const;
7932
  ```
 
8080
  supports equivalent keys (an instance of `unordered_multimap` may
8081
  contain multiple copies of each key value) and that associates values of
8082
  another type `mapped_type` with the keys. The `unordered_multimap` class
8083
  supports forward iterators.
8084
 
8085
+ An `unordered_multimap` meets all of the requirements of a container
8086
+ [[container.reqmts]], of an allocator-aware container
8087
+ [[container.alloc.reqmts]], and of an unordered associative container
8088
+ [[unord.req]]. It provides the operations described in the preceding
8089
+ requirements table for equivalent keys; that is, an `unordered_multimap`
8090
+ supports the `a_eq` operations in that table, not the `a_uniq`
8091
+ operations. For an `unordered_multimap<Key, T>` the `key_type` is `Key`,
8092
+ the `mapped_type` is `T`, and the `value_type` is `pair<const Key, T>`.
8093
 
8094
  Subclause  [[unord.multimap]] only describes operations on
8095
  `unordered_multimap` that are not described in one of the requirement
8096
  tables, or for which there is additional semantic information.
8097
 
 
8113
  using allocator_type = Allocator;
8114
  using pointer = typename allocator_traits<Allocator>::pointer;
8115
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8116
  using reference = value_type&;
8117
  using const_reference = const value_type&;
8118
+ using size_type = implementation-defined // type of unordered_multimap::size_type; // see [container.requirements]
8119
+ using difference_type = implementation-defined // type of unordered_multimap::difference_type; // see [container.requirements]
8120
 
8121
  using iterator = implementation-defined // type of unordered_multimap::iterator; // see [container.requirements]
8122
  using const_iterator = implementation-defined // type of unordered_multimap::const_iterator; // see [container.requirements]
8123
  using local_iterator = implementation-defined // type of unordered_multimap::local_iterator; // see [container.requirements]
8124
  using const_local_iterator = implementation-defined // type of unordered_multimap::const_local_iterator; // see [container.requirements]
 
8134
  unordered_multimap(InputIterator f, InputIterator l,
8135
  size_type n = see below,
8136
  const hasher& hf = hasher(),
8137
  const key_equal& eql = key_equal(),
8138
  const allocator_type& a = allocator_type());
8139
+ template<container-compatible-range<value_type> R>
8140
+ unordered_multimap(from_range_t, R&& rg,
8141
+ size_type n = see below,
8142
+ const hasher& hf = hasher(),
8143
+ const key_equal& eql = key_equal(),
8144
+ const allocator_type& a = allocator_type());
8145
  unordered_multimap(const unordered_multimap&);
8146
  unordered_multimap(unordered_multimap&&);
8147
  explicit unordered_multimap(const Allocator&);
8148
+ unordered_multimap(const unordered_multimap&, const type_identity_t<Allocator>&);
8149
+ unordered_multimap(unordered_multimap&&, const type_identity_t<Allocator>&);
8150
  unordered_multimap(initializer_list<value_type> il,
8151
  size_type n = see below,
8152
  const hasher& hf = hasher(),
8153
  const key_equal& eql = key_equal(),
8154
  const allocator_type& a = allocator_type());
 
8161
  : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
8162
  template<class InputIterator>
8163
  unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8164
  const allocator_type& a)
8165
  : unordered_multimap(f, l, n, hf, key_equal(), a) { }
8166
+ template<container-compatible-range<value_type> R>
8167
+ unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a)
8168
+ : unordered_multimap(from_range, std::forward<R>(rg),
8169
+ n, hasher(), key_equal(), a) { }
8170
+ template<container-compatible-range<value_type> R>
8171
+ unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf,
8172
+ const allocator_type& a)
8173
+ : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8174
  unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
8175
  : unordered_multimap(il, n, hasher(), key_equal(), a) { }
8176
  unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
8177
  const allocator_type& a)
8178
  : unordered_multimap(il, n, hf, key_equal(), a) { }
 
8206
  template<class P> iterator insert(P&& obj);
8207
  iterator insert(const_iterator hint, const value_type& obj);
8208
  iterator insert(const_iterator hint, value_type&& obj);
8209
  template<class P> iterator insert(const_iterator hint, P&& obj);
8210
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
8211
+ template<container-compatible-range<value_type> R>
8212
+ void insert_range(R&& rg);
8213
  void insert(initializer_list<value_type>);
8214
 
8215
  node_type extract(const_iterator position);
8216
  node_type extract(const key_type& x);
8217
+ template<class K> node_type extract(K&& x);
8218
  iterator insert(node_type&& nh);
8219
  iterator insert(const_iterator hint, node_type&& nh);
8220
 
8221
  iterator erase(iterator position);
8222
  iterator erase(const_iterator position);
8223
  size_type erase(const key_type& k);
8224
+ template<class K> size_type erase(K&& x);
8225
  iterator erase(const_iterator first, const_iterator last);
8226
  void swap(unordered_multimap&)
8227
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8228
  is_nothrow_swappable_v<Hash> &&
8229
  is_nothrow_swappable_v<Pred>);
 
8290
  typename see below::size_type = see below,
8291
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
8292
  -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
8293
  Hash, Pred, Allocator>;
8294
 
8295
+ template<ranges::input_range R,
8296
+ class Hash = hash<range-key-type<R>>,
8297
+ class Pred = equal_to<range-key-type<R>>,
8298
+ class Allocator = allocator<range-to-alloc-type<R>>>
8299
+ unordered_multimap(from_range_t, R&&, typename see below::size_type = see below,
8300
+ Hash = Hash(), Pred = Pred(), Allocator = Allocator())
8301
+ -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>;
8302
+
8303
  template<class Key, class T, class Hash = hash<Key>,
8304
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
8305
  unordered_multimap(initializer_list<pair<Key, T>>,
8306
  typename see below::size_type = see below,
8307
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
 
8323
  unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash,
8324
  Allocator)
8325
  -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Hash,
8326
  equal_to<iter-key-type<InputIterator>>, Allocator>;
8327
 
8328
+ template<ranges::input_range R, class Allocator>
8329
+ unordered_multimap(from_range_t, R&&, typename see below::size_type, Allocator)
8330
+ -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
8331
+ equal_to<range-key-type<R>>, Allocator>;
8332
+
8333
+ template<ranges::input_range R, class Allocator>
8334
+ unordered_multimap(from_range_t, R&&, Allocator)
8335
+ -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>,
8336
+ equal_to<range-key-type<R>>, Allocator>;
8337
+
8338
+ template<ranges::input_range R, class Hash, class Allocator>
8339
+ unordered_multimap(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
8340
+ -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash,
8341
+ equal_to<range-key-type<R>>, Allocator>;
8342
+
8343
  template<class Key, class T, class Allocator>
8344
  unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type,
8345
  Allocator)
8346
  -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
8347
 
 
8351
 
8352
  template<class Key, class T, class Hash, class Allocator>
8353
  unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type,
8354
  Hash, Allocator)
8355
  -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;
 
 
 
 
 
 
8356
  }
8357
  ```
8358
 
8359
  A `size_type` parameter type in an `unordered_multimap` deduction guide
8360
  refers to the `size_type` member type of the type deduced by the
 
8382
  unordered_multimap(InputIterator f, InputIterator l,
8383
  size_type n = see below,
8384
  const hasher& hf = hasher(),
8385
  const key_equal& eql = key_equal(),
8386
  const allocator_type& a = allocator_type());
8387
+ template<container-compatible-range<value_type> R>
8388
+ unordered_multimap(from_range_t, R&& rg,
8389
+ size_type n = see below,
8390
+ const hasher& hf = hasher(),
8391
+ const key_equal& eql = key_equal(),
8392
+ const allocator_type& a = allocator_type());
8393
  unordered_multimap(initializer_list<value_type> il,
8394
  size_type n = see below,
8395
  const hasher& hf = hasher(),
8396
  const key_equal& eql = key_equal(),
8397
  const allocator_type& a = allocator_type());
 
8399
 
8400
  *Effects:* Constructs an empty `unordered_multimap` using the specified
8401
  hash function, key equality predicate, and allocator, and using at least
8402
  `n` buckets. If `n` is not provided, the number of buckets is
8403
  *implementation-defined*. Then inserts elements from the range \[`f`,
8404
+ `l`), `rg`, or `il`, respectively. `max_load_factor()` returns `1.0`.
 
8405
 
8406
  *Complexity:* Average case linear, worst case quadratic.
8407
 
8408
  #### Modifiers <a id="unord.multimap.modifiers">[[unord.multimap.modifiers]]</a>
8409
 
 
8455
  An `unordered_set` is an unordered associative container that supports
8456
  unique keys (an `unordered_set` contains at most one of each key value)
8457
  and in which the elements’ keys are the elements themselves. The
8458
  `unordered_set` class supports forward iterators.
8459
 
8460
+ An `unordered_set` meets all of the requirements of a container
8461
+ [[container.reqmts]], of an allocator-aware container
8462
+ [[container.alloc.reqmts]], of an unordered associative container
8463
+ [[unord.req]]. It provides the operations described in the preceding
8464
+ requirements table for unique keys; that is, an `unordered_set` supports
8465
+ the `a_uniq` operations in that table, not the `a_eq` operations. For an
8466
+ `unordered_set<Key>` the `key_type` and the `value_type` are both `Key`.
8467
+ The `iterator` and `const_iterator` types are both constant iterator
8468
+ types. It is unspecified whether they are the same type.
8469
 
8470
  Subclause  [[unord.set]] only describes operations on `unordered_set`
8471
  that are not described in one of the requirement tables, or for which
8472
  there is additional semantic information.
8473
 
 
8487
  using allocator_type = Allocator;
8488
  using pointer = typename allocator_traits<Allocator>::pointer;
8489
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8490
  using reference = value_type&;
8491
  using const_reference = const value_type&;
8492
+ using size_type = implementation-defined // type of unordered_set::size_type; // see [container.requirements]
8493
+ using difference_type = implementation-defined // type of unordered_set::difference_type; // see [container.requirements]
8494
 
8495
  using iterator = implementation-defined // type of unordered_set::iterator; // see [container.requirements]
8496
  using const_iterator = implementation-defined // type of unordered_set::const_iterator; // see [container.requirements]
8497
  using local_iterator = implementation-defined // type of unordered_set::local_iterator; // see [container.requirements]
8498
  using const_local_iterator = implementation-defined // type of unordered_set::const_local_iterator; // see [container.requirements]
 
8509
  unordered_set(InputIterator f, InputIterator l,
8510
  size_type n = see below,
8511
  const hasher& hf = hasher(),
8512
  const key_equal& eql = key_equal(),
8513
  const allocator_type& a = allocator_type());
8514
+ template<container-compatible-range<value_type> R>
8515
+ unordered_set(from_range_t, R&& rg,
8516
+ size_type n = see below,
8517
+ const hasher& hf = hasher(),
8518
+ const key_equal& eql = key_equal(),
8519
+ const allocator_type& a = allocator_type());
8520
  unordered_set(const unordered_set&);
8521
  unordered_set(unordered_set&&);
8522
  explicit unordered_set(const Allocator&);
8523
+ unordered_set(const unordered_set&, const type_identity_t<Allocator>&);
8524
+ unordered_set(unordered_set&&, const type_identity_t<Allocator>&);
8525
  unordered_set(initializer_list<value_type> il,
8526
  size_type n = see below,
8527
  const hasher& hf = hasher(),
8528
  const key_equal& eql = key_equal(),
8529
  const allocator_type& a = allocator_type());
 
8538
  unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8539
  const allocator_type& a)
8540
  : unordered_set(f, l, n, hf, key_equal(), a) { }
8541
  unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
8542
  : unordered_set(il, n, hasher(), key_equal(), a) { }
8543
+ template<container-compatible-range<value_type> R>
8544
+ unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a)
8545
+ : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
8546
+ template<container-compatible-range<value_type> R>
8547
+ unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
8548
+ : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8549
  unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
8550
  const allocator_type& a)
8551
  : unordered_set(il, n, hf, key_equal(), a) { }
8552
  ~unordered_set();
8553
  unordered_set& operator=(const unordered_set&);
 
8577
  pair<iterator, bool> insert(const value_type& obj);
8578
  pair<iterator, bool> insert(value_type&& obj);
8579
  iterator insert(const_iterator hint, const value_type& obj);
8580
  iterator insert(const_iterator hint, value_type&& obj);
8581
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
8582
+ template<container-compatible-range<value_type> R>
8583
+ void insert_range(R&& rg);
8584
  void insert(initializer_list<value_type>);
8585
 
8586
  node_type extract(const_iterator position);
8587
  node_type extract(const key_type& x);
8588
+ template<class K> node_type extract(K&& x);
8589
  insert_return_type insert(node_type&& nh);
8590
  iterator insert(const_iterator hint, node_type&& nh);
8591
 
8592
+ iterator erase(iterator position)
8593
+ requires (!same_as<iterator, const_iterator>);
8594
  iterator erase(const_iterator position);
8595
  size_type erase(const key_type& k);
8596
+ template<class K> size_type erase(K&& x);
8597
  iterator erase(const_iterator first, const_iterator last);
8598
  void swap(unordered_set&)
8599
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8600
  is_nothrow_swappable_v<Hash> &&
8601
  is_nothrow_swappable_v<Pred>);
 
8661
  unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
8662
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
8663
  -> unordered_set<iter-value-type<InputIterator>,
8664
  Hash, Pred, Allocator>;
8665
 
8666
+ template<ranges::input_range R,
8667
+ class Hash = hash<ranges::range_value_t<R>>,
8668
+ class Pred = equal_to<ranges::range_value_t<R>>,
8669
+ class Allocator = allocator<ranges::range_value_t<R>>>
8670
+ unordered_set(from_range_t, R&&, typename see below::size_type = see below,
8671
+ Hash = Hash(), Pred = Pred(), Allocator = Allocator())
8672
+ -> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>;
8673
+
8674
  template<class T, class Hash = hash<T>,
8675
  class Pred = equal_to<T>, class Allocator = allocator<T>>
8676
  unordered_set(initializer_list<T>, typename see below::size_type = see below,
8677
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
8678
  -> unordered_set<T, Hash, Pred, Allocator>;
 
8689
  Hash, Allocator)
8690
  -> unordered_set<iter-value-type<InputIterator>, Hash,
8691
  equal_to<iter-value-type<InputIterator>>,
8692
  Allocator>;
8693
 
8694
+ template<ranges::input_range R, class Allocator>
8695
+ unordered_set(from_range_t, R&&, typename see below::size_type, Allocator)
8696
+ -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
8697
+ equal_to<ranges::range_value_t<R>>, Allocator>;
8698
+
8699
+ template<ranges::input_range R, class Allocator>
8700
+ unordered_set(from_range_t, R&&, Allocator)
8701
+ -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
8702
+ equal_to<ranges::range_value_t<R>>, Allocator>;
8703
+
8704
+ template<ranges::input_range R, class Hash, class Allocator>
8705
+ unordered_set(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
8706
+ -> unordered_set<ranges::range_value_t<R>, Hash,
8707
+ equal_to<ranges::range_value_t<R>>, Allocator>;
8708
+
8709
  template<class T, class Allocator>
8710
  unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
8711
  -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;
8712
 
8713
  template<class T, class Hash, class Allocator>
8714
  unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
8715
  -> unordered_set<T, Hash, equal_to<T>, Allocator>;
 
 
 
 
 
 
8716
  }
8717
  ```
8718
 
8719
  A `size_type` parameter type in an `unordered_set` deduction guide
8720
  refers to the `size_type` member type of the type deduced by the
 
8742
  unordered_set(InputIterator f, InputIterator l,
8743
  size_type n = see below,
8744
  const hasher& hf = hasher(),
8745
  const key_equal& eql = key_equal(),
8746
  const allocator_type& a = allocator_type());
8747
+ template<container-compatible-range<value_type> R>
8748
+ unordered_multiset(from_range_t, R&& rg,
8749
+ size_type n = see below,
8750
+ const hasher& hf = hasher(),
8751
+ const key_equal& eql = key_equal(),
8752
+ const allocator_type& a = allocator_type());
8753
  unordered_set(initializer_list<value_type> il,
8754
  size_type n = see below,
8755
  const hasher& hf = hasher(),
8756
  const key_equal& eql = key_equal(),
8757
  const allocator_type& a = allocator_type());
 
8759
 
8760
  *Effects:* Constructs an empty `unordered_set` using the specified hash
8761
  function, key equality predicate, and allocator, and using at least `n`
8762
  buckets. If `n` is not provided, the number of buckets is
8763
  *implementation-defined*. Then inserts elements from the range \[`f`,
8764
+ `l`), `rg`, or `il`, respectively. `max_load_factor()` returns `1.0`.
 
8765
 
8766
  *Complexity:* Average case linear, worst case quadratic.
8767
 
8768
  #### Erasure <a id="unord.set.erasure">[[unord.set.erasure]]</a>
8769
 
 
8795
  supports equivalent keys (an instance of `unordered_multiset` may
8796
  contain multiple copies of the same key value) and in which each
8797
  element’s key is the element itself. The `unordered_multiset` class
8798
  supports forward iterators.
8799
 
8800
+ An `unordered_multiset` meets all of the requirements of a container
8801
+ [[container.reqmts]], of an allocator-aware container
8802
+ [[container.alloc.reqmts]], and of an unordered associative container
8803
+ [[unord.req]]. It provides the operations described in the preceding
8804
+ requirements table for equivalent keys; that is, an `unordered_multiset`
8805
+ supports the `a_eq` operations in that table, not the `a_uniq`
8806
+ operations. For an `unordered_multiset<Key>` the `key_type` and the
8807
+ `value_type` are both `Key`. The `iterator` and `const_iterator` types
8808
+ are both constant iterator types. It is unspecified whether they are the
8809
+ same type.
8810
 
8811
  Subclause  [[unord.multiset]] only describes operations on
8812
  `unordered_multiset` that are not described in one of the requirement
8813
  tables, or for which there is additional semantic information.
8814
 
 
8828
  using allocator_type = Allocator;
8829
  using pointer = typename allocator_traits<Allocator>::pointer;
8830
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8831
  using reference = value_type&;
8832
  using const_reference = const value_type&;
8833
+ using size_type = implementation-defined // type of unordered_multiset::size_type; // see [container.requirements]
8834
+ using difference_type = implementation-defined // type of unordered_multiset::difference_type; // see [container.requirements]
8835
 
8836
  using iterator = implementation-defined // type of unordered_multiset::iterator; // see [container.requirements]
8837
  using const_iterator = implementation-defined // type of unordered_multiset::const_iterator; // see [container.requirements]
8838
  using local_iterator = implementation-defined // type of unordered_multiset::local_iterator; // see [container.requirements]
8839
  using const_local_iterator = implementation-defined // type of unordered_multiset::const_local_iterator; // see [container.requirements]
 
8849
  unordered_multiset(InputIterator f, InputIterator l,
8850
  size_type n = see below,
8851
  const hasher& hf = hasher(),
8852
  const key_equal& eql = key_equal(),
8853
  const allocator_type& a = allocator_type());
8854
+ template<container-compatible-range<value_type> R>
8855
+ unordered_multiset(from_range_t, R&& rg,
8856
+ size_type n = see below,
8857
+ const hasher& hf = hasher(),
8858
+ const key_equal& eql = key_equal(),
8859
+ const allocator_type& a = allocator_type());
8860
  unordered_multiset(const unordered_multiset&);
8861
  unordered_multiset(unordered_multiset&&);
8862
  explicit unordered_multiset(const Allocator&);
8863
+ unordered_multiset(const unordered_multiset&, const type_identity_t<Allocator>&);
8864
+ unordered_multiset(unordered_multiset&&, const type_identity_t<Allocator>&);
8865
  unordered_multiset(initializer_list<value_type> il,
8866
  size_type n = see below,
8867
  const hasher& hf = hasher(),
8868
  const key_equal& eql = key_equal(),
8869
  const allocator_type& a = allocator_type());
 
8876
  : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
8877
  template<class InputIterator>
8878
  unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8879
  const allocator_type& a)
8880
  : unordered_multiset(f, l, n, hf, key_equal(), a) { }
8881
+ template<container-compatible-range<value_type> R>
8882
+ unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a)
8883
+ : unordered_multiset(from_range, std::forward<R>(rg),
8884
+ n, hasher(), key_equal(), a) { }
8885
+ template<container-compatible-range<value_type> R>
8886
+ unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf,
8887
+ const allocator_type& a)
8888
+ : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8889
  unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
8890
  : unordered_multiset(il, n, hasher(), key_equal(), a) { }
8891
  unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
8892
  const allocator_type& a)
8893
  : unordered_multiset(il, n, hf, key_equal(), a) { }
 
8919
  iterator insert(const value_type& obj);
8920
  iterator insert(value_type&& obj);
8921
  iterator insert(const_iterator hint, const value_type& obj);
8922
  iterator insert(const_iterator hint, value_type&& obj);
8923
  template<class InputIterator> void insert(InputIterator first, InputIterator last);
8924
+ template<container-compatible-range<value_type> R>
8925
+ void insert_range(R&& rg);
8926
  void insert(initializer_list<value_type>);
8927
 
8928
  node_type extract(const_iterator position);
8929
  node_type extract(const key_type& x);
8930
+ template<class K> node_type extract(K&& x);
8931
  iterator insert(node_type&& nh);
8932
  iterator insert(const_iterator hint, node_type&& nh);
8933
 
8934
+ iterator erase(iterator position)
8935
+ requires (!same_as<iterator, const_iterator>);
8936
  iterator erase(const_iterator position);
8937
  size_type erase(const key_type& k);
8938
+ template<class K> size_type erase(K&& x);
8939
  iterator erase(const_iterator first, const_iterator last);
8940
  void swap(unordered_multiset&)
8941
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8942
  is_nothrow_swappable_v<Hash> &&
8943
  is_nothrow_swappable_v<Pred>);
 
9003
  unordered_multiset(InputIterator, InputIterator, see below::size_type = see below,
9004
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
9005
  -> unordered_multiset<iter-value-type<InputIterator>,
9006
  Hash, Pred, Allocator>;
9007
 
9008
+ template<ranges::input_range R,
9009
+ class Hash = hash<ranges::range_value_t<R>>,
9010
+ class Pred = equal_to<ranges::range_value_t<R>>,
9011
+ class Allocator = allocator<ranges::range_value_t<R>>>
9012
+ unordered_multiset(from_range_t, R&&, typename see below::size_type = see below,
9013
+ Hash = Hash(), Pred = Pred(), Allocator = Allocator())
9014
+ -> unordered_multiset<ranges::range_value_t<R>, Hash, Pred, Allocator>;
9015
+
9016
  template<class T, class Hash = hash<T>,
9017
  class Pred = equal_to<T>, class Allocator = allocator<T>>
9018
  unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
9019
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
9020
  -> unordered_multiset<T, Hash, Pred, Allocator>;
 
9031
  Hash, Allocator)
9032
  -> unordered_multiset<iter-value-type<InputIterator>, Hash,
9033
  equal_to<iter-value-type<InputIterator>>,
9034
  Allocator>;
9035
 
9036
+ template<ranges::input_range R, class Allocator>
9037
+ unordered_multiset(from_range_t, R&&, typename see below::size_type, Allocator)
9038
+ -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
9039
+ equal_to<ranges::range_value_t<R>>, Allocator>;
9040
+
9041
+ template<ranges::input_range R, class Allocator>
9042
+ unordered_multiset(from_range_t, R&&, Allocator)
9043
+ -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
9044
+ equal_to<ranges::range_value_t<R>>, Allocator>;
9045
+
9046
+ template<ranges::input_range R, class Hash, class Allocator>
9047
+ unordered_multiset(from_range_t, R&&, typename see below::size_type, Hash, Allocator)
9048
+ -> unordered_multiset<ranges::range_value_t<R>, Hash, equal_to<ranges::range_value_t<R>>,
9049
+ Allocator>;
9050
+
9051
  template<class T, class Allocator>
9052
  unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
9053
  -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;
9054
 
9055
  template<class T, class Hash, class Allocator>
9056
  unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
9057
  -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;
 
 
 
 
 
 
9058
  }
9059
  ```
9060
 
9061
  A `size_type` parameter type in an `unordered_multiset` deduction guide
9062
  refers to the `size_type` member type of the type deduced by the
 
9084
  unordered_multiset(InputIterator f, InputIterator l,
9085
  size_type n = see below,
9086
  const hasher& hf = hasher(),
9087
  const key_equal& eql = key_equal(),
9088
  const allocator_type& a = allocator_type());
9089
+ template<container-compatible-range<value_type> R>
9090
+ unordered_multiset(from_range_t, R&& rg,
9091
+ size_type n = see below,
9092
+ const hasher& hf = hasher(),
9093
+ const key_equal& eql = key_equal(),
9094
+ const allocator_type& a = allocator_type());
9095
  unordered_multiset(initializer_list<value_type> il,
9096
  size_type n = see below,
9097
  const hasher& hf = hasher(),
9098
  const key_equal& eql = key_equal(),
9099
  const allocator_type& a = allocator_type());
 
9101
 
9102
  *Effects:* Constructs an empty `unordered_multiset` using the specified
9103
  hash function, key equality predicate, and allocator, and using at least
9104
  `n` buckets. If `n` is not provided, the number of buckets is
9105
  *implementation-defined*. Then inserts elements from the range \[`f`,
9106
+ `l`), `rg`, or `il`, respectively. `max_load_factor()` returns `1.0`.
 
9107
 
9108
  *Complexity:* Average case linear, worst case quadratic.
9109
 
9110
  #### Erasure <a id="unord.multiset.erasure">[[unord.multiset.erasure]]</a>
9111
 
 
9131
 
9132
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
9133
 
9134
  ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
9135
 
9136
+ The headers `<queue>`, `<stack>`, `<flat_map>`, and `<flat_set>` define
9137
+ the container adaptors `queue` and `priority_queue`, `stack`, `flat_map`
9138
+ and `flat_multimap`, and `flat_set` and `flat_multiset`, respectively.
9139
 
9140
+ Each container adaptor takes one or more template parameters named
9141
+ `Container`, `KeyContainer`, or `MappedContainer` that denote the types
9142
+ of containers that the container adaptor adapts. Each container adaptor
9143
+ has at least one constructor that takes a reference argument to one or
9144
+ more such template parameters. For each constructor reference argument
9145
+ to a container `C`, the constructor copies the container into the
9146
+ container adaptor. If `C` takes an allocator, then a compatible
9147
+ allocator may be passed in to the adaptor’s constructor. Otherwise,
9148
+ normal copy or move construction is used for the container argument. For
9149
+ the container adaptors that take a single container template parameter
9150
+ `Container`, the first template parameter `T` of the container adaptor
9151
+ shall denote the same type as `Container::value_type`.
9152
 
9153
  For container adaptors, no `swap` function throws an exception unless
9154
+ that exception is thrown by the swap of the adaptor’s `Container`,
9155
+ `KeyContainer`, `MappedContainer`, or `Compare` object (if any).
9156
+
9157
+ A constructor template of a container adaptor shall not participate in
9158
+ overload resolution if it has an `InputIterator` template parameter and
9159
+ a type that does not qualify as an input iterator is deduced for that
9160
+ parameter.
9161
+
9162
+ For container adaptors that have them, the `insert`, `emplace`, and
9163
+ `erase` members affect the validity of iterators, references, and
9164
+ pointers to the adaptor’s container(s) in the same way that the
9165
+ containers’ respective `insert`, `emplace`, and `erase` members do.
9166
+
9167
+ [*Example 1*: A call to `flat_map<Key, T>::insert` can invalidate all
9168
+ iterators to the `flat_map`. — *end example*]
9169
 
9170
  A deduction guide for a container adaptor shall not participate in
9171
  overload resolution if any of the following are true:
9172
 
9173
  - It has an `InputIterator` template parameter and a type that does not
9174
  qualify as an input iterator is deduced for that parameter.
9175
  - It has a `Compare` template parameter and a type that qualifies as an
9176
  allocator is deduced for that parameter.
9177
+ - It has a `Container`, `KeyContainer`, or `MappedContainer` template
9178
+ parameter and a type that qualifies as an allocator is deduced for
9179
+ that parameter.
9180
+ - It has no `Container`, `KeyContainer`, or `MappedContainer` template
9181
+ parameter, and it has an `Allocator` template parameter, and a type
9182
+ that does not qualify as an allocator is deduced for that parameter.
9183
  - It has both `Container` and `Allocator` template parameters, and
9184
  `uses_allocator_v<Container, Allocator>` is `false`.
9185
+ - It has both `KeyContainer` and `Allocator` template parameters, and
9186
+ `uses_allocator_v<KeyContainer, Allocator>` is `false`.
9187
+ - It has both `KeyContainer` and `Compare` template parameters, and
9188
+ ``` cpp
9189
+ is_invocable_v<const Compare&,
9190
+ const typename KeyContainer::value_type&,
9191
+ const typename KeyContainer::value_type&>
9192
+ ```
9193
+
9194
+ is not a valid expression or is `false`.
9195
+ - It has both `MappedContainer` and `Allocator` template parameters, and
9196
+ `uses_allocator_v<MappedContainer, Allocator>` is `false`.
9197
+
9198
+ The exposition-only alias template *`iter-value-type`* defined in
9199
+ [[sequences.general]] and the exposition-only alias templates
9200
+ *`iter-key-type`*, *`iter-mapped-type`*, *`range-key-type`*, and
9201
+ *`range-mapped-type`* defined in [[associative.general]] may appear in
9202
+ deduction guides for container adaptors.
9203
+
9204
+ The following exposition-only alias template may appear in deduction
9205
+ guides for container adaptors:
9206
+
9207
+ ``` cpp
9208
+ template<class Allocator, class T>
9209
+ using alloc-rebind = // exposition only
9210
+ typename allocator_traits<Allocator>::template rebind_alloc<T>;
9211
+ ```
9212
 
9213
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
9214
 
9215
  ``` cpp
9216
  #include <compare> // see [compare.syn]
9217
  #include <initializer_list> // see [initializer.list.syn]
9218
 
9219
  namespace std {
9220
+ // [queue], class template queue
9221
  template<class T, class Container = deque<T>> class queue;
9222
 
9223
  template<class T, class Container>
9224
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
9225
  template<class T, class Container>
 
9239
  template<class T, class Container>
9240
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
9241
  template<class T, class Container, class Alloc>
9242
  struct uses_allocator<queue<T, Container>, Alloc>;
9243
 
9244
+ // [priority.queue], class template priority_queue
9245
  template<class T, class Container = vector<T>,
9246
  class Compare = less<typename Container::value_type>>
9247
  class priority_queue;
9248
 
9249
  template<class T, class Container, class Compare>
 
9259
  ``` cpp
9260
  #include <compare> // see [compare.syn]
9261
  #include <initializer_list> // see [initializer.list.syn]
9262
 
9263
  namespace std {
9264
+ // [stack], class template stack
9265
  template<class T, class Container = deque<T>> class stack;
9266
 
9267
  template<class T, class Container>
9268
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
9269
  template<class T, class Container>
 
9285
  template<class T, class Container, class Alloc>
9286
  struct uses_allocator<stack<T, Container>, Alloc>;
9287
  }
9288
  ```
9289
 
9290
+ ### Header `<flat_map>` synopsis <a id="flat.map.syn">[[flat.map.syn]]</a>
9291
+
9292
+ ``` cpp
9293
+ #include <compare> // see [compare.syn]
9294
+ #include <initializer_list> // see [initializer.list.syn]
9295
+
9296
+ namespace std {
9297
+ // [flat.map], class template flat_map
9298
+ template<class Key, class T, class Compare = less<Key>,
9299
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
9300
+ class flat_map;
9301
+
9302
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
9303
+ inline constexpr sorted_unique_t sorted_unique{};
9304
+
9305
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9306
+ class Allocator>
9307
+ struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
9308
+ Allocator>;
9309
+
9310
+ // [flat.map.erasure], erasure for flat_map
9311
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9312
+ class Predicate>
9313
+ typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
9314
+ erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
9315
+
9316
+ // [flat.multimap], class template flat_multimap
9317
+ template<class Key, class T, class Compare = less<Key>,
9318
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
9319
+ class flat_multimap;
9320
+
9321
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
9322
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
9323
+
9324
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9325
+ class Allocator>
9326
+ struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
9327
+ Allocator>;
9328
+
9329
+ // [flat.multimap.erasure], erasure for flat_multimap
9330
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9331
+ class Predicate>
9332
+ typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
9333
+ erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
9334
+ }
9335
+ ```
9336
+
9337
+ ### Header `<flat_set>` synopsis <a id="flat.set.syn">[[flat.set.syn]]</a>
9338
+
9339
+ ``` cpp
9340
+ #include <compare> // see [compare.syn]
9341
+ #include <initializer_list> // see [initializer.list.syn]
9342
+
9343
+ namespace std {
9344
+ // [flat.set], class template flat_set
9345
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
9346
+ class flat_set;
9347
+
9348
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
9349
+ inline constexpr sorted_unique_t sorted_unique{};
9350
+
9351
+ template<class Key, class Compare, class KeyContainer, class Allocator>
9352
+ struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
9353
+
9354
+ // [flat.set.erasure], erasure for flat_set
9355
+ template<class Key, class Compare, class KeyContainer, class Predicate>
9356
+ typename flat_set<Key, Compare, KeyContainer>::size_type
9357
+ erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
9358
+
9359
+ // [flat.multiset], class template flat_multiset
9360
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
9361
+ class flat_multiset;
9362
+
9363
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
9364
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
9365
+
9366
+ template<class Key, class Compare, class KeyContainer, class Allocator>
9367
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>;
9368
+
9369
+ // [flat.multiset.erasure], erasure for flat_multiset
9370
+ template<class Key, class Compare, class KeyContainer, class Predicate>
9371
+ typename flat_multiset<Key, Compare, KeyContainer>::size_type
9372
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
9373
+ }
9374
+ ```
9375
+
9376
  ### Class template `queue` <a id="queue">[[queue]]</a>
9377
 
9378
  #### Definition <a id="queue.defn">[[queue.defn]]</a>
9379
 
9380
  Any sequence container supporting operations `front()`, `back()`,
 
9397
 
9398
  public:
9399
  queue() : queue(Container()) {}
9400
  explicit queue(const Container&);
9401
  explicit queue(Container&&);
9402
+ template<class InputIterator> queue(InputIterator first, InputIterator last);
9403
+ template<container-compatible-range<T> R> queue(from_range_t, R&& rg);
9404
  template<class Alloc> explicit queue(const Alloc&);
9405
  template<class Alloc> queue(const Container&, const Alloc&);
9406
  template<class Alloc> queue(Container&&, const Alloc&);
9407
  template<class Alloc> queue(const queue&, const Alloc&);
9408
  template<class Alloc> queue(queue&&, const Alloc&);
9409
+ template<class InputIterator, class Alloc>
9410
+ queue(InputIterator first, InputIterator last, const Alloc&);
9411
+ template<container-compatible-range<T> R, class Alloc>
9412
+ queue(from_range_t, R&& rg, const Alloc&);
9413
 
9414
  [[nodiscard]] bool empty() const { return c.empty(); }
9415
  size_type size() const { return c.size(); }
9416
  reference front() { return c.front(); }
9417
  const_reference front() const { return c.front(); }
9418
  reference back() { return c.back(); }
9419
  const_reference back() const { return c.back(); }
9420
  void push(const value_type& x) { c.push_back(x); }
9421
  void push(value_type&& x) { c.push_back(std::move(x)); }
9422
+ template<container-compatible-range<T> R> void push_range(R&& rg);
9423
  template<class... Args>
9424
  decltype(auto) emplace(Args&&... args)
9425
  { return c.emplace_back(std::forward<Args>(args)...); }
9426
  void pop() { c.pop_front(); }
9427
  void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
 
9429
  };
9430
 
9431
  template<class Container>
9432
  queue(Container) -> queue<typename Container::value_type, Container>;
9433
 
9434
+ template<class InputIterator>
9435
+ queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>;
9436
+
9437
+ template<ranges::input_range R>
9438
+ queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>;
9439
+
9440
  template<class Container, class Allocator>
9441
  queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
9442
 
9443
+ template<class InputIterator, class Allocator>
9444
+ queue(InputIterator, InputIterator, Allocator)
9445
+ -> queue<iter-value-type<InputIterator>, deque<iter-value-type<InputIterator>,
9446
+ Allocator>>;
9447
+
9448
+ template<ranges::input_range R, class Allocator>
9449
+ queue(from_range_t, R&&, Allocator)
9450
+ -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>;
9451
 
9452
  template<class T, class Container, class Alloc>
9453
  struct uses_allocator<queue<T, Container>, Alloc>
9454
  : uses_allocator<Container, Alloc>::type { };
9455
  }
 
9467
  explicit queue(Container&& cont);
9468
  ```
9469
 
9470
  *Effects:* Initializes `c` with `std::move(cont)`.
9471
 
9472
+ ``` cpp
9473
+ template<class InputIterator>
9474
+ queue(InputIterator first, InputIterator last);
9475
+ ```
9476
+
9477
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
9478
+ as the second argument.
9479
+
9480
+ ``` cpp
9481
+ template<container-compatible-range<T> R>
9482
+ queue(from_range_t, R&& rg);
9483
+ ```
9484
+
9485
+ *Effects:* Initializes `c` with
9486
+ `ranges::to<Container>(std::forward<R>(rg))`.
9487
+
9488
  #### Constructors with allocators <a id="queue.cons.alloc">[[queue.cons.alloc]]</a>
9489
 
9490
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
9491
  in this subclause shall not participate in overload resolution.
9492
 
 
9522
  ```
9523
 
9524
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
9525
  and `a` as the second argument.
9526
 
9527
+ ``` cpp
9528
+ template<class InputIterator, class Alloc>
9529
+ queue(InputIterator first, InputIterator last, const Alloc& alloc);
9530
+ ```
9531
+
9532
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
9533
+ the second argument, and `alloc` as the third argument.
9534
+
9535
+ ``` cpp
9536
+ template<container-compatible-range<T> R, class Alloc>
9537
+ queue(from_range_t, R&& rg, const Alloc& a);
9538
+ ```
9539
+
9540
+ *Effects:* Initializes `c` with
9541
+ `ranges::to<Container>(std::forward<R>(rg), a)`.
9542
+
9543
+ #### Modifiers <a id="queue.mod">[[queue.mod]]</a>
9544
+
9545
+ ``` cpp
9546
+ template<container-compatible-range<T> R>
9547
+ void push_range(R&& rg);
9548
+ ```
9549
+
9550
+ *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
9551
+ is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
9552
+
9553
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
9554
 
9555
  ``` cpp
9556
  template<class T, class Container>
9557
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
 
9646
  public:
9647
  priority_queue() : priority_queue(Compare()) {}
9648
  explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
9649
  priority_queue(const Compare& x, const Container&);
9650
  priority_queue(const Compare& x, Container&&);
9651
+ template<class InputIterator>
9652
+ priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
9653
  template<class InputIterator>
9654
  priority_queue(InputIterator first, InputIterator last, const Compare& x,
9655
  const Container&);
9656
  template<class InputIterator>
9657
+ priority_queue(InputIterator first, InputIterator last, const Compare& x,
9658
+ Container&&);
9659
+ template<container-compatible-range<T> R>
9660
+ priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
9661
  template<class Alloc> explicit priority_queue(const Alloc&);
9662
  template<class Alloc> priority_queue(const Compare&, const Alloc&);
9663
  template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
9664
  template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
9665
  template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
9666
  template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
9667
+ template<class InputIterator, class Alloc>
9668
+ priority_queue(InputIterator, InputIterator, const Alloc&);
9669
+ template<class InputIterator, class Alloc>
9670
+ priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&);
9671
+ template<class InputIterator, class Alloc>
9672
+ priority_queue(InputIterator, InputIterator, const Compare&, const Container&,
9673
+ const Alloc&);
9674
+ template<class InputIterator, class Alloc>
9675
+ priority_queue(InputIterator, InputIterator, const Compare&, Container&&, const Alloc&);
9676
+ template<container-compatible-range<T> R, class Alloc>
9677
+ priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&);
9678
+ template<container-compatible-range<T> R, class Alloc>
9679
+ priority_queue(from_range_t, R&& rg, const Alloc&);
9680
 
9681
  [[nodiscard]] bool empty() const { return c.empty(); }
9682
  size_type size() const { return c.size(); }
9683
  const_reference top() const { return c.front(); }
9684
  void push(const value_type& x);
9685
  void push(value_type&& x);
9686
+ template<container-compatible-range<T> R>
9687
+ void push_range(R&& rg);
9688
  template<class... Args> void emplace(Args&&... args);
9689
  void pop();
9690
  void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
9691
  is_nothrow_swappable_v<Compare>)
9692
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
 
9695
  template<class Compare, class Container>
9696
  priority_queue(Compare, Container)
9697
  -> priority_queue<typename Container::value_type, Container, Compare>;
9698
 
9699
  template<class InputIterator,
9700
+ class Compare = less<iter-value-type<InputIterator>>,
9701
+ class Container = vector<iter-value-type<InputIterator>>>
9702
  priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
9703
+ -> priority_queue<iter-value-type<InputIterator>, Container, Compare>;
9704
+
9705
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
9706
+ priority_queue(from_range_t, R&&, Compare = Compare())
9707
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>;
9708
 
9709
  template<class Compare, class Container, class Allocator>
9710
  priority_queue(Compare, Container, Allocator)
9711
  -> priority_queue<typename Container::value_type, Container, Compare>;
9712
 
9713
+ template<class InputIterator, class Allocator>
9714
+ priority_queue(InputIterator, InputIterator, Allocator)
9715
+ -> priority_queue<iter-value-type<InputIterator>,
9716
+ vector<iter-value-type<InputIterator>, Allocator>,
9717
+ less<iter-value-type<InputIterator>>>;
9718
+
9719
+ template<class InputIterator, class Compare, class Allocator>
9720
+ priority_queue(InputIterator, InputIterator, Compare, Allocator)
9721
+ -> priority_queue<iter-value-type<InputIterator>,
9722
+ vector<iter-value-type<InputIterator>, Allocator>, Compare>;
9723
+
9724
+ template<class InputIterator, class Compare, class Container, class Allocator>
9725
+ priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
9726
+ -> priority_queue<typename Container::value_type, Container, Compare>;
9727
+
9728
+ template<ranges::input_range R, class Compare, class Allocator>
9729
+ priority_queue(from_range_t, R&&, Compare, Allocator)
9730
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
9731
+ Compare>;
9732
+
9733
+ template<ranges::input_range R, class Allocator>
9734
+ priority_queue(from_range_t, R&&, Allocator)
9735
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>;
9736
+
9737
  // no equality is provided
9738
 
 
 
 
 
9739
  template<class T, class Container, class Compare, class Alloc>
9740
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
9741
  : uses_allocator<Container, Alloc>::type { };
9742
  }
9743
  ```
 
9753
 
9754
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
9755
  constructing or move constructing as appropriate); calls
9756
  `make_heap(c.begin(), c.end(), comp)`.
9757
 
9758
+ ``` cpp
9759
+ template<class InputIterator>
9760
+ priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
9761
+ ```
9762
+
9763
+ *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9764
+
9765
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
9766
+ as the second argument, and initializes `comp` with `x`; then calls
9767
+ `make_heap(c.begin(), c.end(), comp)`.
9768
+
9769
  ``` cpp
9770
  template<class InputIterator>
9771
  priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y);
9772
  template<class InputIterator>
9773
+ priority_queue(InputIterator first, InputIterator last, const Compare& x, Container&& y);
 
9774
  ```
9775
 
9776
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9777
 
9778
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
9779
  constructing or move constructing as appropriate); calls
9780
  `c.insert(c.end(), first, last)`; and finally calls
9781
  `make_heap(c.begin(), c.end(), comp)`.
9782
 
9783
+ ``` cpp
9784
+ template<container-compatible-range<T> R>
9785
+ priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
9786
+ ```
9787
+
9788
+ *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9789
+
9790
+ *Effects:* Initializes `comp` with `x` and `c` with
9791
+ `ranges::to<Container>(std::forward<R>(rg))` and finally calls
9792
+ `make_heap(c.begin(), c.end(), comp)`.
9793
+
9794
  #### Constructors with allocators <a id="priqueue.cons.alloc">[[priqueue.cons.alloc]]</a>
9795
 
9796
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
9797
  in this subclause shall not participate in overload resolution.
9798
 
 
9840
 
9841
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
9842
  and `a` as the second argument, and initializes `comp` with
9843
  `std::move(q.comp)`.
9844
 
9845
+ ``` cpp
9846
+ template<class InputIterator, class Alloc>
9847
+ priority_queue(InputIterator first, InputIterator last, const Alloc& a);
9848
+ ```
9849
+
9850
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
9851
+ the second argument, and `a` as the third argument, and
9852
+ value-initializes `comp`; calls `make_heap(c.begin(), c.end(), comp)`.
9853
+
9854
+ ``` cpp
9855
+ template<class InputIterator, class Alloc>
9856
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare, const Alloc& a);
9857
+ ```
9858
+
9859
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
9860
+ the second argument, and `a` as the third argument, and initializes
9861
+ `comp` with `compare`; calls `make_heap(c.begin(), c.end(), comp)`.
9862
+
9863
+ ``` cpp
9864
+ template<class InputIterator, class Alloc>
9865
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare,
9866
+ const Container& cont, const Alloc& a);
9867
+ ```
9868
+
9869
+ *Effects:* Initializes `c` with `cont` as the first argument and `a` as
9870
+ the second argument, and initializes `comp` with `compare`; calls
9871
+ `c.insert(c.end(), first, last)`; and finally calls
9872
+ `make_heap(c.begin(), c.end(), comp)`.
9873
+
9874
+ ``` cpp
9875
+ template<class InputIterator, class Alloc>
9876
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& cont,
9877
+ const Alloc& a);
9878
+ ```
9879
+
9880
+ *Effects:* Initializes `c` with `std::move(cont)` as the first argument
9881
+ and `a` as the second argument, and initializes `comp` with `compare`;
9882
+ calls `c.insert(c.end(), first, last)`; and finally calls
9883
+ `make_heap(c.begin(), c.end(), comp)`.
9884
+
9885
+ ``` cpp
9886
+ template<container-compatible-range<T> R, class Alloc>
9887
+ priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a);
9888
+ ```
9889
+
9890
+ *Effects:* Initializes `comp` with `compare` and `c` with
9891
+ `ranges::to<Container>(std::forward<R>(rg), a)`; calls
9892
+ `make_heap(c.begin(), c.end(), comp)`.
9893
+
9894
+ ``` cpp
9895
+ template<container-compatible-range<T> R, class Alloc>
9896
+ priority_queue(from_range_t, R&& rg, const Alloc& a);
9897
+ ```
9898
+
9899
+ *Effects:* Initializes `c` with
9900
+ `ranges::to<Container>(std::forward<R>(rg), a)`; calls
9901
+ `make_heap(c.begin(), c.end(), comp)`.
9902
+
9903
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
9904
 
9905
  ``` cpp
9906
  void push(const value_type& x);
9907
  ```
 
9922
  ``` cpp
9923
  c.push_back(std::move(x));
9924
  push_heap(c.begin(), c.end(), comp);
9925
  ```
9926
 
9927
+ ``` cpp
9928
+ template<container-compatible-range<T> R>
9929
+ void push_range(R&& rg);
9930
+ ```
9931
+
9932
+ *Effects:* Inserts all elements of `rg` in `c` via
9933
+ `c.append_range(std::forward<R>(rg))` if that is a valid expression, or
9934
+ `ranges::copy(rg, back_inserter(c))` otherwise. Then restores the heap
9935
+ property as if by `make_heap(c.begin(), c.end(), comp)`.
9936
+
9937
+ *Ensures:* `is_heap(c.begin(), c.end(), comp)` is `true`.
9938
+
9939
  ``` cpp
9940
  template<class... Args> void emplace(Args&&... args);
9941
  ```
9942
 
9943
  *Effects:* As if by:
 
9971
 
9972
  *Effects:* As if by `x.swap(y)`.
9973
 
9974
  ### Class template `stack` <a id="stack">[[stack]]</a>
9975
 
9976
+ #### General <a id="stack.general">[[stack.general]]</a>
9977
+
9978
  Any sequence container supporting operations `back()`, `push_back()` and
9979
  `pop_back()` can be used to instantiate `stack`. In particular, `vector`
9980
  [[vector]], `list` [[list]] and `deque` [[deque]] can be used.
9981
 
9982
  #### Definition <a id="stack.defn">[[stack.defn]]</a>
 
9997
 
9998
  public:
9999
  stack() : stack(Container()) {}
10000
  explicit stack(const Container&);
10001
  explicit stack(Container&&);
10002
+ template<class InputIterator> stack(InputIterator first, InputIterator last);
10003
+ template<container-compatible-range<T> R> stack(from_range_t, R&& rg);
10004
  template<class Alloc> explicit stack(const Alloc&);
10005
  template<class Alloc> stack(const Container&, const Alloc&);
10006
  template<class Alloc> stack(Container&&, const Alloc&);
10007
  template<class Alloc> stack(const stack&, const Alloc&);
10008
  template<class Alloc> stack(stack&&, const Alloc&);
10009
+ template<class InputIterator, class Alloc>
10010
+ stack(InputIterator first, InputIterator last, const Alloc&);
10011
+ template<container-compatible-range<T> R, class Alloc>
10012
+ stack(from_range_t, R&& rg, const Alloc&);
10013
 
10014
  [[nodiscard]] bool empty() const { return c.empty(); }
10015
  size_type size() const { return c.size(); }
10016
  reference top() { return c.back(); }
10017
  const_reference top() const { return c.back(); }
10018
  void push(const value_type& x) { c.push_back(x); }
10019
  void push(value_type&& x) { c.push_back(std::move(x)); }
10020
+ template<container-compatible-range<T> R>
10021
+ void push_range(R&& rg);
10022
  template<class... Args>
10023
  decltype(auto) emplace(Args&&... args)
10024
  { return c.emplace_back(std::forward<Args>(args)...); }
10025
  void pop() { c.pop_back(); }
10026
  void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
 
10028
  };
10029
 
10030
  template<class Container>
10031
  stack(Container) -> stack<typename Container::value_type, Container>;
10032
 
10033
+ template<class InputIterator>
10034
+ stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>;
10035
+
10036
+ template<ranges::input_range R>
10037
+ stack(from_range_t, R&&) -> stack<ranges::range_value_t<R>>;
10038
+
10039
  template<class Container, class Allocator>
10040
  stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
10041
 
10042
+ template<class InputIterator, class Allocator>
10043
+ stack(InputIterator, InputIterator, Allocator)
10044
+ -> stack<iter-value-type<InputIterator>, deque<iter-value-type<InputIterator>,
10045
+ Allocator>>;
10046
+
10047
+ template<ranges::input_range R, class Allocator>
10048
+ stack(from_range_t, R&&, Allocator)
10049
+ -> stack<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>;
10050
+
10051
  template<class T, class Container, class Alloc>
10052
  struct uses_allocator<stack<T, Container>, Alloc>
10053
  : uses_allocator<Container, Alloc>::type { };
10054
  }
10055
  ```
 
10066
  explicit stack(Container&& cont);
10067
  ```
10068
 
10069
  *Effects:* Initializes `c` with `std::move(cont)`.
10070
 
10071
+ ``` cpp
10072
+ template<class InputIterator>
10073
+ stack(InputIterator first, InputIterator last);
10074
+ ```
10075
+
10076
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
10077
+ as the second argument.
10078
+
10079
+ ``` cpp
10080
+ template<container-compatible-range<T> R>
10081
+ stack(from_range_t, R&& rg);
10082
+ ```
10083
+
10084
+ *Effects:* Initializes `c` with
10085
+ `ranges::to<Container>(std::forward<R>(rg))`.
10086
+
10087
  #### Constructors with allocators <a id="stack.cons.alloc">[[stack.cons.alloc]]</a>
10088
 
10089
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
10090
  in this subclause shall not participate in overload resolution.
10091
 
 
10121
  ```
10122
 
10123
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
10124
  and `a` as the second argument.
10125
 
10126
+ ``` cpp
10127
+ template<class InputIterator, class Alloc>
10128
+ stack(InputIterator first, InputIterator last, const Alloc& alloc);
10129
+ ```
10130
+
10131
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
10132
+ the second argument, and `alloc` as the third argument.
10133
+
10134
+ ``` cpp
10135
+ template<container-compatible-range<T> R, class Alloc>
10136
+ stack(from_range_t, R&& rg, const Alloc& a);
10137
+ ```
10138
+
10139
+ *Effects:* Initializes `c` with
10140
+ `ranges::to<Container>(std::forward<R>(rg), a)`.
10141
+
10142
+ #### Modifiers <a id="stack.mod">[[stack.mod]]</a>
10143
+
10144
+ ``` cpp
10145
+ template<container-compatible-range<T> R>
10146
+ void push_range(R&& rg);
10147
+ ```
10148
+
10149
+ *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
10150
+ is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
10151
+
10152
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
10153
 
10154
  ``` cpp
10155
  template<class T, class Container>
10156
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
 
10210
 
10211
  *Constraints:* `is_swappable_v<Container>` is `true`.
10212
 
10213
  *Effects:* As if by `x.swap(y)`.
10214
 
10215
+ ### Class template `flat_map` <a id="flat.map">[[flat.map]]</a>
10216
+
10217
+ #### Overview <a id="flat.map.overview">[[flat.map.overview]]</a>
10218
+
10219
+ A `flat_map` is a container adaptor that provides an associative
10220
+ container interface that supports unique keys (i.e., contains at most
10221
+ one of each key value) and provides for fast retrieval of values of
10222
+ another type `T` based on the keys. `flat_map` supports iterators that
10223
+ meet the *Cpp17InputIterator* requirements and model the
10224
+ `random_access_iterator` concept [[iterator.concept.random.access]].
10225
+
10226
+ A `flat_map` meets all of the requirements of a container
10227
+ [[container.reqmts]] and of a reversible container
10228
+ [[container.rev.reqmts]], plus the optional container requirements
10229
+ [[container.opt.reqmts]]. `flat_map` meets the requirements of an
10230
+ associative container [[associative.reqmts]], except that:
10231
+
10232
+ - it does not meet the requirements related to node handles
10233
+ [[container.node]],
10234
+ - it does not meet the requirements related to iterator invalidation,
10235
+ and
10236
+ - the time complexity of the operations that insert or erase a single
10237
+ element from the map is linear, including the ones that take an
10238
+ insertion position iterator.
10239
+
10240
+ [*Note 1*: A `flat_map` does not meet the additional requirements of an
10241
+ allocator-aware container [[container.alloc.reqmts]]. — *end note*]
10242
+
10243
+ A `flat_map` also provides most operations described in
10244
+ [[associative.reqmts]] for unique keys. This means that a `flat_map`
10245
+ supports the `a_uniq` operations in [[associative.reqmts]] but not the
10246
+ `a_eq` operations. For a `flat_map<Key, T>` the `key_type` is `Key` and
10247
+ the `value_type` is `pair<Key, T>`.
10248
+
10249
+ Descriptions are provided here only for operations on `flat_map` that
10250
+ are not described in one of those sets of requirements or for operations
10251
+ where there is additional semantic information.
10252
+
10253
+ A `flat_map` maintains the following invariants:
10254
+
10255
+ - it contains the same number of keys and values;
10256
+ - the keys are sorted with respect to the comparison object; and
10257
+ - the value at offset `off` within the value container is the value
10258
+ associated with the key at offset `off` within the key container.
10259
+
10260
+ If any member function in [[flat.map.defn]] exits via an exception the
10261
+ invariants are restored.
10262
+
10263
+ [*Note 2*: This can result in the `flat_map` being
10264
+ emptied. — *end note*]
10265
+
10266
+ Any type `C` that meets the sequence container requirements
10267
+ [[sequence.reqmts]] can be used to instantiate `flat_map`, as long as
10268
+ `C::iterator` meets the *Cpp17RandomAccessIterator* requirements and
10269
+ invocations of member functions `C::size` and `C::max_size` do not exit
10270
+ via an exception. In particular, `vector` [[vector]] and `deque`
10271
+ [[deque]] can be used.
10272
+
10273
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
10274
+
10275
+ The program is ill-formed if `Key` is not the same type as
10276
+ `KeyContainer::value_type` or `T` is not the same type as
10277
+ `MappedContainer::value_type`.
10278
+
10279
+ The effect of calling a constructor that takes both `key_container_type`
10280
+ and `mapped_container_type` arguments with containers of different sizes
10281
+ is undefined.
10282
+
10283
+ The effect of calling a constructor or member function that takes a
10284
+ `sorted_unique_t` argument with a container, containers, or range that
10285
+ is not sorted with respect to `key_comp()`, or that contains equal
10286
+ elements, is undefined.
10287
+
10288
+ #### Definition <a id="flat.map.defn">[[flat.map.defn]]</a>
10289
+
10290
+ ``` cpp
10291
+ namespace std {
10292
+ template<class Key, class T, class Compare = less<Key>,
10293
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
10294
+ class flat_map {
10295
+ public:
10296
+ // types
10297
+ using key_type = Key;
10298
+ using mapped_type = T;
10299
+ using value_type = pair<key_type, mapped_type>;
10300
+ using key_compare = Compare;
10301
+ using reference = pair<const key_type&, mapped_type&>;
10302
+ using const_reference = pair<const key_type&, const mapped_type&>;
10303
+ using size_type = size_t;
10304
+ using difference_type = ptrdiff_t;
10305
+ using iterator = implementation-defined // type of flat_map::iterator; // see [container.requirements]
10306
+ using const_iterator = implementation-defined // type of flat_map::const_iterator; // see [container.requirements]
10307
+ using reverse_iterator = std::reverse_iterator<iterator>;
10308
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
10309
+ using key_container_type = KeyContainer;
10310
+ using mapped_container_type = MappedContainer;
10311
+
10312
+ class value_compare {
10313
+ private:
10314
+ key_compare comp; // exposition only
10315
+ value_compare(key_compare c) : comp(c) { } // exposition only
10316
+
10317
+ public:
10318
+ bool operator()(const_reference x, const_reference y) const {
10319
+ return comp(x.first, y.first);
10320
+ }
10321
+ };
10322
+
10323
+ struct containers {
10324
+ key_container_type keys;
10325
+ mapped_container_type values;
10326
+ };
10327
+
10328
+ // [flat.map.cons], construct/copy/destroy
10329
+ flat_map() : flat_map(key_compare()) { }
10330
+
10331
+ flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
10332
+ const key_compare& comp = key_compare());
10333
+ template<class Allocator>
10334
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10335
+ const Allocator& a);
10336
+ template<class Allocator>
10337
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10338
+ const key_compare& comp, const Allocator& a);
10339
+
10340
+ flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
10341
+ const key_compare& comp = key_compare());
10342
+ template<class Allocator>
10343
+ flat_map(sorted_unique_t, const key_container_type& key_cont,
10344
+ const mapped_container_type& mapped_cont, const Allocator& a);
10345
+ template<class Allocator>
10346
+ flat_map(sorted_unique_t, const key_container_type& key_cont,
10347
+ const mapped_container_type& mapped_cont,
10348
+ const key_compare& comp, const Allocator& a);
10349
+
10350
+ explicit flat_map(const key_compare& comp)
10351
+ : c(), compare(comp) { }
10352
+ template<class Allocator>
10353
+ flat_map(const key_compare& comp, const Allocator& a);
10354
+ template<class Allocator>
10355
+ explicit flat_map(const Allocator& a);
10356
+
10357
+ template<class InputIterator>
10358
+ flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
10359
+ : c(), compare(comp) { insert(first, last); }
10360
+ template<class InputIterator, class Allocator>
10361
+ flat_map(InputIterator first, InputIterator last,
10362
+ const key_compare& comp, const Allocator& a);
10363
+ template<class InputIterator, class Allocator>
10364
+ flat_map(InputIterator first, InputIterator last, const Allocator& a);
10365
+
10366
+ template<container-compatible-range<value_type> R>
10367
+ flat_map(from_range_t fr, R&& rg)
10368
+ : flat_map(fr, std::forward<R>(rg), key_compare()) { }
10369
+ template<container-compatible-range<value_type> R, class Allocator>
10370
+ flat_map(from_range_t, R&& rg, const Allocator& a);
10371
+ template<container-compatible-range<value_type> R>
10372
+ flat_map(from_range_t, R&& rg, const key_compare& comp)
10373
+ : flat_map(comp) { insert_range(std::forward<R>(rg)); }
10374
+ template<container-compatible-range<value_type> R, class Allocator>
10375
+ flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
10376
+
10377
+ template<class InputIterator>
10378
+ flat_map(sorted_unique_t s, InputIterator first, InputIterator last,
10379
+ const key_compare& comp = key_compare())
10380
+ : c(), compare(comp) { insert(s, first, last); }
10381
+ template<class InputIterator, class Allocator>
10382
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last,
10383
+ const key_compare& comp, const Allocator& a);
10384
+ template<class InputIterator, class Allocator>
10385
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
10386
+
10387
+ flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare())
10388
+ : flat_map(il.begin(), il.end(), comp) { }
10389
+ template<class Allocator>
10390
+ flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
10391
+ template<class Allocator>
10392
+ flat_map(initializer_list<value_type> il, const Allocator& a);
10393
+
10394
+ flat_map(sorted_unique_t s, initializer_list<value_type> il,
10395
+ const key_compare& comp = key_compare())
10396
+ : flat_map(s, il.begin(), il.end(), comp) { }
10397
+ template<class Allocator>
10398
+ flat_map(sorted_unique_t, initializer_list<value_type> il,
10399
+ const key_compare& comp, const Allocator& a);
10400
+ template<class Allocator>
10401
+ flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
10402
+
10403
+ flat_map& operator=(initializer_list<value_type> il);
10404
+
10405
+ // iterators
10406
+ iterator begin() noexcept;
10407
+ const_iterator begin() const noexcept;
10408
+ iterator end() noexcept;
10409
+ const_iterator end() const noexcept;
10410
+
10411
+ reverse_iterator rbegin() noexcept;
10412
+ const_reverse_iterator rbegin() const noexcept;
10413
+ reverse_iterator rend() noexcept;
10414
+ const_reverse_iterator rend() const noexcept;
10415
+
10416
+ const_iterator cbegin() const noexcept;
10417
+ const_iterator cend() const noexcept;
10418
+ const_reverse_iterator crbegin() const noexcept;
10419
+ const_reverse_iterator crend() const noexcept;
10420
+
10421
+ // [flat.map.capacity], capacity
10422
+ [[nodiscard]] bool empty() const noexcept;
10423
+ size_type size() const noexcept;
10424
+ size_type max_size() const noexcept;
10425
+
10426
+ // [flat.map.access], element access
10427
+ mapped_type& operator[](const key_type& x);
10428
+ mapped_type& operator[](key_type&& x);
10429
+ template<class K> mapped_type& operator[](K&& x);
10430
+ mapped_type& at(const key_type& x);
10431
+ const mapped_type& at(const key_type& x) const;
10432
+ template<class K> mapped_type& at(const K& x);
10433
+ template<class K> const mapped_type& at(const K& x) const;
10434
+
10435
+ // [flat.map.modifiers], modifiers
10436
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
10437
+ template<class... Args>
10438
+ iterator emplace_hint(const_iterator position, Args&&... args);
10439
+
10440
+ pair<iterator, bool> insert(const value_type& x)
10441
+ { return emplace(x); }
10442
+ pair<iterator, bool> insert(value_type&& x)
10443
+ { return emplace(std::move(x)); }
10444
+ iterator insert(const_iterator position, const value_type& x)
10445
+ { return emplace_hint(position, x); }
10446
+ iterator insert(const_iterator position, value_type&& x)
10447
+ { return emplace_hint(position, std::move(x)); }
10448
+
10449
+ template<class P> pair<iterator, bool> insert(P&& x);
10450
+ template<class P>
10451
+ iterator insert(const_iterator position, P&&);
10452
+ template<class InputIterator>
10453
+ void insert(InputIterator first, InputIterator last);
10454
+ template<class InputIterator>
10455
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
10456
+ template<container-compatible-range<value_type> R>
10457
+ void insert_range(R&& rg);
10458
+
10459
+ void insert(initializer_list<value_type> il)
10460
+ { insert(il.begin(), il.end()); }
10461
+ void insert(sorted_unique_t s, initializer_list<value_type> il)
10462
+ { insert(s, il.begin(), il.end()); }
10463
+
10464
+ containers extract() &&;
10465
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
10466
+
10467
+ template<class... Args>
10468
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
10469
+ template<class... Args>
10470
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
10471
+ template<class K, class... Args>
10472
+ pair<iterator, bool> try_emplace(K&& k, Args&&... args);
10473
+ template<class... Args>
10474
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
10475
+ template<class... Args>
10476
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
10477
+ template<class K, class... Args>
10478
+ iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
10479
+ template<class M>
10480
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
10481
+ template<class M>
10482
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
10483
+ template<class K, class M>
10484
+ pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
10485
+ template<class M>
10486
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
10487
+ template<class M>
10488
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
10489
+ template<class K, class M>
10490
+ iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
10491
+
10492
+ iterator erase(iterator position);
10493
+ iterator erase(const_iterator position);
10494
+ size_type erase(const key_type& x);
10495
+ template<class K> size_type erase(K&& x);
10496
+ iterator erase(const_iterator first, const_iterator last);
10497
+
10498
+ void swap(flat_map& y) noexcept;
10499
+ void clear() noexcept;
10500
+
10501
+ // observers
10502
+ key_compare key_comp() const;
10503
+ value_compare value_comp() const;
10504
+
10505
+ const key_container_type& keys() const noexcept { return c.keys; }
10506
+ const mapped_container_type& values() const noexcept { return c.values; }
10507
+
10508
+ // map operations
10509
+ iterator find(const key_type& x);
10510
+ const_iterator find(const key_type& x) const;
10511
+ template<class K> iterator find(const K& x);
10512
+ template<class K> const_iterator find(const K& x) const;
10513
+
10514
+ size_type count(const key_type& x) const;
10515
+ template<class K> size_type count(const K& x) const;
10516
+
10517
+ bool contains(const key_type& x) const;
10518
+ template<class K> bool contains(const K& x) const;
10519
+
10520
+ iterator lower_bound(const key_type& x);
10521
+ const_iterator lower_bound(const key_type& x) const;
10522
+ template<class K> iterator lower_bound(const K& x);
10523
+ template<class K> const_iterator lower_bound(const K& x) const;
10524
+
10525
+ iterator upper_bound(const key_type& x);
10526
+ const_iterator upper_bound(const key_type& x) const;
10527
+ template<class K> iterator upper_bound(const K& x);
10528
+ template<class K> const_iterator upper_bound(const K& x) const;
10529
+
10530
+ pair<iterator, iterator> equal_range(const key_type& x);
10531
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
10532
+ template<class K> pair<iterator, iterator> equal_range(const K& x);
10533
+ template<class K> pair<const_iterator, const_iterator> equal_range(const K& x) const;
10534
+
10535
+ friend bool operator==(const flat_map& x, const flat_map& y);
10536
+
10537
+ friend synth-three-way-result<value_type>
10538
+ operator<=>(const flat_map& x, const flat_map& y);
10539
+
10540
+ friend void swap(flat_map& x, flat_map& y) noexcept
10541
+ { x.swap(y); }
10542
+
10543
+ private:
10544
+ containers c; // exposition only
10545
+ key_compare compare; // exposition only
10546
+
10547
+ struct key_equiv { // exposition only
10548
+ key_equiv(key_compare c) : comp(c) { }
10549
+ bool operator()(const_reference x, const_reference y) const {
10550
+ return !comp(x.first, y.first) && !comp(y.first, x.first);
10551
+ }
10552
+ key_compare comp;
10553
+ };
10554
+ };
10555
+
10556
+ template<class KeyContainer, class MappedContainer,
10557
+ class Compare = less<typename KeyContainer::value_type>>
10558
+ flat_map(KeyContainer, MappedContainer, Compare = Compare())
10559
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10560
+ Compare, KeyContainer, MappedContainer>;
10561
+
10562
+ template<class KeyContainer, class MappedContainer, class Allocator>
10563
+ flat_map(KeyContainer, MappedContainer, Allocator)
10564
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10565
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
10566
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
10567
+ flat_map(KeyContainer, MappedContainer, Compare, Allocator)
10568
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10569
+ Compare, KeyContainer, MappedContainer>;
10570
+
10571
+ template<class KeyContainer, class MappedContainer,
10572
+ class Compare = less<typename KeyContainer::value_type>>
10573
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare = Compare())
10574
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10575
+ Compare, KeyContainer, MappedContainer>;
10576
+
10577
+ template<class KeyContainer, class MappedContainer, class Allocator>
10578
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Allocator)
10579
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10580
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
10581
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
10582
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare, Allocator)
10583
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
10584
+ Compare, KeyContainer, MappedContainer>;
10585
+
10586
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
10587
+ flat_map(InputIterator, InputIterator, Compare = Compare())
10588
+ -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
10589
+
10590
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
10591
+ flat_map(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
10592
+ -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
10593
+
10594
+ template<ranges::input_range R, class Compare = less<range-key-type<R>>,
10595
+ class Allocator = allocator<byte>>
10596
+ flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
10597
+ -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare,
10598
+ vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
10599
+ vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
10600
+
10601
+ template<ranges::input_range R, class Allocator>
10602
+ flat_map(from_range_t, R&&, Allocator)
10603
+ -> flat_map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
10604
+ vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
10605
+ vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
10606
+
10607
+ template<class Key, class T, class Compare = less<Key>>
10608
+ flat_map(initializer_list<pair<Key, T>>, Compare = Compare())
10609
+ -> flat_map<Key, T, Compare>;
10610
+
10611
+ template<class Key, class T, class Compare = less<Key>>
10612
+ flat_map(sorted_unique_t, initializer_list<pair<Key, T>>, Compare = Compare())
10613
+ -> flat_map<Key, T, Compare>;
10614
+
10615
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
10616
+ class Allocator>
10617
+ struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>, Allocator>
10618
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
10619
+ uses_allocator_v<MappedContainer, Allocator>> { };
10620
+ }
10621
+ ```
10622
+
10623
+ The member type `containers` has the data members and special members
10624
+ specified above. It has no base classes or members other than those
10625
+ specified.
10626
+
10627
+ #### Constructors <a id="flat.map.cons">[[flat.map.cons]]</a>
10628
+
10629
+ ``` cpp
10630
+ flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
10631
+ const key_compare& comp = key_compare());
10632
+ ```
10633
+
10634
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
10635
+ with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
10636
+ range \[`begin()`, `end()`) with respect to `value_comp()`; and finally
10637
+ erases the duplicate elements as if by:
10638
+
10639
+ ``` cpp
10640
+ auto zv = ranges::zip_view(c.keys, c.values);
10641
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
10642
+ auto dist = distance(zv.begin(), it);
10643
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
10644
+ c.values.erase(c.values.begin() + dist, c.values.end());
10645
+ ```
10646
+
10647
+ *Complexity:* Linear in N if the container arguments are already sorted
10648
+ with respect to `value_comp()` and otherwise N log N, where N is the
10649
+ value of `key_cont.size()` before this call.
10650
+
10651
+ ``` cpp
10652
+ template<class Allocator>
10653
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10654
+ const Allocator& a);
10655
+ template<class Allocator>
10656
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10657
+ const key_compare& comp, const Allocator& a);
10658
+ ```
10659
+
10660
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10661
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10662
+ `true`.
10663
+
10664
+ *Effects:* Equivalent to `flat_map(key_cont, mapped_cont)` and
10665
+ `flat_map(key_cont, mapped_cont, comp)`, respectively, except that
10666
+ `c.keys` and `c.values` are constructed with uses-allocator
10667
+ construction [[allocator.uses.construction]].
10668
+
10669
+ *Complexity:* Same as `flat_map(key_cont, mapped_cont)` and
10670
+ `flat_map(key_cont, mapped_cont, comp)`, respectively.
10671
+
10672
+ ``` cpp
10673
+ flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
10674
+ const key_compare& comp = key_compare());
10675
+ ```
10676
+
10677
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
10678
+ with `std::move(mapped_cont)`, and `compare` with `comp`.
10679
+
10680
+ *Complexity:* Constant.
10681
+
10682
+ ``` cpp
10683
+ template<class Allocator>
10684
+ flat_map(sorted_unique_t s, const key_container_type& key_cont,
10685
+ const mapped_container_type& mapped_cont, const Allocator& a);
10686
+ template<class Allocator>
10687
+ flat_map(sorted_unique_t s, const key_container_type& key_cont,
10688
+ const mapped_container_type& mapped_cont, const key_compare& comp,
10689
+ const Allocator& a);
10690
+ ```
10691
+
10692
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10693
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10694
+ `true`.
10695
+
10696
+ *Effects:* Equivalent to `flat_map(s, key_cont, mapped_cont)` and
10697
+ `flat_map(s, key_cont, mapped_cont, comp)`, respectively, except that
10698
+ `c.keys` and `c.values` are constructed with uses-allocator
10699
+ construction [[allocator.uses.construction]].
10700
+
10701
+ *Complexity:* Linear.
10702
+
10703
+ ``` cpp
10704
+ template<class Allocator>
10705
+ flat_map(const key_compare& comp, const Allocator& a);
10706
+ template<class Allocator>
10707
+ explicit flat_map(const Allocator& a);
10708
+ template<class InputIterator, class Allocator>
10709
+ flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
10710
+ template<class InputIterator, class Allocator>
10711
+ flat_map(InputIterator first, InputIterator last, const Allocator& a);
10712
+ template<container-compatible-range<value_type> R, class Allocator>
10713
+ flat_map(from_range_t, R&& rg, const Allocator& a);
10714
+ template<container-compatible-range<value_type> R, class Allocator>
10715
+ flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
10716
+ template<class InputIterator, class Allocator>
10717
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last,
10718
+ const key_compare& comp, const Allocator& a);
10719
+ template<class InputIterator, class Allocator>
10720
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
10721
+ template<class Allocator>
10722
+ flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
10723
+ template<class Allocator>
10724
+ flat_map(initializer_list<value_type> il, const Allocator& a);
10725
+ template<class Allocator>
10726
+ flat_map(sorted_unique_t, initializer_list<value_type> il,
10727
+ const key_compare& comp, const Allocator& a);
10728
+ template<class Allocator>
10729
+ flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
10730
+ ```
10731
+
10732
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10733
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10734
+ `true`.
10735
+
10736
+ *Effects:* Equivalent to the corresponding non-allocator constructors
10737
+ except that `c.keys` and `c.values` are constructed with uses-allocator
10738
+ construction [[allocator.uses.construction]].
10739
+
10740
+ #### Capacity <a id="flat.map.capacity">[[flat.map.capacity]]</a>
10741
+
10742
+ ``` cpp
10743
+ size_type size() const noexcept;
10744
+ ```
10745
+
10746
+ *Returns:* `c.keys.size()`.
10747
+
10748
+ ``` cpp
10749
+ size_type max_size() const noexcept;
10750
+ ```
10751
+
10752
+ *Returns:* `min<size_type>(c.keys.max_size(), c.values.max_size())`.
10753
+
10754
+ #### Access <a id="flat.map.access">[[flat.map.access]]</a>
10755
+
10756
+ ``` cpp
10757
+ mapped_type& operator[](const key_type& x);
10758
+ ```
10759
+
10760
+ *Effects:* Equivalent to: `return try_emplace(x).first->second;`
10761
+
10762
+ ``` cpp
10763
+ mapped_type& operator[](key_type&& x);
10764
+ ```
10765
+
10766
+ *Effects:* Equivalent to:
10767
+ `return try_emplace(std::move(x)).first->second;`
10768
+
10769
+ ``` cpp
10770
+ template<class K> mapped_type& operator[](K&& x);
10771
+ ```
10772
+
10773
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
10774
+ denotes a type.
10775
+
10776
+ *Effects:* Equivalent to:
10777
+ `return try_emplace(std::forward<K>(x)).first->second;`
10778
+
10779
+ ``` cpp
10780
+ mapped_type& at(const key_type& x);
10781
+ const mapped_type& at(const key_type& x) const;
10782
+ ```
10783
+
10784
+ *Returns:* A reference to the `mapped_type` corresponding to `x` in
10785
+ `*this`.
10786
+
10787
+ *Throws:* An exception object of type `out_of_range` if no such element
10788
+ is present.
10789
+
10790
+ *Complexity:* Logarithmic.
10791
+
10792
+ ``` cpp
10793
+ template<class K> mapped_type& at(const K& x);
10794
+ template<class K> const mapped_type& at(const K& x) const;
10795
+ ```
10796
+
10797
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
10798
+ denotes a type.
10799
+
10800
+ *Preconditions:* The expression `find(x)` is well-formed and has
10801
+ well-defined behavior.
10802
+
10803
+ *Returns:* A reference to the `mapped_type` corresponding to `x` in
10804
+ `*this`.
10805
+
10806
+ *Throws:* An exception object of type `out_of_range` if no such element
10807
+ is present.
10808
+
10809
+ *Complexity:* Logarithmic.
10810
+
10811
+ #### Modifiers <a id="flat.map.modifiers">[[flat.map.modifiers]]</a>
10812
+
10813
+ ``` cpp
10814
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
10815
+ ```
10816
+
10817
+ *Constraints:*
10818
+ `is_constructible_v<pair<key_type, mapped_type>, Args...>` is `true`.
10819
+
10820
+ *Effects:* Initializes an object `t` of type
10821
+ `pair<key_type, mapped_type>` with `std::forward<Args>(args)...`; if the
10822
+ map already contains an element whose key is equivalent to `t.first`,
10823
+ `*this` is unchanged. Otherwise, equivalent to:
10824
+
10825
+ ``` cpp
10826
+ auto key_it = ranges::upper_bound(c.keys, t.first, compare);
10827
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
10828
+ c.keys.insert(key_it, std::move(t.first));
10829
+ c.values.insert(value_it, std::move(t.second));
10830
+ ```
10831
+
10832
+ *Returns:* The `bool` component of the returned pair is `true` if and
10833
+ only if the insertion took place, and the iterator component of the pair
10834
+ points to the element with key equivalent to `t.first`.
10835
+
10836
+ ``` cpp
10837
+ template<class P> pair<iterator, bool> insert(P&& x);
10838
+ template<class P> iterator insert(const_iterator position, P&& x);
10839
+ ```
10840
+
10841
+ *Constraints:* `is_constructible_v<pair<key_type, mapped_type>, P>` is
10842
+ `true`.
10843
+
10844
+ *Effects:* The first form is equivalent to
10845
+ `return emplace(std::forward<P>(x));`. The second form is equivalent to
10846
+ `return emplace_hint(position, std::forward<P>(x));`.
10847
+
10848
+ ``` cpp
10849
+ template<class InputIterator>
10850
+ void insert(InputIterator first, InputIterator last);
10851
+ ```
10852
+
10853
+ *Effects:* Adds elements to `c` as if by:
10854
+
10855
+ ``` cpp
10856
+ for (; first != last; ++first) {
10857
+ value_type value = *first;
10858
+ c.keys.insert(c.keys.end(), std::move(value.first));
10859
+ c.values.insert(c.values.end(), std::move(value.second));
10860
+ }
10861
+ ```
10862
+
10863
+ Then, sorts the range of newly inserted elements with respect to
10864
+ `value_comp()`; merges the resulting sorted range and the sorted range
10865
+ of pre-existing elements into a single sorted range; and finally erases
10866
+ the duplicate elements as if by:
10867
+
10868
+ ``` cpp
10869
+ auto zv = ranges::zip_view(c.keys, c.values);
10870
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
10871
+ auto dist = distance(zv.begin(), it);
10872
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
10873
+ c.values.erase(c.values.begin() + dist, c.values.end());
10874
+ ```
10875
+
10876
+ *Complexity:* N + M log M, where N is `size()` before the operation and
10877
+ M is `distance(first, last)`.
10878
+
10879
+ *Remarks:* Since this operation performs an in-place merge, it may
10880
+ allocate memory.
10881
+
10882
+ ``` cpp
10883
+ template<class InputIterator>
10884
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
10885
+ ```
10886
+
10887
+ *Effects:* Adds elements to `c` as if by:
10888
+
10889
+ ``` cpp
10890
+ for (; first != last; ++first) {
10891
+ value_type value = *first;
10892
+ c.keys.insert(c.keys.end(), std::move(value.first));
10893
+ c.values.insert(c.values.end(), std::move(value.second));
10894
+ }
10895
+ ```
10896
+
10897
+ Then, merges the sorted range of newly added elements and the sorted
10898
+ range of pre-existing elements into a single sorted range; and finally
10899
+ erases the duplicate elements as if by:
10900
+
10901
+ ``` cpp
10902
+ auto zv = ranges::zip_view(c.keys, c.values);
10903
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
10904
+ auto dist = distance(zv.begin(), it);
10905
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
10906
+ c.values.erase(c.values.begin() + dist, c.values.end());
10907
+ ```
10908
+
10909
+ *Complexity:* Linear in N, where N is `size()` after the operation.
10910
+
10911
+ *Remarks:* Since this operation performs an in-place merge, it may
10912
+ allocate memory.
10913
+
10914
+ ``` cpp
10915
+ template<container-compatible-range<value_type> R>
10916
+ void insert_range(R&& rg);
10917
+ ```
10918
+
10919
+ *Effects:* Adds elements to `c` as if by:
10920
+
10921
+ ``` cpp
10922
+ for (const auto& e : rg) {
10923
+ c.keys.insert(c.keys.end(), e.first);
10924
+ c.values.insert(c.values.end(), e.second);
10925
+ }
10926
+ ```
10927
+
10928
+ Then, sorts the range of newly inserted elements with respect to
10929
+ `value_comp()`; merges the resulting sorted range and the sorted range
10930
+ of pre-existing elements into a single sorted range; and finally erases
10931
+ the duplicate elements as if by:
10932
+
10933
+ ``` cpp
10934
+ auto zv = ranges::zip_view(c.keys, c.values);
10935
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
10936
+ auto dist = distance(zv.begin(), it);
10937
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
10938
+ c.values.erase(c.values.begin() + dist, c.values.end());
10939
+ ```
10940
+
10941
+ *Complexity:* N + M log M, where N is `size()` before the operation and
10942
+ M is `ranges::distance(rg)`.
10943
+
10944
+ *Remarks:* Since this operation performs an in-place merge, it may
10945
+ allocate memory.
10946
+
10947
+ ``` cpp
10948
+ template<class... Args>
10949
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
10950
+ template<class... Args>
10951
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
10952
+ template<class... Args>
10953
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
10954
+ template<class... Args>
10955
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
10956
+ ```
10957
+
10958
+ *Constraints:* `is_constructible_v<mapped_type, Args...>` is `true`.
10959
+
10960
+ *Effects:* If the map already contains an element whose key is
10961
+ equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
10962
+ equivalent to:
10963
+
10964
+ ``` cpp
10965
+ auto key_it = ranges::upper_bound(c.keys, k, compare);
10966
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
10967
+ c.keys.insert(key_it, std::forward<decltype(k)>(k));
10968
+ c.values.emplace(value_it, std::forward<Args>(args)...);
10969
+ ```
10970
+
10971
+ *Returns:* In the first two overloads, the `bool` component of the
10972
+ returned pair is `true` if and only if the insertion took place. The
10973
+ returned iterator points to the map element whose key is equivalent to
10974
+ `k`.
10975
+
10976
+ *Complexity:* The same as `emplace` for the first two overloads, and the
10977
+ same as `emplace_hint` for the last two overloads.
10978
+
10979
+ ``` cpp
10980
+ template<class K, class... Args>
10981
+ pair<iterator, bool> try_emplace(K&& k, Args&&... args);
10982
+ template<class K, class... Args>
10983
+ iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
10984
+ ```
10985
+
10986
+ *Constraints:*
10987
+
10988
+ - The *qualified-id* `Compare::is_transparent` is valid and denotes a
10989
+ type.
10990
+ - `is_constructible_v<key_type, K>` is `true`.
10991
+ - `is_constructible_v<mapped_type, Args...>` is `true`.
10992
+ - For the first overload, `is_convertible_v<K&&, const_iterator>` and
10993
+ `is_convertible_v<K&&, iterator>` are both `false`.
10994
+
10995
+ *Preconditions:* The conversion from `k` into `key_type` constructs an
10996
+ object `u`, for which `find(k) == find(u)` is `true`.
10997
+
10998
+ *Effects:* If the map already contains an element whose key is
10999
+ equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
11000
+ equivalent to:
11001
+
11002
+ ``` cpp
11003
+ auto key_it = ranges::upper_bound(c.keys, k, compare);
11004
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
11005
+ c.keys.emplace(key_it, std::forward<K>(k));
11006
+ c.values.emplace(value_it, std::forward<Args>(args)...);
11007
+ ```
11008
+
11009
+ *Returns:* In the first overload, the `bool` component of the returned
11010
+ pair is `true` if and only if the insertion took place. The returned
11011
+ iterator points to the map element whose key is equivalent to `k`.
11012
+
11013
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
11014
+
11015
+ ``` cpp
11016
+ template<class M>
11017
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
11018
+ template<class M>
11019
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
11020
+ template<class M>
11021
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
11022
+ template<class M>
11023
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
11024
+ ```
11025
+
11026
+ *Constraints:* `is_assignable_v<mapped_type&, M>` is `true` and
11027
+ `is_constructible_v<mapped_type, M>` is `true`.
11028
+
11029
+ *Effects:* If the map already contains an element `e` whose key is
11030
+ equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
11031
+ Otherwise, equivalent to
11032
+
11033
+ ``` cpp
11034
+ try_emplace(std::forward<decltype(k)>(k), std::forward<M>(obj))
11035
+ ```
11036
+
11037
+ for the first two overloads or
11038
+
11039
+ ``` cpp
11040
+ try_emplace(hint, std::forward<decltype(k)>(k), std::forward<M>(obj))
11041
+ ```
11042
+
11043
+ for the last two overloads.
11044
+
11045
+ *Returns:* In the first two overloads, the `bool` component of the
11046
+ returned pair is `true` if and only if the insertion took place. The
11047
+ returned iterator points to the map element whose key is equivalent to
11048
+ `k`.
11049
+
11050
+ *Complexity:* The same as `emplace` for the first two overloads and the
11051
+ same as `emplace_hint` for the last two overloads.
11052
+
11053
+ ``` cpp
11054
+ template<class K, class M>
11055
+ pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
11056
+ template<class K, class M>
11057
+ iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
11058
+ ```
11059
+
11060
+ *Constraints:*
11061
+
11062
+ - The *qualified-id* `Compare::is_transparent` is valid and denotes a
11063
+ type.
11064
+ - `is_constructible_v<key_type, K>` is `true`.
11065
+ - `is_assignable_v<mapped_type&, M>` is `true`.
11066
+ - `is_constructible_v<mapped_type, M>` is `true`.
11067
+
11068
+ *Preconditions:* The conversion from `k` into `key_type` constructs an
11069
+ object `u`, for which `find(k) == find(u)` is `true`.
11070
+
11071
+ *Effects:* If the map already contains an element `e` whose key is
11072
+ equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
11073
+ Otherwise, equivalent to
11074
+
11075
+ ``` cpp
11076
+ try_emplace(std::forward<K>(k), std::forward<M>(obj))
11077
+ ```
11078
+
11079
+ for the first overload or
11080
+
11081
+ ``` cpp
11082
+ try_emplace(hint, std::forward<K>(k), std::forward<M>(obj))
11083
+ ```
11084
+
11085
+ for the second overload.
11086
+
11087
+ *Returns:* In the first overload, the `bool` component of the returned
11088
+ pair is `true` if and only if the insertion took place. The returned
11089
+ iterator points to the map element whose key is equivalent to `k`.
11090
+
11091
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
11092
+
11093
+ ``` cpp
11094
+ void swap(flat_map& y) noexcept;
11095
+ ```
11096
+
11097
+ *Effects:* Equivalent to:
11098
+
11099
+ ``` cpp
11100
+ ranges::swap(compare, y.compare);
11101
+ ranges::swap(c.keys, y.c.keys);
11102
+ ranges::swap(c.values, y.c.values);
11103
+ ```
11104
+
11105
+ ``` cpp
11106
+ containers extract() &&;
11107
+ ```
11108
+
11109
+ *Ensures:* `*this` is emptied, even if the function exits via an
11110
+ exception.
11111
+
11112
+ *Returns:* `std::move(c)`.
11113
+
11114
+ ``` cpp
11115
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
11116
+ ```
11117
+
11118
+ *Preconditions:* `key_cont.size() == mapped_cont.size()` is `true`, the
11119
+ elements of `key_cont` are sorted with respect to `compare`, and
11120
+ `key_cont` contains no equal elements.
11121
+
11122
+ *Effects:* Equivalent to:
11123
+
11124
+ ``` cpp
11125
+ c.keys = std::move(key_cont);
11126
+ c.values = std::move(mapped_cont);
11127
+ ```
11128
+
11129
+ #### Erasure <a id="flat.map.erasure">[[flat.map.erasure]]</a>
11130
+
11131
+ ``` cpp
11132
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11133
+ class Predicate>
11134
+ typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11135
+ erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11136
+ ```
11137
+
11138
+ *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
11139
+ requirements.
11140
+
11141
+ *Effects:* Let E be `bool(pred(pair<const Key&, const T&>(e)))`. Erases
11142
+ all elements `e` in `c` for which E holds.
11143
+
11144
+ *Returns:* The number of elements erased.
11145
+
11146
+ *Complexity:* Exactly `c.size()` applications of the predicate.
11147
+
11148
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
11149
+ exits via an exception, `c` is in a valid but unspecified
11150
+ state [[defns.valid]].
11151
+
11152
+ [*Note 1*: `c` still meets its invariants, but can be
11153
+ empty. — *end note*]
11154
+
11155
+ ### Class template `flat_multimap` <a id="flat.multimap">[[flat.multimap]]</a>
11156
+
11157
+ #### Overview <a id="flat.multimap.overview">[[flat.multimap.overview]]</a>
11158
+
11159
+ A `flat_multimap` is a container adaptor that provides an associative
11160
+ container interface that supports equivalent keys (i.e., possibly
11161
+ containing multiple copies of the same key value) and provides for fast
11162
+ retrieval of values of another type `T` based on the keys.
11163
+ `flat_multimap` supports iterators that meet the *Cpp17InputIterator*
11164
+ requirements and model the `random_access_iterator` concept
11165
+ [[iterator.concept.random.access]].
11166
+
11167
+ A `flat_multimap` meets all of the requirements for a container
11168
+ [[container.reqmts]] and for a reversible container
11169
+ [[container.rev.reqmts]], plus the optional container requirements
11170
+ [[container.opt.reqmts]]. `flat_multimap` meets the requirements of an
11171
+ associative container [[associative.reqmts]], except that:
11172
+
11173
+ - it does not meet the requirements related to node handles
11174
+ [[container.node]],
11175
+ - it does not meet the requirements related to iterator invalidation,
11176
+ and
11177
+ - the time complexity of the operations that insert or erase a single
11178
+ element from the map is linear, including the ones that take an
11179
+ insertion position iterator.
11180
+
11181
+ [*Note 1*: A `flat_multimap` does not meet the additional requirements
11182
+ of an allocator-aware container
11183
+ [[container.alloc.reqmts]]. — *end note*]
11184
+
11185
+ A `flat_multimap` also provides most operations described in
11186
+ [[associative.reqmts]] for equal keys. This means that a `flat_multimap`
11187
+ supports the `a_eq` operations in [[associative.reqmts]] but not the
11188
+ `a_uniq` operations. For a `flat_multimap<Key, T>` the `key_type` is
11189
+ `Key` and the `value_type` is `pair<Key, T>`.
11190
+
11191
+ Except as otherwise noted, operations on `flat_multimap` are equivalent
11192
+ to those of `flat_map`, except that `flat_multimap` operations do not
11193
+ remove or replace elements with equal keys.
11194
+
11195
+ [*Example 1*: `flat_multimap` constructors and emplace do not erase
11196
+ non-unique elements after sorting them. — *end example*]
11197
+
11198
+ A `flat_multimap` maintains the following invariants:
11199
+
11200
+ - it contains the same number of keys and values;
11201
+ - the keys are sorted with respect to the comparison object; and
11202
+ - the value at offset `off` within the value container is the value
11203
+ associated with the key at offset `off` within the key container.
11204
+
11205
+ If any member function in [[flat.multimap.defn]] exits via an exception,
11206
+ the invariants are restored.
11207
+
11208
+ [*Note 2*: This can result in the `flat_multimap` being
11209
+ emptied. — *end note*]
11210
+
11211
+ Any type `C` that meets the sequence container requirements
11212
+ [[sequence.reqmts]] can be used to instantiate `flat_multimap`, as long
11213
+ as `C::iterator` meets the *Cpp17RandomAccessIterator* requirements and
11214
+ invocations of member functions `C::size` and `C::max_size` do not exit
11215
+ via an exception. In particular, `vector` [[vector]] and `deque`
11216
+ [[deque]] can be used.
11217
+
11218
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
11219
+
11220
+ The program is ill-formed if `Key` is not the same type as
11221
+ `KeyContainer::value_type` or `T` is not the same type as
11222
+ `MappedContainer::value_type`.
11223
+
11224
+ The effect of calling a constructor that takes both `key_container_type`
11225
+ and `mapped_container_type` arguments with containers of different sizes
11226
+ is undefined.
11227
+
11228
+ The effect of calling a constructor or member function that takes a
11229
+ `sorted_equivalent_t` argument with a container, containers, or range
11230
+ that are not sorted with respect to `key_comp()` is undefined.
11231
+
11232
+ #### Definition <a id="flat.multimap.defn">[[flat.multimap.defn]]</a>
11233
+
11234
+ ``` cpp
11235
+ namespace std {
11236
+ template<class Key, class T, class Compare = less<Key>,
11237
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
11238
+ class flat_multimap {
11239
+ public:
11240
+ // types
11241
+ using key_type = Key;
11242
+ using mapped_type = T;
11243
+ using value_type = pair<key_type, mapped_type>;
11244
+ using key_compare = Compare;
11245
+ using reference = pair<const key_type&, mapped_type&>;
11246
+ using const_reference = pair<const key_type&, const mapped_type&>;
11247
+ using size_type = size_t;
11248
+ using difference_type = ptrdiff_t;
11249
+ using iterator = implementation-defined // type of flat_multimap::iterator; // see [container.requirements]
11250
+ using const_iterator = implementation-defined // type of flat_multimap::const_iterator; // see [container.requirements]
11251
+ using reverse_iterator = std::reverse_iterator<iterator>;
11252
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
11253
+ using key_container_type = KeyContainer;
11254
+ using mapped_container_type = MappedContainer;
11255
+
11256
+ class value_compare {
11257
+ private:
11258
+ key_compare comp; // exposition only
11259
+ value_compare(key_compare c) : comp(c) { } // exposition only
11260
+
11261
+ public:
11262
+ bool operator()(const_reference x, const_reference y) const {
11263
+ return comp(x.first, y.first);
11264
+ }
11265
+ };
11266
+
11267
+ struct containers {
11268
+ key_container_type keys;
11269
+ mapped_container_type values;
11270
+ };
11271
+
11272
+ // [flat.multimap.cons], construct/copy/destroy
11273
+ flat_multimap() : flat_multimap(key_compare()) { }
11274
+
11275
+ flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
11276
+ const key_compare& comp = key_compare());
11277
+ template<class Allocator>
11278
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11279
+ const Allocator& a);
11280
+ template<class Allocator>
11281
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11282
+ const key_compare& comp, const Allocator& a);
11283
+
11284
+ flat_multimap(sorted_equivalent_t,
11285
+ key_container_type key_cont, mapped_container_type mapped_cont,
11286
+ const key_compare& comp = key_compare());
11287
+ template<class Allocator>
11288
+ flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
11289
+ const mapped_container_type& mapped_cont, const Allocator& a);
11290
+ template<class Allocator>
11291
+ flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
11292
+ const mapped_container_type& mapped_cont,
11293
+ const key_compare& comp, const Allocator& a);
11294
+
11295
+ explicit flat_multimap(const key_compare& comp)
11296
+ : c(), compare(comp) { }
11297
+ template<class Allocator>
11298
+ flat_multimap(const key_compare& comp, const Allocator& a);
11299
+ template<class Allocator>
11300
+ explicit flat_multimap(const Allocator& a);
11301
+
11302
+ template<class InputIterator>
11303
+ flat_multimap(InputIterator first, InputIterator last,
11304
+ const key_compare& comp = key_compare())
11305
+ : c(), compare(comp)
11306
+ { insert(first, last); }
11307
+ template<class InputIterator, class Allocator>
11308
+ flat_multimap(InputIterator first, InputIterator last,
11309
+ const key_compare& comp, const Allocator& a);
11310
+ template<class InputIterator, class Allocator>
11311
+ flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
11312
+
11313
+ template<container-compatible-range<value_type> R>
11314
+ flat_multimap(from_range_t fr, R&& rg)
11315
+ : flat_multimap(fr, std::forward<R>(rg), key_compare()) { }
11316
+ template<container-compatible-range<value_type> R, class Allocator>
11317
+ flat_multimap(from_range_t, R&& rg, const Allocator& a);
11318
+ template<container-compatible-range<value_type> R>
11319
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp)
11320
+ : flat_multimap(comp) { insert_range(std::forward<R>(rg)); }
11321
+ template<container-compatible-range<value_type> R, class Allocator>
11322
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11323
+
11324
+ template<class InputIterator>
11325
+ flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last,
11326
+ const key_compare& comp = key_compare())
11327
+ : c(), compare(comp) { insert(s, first, last); }
11328
+ template<class InputIterator, class Allocator>
11329
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11330
+ const key_compare& comp, const Allocator& a);
11331
+ template<class InputIterator, class Allocator>
11332
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11333
+ const Allocator& a);
11334
+
11335
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare())
11336
+ : flat_multimap(il.begin(), il.end(), comp) { }
11337
+ template<class Allocator>
11338
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp,
11339
+ const Allocator& a);
11340
+ template<class Allocator>
11341
+ flat_multimap(initializer_list<value_type> il, const Allocator& a);
11342
+
11343
+ flat_multimap(sorted_equivalent_t s, initializer_list<value_type> il,
11344
+ const key_compare& comp = key_compare())
11345
+ : flat_multimap(s, il.begin(), il.end(), comp) { }
11346
+ template<class Allocator>
11347
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
11348
+ const key_compare& comp, const Allocator& a);
11349
+ template<class Allocator>
11350
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
11351
+
11352
+ flat_multimap& operator=(initializer_list<value_type> il);
11353
+
11354
+ // iterators
11355
+ iterator begin() noexcept;
11356
+ const_iterator begin() const noexcept;
11357
+ iterator end() noexcept;
11358
+ const_iterator end() const noexcept;
11359
+
11360
+ reverse_iterator rbegin() noexcept;
11361
+ const_reverse_iterator rbegin() const noexcept;
11362
+ reverse_iterator rend() noexcept;
11363
+ const_reverse_iterator rend() const noexcept;
11364
+
11365
+ const_iterator cbegin() const noexcept;
11366
+ const_iterator cend() const noexcept;
11367
+ const_reverse_iterator crbegin() const noexcept;
11368
+ const_reverse_iterator crend() const noexcept;
11369
+
11370
+ // capacity
11371
+ [[nodiscard]] bool empty() const noexcept;
11372
+ size_type size() const noexcept;
11373
+ size_type max_size() const noexcept;
11374
+
11375
+ // modifiers
11376
+ template<class... Args> iterator emplace(Args&&... args);
11377
+ template<class... Args>
11378
+ iterator emplace_hint(const_iterator position, Args&&... args);
11379
+
11380
+ iterator insert(const value_type& x)
11381
+ { return emplace(x); }
11382
+ iterator insert(value_type&& x)
11383
+ { return emplace(std::move(x)); }
11384
+ iterator insert(const_iterator position, const value_type& x)
11385
+ { return emplace_hint(position, x); }
11386
+ iterator insert(const_iterator position, value_type&& x)
11387
+ { return emplace_hint(position, std::move(x)); }
11388
+
11389
+ template<class P> iterator insert(P&& x);
11390
+ template<class P>
11391
+ iterator insert(const_iterator position, P&&);
11392
+ template<class InputIterator>
11393
+ void insert(InputIterator first, InputIterator last);
11394
+ template<class InputIterator>
11395
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
11396
+ template<container-compatible-range<value_type> R>
11397
+ void insert_range(R&& rg);
11398
+
11399
+ void insert(initializer_list<value_type> il)
11400
+ { insert(il.begin(), il.end()); }
11401
+ void insert(sorted_equivalent_t s, initializer_list<value_type> il)
11402
+ { insert(s, il.begin(), il.end()); }
11403
+
11404
+ containers extract() &&;
11405
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
11406
+
11407
+ iterator erase(iterator position);
11408
+ iterator erase(const_iterator position);
11409
+ size_type erase(const key_type& x);
11410
+ template<class K> size_type erase(K&& x);
11411
+ iterator erase(const_iterator first, const_iterator last);
11412
+
11413
+ void swap(flat_multimap&) noexcept;
11414
+ void clear() noexcept;
11415
+
11416
+ // observers
11417
+ key_compare key_comp() const;
11418
+ value_compare value_comp() const;
11419
+
11420
+ const key_container_type& keys() const noexcept { return c.keys; }
11421
+ const mapped_container_type& values() const noexcept { return c.values; }
11422
+
11423
+ // map operations
11424
+ iterator find(const key_type& x);
11425
+ const_iterator find(const key_type& x) const;
11426
+ template<class K> iterator find(const K& x);
11427
+ template<class K> const_iterator find(const K& x) const;
11428
+
11429
+ size_type count(const key_type& x) const;
11430
+ template<class K> size_type count(const K& x) const;
11431
+
11432
+ bool contains(const key_type& x) const;
11433
+ template<class K> bool contains(const K& x) const;
11434
+
11435
+ iterator lower_bound(const key_type& x);
11436
+ const_iterator lower_bound(const key_type& x) const;
11437
+ template<class K> iterator lower_bound(const K& x);
11438
+ template<class K> const_iterator lower_bound(const K& x) const;
11439
+
11440
+ iterator upper_bound(const key_type& x);
11441
+ const_iterator upper_bound(const key_type& x) const;
11442
+ template<class K> iterator upper_bound(const K& x);
11443
+ template<class K> const_iterator upper_bound(const K& x) const;
11444
+
11445
+ pair<iterator, iterator> equal_range(const key_type& x);
11446
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
11447
+ template<class K>
11448
+ pair<iterator, iterator> equal_range(const K& x);
11449
+ template<class K>
11450
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
11451
+
11452
+ friend bool operator==(const flat_multimap& x, const flat_multimap& y);
11453
+
11454
+ friend synth-three-way-result<value_type>
11455
+ operator<=>(const flat_multimap& x, const flat_multimap& y);
11456
+
11457
+ friend void swap(flat_multimap& x, flat_multimap& y) noexcept
11458
+ { x.swap(y); }
11459
+
11460
+ private:
11461
+ containers c; // exposition only
11462
+ key_compare compare; // exposition only
11463
+ };
11464
+
11465
+ template<class KeyContainer, class MappedContainer,
11466
+ class Compare = less<typename KeyContainer::value_type>>
11467
+ flat_multimap(KeyContainer, MappedContainer, Compare = Compare())
11468
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11469
+ Compare, KeyContainer, MappedContainer>;
11470
+
11471
+ template<class KeyContainer, class MappedContainer, class Allocator>
11472
+ flat_multimap(KeyContainer, MappedContainer, Allocator)
11473
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11474
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
11475
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
11476
+ flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)
11477
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11478
+ Compare, KeyContainer, MappedContainer>;
11479
+
11480
+ template<class KeyContainer, class MappedContainer,
11481
+ class Compare = less<typename KeyContainer::value_type>>
11482
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())
11483
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11484
+ Compare, KeyContainer, MappedContainer>;
11485
+
11486
+ template<class KeyContainer, class MappedContainer, class Allocator>
11487
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)
11488
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11489
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
11490
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
11491
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)
11492
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
11493
+ Compare, KeyContainer, MappedContainer>;
11494
+
11495
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
11496
+ flat_multimap(InputIterator, InputIterator, Compare = Compare())
11497
+ -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
11498
+
11499
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
11500
+ flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
11501
+ -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
11502
+
11503
+ template<ranges::input_range R, class Compare = less<range-key-type<R>>,
11504
+ class Allocator = allocator<byte>>
11505
+ flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
11506
+ -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare,
11507
+ vector<range-key-type<R>,
11508
+ alloc-rebind<Allocator, range-key-type<R>>>,
11509
+ vector<range-mapped-type<R>,
11510
+ alloc-rebind<Allocator, range-mapped-type<R>>>>;
11511
+
11512
+ template<ranges::input_range R, class Allocator>
11513
+ flat_multimap(from_range_t, R&&, Allocator)
11514
+ -> flat_multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
11515
+ vector<range-key-type<R>,
11516
+ alloc-rebind<Allocator, range-key-type<R>>>,
11517
+ vector<range-mapped-type<R>,
11518
+ alloc-rebind<Allocator, range-mapped-type<R>>>>;
11519
+
11520
+ template<class Key, class T, class Compare = less<Key>>
11521
+ flat_multimap(initializer_list<pair<Key, T>>, Compare = Compare())
11522
+ -> flat_multimap<Key, T, Compare>;
11523
+
11524
+ template<class Key, class T, class Compare = less<Key>>
11525
+ flat_multimap(sorted_equivalent_t, initializer_list<pair<Key, T>>, Compare = Compare())
11526
+ -> flat_multimap<Key, T, Compare>;
11527
+
11528
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11529
+ class Allocator>
11530
+ struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
11531
+ Allocator>
11532
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
11533
+ uses_allocator_v<MappedContainer, Allocator>> { };
11534
+ }
11535
+ ```
11536
+
11537
+ The member type `containers` has the data members and special members
11538
+ specified above. It has no base classes or members other than those
11539
+ specified.
11540
+
11541
+ #### Constructors <a id="flat.multimap.cons">[[flat.multimap.cons]]</a>
11542
+
11543
+ ``` cpp
11544
+ flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
11545
+ const key_compare& comp = key_compare());
11546
+ ```
11547
+
11548
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
11549
+ with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
11550
+ range \[`begin()`, `end()`) with respect to `value_comp()`.
11551
+
11552
+ *Complexity:* Linear in N if the container arguments are already sorted
11553
+ with respect to `value_comp()` and otherwise N log N, where N is the
11554
+ value of `key_cont.size()` before this call.
11555
+
11556
+ ``` cpp
11557
+ template<class Allocator>
11558
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11559
+ const Allocator& a);
11560
+ template<class Allocator>
11561
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11562
+ const key_compare& comp, const Allocator& a);
11563
+ ```
11564
+
11565
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11566
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11567
+ `true`.
11568
+
11569
+ *Effects:* Equivalent to `flat_multimap(key_cont, mapped_cont)` and
11570
+ `flat_multimap(key_cont, mapped_cont, comp)`, respectively, except that
11571
+ `c.keys` and `c.values` are constructed with uses-allocator
11572
+ construction [[allocator.uses.construction]].
11573
+
11574
+ *Complexity:* Same as `flat_multimap(key_cont, mapped_cont)` and
11575
+ `flat_multimap(key_cont, mapped_cont, comp)`, respectively.
11576
+
11577
+ ``` cpp
11578
+ flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont,
11579
+ const key_compare& comp = key_compare());
11580
+ ```
11581
+
11582
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
11583
+ with `std::move(mapped_cont)`, and `compare` with `comp`.
11584
+
11585
+ *Complexity:* Constant.
11586
+
11587
+ ``` cpp
11588
+ template<class Allocator>
11589
+ flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
11590
+ const mapped_container_type& mapped_cont, const Allocator& a);
11591
+ template<class Allocator>
11592
+ flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
11593
+ const mapped_container_type& mapped_cont, const key_compare& comp,
11594
+ const Allocator& a);
11595
+ ```
11596
+
11597
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11598
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11599
+ `true`.
11600
+
11601
+ *Effects:* Equivalent to `flat_multimap(s, key_cont, mapped_cont)` and
11602
+ `flat_multimap(s, key_cont, mapped_cont, comp)`, respectively, except
11603
+ that `c.keys` and `c.values` are constructed with uses-allocator
11604
+ construction [[allocator.uses.construction]].
11605
+
11606
+ *Complexity:* Linear.
11607
+
11608
+ ``` cpp
11609
+ template<class Allocator>
11610
+ flat_multimap(const key_compare& comp, const Allocator& a);
11611
+ template<class Allocator>
11612
+ explicit flat_multimap(const Allocator& a);
11613
+ template<class InputIterator, class Allocator>
11614
+ flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
11615
+ const Allocator& a);
11616
+ template<class InputIterator, class Allocator>
11617
+ flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
11618
+ template<container-compatible-range<value_type> R, class Allocator>
11619
+ flat_multimap(from_range_t, R&& rg, const Allocator& a);
11620
+ template<container-compatible-range<value_type> R, class Allocator>
11621
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11622
+ template<class InputIterator, class Allocator>
11623
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11624
+ const key_compare& comp, const Allocator& a);
11625
+ template<class InputIterator, class Allocator>
11626
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11627
+ const Allocator& a);
11628
+ template<class Allocator>
11629
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
11630
+ template<class Allocator>
11631
+ flat_multimap(initializer_list<value_type> il, const Allocator& a);
11632
+ template<class Allocator>
11633
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
11634
+ const key_compare& comp, const Allocator& a);
11635
+ template<class Allocator>
11636
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
11637
+ ```
11638
+
11639
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11640
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11641
+ `true`.
11642
+
11643
+ *Effects:* Equivalent to the corresponding non-allocator constructors
11644
+ except that `c.keys` and `c.values` are constructed with uses-allocator
11645
+ construction [[allocator.uses.construction]].
11646
+
11647
+ #### Erasure <a id="flat.multimap.erasure">[[flat.multimap.erasure]]</a>
11648
+
11649
+ ``` cpp
11650
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11651
+ class Predicate>
11652
+ typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11653
+ erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11654
+ ```
11655
+
11656
+ *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
11657
+ requirements.
11658
+
11659
+ *Effects:* Let E be `bool(pred(pair<const Key&, const T&>(e)))`. Erases
11660
+ all elements `e` in `c` for which E holds.
11661
+
11662
+ *Returns:* The number of elements erased.
11663
+
11664
+ *Complexity:* Exactly `c.size()` applications of the predicate.
11665
+
11666
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
11667
+ exits via an exception, `c` is in a valid but unspecified
11668
+ state [[defns.valid]].
11669
+
11670
+ [*Note 1*: `c` still meets its invariants, but can be
11671
+ empty. — *end note*]
11672
+
11673
+ ### Class template `flat_set` <a id="flat.set">[[flat.set]]</a>
11674
+
11675
+ #### Overview <a id="flat.set.overview">[[flat.set.overview]]</a>
11676
+
11677
+ A `flat_set` is a container adaptor that provides an associative
11678
+ container interface that supports unique keys (i.e., contains at most
11679
+ one of each key value) and provides for fast retrieval of the keys
11680
+ themselves. `flat_set` supports iterators that model the
11681
+ `random_access_iterator` concept [[iterator.concept.random.access]].
11682
+
11683
+ A `flat_set` meets all of the requirements for a container
11684
+ [[container.reqmts]] and for a reversible container
11685
+ [[container.rev.reqmts]], plus the optional container requirements
11686
+ [[container.opt.reqmts]]. `flat_set` meets the requirements of an
11687
+ associative container [[associative.reqmts]], except that:
11688
+
11689
+ - it does not meet the requirements related to node handles
11690
+ [[container.node.overview]],
11691
+ - it does not meet the requirements related to iterator invalidation,
11692
+ and
11693
+ - the time complexity of the operations that insert or erase a single
11694
+ element from the set is linear, including the ones that take an
11695
+ insertion position iterator.
11696
+
11697
+ [*Note 1*: A `flat_set` does not meet the additional requirements of an
11698
+ allocator-aware container, as described in
11699
+ [[container.alloc.reqmts]]. — *end note*]
11700
+
11701
+ A `flat_set` also provides most operations described in
11702
+ [[associative.reqmts]] for unique keys. This means that a `flat_set`
11703
+ supports the `a_uniq` operations in [[associative.reqmts]] but not the
11704
+ `a_eq` operations. For a `flat_set<Key>`, both the `key_type` and
11705
+ `value_type` are `Key`.
11706
+
11707
+ Descriptions are provided here only for operations on `flat_set` that
11708
+ are not described in one of those sets of requirements or for operations
11709
+ where there is additional semantic information.
11710
+
11711
+ A `flat_set` maintains the invariant that the keys are sorted with
11712
+ respect to the comparison object.
11713
+
11714
+ If any member function in [[flat.set.defn]] exits via an exception, the
11715
+ invariant is restored.
11716
+
11717
+ [*Note 2*: This can result in the `flat_set`’s being
11718
+ emptied. — *end note*]
11719
+
11720
+ Any sequence container [[sequence.reqmts]] supporting
11721
+ *Cpp17RandomAccessIterator* can be used to instantiate `flat_set`. In
11722
+ particular, `vector` [[vector]] and `deque` [[deque]] can be used.
11723
+
11724
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
11725
+
11726
+ The program is ill-formed if `Key` is not the same type as
11727
+ `KeyContainer::value_type`.
11728
+
11729
+ The effect of calling a constructor or member function that takes a
11730
+ `sorted_unique_t` argument with a range that is not sorted with respect
11731
+ to `key_comp()`, or that contains equal elements, is undefined.
11732
+
11733
+ #### Definition <a id="flat.set.defn">[[flat.set.defn]]</a>
11734
+
11735
+ ``` cpp
11736
+ namespace std {
11737
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
11738
+ class flat_set {
11739
+ public:
11740
+ // types
11741
+ using key_type = Key;
11742
+ using value_type = Key;
11743
+ using key_compare = Compare;
11744
+ using value_compare = Compare;
11745
+ using reference = value_type&;
11746
+ using const_reference = const value_type&;
11747
+ using size_type = typename KeyContainer::size_type;
11748
+ using difference_type = typename KeyContainer::difference_type;
11749
+ using iterator = implementation-defined // type of flat_set::iterator; // see [container.requirements]
11750
+ using const_iterator = implementation-defined // type of flat_set::const_iterator; // see [container.requirements]
11751
+ using reverse_iterator = std::reverse_iterator<iterator>;
11752
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
11753
+ using container_type = KeyContainer;
11754
+
11755
+ // [flat.set.cons], constructors
11756
+ flat_set() : flat_set(key_compare()) { }
11757
+
11758
+ explicit flat_set(container_type cont, const key_compare& comp = key_compare());
11759
+ template<class Allocator>
11760
+ flat_set(const container_type& cont, const Allocator& a);
11761
+ template<class Allocator>
11762
+ flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
11763
+
11764
+ flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare())
11765
+ : c(std::move(cont)), compare(comp) { }
11766
+ template<class Allocator>
11767
+ flat_set(sorted_unique_t, const container_type& cont, const Allocator& a);
11768
+ template<class Allocator>
11769
+ flat_set(sorted_unique_t, const container_type& cont,
11770
+ const key_compare& comp, const Allocator& a);
11771
+
11772
+ explicit flat_set(const key_compare& comp)
11773
+ : c(), compare(comp) { }
11774
+ template<class Allocator>
11775
+ flat_set(const key_compare& comp, const Allocator& a);
11776
+ template<class Allocator>
11777
+ explicit flat_set(const Allocator& a);
11778
+
11779
+ template<class InputIterator>
11780
+ flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
11781
+ : c(), compare(comp)
11782
+ { insert(first, last); }
11783
+ template<class InputIterator, class Allocator>
11784
+ flat_set(InputIterator first, InputIterator last,
11785
+ const key_compare& comp, const Allocator& a);
11786
+ template<class InputIterator, class Allocator>
11787
+ flat_set(InputIterator first, InputIterator last, const Allocator& a);
11788
+
11789
+ template<container-compatible-range<value_type> R>
11790
+ flat_set(from_range_t fr, R&& rg)
11791
+ : flat_set(fr, std::forward<R>(rg), key_compare()) { }
11792
+ template<container-compatible-range<value_type> R, class Allocator>
11793
+ flat_set(from_range_t, R&& rg, const Allocator& a);
11794
+ template<container-compatible-range<value_type> R>
11795
+ flat_set(from_range_t, R&& rg, const key_compare& comp)
11796
+ : flat_set(comp)
11797
+ { insert_range(std::forward<R>(rg)); }
11798
+ template<container-compatible-range<value_type> R, class Allocator>
11799
+ flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11800
+
11801
+ template<class InputIterator>
11802
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
11803
+ const key_compare& comp = key_compare())
11804
+ : c(first, last), compare(comp) { }
11805
+ template<class InputIterator, class Allocator>
11806
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
11807
+ const key_compare& comp, const Allocator& a);
11808
+ template<class InputIterator, class Allocator>
11809
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
11810
+
11811
+ flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare())
11812
+ : flat_set(il.begin(), il.end(), comp) { }
11813
+ template<class Allocator>
11814
+ flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
11815
+ template<class Allocator>
11816
+ flat_set(initializer_list<value_type> il, const Allocator& a);
11817
+
11818
+ flat_set(sorted_unique_t s, initializer_list<value_type> il,
11819
+ const key_compare& comp = key_compare())
11820
+ : flat_set(s, il.begin(), il.end(), comp) { }
11821
+ template<class Allocator>
11822
+ flat_set(sorted_unique_t, initializer_list<value_type> il,
11823
+ const key_compare& comp, const Allocator& a);
11824
+ template<class Allocator>
11825
+ flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
11826
+
11827
+ flat_set& operator=(initializer_list<value_type>);
11828
+
11829
+ // iterators
11830
+ iterator begin() noexcept;
11831
+ const_iterator begin() const noexcept;
11832
+ iterator end() noexcept;
11833
+ const_iterator end() const noexcept;
11834
+
11835
+ reverse_iterator rbegin() noexcept;
11836
+ const_reverse_iterator rbegin() const noexcept;
11837
+ reverse_iterator rend() noexcept;
11838
+ const_reverse_iterator rend() const noexcept;
11839
+
11840
+ const_iterator cbegin() const noexcept;
11841
+ const_iterator cend() const noexcept;
11842
+ const_reverse_iterator crbegin() const noexcept;
11843
+ const_reverse_iterator crend() const noexcept;
11844
+
11845
+ // capacity
11846
+ [[nodiscard]] bool empty() const noexcept;
11847
+ size_type size() const noexcept;
11848
+ size_type max_size() const noexcept;
11849
+
11850
+ // [flat.set.modifiers], modifiers
11851
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
11852
+ template<class... Args>
11853
+ iterator emplace_hint(const_iterator position, Args&&... args);
11854
+
11855
+ pair<iterator, bool> insert(const value_type& x)
11856
+ { return emplace(x); }
11857
+ pair<iterator, bool> insert(value_type&& x)
11858
+ { return emplace(std::move(x)); }
11859
+ template<class K> pair<iterator, bool> insert(K&& x);
11860
+ iterator insert(const_iterator position, const value_type& x)
11861
+ { return emplace_hint(position, x); }
11862
+ iterator insert(const_iterator position, value_type&& x)
11863
+ { return emplace_hint(position, std::move(x)); }
11864
+ template<class K> iterator insert(const_iterator hint, K&& x);
11865
+
11866
+ template<class InputIterator>
11867
+ void insert(InputIterator first, InputIterator last);
11868
+ template<class InputIterator>
11869
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
11870
+ template<container-compatible-range<value_type> R>
11871
+ void insert_range(R&& rg);
11872
+
11873
+ void insert(initializer_list<value_type> il)
11874
+ { insert(il.begin(), il.end()); }
11875
+ void insert(sorted_unique_t s, initializer_list<value_type> il)
11876
+ { insert(s, il.begin(), il.end()); }
11877
+
11878
+ container_type extract() &&;
11879
+ void replace(container_type&&);
11880
+
11881
+ iterator erase(iterator position);
11882
+ iterator erase(const_iterator position);
11883
+ size_type erase(const key_type& x);
11884
+ template<class K> size_type erase(K&& x);
11885
+ iterator erase(const_iterator first, const_iterator last);
11886
+
11887
+ void swap(flat_set& y) noexcept;
11888
+ void clear() noexcept;
11889
+
11890
+ // observers
11891
+ key_compare key_comp() const;
11892
+ value_compare value_comp() const;
11893
+
11894
+ // set operations
11895
+ iterator find(const key_type& x);
11896
+ const_iterator find(const key_type& x) const;
11897
+ template<class K> iterator find(const K& x);
11898
+ template<class K> const_iterator find(const K& x) const;
11899
+
11900
+ size_type count(const key_type& x) const;
11901
+ template<class K> size_type count(const K& x) const;
11902
+
11903
+ bool contains(const key_type& x) const;
11904
+ template<class K> bool contains(const K& x) const;
11905
+
11906
+ iterator lower_bound(const key_type& x);
11907
+ const_iterator lower_bound(const key_type& x) const;
11908
+ template<class K> iterator lower_bound(const K& x);
11909
+ template<class K> const_iterator lower_bound(const K& x) const;
11910
+
11911
+ iterator upper_bound(const key_type& x);
11912
+ const_iterator upper_bound(const key_type& x) const;
11913
+ template<class K> iterator upper_bound(const K& x);
11914
+ template<class K> const_iterator upper_bound(const K& x) const;
11915
+
11916
+ pair<iterator, iterator> equal_range(const key_type& x);
11917
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
11918
+ template<class K>
11919
+ pair<iterator, iterator> equal_range(const K& x);
11920
+ template<class K>
11921
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
11922
+
11923
+ friend bool operator==(const flat_set& x, const flat_set& y);
11924
+
11925
+ friend synth-three-way-result<value_type>
11926
+ operator<=>(const flat_set& x, const flat_set& y);
11927
+
11928
+ friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); }
11929
+
11930
+ private:
11931
+ container_type c; // exposition only
11932
+ key_compare compare; // exposition only
11933
+ };
11934
+
11935
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
11936
+ flat_set(KeyContainer, Compare = Compare())
11937
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
11938
+ template<class KeyContainer, class Allocator>
11939
+ flat_set(KeyContainer, Allocator)
11940
+ -> flat_set<typename KeyContainer::value_type,
11941
+ less<typename KeyContainer::value_type>, KeyContainer>;
11942
+ template<class KeyContainer, class Compare, class Allocator>
11943
+ flat_set(KeyContainer, Compare, Allocator)
11944
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
11945
+
11946
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
11947
+ flat_set(sorted_unique_t, KeyContainer, Compare = Compare())
11948
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
11949
+ template<class KeyContainer, class Allocator>
11950
+ flat_set(sorted_unique_t, KeyContainer, Allocator)
11951
+ -> flat_set<typename KeyContainer::value_type,
11952
+ less<typename KeyContainer::value_type>, KeyContainer>;
11953
+ template<class KeyContainer, class Compare, class Allocator>
11954
+ flat_set(sorted_unique_t, KeyContainer, Compare, Allocator)
11955
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
11956
+
11957
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
11958
+ flat_set(InputIterator, InputIterator, Compare = Compare())
11959
+ -> flat_set<iter-value-type<InputIterator>, Compare>;
11960
+
11961
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
11962
+ flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
11963
+ -> flat_set<iter-value-type<InputIterator>, Compare>;
11964
+
11965
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
11966
+ class Allocator = allocator<ranges::range_value_t<R>>>
11967
+ flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
11968
+ -> flat_set<ranges::range_value_t<R>, Compare,
11969
+ vector<ranges::range_value_t<R>,
11970
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
11971
+
11972
+ template<ranges::input_range R, class Allocator>
11973
+ flat_set(from_range_t, R&&, Allocator)
11974
+ -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
11975
+ vector<ranges::range_value_t<R>,
11976
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
11977
+
11978
+ template<class Key, class Compare = less<Key>>
11979
+ flat_set(initializer_list<Key>, Compare = Compare())
11980
+ -> flat_set<Key, Compare>;
11981
+
11982
+ template<class Key, class Compare = less<Key>>
11983
+ flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())
11984
+ -> flat_set<Key, Compare>;
11985
+
11986
+ template<class Key, class Compare, class KeyContainer, class Allocator>
11987
+ struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>
11988
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
11989
+ }
11990
+ ```
11991
+
11992
+ #### Constructors <a id="flat.set.cons">[[flat.set.cons]]</a>
11993
+
11994
+ ``` cpp
11995
+ explicit flat_set(container_type cont, const key_compare& comp = key_compare());
11996
+ ```
11997
+
11998
+ *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
11999
+ `comp`, sorts the range \[`begin()`, `end()`) with respect to *compare*,
12000
+ and finally erases all but the first element from each group of
12001
+ consecutive equivalent elements.
12002
+
12003
+ *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
12004
+ and otherwise N log N, where N is the value of `cont.size()` before this
12005
+ call.
12006
+
12007
+ ``` cpp
12008
+ template<class Allocator>
12009
+ flat_set(const container_type& cont, const Allocator& a);
12010
+ template<class Allocator>
12011
+ flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
12012
+ ```
12013
+
12014
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12015
+
12016
+ *Effects:* Equivalent to `flat_set(cont)` and `flat_set(cont, comp)`,
12017
+ respectively, except that *c* is constructed with uses-allocator
12018
+ construction [[allocator.uses.construction]].
12019
+
12020
+ *Complexity:* Same as `flat_set(cont)` and `flat_set(cont, comp)`,
12021
+ respectively.
12022
+
12023
+ ``` cpp
12024
+ template<class Allocator>
12025
+ flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a);
12026
+ template<class Allocator>
12027
+ flat_set(sorted_unique_t s, const container_type& cont,
12028
+ const key_compare& comp, const Allocator& a);
12029
+ ```
12030
+
12031
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12032
+
12033
+ *Effects:* Equivalent to `flat_set(s, cont)` and
12034
+ `flat_set(s, cont, comp)`, respectively, except that *c* is constructed
12035
+ with uses-allocator construction [[allocator.uses.construction]].
12036
+
12037
+ *Complexity:* Linear.
12038
+
12039
+ ``` cpp
12040
+ template<class Allocator>
12041
+ flat_set(const key_compare& comp, const Allocator& a);
12042
+ template<class Allocator>
12043
+ explicit flat_set(const Allocator& a);
12044
+ template<class InputIterator, class Allocator>
12045
+ flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
12046
+ template<class InputIterator, class Allocator>
12047
+ flat_set(InputIterator first, InputIterator last, const Allocator& a);
12048
+ template<container-compatible-range<value_type> R, class Allocator>
12049
+ flat_set(from_range_t, R&& rg, const Allocator& a);
12050
+ template<container-compatible-range<value_type> R, class Allocator>
12051
+ flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12052
+ template<class InputIterator, class Allocator>
12053
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
12054
+ const key_compare& comp, const Allocator& a);
12055
+ template<class InputIterator, class Allocator>
12056
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
12057
+ template<class Allocator>
12058
+ flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
12059
+ template<class Allocator>
12060
+ flat_set(initializer_list<value_type> il, const Allocator& a);
12061
+ template<class Allocator>
12062
+ flat_set(sorted_unique_t, initializer_list<value_type> il,
12063
+ const key_compare& comp, const Allocator& a);
12064
+ template<class Allocator>
12065
+ flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
12066
+ ```
12067
+
12068
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12069
+
12070
+ *Effects:* Equivalent to the corresponding non-allocator constructors
12071
+ except that *c* is constructed with uses-allocator
12072
+ construction [[allocator.uses.construction]].
12073
+
12074
+ #### Modifiers <a id="flat.set.modifiers">[[flat.set.modifiers]]</a>
12075
+
12076
+ ``` cpp
12077
+ template<class K> pair<iterator, bool> insert(K&& x);
12078
+ template<class K> iterator insert(const_iterator hint, K&& x);
12079
+ ```
12080
+
12081
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
12082
+ denotes a type. `is_constructible_v<value_type, K>` is `true`.
12083
+
12084
+ *Preconditions:* The conversion from `x` into `value_type` constructs an
12085
+ object `u`, for which `find(x) == find(u)` is true.
12086
+
12087
+ *Effects:* If the set already contains an element equivalent to `x`,
12088
+ `*this` and `x` are unchanged. Otherwise, inserts a new element as if by
12089
+ `emplace(std::forward<K>(x))`.
12090
+
12091
+ *Returns:* In the first overload, the `bool` component of the returned
12092
+ pair is `true` if and only if the insertion took place. The returned
12093
+ iterator points to the element whose key is equivalent to `x`.
12094
+
12095
+ ``` cpp
12096
+ template<class InputIterator>
12097
+ void insert(InputIterator first, InputIterator last);
12098
+ ```
12099
+
12100
+ *Effects:* Adds elements to *c* as if by:
12101
+
12102
+ ``` cpp
12103
+ c.insert(c.end(), first, last);
12104
+ ```
12105
+
12106
+ Then, sorts the range of newly inserted elements with respect to
12107
+ *compare*; merges the resulting sorted range and the sorted range of
12108
+ pre-existing elements into a single sorted range; and finally erases all
12109
+ but the first element from each group of consecutive equivalent
12110
+ elements.
12111
+
12112
+ *Complexity:* N + M log M, where N is `size()` before the operation and
12113
+ M is `distance(first, last)`.
12114
+
12115
+ *Remarks:* Since this operation performs an in-place merge, it may
12116
+ allocate memory.
12117
+
12118
+ ``` cpp
12119
+ template<class InputIterator>
12120
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
12121
+ ```
12122
+
12123
+ *Effects:* Equivalent to `insert(first, last)`.
12124
+
12125
+ *Complexity:* Linear.
12126
+
12127
+ ``` cpp
12128
+ template<container-compatible-range<value_type> R>
12129
+ void insert_range(R&& rg);
12130
+ ```
12131
+
12132
+ *Effects:* Adds elements to *c* as if by:
12133
+
12134
+ ``` cpp
12135
+ for (const auto& e : rg) {
12136
+ c.insert(c.end(), e);
12137
+ }
12138
+ ```
12139
+
12140
+ Then, sorts the range of newly inserted elements with respect to
12141
+ *compare*; merges the resulting sorted range and the sorted range of
12142
+ pre-existing elements into a single sorted range; and finally erases all
12143
+ but the first element from each group of consecutive equivalent
12144
+ elements.
12145
+
12146
+ *Complexity:* N + M log M, where N is `size()` before the operation and
12147
+ M is `ranges::distance(rg)`.
12148
+
12149
+ *Remarks:* Since this operation performs an in-place merge, it may
12150
+ allocate memory.
12151
+
12152
+ ``` cpp
12153
+ void swap(flat_set& y) noexcept;
12154
+ ```
12155
+
12156
+ *Effects:* Equivalent to:
12157
+
12158
+ ``` cpp
12159
+ ranges::swap(compare, y.compare);
12160
+ ranges::swap(c, y.c);
12161
+ ```
12162
+
12163
+ ``` cpp
12164
+ container_type extract() &&;
12165
+ ```
12166
+
12167
+ *Ensures:* `*this` is emptied, even if the function exits via an
12168
+ exception.
12169
+
12170
+ *Returns:* `std::move(`*`c`*`)`.
12171
+
12172
+ ``` cpp
12173
+ void replace(container_type&& cont);
12174
+ ```
12175
+
12176
+ *Preconditions:* The elements of `cont` are sorted with respect to
12177
+ *compare*, and `cont` contains no equal elements.
12178
+
12179
+ *Effects:* Equivalent to: *`c`*` = std::move(cont);`
12180
+
12181
+ #### Erasure <a id="flat.set.erasure">[[flat.set.erasure]]</a>
12182
+
12183
+ ``` cpp
12184
+ template<class Key, class Compare, class KeyContainer, class Predicate>
12185
+ typename flat_set<Key, Compare, KeyContainer>::size_type
12186
+ erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
12187
+ ```
12188
+
12189
+ *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
12190
+
12191
+ *Effects:* Let E be `bool(pred(as_const(e)))`. Erases all elements `e`
12192
+ in `c` for which E holds.
12193
+
12194
+ *Returns:* The number of elements erased.
12195
+
12196
+ *Complexity:* Exactly `c.size()` applications of the predicate.
12197
+
12198
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
12199
+ exits via an exception, `c` is in a valid but unspecified
12200
+ state [[defns.valid]].
12201
+
12202
+ [*Note 1*: `c` still meets its invariants, but can be
12203
+ empty. — *end note*]
12204
+
12205
+ ### Class template `flat_multiset` <a id="flat.multiset">[[flat.multiset]]</a>
12206
+
12207
+ #### Overview <a id="flat.multiset.overview">[[flat.multiset.overview]]</a>
12208
+
12209
+ A `flat_multiset` is a container adaptor that provides an associative
12210
+ container interface that supports equivalent keys (i.e., possibly
12211
+ containing multiple copies of the same key value) and provides for fast
12212
+ retrieval of the keys themselves. `flat_multiset` supports iterators
12213
+ that model the `random_access_iterator` concept
12214
+ [[iterator.concept.random.access]].
12215
+
12216
+ A `flat_multiset` meets all of the requirements for a container
12217
+ [[container.reqmts]] and for a reversible container
12218
+ [[container.rev.reqmts]], plus the optional container requirements
12219
+ [[container.opt.reqmts]]. `flat_multiset` meets the requirements of an
12220
+ associative container [[associative.reqmts]], except that:
12221
+
12222
+ - it does not meet the requirements related to node handles
12223
+ [[container.node.overview]],
12224
+ - it does not meet the requirements related to iterator invalidation,
12225
+ and
12226
+ - the time complexity of the operations that insert or erase a single
12227
+ element from the set is linear, including the ones that take an
12228
+ insertion position iterator.
12229
+
12230
+ [*Note 1*: A `flat_multiset` does not meet the additional requirements
12231
+ of an allocator-aware container, as described in
12232
+ [[container.alloc.reqmts]]. — *end note*]
12233
+
12234
+ A `flat_multiset` also provides most operations described in
12235
+ [[associative.reqmts]] for equal keys. This means that a `flat_multiset`
12236
+ supports the `a_eq` operations in [[associative.reqmts]] but not the
12237
+ `a_uniq` operations. For a `flat_multiset<Key>`, both the `key_type` and
12238
+ `value_type` are `Key`.
12239
+
12240
+ Descriptions are provided here only for operations on `flat_multiset`
12241
+ that are not described in one of the general sections or for operations
12242
+ where there is additional semantic information.
12243
+
12244
+ A `flat_multiset` maintains the invariant that the keys are sorted with
12245
+ respect to the comparison object.
12246
+
12247
+ If any member function in [[flat.multiset.defn]] exits via an exception,
12248
+ the invariant is restored.
12249
+
12250
+ [*Note 2*: This can result in the `flat_multiset`’s being
12251
+ emptied. — *end note*]
12252
+
12253
+ Any sequence container [[sequence.reqmts]] supporting
12254
+ *Cpp17RandomAccessIterator* can be used to instantiate `flat_multiset`.
12255
+ In particular, `vector` [[vector]] and `deque` [[deque]] can be used.
12256
+
12257
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
12258
+
12259
+ The program is ill-formed if `Key` is not the same type as
12260
+ `KeyContainer::value_type`.
12261
+
12262
+ The effect of calling a constructor or member function that takes a
12263
+ `sorted_equivalent_t` argument with a range that is not sorted with
12264
+ respect to `key_comp()` is undefined.
12265
+
12266
+ #### Definition <a id="flat.multiset.defn">[[flat.multiset.defn]]</a>
12267
+
12268
+ ``` cpp
12269
+ namespace std {
12270
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
12271
+ class flat_multiset {
12272
+ public:
12273
+ // types
12274
+ using key_type = Key;
12275
+ using value_type = Key;
12276
+ using key_compare = Compare;
12277
+ using value_compare = Compare;
12278
+ using reference = value_type&;
12279
+ using const_reference = const value_type&;
12280
+ using size_type = typename KeyContainer::size_type;
12281
+ using difference_type = typename KeyContainer::difference_type;
12282
+ using iterator = implementation-defined // type of flat_multiset::iterator; // see [container.requirements]
12283
+ using const_iterator = implementation-defined // type of flat_multiset::const_iterator; // see [container.requirements]
12284
+ using reverse_iterator = std::reverse_iterator<iterator>;
12285
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
12286
+ using container_type = KeyContainer;
12287
+
12288
+ // [flat.multiset.cons], constructors
12289
+ flat_multiset() : flat_multiset(key_compare()) { }
12290
+
12291
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
12292
+ template<class Allocator>
12293
+ flat_multiset(const container_type& cont, const Allocator& a);
12294
+ template<class Allocator>
12295
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
12296
+
12297
+ flat_multiset(sorted_equivalent_t, container_type cont,
12298
+ const key_compare& comp = key_compare())
12299
+ : c(std::move(cont)), compare(comp) { }
12300
+ template<class Allocator>
12301
+ flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a);
12302
+ template<class Allocator>
12303
+ flat_multiset(sorted_equivalent_t, const container_type& cont,
12304
+ const key_compare& comp, const Allocator& a);
12305
+
12306
+ explicit flat_multiset(const key_compare& comp)
12307
+ : c(), compare(comp) { }
12308
+ template<class Allocator>
12309
+ flat_multiset(const key_compare& comp, const Allocator& a);
12310
+ template<class Allocator>
12311
+ explicit flat_multiset(const Allocator& a);
12312
+
12313
+ template<class InputIterator>
12314
+ flat_multiset(InputIterator first, InputIterator last,
12315
+ const key_compare& comp = key_compare())
12316
+ : c(), compare(comp)
12317
+ { insert(first, last); }
12318
+ template<class InputIterator, class Allocator>
12319
+ flat_multiset(InputIterator first, InputIterator last,
12320
+ const key_compare& comp, const Allocator& a);
12321
+ template<class InputIterator, class Allocator>
12322
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
12323
+
12324
+ template<container-compatible-range<value_type> R>
12325
+ flat_multiset(from_range_t fr, R&& rg)
12326
+ : flat_multiset(fr, std::forward<R>(rg), key_compare()) { }
12327
+ template<container-compatible-range<value_type> R, class Allocator>
12328
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
12329
+ template<container-compatible-range<value_type> R>
12330
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp)
12331
+ : flat_multiset(comp)
12332
+ { insert_range(std::forward<R>(rg)); }
12333
+ template<container-compatible-range<value_type> R, class Allocator>
12334
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12335
+
12336
+ template<class InputIterator>
12337
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12338
+ const key_compare& comp = key_compare())
12339
+ : c(first, last), compare(comp) { }
12340
+ template<class InputIterator, class Allocator>
12341
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12342
+ const key_compare& comp, const Allocator& a);
12343
+ template<class InputIterator, class Allocator>
12344
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12345
+ const Allocator& a);
12346
+
12347
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare())
12348
+ : flat_multiset(il.begin(), il.end(), comp) { }
12349
+ template<class Allocator>
12350
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp,
12351
+ const Allocator& a);
12352
+ template<class Allocator>
12353
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
12354
+
12355
+ flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il,
12356
+ const key_compare& comp = key_compare())
12357
+ : flat_multiset(s, il.begin(), il.end(), comp) { }
12358
+ template<class Allocator>
12359
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
12360
+ const key_compare& comp, const Allocator& a);
12361
+ template<class Allocator>
12362
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
12363
+
12364
+ flat_multiset& operator=(initializer_list<value_type>);
12365
+
12366
+ // iterators
12367
+ iterator begin() noexcept;
12368
+ const_iterator begin() const noexcept;
12369
+ iterator end() noexcept;
12370
+ const_iterator end() const noexcept;
12371
+
12372
+ reverse_iterator rbegin() noexcept;
12373
+ const_reverse_iterator rbegin() const noexcept;
12374
+ reverse_iterator rend() noexcept;
12375
+ const_reverse_iterator rend() const noexcept;
12376
+
12377
+ const_iterator cbegin() const noexcept;
12378
+ const_iterator cend() const noexcept;
12379
+ const_reverse_iterator crbegin() const noexcept;
12380
+ const_reverse_iterator crend() const noexcept;
12381
+
12382
+ // capacity
12383
+ [[nodiscard]] bool empty() const noexcept;
12384
+ size_type size() const noexcept;
12385
+ size_type max_size() const noexcept;
12386
+
12387
+ // [flat.multiset.modifiers], modifiers
12388
+ template<class... Args> iterator emplace(Args&&... args);
12389
+ template<class... Args>
12390
+ iterator emplace_hint(const_iterator position, Args&&... args);
12391
+
12392
+ iterator insert(const value_type& x)
12393
+ { return emplace(x); }
12394
+ iterator insert(value_type&& x)
12395
+ { return emplace(std::move(x)); }
12396
+ iterator insert(const_iterator position, const value_type& x)
12397
+ { return emplace_hint(position, x); }
12398
+ iterator insert(const_iterator position, value_type&& x)
12399
+ { return emplace_hint(position, std::move(x)); }
12400
+
12401
+ template<class InputIterator>
12402
+ void insert(InputIterator first, InputIterator last);
12403
+ template<class InputIterator>
12404
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
12405
+ template<container-compatible-range<value_type> R>
12406
+ void insert_range(R&& rg);
12407
+
12408
+ void insert(initializer_list<value_type> il)
12409
+ { insert(il.begin(), il.end()); }
12410
+ void insert(sorted_equivalent_t s, initializer_list<value_type> il)
12411
+ { insert(s, il.begin(), il.end()); }
12412
+
12413
+ container_type extract() &&;
12414
+ void replace(container_type&&);
12415
+
12416
+ iterator erase(iterator position);
12417
+ iterator erase(const_iterator position);
12418
+ size_type erase(const key_type& x);
12419
+ template<class K> size_type erase(K&& x);
12420
+ iterator erase(const_iterator first, const_iterator last);
12421
+
12422
+ void swap(flat_multiset& y) noexcept;
12423
+ void clear() noexcept;
12424
+
12425
+ // observers
12426
+ key_compare key_comp() const;
12427
+ value_compare value_comp() const;
12428
+
12429
+ // set operations
12430
+ iterator find(const key_type& x);
12431
+ const_iterator find(const key_type& x) const;
12432
+ template<class K> iterator find(const K& x);
12433
+ template<class K> const_iterator find(const K& x) const;
12434
+
12435
+ size_type count(const key_type& x) const;
12436
+ template<class K> size_type count(const K& x) const;
12437
+
12438
+ bool contains(const key_type& x) const;
12439
+ template<class K> bool contains(const K& x) const;
12440
+
12441
+ iterator lower_bound(const key_type& x);
12442
+ const_iterator lower_bound(const key_type& x) const;
12443
+ template<class K> iterator lower_bound(const K& x);
12444
+ template<class K> const_iterator lower_bound(const K& x) const;
12445
+
12446
+ iterator upper_bound(const key_type& x);
12447
+ const_iterator upper_bound(const key_type& x) const;
12448
+ template<class K> iterator upper_bound(const K& x);
12449
+ template<class K> const_iterator upper_bound(const K& x) const;
12450
+
12451
+ pair<iterator, iterator> equal_range(const key_type& x);
12452
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
12453
+ template<class K>
12454
+ pair<iterator, iterator> equal_range(const K& x);
12455
+ template<class K>
12456
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
12457
+
12458
+ friend bool operator==(const flat_multiset& x, const flat_multiset& y);
12459
+
12460
+ friend synth-three-way-result<value_type>
12461
+ operator<=>(const flat_multiset& x, const flat_multiset& y);
12462
+
12463
+ friend void swap(flat_multiset& x, flat_multiset& y) noexcept
12464
+ { x.swap(y); }
12465
+
12466
+ private:
12467
+ container_type c; // exposition only
12468
+ key_compare compare; // exposition only
12469
+ };
12470
+
12471
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
12472
+ flat_multiset(KeyContainer, Compare = Compare())
12473
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
12474
+ template<class KeyContainer, class Allocator>
12475
+ flat_multiset(KeyContainer, Allocator)
12476
+ -> flat_multiset<typename KeyContainer::value_type,
12477
+ less<typename KeyContainer::value_type>, KeyContainer>;
12478
+ template<class KeyContainer, class Compare, class Allocator>
12479
+ flat_multiset(KeyContainer, Compare, Allocator)
12480
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
12481
+
12482
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
12483
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())
12484
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
12485
+ template<class KeyContainer, class Allocator>
12486
+ flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)
12487
+ -> flat_multiset<typename KeyContainer::value_type,
12488
+ less<typename KeyContainer::value_type>, KeyContainer>;
12489
+ template<class KeyContainer, class Compare, class Allocator>
12490
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
12491
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
12492
+
12493
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
12494
+ flat_multiset(InputIterator, InputIterator, Compare = Compare())
12495
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
12496
+
12497
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
12498
+ flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
12499
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
12500
+
12501
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
12502
+ class Allocator = allocator<ranges::range_value_t<R>>>
12503
+ flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
12504
+ -> flat_multiset<ranges::range_value_t<R>, Compare,
12505
+ vector<ranges::range_value_t<R>,
12506
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
12507
+
12508
+ template<ranges::input_range R, class Allocator>
12509
+ flat_multiset(from_range_t, R&&, Allocator)
12510
+ -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
12511
+ vector<ranges::range_value_t<R>,
12512
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
12513
+
12514
+ template<class Key, class Compare = less<Key>>
12515
+ flat_multiset(initializer_list<Key>, Compare = Compare())
12516
+ -> flat_multiset<Key, Compare>;
12517
+
12518
+ template<class Key, class Compare = less<Key>>
12519
+ flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())
12520
+ -> flat_multiset<Key, Compare>;
12521
+
12522
+ template<class Key, class Compare, class KeyContainer, class Allocator>
12523
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>
12524
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
12525
+ }
12526
+ ```
12527
+
12528
+ #### Constructors <a id="flat.multiset.cons">[[flat.multiset.cons]]</a>
12529
+
12530
+ ``` cpp
12531
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
12532
+ ```
12533
+
12534
+ *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
12535
+ `comp`, and sorts the range \[`begin()`, `end()`) with respect to
12536
+ *compare*.
12537
+
12538
+ *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
12539
+ and otherwise N log N, where N is the value of `cont.size()` before this
12540
+ call.
12541
+
12542
+ ``` cpp
12543
+ template<class Allocator>
12544
+ flat_multiset(const container_type& cont, const Allocator& a);
12545
+ template<class Allocator>
12546
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
12547
+ ```
12548
+
12549
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12550
+
12551
+ *Effects:* Equivalent to `flat_multiset(cont)` and
12552
+ `flat_multiset(cont, comp)`, respectively, except that *c* is
12553
+ constructed with uses-allocator
12554
+ construction [[allocator.uses.construction]].
12555
+
12556
+ *Complexity:* Same as `flat_multiset(cont)` and
12557
+ `flat_multiset(cont, comp)`, respectively.
12558
+
12559
+ ``` cpp
12560
+ template<class Allocator>
12561
+ flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a);
12562
+ template<class Allocator>
12563
+ flat_multiset(sorted_equivalent_t s, const container_type& cont,
12564
+ const key_compare& comp, const Allocator& a);
12565
+ ```
12566
+
12567
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12568
+
12569
+ *Effects:* Equivalent to `flat_multiset(s, cont)` and
12570
+ `flat_multiset(s, cont, comp)`, respectively, except that *c* is
12571
+ constructed with uses-allocator
12572
+ construction [[allocator.uses.construction]].
12573
+
12574
+ *Complexity:* Linear.
12575
+
12576
+ ``` cpp
12577
+ template<class Allocator>
12578
+ flat_multiset(const key_compare& comp, const Allocator& a);
12579
+ template<class Allocator>
12580
+ explicit flat_multiset(const Allocator& a);
12581
+ template<class InputIterator, class Allocator>
12582
+ flat_multiset(InputIterator first, InputIterator last,
12583
+ const key_compare& comp, const Allocator& a);
12584
+ template<class InputIterator, class Allocator>
12585
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
12586
+ template<container-compatible-range<value_type> R, class Allocator>
12587
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
12588
+ template<container-compatible-range<value_type> R, class Allocator>
12589
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12590
+ template<class InputIterator, class Allocator>
12591
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12592
+ const key_compare& comp, const Allocator& a);
12593
+ template<class InputIterator, class Allocator>
12594
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a);
12595
+ template<class Allocator>
12596
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
12597
+ template<class Allocator>
12598
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
12599
+ template<class Allocator>
12600
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
12601
+ const key_compare& comp, const Allocator& a);
12602
+ template<class Allocator>
12603
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
12604
+ ```
12605
+
12606
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12607
+
12608
+ *Effects:* Equivalent to the corresponding non-allocator constructors
12609
+ except that *c* is constructed with uses-allocator
12610
+ construction [[allocator.uses.construction]].
12611
+
12612
+ #### Modifiers <a id="flat.multiset.modifiers">[[flat.multiset.modifiers]]</a>
12613
+
12614
+ ``` cpp
12615
+ template<class... Args> iterator emplace(Args&&... args);
12616
+ ```
12617
+
12618
+ *Constraints:* `is_constructible_v<value_type, Args...>` is `true`.
12619
+
12620
+ *Effects:* First, initializes an object `t` of type `value_type` with
12621
+ `std::forward<Args>(args)...`, then inserts `t` as if by:
12622
+
12623
+ ``` cpp
12624
+ auto it = ranges::upper_bound(c, t, compare);
12625
+ c.insert(it, std::move(t));
12626
+ ```
12627
+
12628
+ *Returns:* An iterator that points to the inserted element.
12629
+
12630
+ ``` cpp
12631
+ template<class InputIterator>
12632
+ void insert(InputIterator first, InputIterator last);
12633
+ ```
12634
+
12635
+ *Effects:* Adds elements to *c* as if by:
12636
+
12637
+ ``` cpp
12638
+ c.insert(c.end(), first, last);
12639
+ ```
12640
+
12641
+ Then, sorts the range of newly inserted elements with respect to
12642
+ *compare*, and merges the resulting sorted range and the sorted range of
12643
+ pre-existing elements into a single sorted range.
12644
+
12645
+ *Complexity:* N + M log M, where N is `size()` before the operation and
12646
+ M is `distance(first, last)`.
12647
+
12648
+ *Remarks:* Since this operation performs an in-place merge, it may
12649
+ allocate memory.
12650
+
12651
+ ``` cpp
12652
+ template<class InputIterator>
12653
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
12654
+ ```
12655
+
12656
+ *Effects:* Equivalent to `insert(first, last)`.
12657
+
12658
+ *Complexity:* Linear.
12659
+
12660
+ ``` cpp
12661
+ void swap(flat_multiset& y) noexcept;
12662
+ ```
12663
+
12664
+ *Effects:* Equivalent to:
12665
+
12666
+ ``` cpp
12667
+ ranges::swap(compare, y.compare);
12668
+ ranges::swap(c, y.c);
12669
+ ```
12670
+
12671
+ ``` cpp
12672
+ container_type extract() &&;
12673
+ ```
12674
+
12675
+ *Ensures:* `*this` is emptied, even if the function exits via an
12676
+ exception.
12677
+
12678
+ *Returns:* `std::move(c)`.
12679
+
12680
+ ``` cpp
12681
+ void replace(container_type&& cont);
12682
+ ```
12683
+
12684
+ *Preconditions:* The elements of `cont` are sorted with respect to
12685
+ *compare*.
12686
+
12687
+ *Effects:* Equivalent to: `c = std::move(cont);`
12688
+
12689
+ #### Erasure <a id="flat.multiset.erasure">[[flat.multiset.erasure]]</a>
12690
+
12691
+ ``` cpp
12692
+ template<class Key, class Compare, class KeyContainer, class Predicate>
12693
+ typename flat_multiset<Key, Compare, KeyContainer>::size_type
12694
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
12695
+ ```
12696
+
12697
+ *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
12698
+
12699
+ *Effects:* Let E be `bool(pred(as_const(e)))`. Erases all elements `e`
12700
+ in `c` for which E holds.
12701
+
12702
+ *Returns:* The number of elements erased.
12703
+
12704
+ *Complexity:* Exactly `c.size()` applications of the predicate.
12705
+
12706
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
12707
+ exits via an exception, `c` is in a valid but unspecified
12708
+ state [[defns.valid]].
12709
+
12710
+ [*Note 1*: `c` still meets its invariants, but can be
12711
+ empty. — *end note*]
12712
+
12713
+ ### Container adaptors formatting <a id="container.adaptors.format">[[container.adaptors.format]]</a>
12714
+
12715
+ For each of `queue`, `priority_queue`, and `stack`, the library provides
12716
+ the following formatter specialization where `adaptor-type` is the name
12717
+ of the template:
12718
+
12719
+ ``` cpp
12720
+ namespace std {
12721
+ template<class charT, class T, formattable<charT> Container, class... U>
12722
+ struct formatter<adaptor-type<T, Container, U...>, charT> {
12723
+ private:
12724
+ using maybe-const-container = // exposition only
12725
+ fmt-maybe-const<Container, charT>;
12726
+ using maybe-const-adaptor = // exposition only
12727
+ maybe-const<is_const_v<maybe-const-container>, // see [ranges.syn]
12728
+ adaptor-type<T, Container, U...>>;
12729
+ formatter<ranges::ref_view<maybe-const-container>, charT> underlying_; // exposition only
12730
+
12731
+ public:
12732
+ template<class ParseContext>
12733
+ constexpr typename ParseContext::iterator
12734
+ parse(ParseContext& ctx);
12735
+
12736
+ template<class FormatContext>
12737
+ typename FormatContext::iterator
12738
+ format(maybe-const-adaptor& r, FormatContext& ctx) const;
12739
+ };
12740
+ }
12741
+ ```
12742
+
12743
+ ``` cpp
12744
+ template<class ParseContext>
12745
+ constexpr typename ParseContext::iterator
12746
+ parse(ParseContext& ctx);
12747
+ ```
12748
+
12749
+ *Effects:* Equivalent to: `return `*`underlying_`*`.parse(ctx);`
12750
+
12751
+ ``` cpp
12752
+ template<class FormatContext>
12753
+ typename FormatContext::iterator
12754
+ format(maybe-const-adaptor& r, FormatContext& ctx) const;
12755
+ ```
12756
+
12757
+ *Effects:* Equivalent to: `return `*`underlying_`*`.format(r.c, ctx);`
12758
+
12759
  ## Views <a id="views">[[views]]</a>
12760
 
12761
  ### General <a id="views.general">[[views.general]]</a>
12762
 
12763
+ The header `<span>` defines the view `span`. The header `<mdspan>`
12764
+ defines the class template `mdspan` and other facilities for interacting
12765
+ with these multidimensional views.
12766
 
12767
+ ### Contiguous access <a id="views.contiguous">[[views.contiguous]]</a>
12768
+
12769
+ #### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
12770
 
12771
  ``` cpp
12772
  namespace std {
12773
  // constants
12774
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
 
12776
  // [views.span], class template span
12777
  template<class ElementType, size_t Extent = dynamic_extent>
12778
  class span;
12779
 
12780
  template<class ElementType, size_t Extent>
12781
+ constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
 
12782
  template<class ElementType, size_t Extent>
12783
+ constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
12784
 
12785
  // [span.objectrep], views of object representation
12786
  template<class ElementType, size_t Extent>
12787
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
12788
  as_bytes(span<ElementType, Extent> s) noexcept;
 
12791
  span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
12792
  as_writable_bytes(span<ElementType, Extent> s) noexcept;
12793
  }
12794
  ```
12795
 
12796
+ #### Class template `span` <a id="views.span">[[views.span]]</a>
12797
 
12798
+ ##### Overview <a id="span.overview">[[span.overview]]</a>
12799
 
12800
  A `span` is a view over a contiguous sequence of objects, the storage of
12801
  which is owned by some other object.
12802
 
12803
  All member functions of `span` have constant time complexity.
 
12815
  using pointer = element_type*;
12816
  using const_pointer = const element_type*;
12817
  using reference = element_type&;
12818
  using const_reference = const element_type&;
12819
  using iterator = implementation-defined // type of span::iterator; // see [span.iterators]
12820
+ using const_iterator = std::const_iterator<iterator>;
12821
  using reverse_iterator = std::reverse_iterator<iterator>;
12822
+ using const_reverse_iterator = std::const_iterator<reverse_iterator>;
12823
  static constexpr size_type extent = Extent;
12824
 
12825
  // [span.cons], constructors, copy, and assignment
12826
  constexpr span() noexcept;
12827
  template<class It>
 
12869
  constexpr pointer data() const noexcept;
12870
 
12871
  // [span.iterators], iterator support
12872
  constexpr iterator begin() const noexcept;
12873
  constexpr iterator end() const noexcept;
12874
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
12875
+ constexpr const_iterator cend() const noexcept { return end(); }
12876
  constexpr reverse_iterator rbegin() const noexcept;
12877
  constexpr reverse_iterator rend() const noexcept;
12878
+ constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
12879
+ constexpr const_reverse_iterator crend() const noexcept { return rend(); }
12880
 
12881
  private:
12882
  pointer data_; // exposition only
12883
  size_type size_; // exposition only
12884
  };
 
12894
  template<class R>
12895
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
12896
  }
12897
  ```
12898
 
12899
+ `span<ElementType, Extent>` is a trivially copyable type
12900
+ [[term.trivially.copyable.type]].
12901
+
12902
  `ElementType` is required to be a complete object type that is not an
12903
  abstract class type.
12904
 
12905
+ ##### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
12906
 
12907
  ``` cpp
12908
  constexpr span() noexcept;
12909
  ```
12910
 
 
12929
  - \[`first`, `first + count`) is a valid range.
12930
  - `It` models `contiguous_iterator`.
12931
  - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
12932
  `extent`.
12933
 
12934
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
12935
+ with `count`.
12936
 
12937
  *Throws:* Nothing.
12938
 
12939
  ``` cpp
12940
  template<class It, class End>
 
12956
  equal to `extent`.
12957
  - \[`first`, `last`) is a valid range.
12958
  - `It` models `contiguous_iterator`.
12959
  - `End` models `sized_sentinel_for<It>`.
12960
 
12961
+ *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
12962
+ with `last - first`.
12963
 
12964
  *Throws:* When and what `last - first` throws.
12965
 
12966
  ``` cpp
12967
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
 
13006
  is equal to `extent`.
13007
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
13008
  - If `is_const_v<element_type>` is `false`, `R` models
13009
  `ranges::borrowed_range`.
13010
 
13011
+ *Effects:* Initializes *`data_`* with `ranges::data(r)` and *`size_`*
13012
+ with `ranges::size(r)`.
13013
 
13014
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
13015
 
13016
  ``` cpp
13017
  constexpr span(const span& other) noexcept = default;
 
13051
  constexpr span& operator=(const span& other) noexcept = default;
13052
  ```
13053
 
13054
  *Ensures:* `size() == other.size() && data() == other.data()`.
13055
 
13056
+ ##### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
13057
 
13058
  ``` cpp
13059
  template<class It, class EndOrSize>
13060
  span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
13061
  ```
 
13067
  span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
13068
  ```
13069
 
13070
  *Constraints:* `R` satisfies `ranges::contiguous_range`.
13071
 
13072
+ ##### Subviews <a id="span.sub">[[span.sub]]</a>
13073
 
13074
  ``` cpp
13075
  template<size_t Count> constexpr span<element_type, Count> first() const;
13076
  ```
13077
 
 
13162
 
13163
  ``` cpp
13164
  return {data() + offset, count == dynamic_extent ? size() - offset : count};
13165
  ```
13166
 
13167
+ ##### Observers <a id="span.obs">[[span.obs]]</a>
13168
 
13169
  ``` cpp
13170
  constexpr size_type size() const noexcept;
13171
  ```
13172
 
13173
+ *Effects:* Equivalent to: `return `*`size_`*`;`
13174
 
13175
  ``` cpp
13176
  constexpr size_type size_bytes() const noexcept;
13177
  ```
13178
 
 
13182
  [[nodiscard]] constexpr bool empty() const noexcept;
13183
  ```
13184
 
13185
  *Effects:* Equivalent to: `return size() == 0;`
13186
 
13187
+ ##### Element access <a id="span.elem">[[span.elem]]</a>
13188
 
13189
  ``` cpp
13190
  constexpr reference operator[](size_type idx) const;
13191
  ```
13192
 
 
13212
 
13213
  ``` cpp
13214
  constexpr pointer data() const noexcept;
13215
  ```
13216
 
13217
+ *Effects:* Equivalent to: `return `*`data_`*`;`
13218
 
13219
+ ##### Iterator support <a id="span.iterators">[[span.iterators]]</a>
13220
 
13221
  ``` cpp
13222
  using iterator = implementation-defined // type of span::iterator;
13223
  ```
13224
 
13225
  The type models `contiguous_iterator` [[iterator.concept.contiguous]],
13226
  meets the *Cpp17RandomAccessIterator*
13227
  requirements [[random.access.iterators]], and meets the requirements for
13228
+ constexpr iterators [[iterator.requirements.general]], whose value type
13229
+ is `value_type` and whose reference type is `reference`.
13230
+
13231
+ All requirements on container iterators [[container.reqmts]] apply to
13232
  `span::iterator` as well.
13233
 
13234
  ``` cpp
13235
  constexpr iterator begin() const noexcept;
13236
  ```
 
13278
 
13279
  *Effects:* Equivalent to:
13280
  `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};` where `R`
13281
  is the return type.
13282
 
13283
+ ### Multidimensional access <a id="views.multidim">[[views.multidim]]</a>
13284
+
13285
+ #### Overview <a id="mdspan.overview">[[mdspan.overview]]</a>
13286
+
13287
+ A *multidimensional index space* is a Cartesian product of integer
13288
+ intervals. Each interval can be represented by a half-open range
13289
+ [Lᵢ, Uᵢ), where Lᵢ and Uᵢ are the lower and upper bounds of the iᵗʰ
13290
+ dimension. The *rank* of a multidimensional index space is the number of
13291
+ intervals it represents. The *size of a multidimensional index space* is
13292
+ the product of Uᵢ - Lᵢ for each dimension i if its rank is greater than
13293
+ 0, and 1 otherwise.
13294
+
13295
+ An integer r is a *rank index* of an index space S if r is in the range
13296
+ [0, rank of $S$).
13297
+
13298
+ A pack of integers `idx` is a *multidimensional index* in a
13299
+ multidimensional index space S (or representation thereof) if both of
13300
+ the following are true:
13301
+
13302
+ - `sizeof...(idx)` is equal to the rank of S, and
13303
+ - for every rank index i of S, the iᵗʰ value of `idx` is an integer in
13304
+ the interval [Lᵢ, Uᵢ) of S.
13305
+
13306
+ #### Header `<mdspan>` synopsis <a id="mdspan.syn">[[mdspan.syn]]</a>
13307
+
13308
+ ``` cpp
13309
+ namespace std {
13310
+ // [mdspan.extents], class template extents
13311
+ template<class IndexType, size_t... Extents>
13312
+ class extents;
13313
+
13314
+ // [mdspan.extents.dextents], alias template dextents
13315
+ template<class IndexType, size_t Rank>
13316
+ using dextents = see below;
13317
+
13318
+ // [mdspan.layout], layout mapping
13319
+ struct layout_left;
13320
+ struct layout_right;
13321
+ struct layout_stride;
13322
+
13323
+ // [mdspan.accessor.default], class template default_accessor
13324
+ template<class ElementType>
13325
+ class default_accessor;
13326
+
13327
+ // [mdspan.mdspan], class template mdspan
13328
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
13329
+ class AccessorPolicy = default_accessor<ElementType>>
13330
+ class mdspan;
13331
+ }
13332
+ ```
13333
+
13334
+ #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
13335
+
13336
+ ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
13337
+
13338
+ The class template `extents` represents a multidimensional index space
13339
+ of rank equal to `sizeof...(Extents)`. In subclause [[views]], `extents`
13340
+ is used synonymously with multidimensional index space.
13341
+
13342
+ ``` cpp
13343
+ namespace std {
13344
+ template<class IndexType, size_t... Extents>
13345
+ class extents {
13346
+ public:
13347
+ using index_type = IndexType;
13348
+ using size_type = make_unsigned_t<index_type>;
13349
+ using rank_type = size_t;
13350
+
13351
+ // [mdspan.extents.obs], observers of the multidimensional index space
13352
+ static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
13353
+ static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
13354
+ static constexpr size_t static_extent(rank_type) noexcept;
13355
+ constexpr index_type extent(rank_type) const noexcept;
13356
+
13357
+ // [mdspan.extents.cons], constructors
13358
+ constexpr extents() noexcept = default;
13359
+
13360
+ template<class OtherIndexType, size_t... OtherExtents>
13361
+ constexpr explicit(see below)
13362
+ extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
13363
+ template<class... OtherIndexTypes>
13364
+ constexpr explicit extents(OtherIndexTypes...) noexcept;
13365
+ template<class OtherIndexType, size_t N>
13366
+ constexpr explicit(N != rank_dynamic())
13367
+ extents(span<OtherIndexType, N>) noexcept;
13368
+ template<class OtherIndexType, size_t N>
13369
+ constexpr explicit(N != rank_dynamic())
13370
+ extents(const array<OtherIndexType, N>&) noexcept;
13371
+
13372
+ // [mdspan.extents.cmp], comparison operators
13373
+ template<class OtherIndexType, size_t... OtherExtents>
13374
+ friend constexpr bool operator==(const extents&,
13375
+ const extents<OtherIndexType, OtherExtents...>&) noexcept;
13376
+
13377
+ // [mdspan.extents.expo], exposition-only helpers
13378
+ constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition only
13379
+ constexpr size_t rev-prod-of-extents(rank_type) const noexcept; // exposition only
13380
+ template<class OtherIndexType>
13381
+ static constexpr auto index-cast(OtherIndexType&&) noexcept; // exposition only
13382
+
13383
+ private:
13384
+ static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition only
13385
+ static constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only
13386
+ array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
13387
+ };
13388
+
13389
+ template<class... Integrals>
13390
+ explicit extents(Integrals...)
13391
+ -> see below;
13392
+ }
13393
+ ```
13394
+
13395
+ *Mandates:*
13396
+
13397
+ - `IndexType` is a signed or unsigned integer type, and
13398
+ - each element of `Extents` is either equal to `dynamic_extent`, or is
13399
+ representable as a value of type `IndexType`.
13400
+
13401
+ Each specialization of `extents` models `regular` and is trivially
13402
+ copyable.
13403
+
13404
+ Let Eᵣ be the rᵗʰ element of `Extents`. Eᵣ is a *dynamic extent* if it
13405
+ is equal to `dynamic_extent`, otherwise Eᵣ is a *static extent*. Let Dᵣ
13406
+ be the value of `dynamic-extents[dynamic-index(r)]` if Eᵣ is a dynamic
13407
+ extent, otherwise Eᵣ.
13408
+
13409
+ The rᵗʰ interval of the multidimensional index space represented by an
13410
+ `extents` object is [0, Dᵣ).
13411
+
13412
+ ##### Exposition-only helpers <a id="mdspan.extents.expo">[[mdspan.extents.expo]]</a>
13413
+
13414
+ ``` cpp
13415
+ static constexpr rank_type dynamic-index(rank_type i) noexcept;
13416
+ ```
13417
+
13418
+ *Preconditions:* `i <= rank()` is `true`.
13419
+
13420
+ *Returns:* The number of Eᵣ with r < `i` for which Eᵣ is a dynamic
13421
+ extent.
13422
+
13423
+ ``` cpp
13424
+ static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
13425
+ ```
13426
+
13427
+ *Preconditions:* `i < rank_dynamic()` is `true`.
13428
+
13429
+ *Returns:* The minimum value of r such that
13430
+ *`dynamic-index`*`(`r` + 1) == i + 1` is `true`.
13431
+
13432
+ ``` cpp
13433
+ constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
13434
+ ```
13435
+
13436
+ *Preconditions:* `i <= rank()` is `true`.
13437
+
13438
+ *Returns:* If `i > 0` is `true`, the product of `extent(`k`)` for all k
13439
+ in the range [0, `i`), otherwise `1`.
13440
+
13441
+ ``` cpp
13442
+ constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
13443
+ ```
13444
+
13445
+ *Preconditions:* `i < rank()` is `true`.
13446
+
13447
+ *Returns:* If `i + 1 < rank()` is `true`, the product of `extent(`k`)`
13448
+ for all k in the range [`i + 1`, `rank()`), otherwise `1`.
13449
+
13450
+ ``` cpp
13451
+ template<class OtherIndexType>
13452
+ static constexpr auto index-cast(OtherIndexType&& i) noexcept;
13453
+ ```
13454
+
13455
+ *Effects:*
13456
+
13457
+ - If `OtherIndexType` is an integral type other than `bool`, then
13458
+ equivalent to `return i;`,
13459
+ - otherwise, equivalent to `return static_cast<index_type>(i);`.
13460
+
13461
+ [*Note 1*: This function will always return an integral type other than
13462
+ `bool`. Since this function’s call sites are constrained on
13463
+ convertibility of `OtherIndexType` to `index_type`, integer-class types
13464
+ can use the `static_cast` branch without loss of
13465
+ precision. — *end note*]
13466
+
13467
+ ##### Constructors <a id="mdspan.extents.cons">[[mdspan.extents.cons]]</a>
13468
+
13469
+ ``` cpp
13470
+ template<class OtherIndexType, size_t... OtherExtents>
13471
+ constexpr explicit(see below)
13472
+ extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
13473
+ ```
13474
+
13475
+ *Constraints:*
13476
+
13477
+ - `sizeof...(OtherExtents) == rank()` is `true`.
13478
+ - `((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents == Extents) && ...)`
13479
+ is `true`.
13480
+
13481
+ *Preconditions:*
13482
+
13483
+ - `other.extent(`r`)` equals Eᵣ for each r for which Eᵣ is a static
13484
+ extent, and
13485
+ - either
13486
+ - `sizeof...(OtherExtents)` is zero, or
13487
+ - `other.extent(`r`)` is representable as a value of type `index_type`
13488
+ for every rank index r of `other`.
13489
+
13490
+ *Ensures:* `*this == other` is `true`.
13491
+
13492
+ *Remarks:* The expression inside `explicit` is equivalent to:
13493
+
13494
+ ``` cpp
13495
+ (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
13496
+ (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
13497
+ ```
13498
+
13499
+ ``` cpp
13500
+ template<class... OtherIndexTypes>
13501
+ constexpr explicit extents(OtherIndexTypes... exts) noexcept;
13502
+ ```
13503
+
13504
+ Let `N` be `sizeof...(OtherIndexTypes)`, and let `exts_arr` be
13505
+ `array<index_type, N>{static_cast<`
13506
+ `index_type>(std::move(exts))...}`.
13507
+
13508
+ *Constraints:*
13509
+
13510
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
13511
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
13512
+ `true`, and
13513
+ - `N == rank_dynamic() || N == rank()` is `true`. \[*Note 1*: One can
13514
+ construct `extents` from just dynamic extents, which are all the
13515
+ values getting stored, or from all the extents with a
13516
+ precondition. — *end note*]
13517
+
13518
+ *Preconditions:*
13519
+
13520
+ - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
13521
+ r for which Eᵣ is a static extent, and
13522
+ - either
13523
+ - `sizeof...(exts) == 0` is `true`, or
13524
+ - each element of `exts` is nonnegative and is representable as a
13525
+ value of type `index_type`.
13526
+
13527
+ *Ensures:* `*this == extents(exts_arr)` is `true`.
13528
+
13529
+ ``` cpp
13530
+ template<class OtherIndexType, size_t N>
13531
+ constexpr explicit(N != rank_dynamic())
13532
+ extents(span<OtherIndexType, N> exts) noexcept;
13533
+ template<class OtherIndexType, size_t N>
13534
+ constexpr explicit(N != rank_dynamic())
13535
+ extents(const array<OtherIndexType, N>& exts) noexcept;
13536
+ ```
13537
+
13538
+ *Constraints:*
13539
+
13540
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
13541
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
13542
+ `true`, and
13543
+ - `N == rank_dynamic() || N == rank()` is `true`.
13544
+
13545
+ *Preconditions:*
13546
+
13547
+ - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
13548
+ for which Eᵣ is a static extent, and
13549
+ - either
13550
+ - `N` is zero, or
13551
+ - `exts[`r`]` is nonnegative and is representable as a value of type
13552
+ `index_type` for every rank index r.
13553
+
13554
+ *Effects:*
13555
+
13556
+ - If `N` equals `dynamic_rank()`, for all d in the range
13557
+ [0, `rank_dynamic()`), direct-non-list-initializes
13558
+ *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
13559
+ - Otherwise, for all d in the range [0, `rank_dynamic()`),
13560
+ direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
13561
+ `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
13562
+
13563
+ ``` cpp
13564
+ template<class... Integrals>
13565
+ explicit extents(Integrals...) -> see below;
13566
+ ```
13567
+
13568
+ *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
13569
+
13570
+ *Remarks:* The deduced type is `dextents<size_t, sizeof...(Integrals)>`.
13571
+
13572
+ ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
13573
+
13574
+ ``` cpp
13575
+ static constexpr size_t static_extent(rank_type i) noexcept;
13576
+ ```
13577
+
13578
+ *Preconditions:* `i < rank()` is `true`.
13579
+
13580
+ *Returns:* E_`i`.
13581
+
13582
+ ``` cpp
13583
+ constexpr index_type extent(rank_type i) const noexcept;
13584
+ ```
13585
+
13586
+ *Preconditions:* `i < rank()` is `true`.
13587
+
13588
+ *Returns:* D_`i`.
13589
+
13590
+ ##### Comparison operators <a id="mdspan.extents.cmp">[[mdspan.extents.cmp]]</a>
13591
+
13592
+ ``` cpp
13593
+ template<class OtherIndexType, size_t... OtherExtents>
13594
+ friend constexpr bool operator==(const extents& lhs,
13595
+ const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
13596
+ ```
13597
+
13598
+ *Returns:* `true` if `lhs.rank()` equals `rhs.rank()` and if
13599
+ `lhs.extent(r)` equals `rhs.extent(r)` for every rank index `r` of
13600
+ `rhs`, otherwise `false`.
13601
+
13602
+ ##### Alias template `dextents` <a id="mdspan.extents.dextents">[[mdspan.extents.dextents]]</a>
13603
+
13604
+ ``` cpp
13605
+ template<class IndexType, size_t Rank>
13606
+ using dextents = see below;
13607
+ ```
13608
+
13609
+ *Result:* A type `E` that is a specialization of `extents` such that
13610
+ `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
13611
+ `E::index_type` denotes `IndexType`.
13612
+
13613
+ #### Layout mapping <a id="mdspan.layout">[[mdspan.layout]]</a>
13614
+
13615
+ ##### General <a id="mdspan.layout.general">[[mdspan.layout.general]]</a>
13616
+
13617
+ In subclauses [[mdspan.layout.reqmts]] and
13618
+ [[mdspan.layout.policy.reqmts]]:
13619
+
13620
+ - `M` denotes a layout mapping class.
13621
+ - `m` denotes a (possibly const) value of type `M`.
13622
+ - `i` and `j` are packs of (possibly const) integers that are
13623
+ multidimensional indices in `m.extents()` [[mdspan.overview]].
13624
+ \[*Note 1*: The type of each element of the packs can be a different
13625
+ integer type. — *end note*]
13626
+ - `r` is a (possibly const) rank index of `typename M::extents_type`.
13627
+ - `dᵣ` is a pack of (possibly const) integers for which
13628
+ `sizeof...(dᵣ) == M::extents_type::rank()` is `true`, the rᵗʰ element
13629
+ is equal to 1, and all other elements are equal to 0.
13630
+
13631
+ In subclauses [[mdspan.layout.reqmts]] through [[mdspan.layout.stride]],
13632
+ let *`is-mapping-of`* be the exposition-only variable template defined
13633
+ as follows:
13634
+
13635
+ ``` cpp
13636
+ template<class Layout, class Mapping>
13637
+ constexpr bool is-mapping-of = // exposition only
13638
+ is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
13639
+ ```
13640
+
13641
+ ##### Requirements <a id="mdspan.layout.reqmts">[[mdspan.layout.reqmts]]</a>
13642
+
13643
+ A type `M` meets the *layout mapping* requirements if
13644
+
13645
+ - `M` models `copyable` and `equality_comparable`,
13646
+ - `is_nothrow_move_constructible_v<M>` is `true`,
13647
+ - `is_nothrow_move_assignable_v<M>` is `true`,
13648
+ - `is_nothrow_swappable_v<M>` is `true`, and
13649
+ - the following types and expressions are well-formed and have the
13650
+ specified semantics.
13651
+
13652
+ ``` cpp
13653
+ typename M::extents_type
13654
+ ```
13655
+
13656
+ *Result:* A type that is a specialization of `extents`.
13657
+
13658
+ ``` cpp
13659
+ typename M::index_type
13660
+ ```
13661
+
13662
+ *Result:* `typename M::extents_type::index_type`.
13663
+
13664
+ ``` cpp
13665
+ typename M::rank_type
13666
+ ```
13667
+
13668
+ *Result:* `typename M::extents_type::rank_type`.
13669
+
13670
+ ``` cpp
13671
+ typename M::layout_type
13672
+ ```
13673
+
13674
+ *Result:* A type `MP` that meets the layout mapping policy
13675
+ requirements [[mdspan.layout.policy.reqmts]] and for which
13676
+ *`is-mapping-of`*`<MP, M>` is `true`.
13677
+
13678
+ ``` cpp
13679
+ m.extents()
13680
+ ```
13681
+
13682
+ *Result:* `const typename M::extents_type&`
13683
+
13684
+ ``` cpp
13685
+ m(i...)
13686
+ ```
13687
+
13688
+ *Result:* `typename M::index_type`
13689
+
13690
+ *Returns:* A nonnegative integer less than
13691
+ `numeric_limits<typename M::index_type>::max()` and less than or equal
13692
+ to `numeric_limits<size_t>::max()`.
13693
+
13694
+ ``` cpp
13695
+ m(i...) == m(static_cast<typename M::index_type>(i)...)
13696
+ ```
13697
+
13698
+ *Result:* `bool`
13699
+
13700
+ *Returns:* `true`
13701
+
13702
+ ``` cpp
13703
+ m.required_span_size()
13704
+ ```
13705
+
13706
+ *Result:* `typename M::index_type`
13707
+
13708
+ *Returns:* If the size of the multidimensional index space `m.extents()`
13709
+ is 0, then `0`, else `1` plus the maximum value of `m(i...)` for all
13710
+ `i`.
13711
+
13712
+ ``` cpp
13713
+ m.is_unique()
13714
+ ```
13715
+
13716
+ *Result:* `bool`
13717
+
13718
+ *Returns:* `true` only if for every `i` and `j` where `(i != j || ...)`
13719
+ is `true`, `m(i...) != m(j...)` is `true`.
13720
+
13721
+ [*Note 1*: A mapping can return `false` even if the condition is met.
13722
+ For certain layouts, it is possibly not feasible to determine
13723
+ efficiently whether the layout is unique. — *end note*]
13724
+
13725
+ ``` cpp
13726
+ m.is_exhaustive()
13727
+ ```
13728
+
13729
+ *Result:* `bool`
13730
+
13731
+ *Returns:* `true` only if for all k in the range
13732
+ [0, `m.required_span_size()`) there exists an `i` such that `m(i...)`
13733
+ equals k.
13734
+
13735
+ [*Note 2*: A mapping can return `false` even if the condition is met.
13736
+ For certain layouts, it is possibly not feasible to determine
13737
+ efficiently whether the layout is exhaustive. — *end note*]
13738
+
13739
+ ``` cpp
13740
+ m.is_strided()
13741
+ ```
13742
+
13743
+ *Result:* `bool`
13744
+
13745
+ *Returns:* `true` only if for every rank index r of `m.extents()` there
13746
+ exists an integer sᵣ such that, for all `i` where (`i`+dᵣ) is a
13747
+ multidimensional index in `m.extents()` [[mdspan.overview]],
13748
+ `m((i + `dᵣ`)...) - m(i...)` equals sᵣ.
13749
+
13750
+ [*Note 3*: This implies that for a strided layout
13751
+ m(i₀, …, iₖ) = m(0, …, 0) + i₀ × s₀ + … + iₖ × sₖ. — *end note*]
13752
+
13753
+ [*Note 4*: A mapping can return `false` even if the condition is met.
13754
+ For certain layouts, it is possibly not feasible to determine
13755
+ efficiently whether the layout is strided. — *end note*]
13756
+
13757
+ ``` cpp
13758
+ m.stride(r)
13759
+ ```
13760
+
13761
+ *Preconditions:* `m.is_strided()` is `true`.
13762
+
13763
+ *Result:* `typename M::index_type`
13764
+
13765
+ *Returns:* sᵣ as defined in `m.is_strided()` above.
13766
+
13767
+ ``` cpp
13768
+ M::is_always_unique()
13769
+ ```
13770
+
13771
+ *Result:* A constant expression [[expr.const]] of type `bool`.
13772
+
13773
+ *Returns:* `true` only if `m.is_unique()` is `true` for all possible
13774
+ objects `m` of type `M`.
13775
+
13776
+ [*Note 5*: A mapping can return `false` even if the above condition is
13777
+ met. For certain layout mappings, it is possibly not feasible to
13778
+ determine whether every instance is unique. — *end note*]
13779
+
13780
+ ``` cpp
13781
+ M::is_always_exhaustive()
13782
+ ```
13783
+
13784
+ *Result:* A constant expression [[expr.const]] of type `bool`.
13785
+
13786
+ *Returns:* `true` only if `m.is_exhaustive()` is `true` for all possible
13787
+ objects `m` of type `M`.
13788
+
13789
+ [*Note 6*: A mapping can return `false` even if the above condition is
13790
+ met. For certain layout mappings, it is possibly not feasible to
13791
+ determine whether every instance is exhaustive. — *end note*]
13792
+
13793
+ ``` cpp
13794
+ M::is_always_strided()
13795
+ ```
13796
+
13797
+ *Result:* A constant expression [[expr.const]] of type `bool`.
13798
+
13799
+ *Returns:* `true` only if `m.is_strided()` is `true` for all possible
13800
+ objects `m` of type `M`.
13801
+
13802
+ [*Note 7*: A mapping can return `false` even if the above condition is
13803
+ met. For certain layout mappings, it is possibly not feasible to
13804
+ determine whether every instance is strided. — *end note*]
13805
+
13806
+ ##### Layout mapping policy requirements <a id="mdspan.layout.policy.reqmts">[[mdspan.layout.policy.reqmts]]</a>
13807
+
13808
+ A type `MP` meets the *layout mapping policy* requirements if for a type
13809
+ `E` that is a specialization of `extents`, `MP::mapping<E>` is valid and
13810
+ denotes a type `X` that meets the layout mapping requirements
13811
+ [[mdspan.layout.reqmts]], and for which the *qualified-id*
13812
+ `X::layout_type` is valid and denotes the type `MP` and the
13813
+ *qualified-id* `X::extents_type` denotes `E`.
13814
+
13815
+ ##### Layout mapping policies <a id="mdspan.layout.policy.overview">[[mdspan.layout.policy.overview]]</a>
13816
+
13817
+ ``` cpp
13818
+ namespace std {
13819
+ struct layout_left {
13820
+ template<class Extents>
13821
+ class mapping;
13822
+ };
13823
+ struct layout_right {
13824
+ template<class Extents>
13825
+ class mapping;
13826
+ };
13827
+ struct layout_stride {
13828
+ template<class Extents>
13829
+ class mapping;
13830
+ };
13831
+ }
13832
+ ```
13833
+
13834
+ Each of `layout_left`, `layout_right`, and `layout_stride` meets the
13835
+ layout mapping policy requirements and is a trivial type.
13836
+
13837
+ ##### Class template `layout_left::mapping` <a id="mdspan.layout.left">[[mdspan.layout.left]]</a>
13838
+
13839
+ ###### Overview <a id="mdspan.layout.left.overview">[[mdspan.layout.left.overview]]</a>
13840
+
13841
+ `layout_left` provides a layout mapping where the leftmost extent has
13842
+ stride 1, and strides increase left-to-right as the product of extents.
13843
+
13844
+ ``` cpp
13845
+ namespace std {
13846
+ template<class Extents>
13847
+ class layout_left::mapping {
13848
+ public:
13849
+ using extents_type = Extents;
13850
+ using index_type = typename extents_type::index_type;
13851
+ using size_type = typename extents_type::size_type;
13852
+ using rank_type = typename extents_type::rank_type;
13853
+ using layout_type = layout_left;
13854
+
13855
+ // [mdspan.layout.left.cons], constructors
13856
+ constexpr mapping() noexcept = default;
13857
+ constexpr mapping(const mapping&) noexcept = default;
13858
+ constexpr mapping(const extents_type&) noexcept;
13859
+ template<class OtherExtents>
13860
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13861
+ mapping(const mapping<OtherExtents>&) noexcept;
13862
+ template<class OtherExtents>
13863
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13864
+ mapping(const layout_right::mapping<OtherExtents>&) noexcept;
13865
+ template<class OtherExtents>
13866
+ constexpr explicit(extents_type::rank() > 0)
13867
+ mapping(const layout_stride::mapping<OtherExtents>&);
13868
+
13869
+ constexpr mapping& operator=(const mapping&) noexcept = default;
13870
+
13871
+ // [mdspan.layout.left.obs], observers
13872
+ constexpr const extents_type& extents() const noexcept { return extents_; }
13873
+
13874
+ constexpr index_type required_span_size() const noexcept;
13875
+
13876
+ template<class... Indices>
13877
+ constexpr index_type operator()(Indices...) const noexcept;
13878
+
13879
+ static constexpr bool is_always_unique() noexcept { return true; }
13880
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
13881
+ static constexpr bool is_always_strided() noexcept { return true; }
13882
+
13883
+ static constexpr bool is_unique() noexcept { return true; }
13884
+ static constexpr bool is_exhaustive() noexcept { return true; }
13885
+ static constexpr bool is_strided() noexcept { return true; }
13886
+
13887
+ constexpr index_type stride(rank_type) const noexcept;
13888
+
13889
+ template<class OtherExtents>
13890
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
13891
+
13892
+ private:
13893
+ extents_type extents_{}; // exposition only
13894
+ };
13895
+ }
13896
+ ```
13897
+
13898
+ If `Extents` is not a specialization of `extents`, then the program is
13899
+ ill-formed.
13900
+
13901
+ `layout_left::mapping<E>` is a trivially copyable type that models
13902
+ `regular` for each `E`.
13903
+
13904
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
13905
+ of the multidimensional index space `Extents()` is representable as a
13906
+ value of type `typename Extents::index_type`.
13907
+
13908
+ ###### Constructors <a id="mdspan.layout.left.cons">[[mdspan.layout.left.cons]]</a>
13909
+
13910
+ ``` cpp
13911
+ constexpr mapping(const extents_type& e) noexcept;
13912
+ ```
13913
+
13914
+ *Preconditions:* The size of the multidimensional index space `e` is
13915
+ representable as a value of type `index_type` [[basic.fundamental]].
13916
+
13917
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
13918
+
13919
+ ``` cpp
13920
+ template<class OtherExtents>
13921
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13922
+ mapping(const mapping<OtherExtents>& other) noexcept;
13923
+ ```
13924
+
13925
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
13926
+ `true`.
13927
+
13928
+ *Preconditions:* `other.required_span_size()` is representable as a
13929
+ value of type `index_type` [[basic.fundamental]].
13930
+
13931
+ *Effects:* Direct-non-list-initializes *extents\_* with
13932
+ `other.extents()`.
13933
+
13934
+ ``` cpp
13935
+ template<class OtherExents>
13936
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13937
+ mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
13938
+ ```
13939
+
13940
+ *Constraints:*
13941
+
13942
+ - `extents_type::rank() <= 1` is `true`, and
13943
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
13944
+
13945
+ *Preconditions:* `other.required_span_size()` is representable as a
13946
+ value of type `index_type` [[basic.fundamental]].
13947
+
13948
+ *Effects:* Direct-non-list-initializes *extents\_* with
13949
+ `other.extents()`.
13950
+
13951
+ ``` cpp
13952
+ template<class OtherExtents>
13953
+ constexpr explicit(extents_type::rank() > 0)
13954
+ mapping(const layout_stride::mapping<OtherExtents>& other);
13955
+ ```
13956
+
13957
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
13958
+ `true`.
13959
+
13960
+ *Preconditions:*
13961
+
13962
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
13963
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
13964
+ `other.extents().`*`fwd-prod-of-extents`*`(`r`)`, and
13965
+ - `other.required_span_size()` is representable as a value of type
13966
+ `index_type` [[basic.fundamental]].
13967
+
13968
+ *Effects:* Direct-non-list-initializes *extents\_* with
13969
+ `other.extents()`.
13970
+
13971
+ ###### Observers <a id="mdspan.layout.left.obs">[[mdspan.layout.left.obs]]</a>
13972
+
13973
+ ``` cpp
13974
+ constexpr index_type required_span_size() const noexcept;
13975
+ ```
13976
+
13977
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
13978
+
13979
+ ``` cpp
13980
+ template<class... Indices>
13981
+ constexpr index_type operator()(Indices... i) const noexcept;
13982
+ ```
13983
+
13984
+ *Constraints:*
13985
+
13986
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
13987
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
13988
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
13989
+
13990
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
13991
+ multidimensional index in *extents\_*[[mdspan.overview]].
13992
+
13993
+ *Effects:* Let `P` be a parameter pack such that
13994
+
13995
+ ``` cpp
13996
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
13997
+ ```
13998
+
13999
+ is `true`. Equivalent to:
14000
+
14001
+ ``` cpp
14002
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
14003
+ ```
14004
+
14005
+ ``` cpp
14006
+ constexpr index_type stride(rank_type i) const;
14007
+ ```
14008
+
14009
+ *Constraints:* `extents_type::rank() > 0` is `true`.
14010
+
14011
+ *Preconditions:* `i < extents_type::rank()` is `true`.
14012
+
14013
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(i)`.
14014
+
14015
+ ``` cpp
14016
+ template<class OtherExtents>
14017
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
14018
+ ```
14019
+
14020
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
14021
+
14022
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
14023
+
14024
+ ##### Class template `layout_right::mapping` <a id="mdspan.layout.right">[[mdspan.layout.right]]</a>
14025
+
14026
+ ###### Overview <a id="mdspan.layout.right.overview">[[mdspan.layout.right.overview]]</a>
14027
+
14028
+ `layout_right` provides a layout mapping where the rightmost extent is
14029
+ stride 1, and strides increase right-to-left as the product of extents.
14030
+
14031
+ ``` cpp
14032
+ namespace std {
14033
+ template<class Extents>
14034
+ class layout_right::mapping {
14035
+ public:
14036
+ using extents_type = Extents;
14037
+ using index_type = typename extents_type::index_type;
14038
+ using size_type = typename extents_type::size_type;
14039
+ using rank_type = typename extents_type::rank_type;
14040
+ using layout_type = layout_right;
14041
+
14042
+ // [mdspan.layout.right.cons], constructors
14043
+ constexpr mapping() noexcept = default;
14044
+ constexpr mapping(const mapping&) noexcept = default;
14045
+ constexpr mapping(const extents_type&) noexcept;
14046
+ template<class OtherExtents>
14047
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14048
+ mapping(const mapping<OtherExtents>&) noexcept;
14049
+ template<class OtherExtents>
14050
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14051
+ mapping(const layout_left::mapping<OtherExtents>&) noexcept;
14052
+ template<class OtherExtents>
14053
+ constexpr explicit(extents_type::rank() > 0)
14054
+ mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
14055
+
14056
+ constexpr mapping& operator=(const mapping&) noexcept = default;
14057
+
14058
+ // [mdspan.layout.right.obs], observers
14059
+ constexpr const extents_type& extents() const noexcept { return extents_; }
14060
+
14061
+ constexpr index_type required_span_size() const noexcept;
14062
+
14063
+ template<class... Indices>
14064
+ constexpr index_type operator()(Indices...) const noexcept;
14065
+
14066
+ static constexpr bool is_always_unique() noexcept { return true; }
14067
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
14068
+ static constexpr bool is_always_strided() noexcept { return true; }
14069
+
14070
+ static constexpr bool is_unique() noexcept { return true; }
14071
+ static constexpr bool is_exhaustive() noexcept { return true; }
14072
+ static constexpr bool is_strided() noexcept { return true; }
14073
+
14074
+ constexpr index_type stride(rank_type) const noexcept;
14075
+
14076
+ template<class OtherExtents>
14077
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
14078
+
14079
+ private:
14080
+ extents_type extents_{}; // exposition only
14081
+ };
14082
+ }
14083
+ ```
14084
+
14085
+ If `Extents` is not a specialization of `extents`, then the program is
14086
+ ill-formed.
14087
+
14088
+ `layout_right::mapping<E>` is a trivially copyable type that models
14089
+ `regular` for each `E`.
14090
+
14091
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
14092
+ of the multidimensional index space `Extents()` is representable as a
14093
+ value of type `typename Extents::index_type`.
14094
+
14095
+ ###### Constructors <a id="mdspan.layout.right.cons">[[mdspan.layout.right.cons]]</a>
14096
+
14097
+ ``` cpp
14098
+ constexpr mapping(const extents_type& e) noexcept;
14099
+ ```
14100
+
14101
+ *Preconditions:* The size of the multidimensional index space `e` is
14102
+ representable as a value of type `index_type` [[basic.fundamental]].
14103
+
14104
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
14105
+
14106
+ ``` cpp
14107
+ template<class OtherExtents>
14108
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14109
+ mapping(const mapping<OtherExtents>& other) noexcept;
14110
+ ```
14111
+
14112
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
14113
+ `true`.
14114
+
14115
+ *Preconditions:* `other.required_span_size()` is representable as a
14116
+ value of type `index_type` [[basic.fundamental]].
14117
+
14118
+ *Effects:* Direct-non-list-initializes *extents\_* with
14119
+ `other.extents()`.
14120
+
14121
+ ``` cpp
14122
+ template<class OtherExtents>
14123
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14124
+ mapping(const layout_left::mapping<OtherExtents>& other) noexcept;
14125
+ ```
14126
+
14127
+ *Constraints:*
14128
+
14129
+ - `extents_type::rank() <= 1` is `true`, and
14130
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
14131
+
14132
+ *Preconditions:* `other.required_span_size()` is representable as a
14133
+ value of type `index_type` [[basic.fundamental]].
14134
+
14135
+ *Effects:* Direct-non-list-initializes *extents\_* with
14136
+ `other.extents()`.
14137
+
14138
+ ``` cpp
14139
+ template<class OtherExtents>
14140
+ constexpr explicit(extents_type::rank() > 0)
14141
+ mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
14142
+ ```
14143
+
14144
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
14145
+ `true`.
14146
+
14147
+ *Preconditions:*
14148
+
14149
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
14150
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
14151
+ `other.extents().`*`rev-prod-of-extents`*`(`r`)`.
14152
+ - `other.required_span_size()` is representable as a value of type
14153
+ `index_type` [[basic.fundamental]].
14154
+
14155
+ *Effects:* Direct-non-list-initializes *extents\_* with
14156
+ `other.extents()`.
14157
+
14158
+ ###### Observers <a id="mdspan.layout.right.obs">[[mdspan.layout.right.obs]]</a>
14159
+
14160
+ ``` cpp
14161
+ index_type required_span_size() const noexcept;
14162
+ ```
14163
+
14164
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
14165
+
14166
+ ``` cpp
14167
+ template<class... Indices>
14168
+ constexpr index_type operator()(Indices... i) const noexcept;
14169
+ ```
14170
+
14171
+ *Constraints:*
14172
+
14173
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
14174
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
14175
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
14176
+
14177
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
14178
+ multidimensional index in *extents\_*[[mdspan.overview]].
14179
+
14180
+ *Effects:* Let `P` be a parameter pack such that
14181
+
14182
+ ``` cpp
14183
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
14184
+ ```
14185
+
14186
+ is `true`. Equivalent to:
14187
+
14188
+ ``` cpp
14189
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
14190
+ ```
14191
+
14192
+ ``` cpp
14193
+ constexpr index_type stride(rank_type i) const noexcept;
14194
+ ```
14195
+
14196
+ *Constraints:* `extents_type::rank() > 0` is `true`.
14197
+
14198
+ *Preconditions:* `i < extents_type::rank()` is `true`.
14199
+
14200
+ *Returns:* `extents().`*`rev-prod-of-extents`*`(i)`.
14201
+
14202
+ ``` cpp
14203
+ template<class OtherExtents>
14204
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
14205
+ ```
14206
+
14207
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
14208
+
14209
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
14210
+
14211
+ ##### Class template `layout_stride::mapping` <a id="mdspan.layout.stride">[[mdspan.layout.stride]]</a>
14212
+
14213
+ ###### Overview <a id="mdspan.layout.stride.overview">[[mdspan.layout.stride.overview]]</a>
14214
+
14215
+ `layout_stride` provides a layout mapping where the strides are
14216
+ user-defined.
14217
+
14218
+ ``` cpp
14219
+ namespace std {
14220
+ template<class Extents>
14221
+ class layout_stride::mapping {
14222
+ public:
14223
+ using extents_type = Extents;
14224
+ using index_type = typename extents_type::index_type;
14225
+ using size_type = typename extents_type::size_type;
14226
+ using rank_type = typename extents_type::rank_type;
14227
+ using layout_type = layout_stride;
14228
+
14229
+ private:
14230
+ static constexpr rank_type rank_ = extents_type::rank(); // exposition only
14231
+
14232
+ public:
14233
+ // [mdspan.layout.stride.cons], constructors
14234
+ constexpr mapping() noexcept;
14235
+ constexpr mapping(const mapping&) noexcept = default;
14236
+ template<class OtherIndexType>
14237
+ constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
14238
+ template<class OtherIndexType>
14239
+ constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
14240
+
14241
+ template<class StridedLayoutMapping>
14242
+ constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
14243
+
14244
+ constexpr mapping& operator=(const mapping&) noexcept = default;
14245
+
14246
+ // [mdspan.layout.stride.obs], observers
14247
+ constexpr const extents_type& extents() const noexcept { return extents_; }
14248
+ constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
14249
+
14250
+ constexpr index_type required_span_size() const noexcept;
14251
+
14252
+ template<class... Indices>
14253
+ constexpr index_type operator()(Indices...) const noexcept;
14254
+
14255
+ static constexpr bool is_always_unique() noexcept { return true; }
14256
+ static constexpr bool is_always_exhaustive() noexcept { return false; }
14257
+ static constexpr bool is_always_strided() noexcept { return true; }
14258
+
14259
+ static constexpr bool is_unique() noexcept { return true; }
14260
+ constexpr bool is_exhaustive() const noexcept;
14261
+ static constexpr bool is_strided() noexcept { return true; }
14262
+
14263
+ constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
14264
+
14265
+ template<class OtherMapping>
14266
+ friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
14267
+
14268
+ private:
14269
+ extents_type extents_{}; // exposition only
14270
+ array<index_type, rank_> strides_{}; // exposition only
14271
+ };
14272
+ }
14273
+ ```
14274
+
14275
+ If `Extents` is not a specialization of `extents`, then the program is
14276
+ ill-formed.
14277
+
14278
+ `layout_stride::mapping<E>` is a trivially copyable type that models
14279
+ `regular` for each `E`.
14280
+
14281
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
14282
+ of the multidimensional index space `Extents()` is representable as a
14283
+ value of type `typename Extents::index_type`.
14284
+
14285
+ ###### Exposition-only helpers <a id="mdspan.layout.stride.expo">[[mdspan.layout.stride.expo]]</a>
14286
+
14287
+ Let `REQUIRED-SPAN-SIZE(e, strides)` be:
14288
+
14289
+ - `1`, if `e.rank() == 0` is `true`,
14290
+ - otherwise `0`, if the size of the multidimensional index space `e` is
14291
+ 0,
14292
+ - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
14293
+ `strides[r]` for all r in the range [0, `e.rank()`).
14294
+
14295
+ Let `OFFSET(m)` be:
14296
+
14297
+ - `m()`, if `e.rank() == 0` is `true`,
14298
+ - otherwise `0`, if the size of the multidimensional index space `e` is
14299
+ 0,
14300
+ - otherwise `m(z...)` for a pack of integers `z` that is a
14301
+ multidimensional index in `m.extents()` and each element of `z` equals
14302
+ 0.
14303
+
14304
+ Let *`is-extents`* be the exposition-only variable template defined as
14305
+ follows:
14306
+
14307
+ ``` cpp
14308
+ template<class T>
14309
+ constexpr bool is-extents = false; // exposition only
14310
+ template<class IndexType, size_t... Args>
14311
+ constexpr bool is-extents<extents<IndexType, Args...>> = true; // exposition only
14312
+ ```
14313
+
14314
+ Let `layout-mapping-alike` be the exposition-only concept defined as
14315
+ follows:
14316
+
14317
+ ``` cpp
14318
+ template<class M>
14319
+ concept layout-mapping-alike = requires { // exposition only
14320
+ requires is-extents<typename M::extents_type>;
14321
+ { M::is_always_strided() } -> same_as<bool>;
14322
+ { M::is_always_exhaustive() } -> same_as<bool>;
14323
+ { M::is_always_unique() } -> same_as<bool>;
14324
+ bool_constant<M::is_always_strided()>::value;
14325
+ bool_constant<M::is_always_exhaustive()>::value;
14326
+ bool_constant<M::is_always_unique()>::value;
14327
+ };
14328
+ ```
14329
+
14330
+ [*Note 2*: This concept checks that the functions
14331
+ `M::is_always_strided()`, `M::is_always_exhaustive()`, and
14332
+ `M::is_always_unique()` exist, are constant expressions, and have a
14333
+ return type of `bool`. — *end note*]
14334
+
14335
+ ###### Constructors <a id="mdspan.layout.stride.cons">[[mdspan.layout.stride.cons]]</a>
14336
+
14337
+ ``` cpp
14338
+ constexpr mapping() noexcept;
14339
+ ```
14340
+
14341
+ *Preconditions:*
14342
+ `layout_right::mapping<extents_type>().required_span_size()` is
14343
+ representable as a value of type `index_type` [[basic.fundamental]].
14344
+
14345
+ *Effects:* Direct-non-list-initializes *extents\_* with
14346
+ `extents_type()`, and for all d in the range \[`0`, *`rank_`*),
14347
+ direct-non-list-initializes *`strides_`*`[`d`]` with
14348
+ `layout_right::mapping<extents_type>().stride(`d`)`.
14349
+
14350
+ ``` cpp
14351
+ template<class OtherIndexType>
14352
+ constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
14353
+ template<class OtherIndexType>
14354
+ constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
14355
+ ```
14356
+
14357
+ *Constraints:*
14358
+
14359
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
14360
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
14361
+ `true`.
14362
+
14363
+ *Preconditions:*
14364
+
14365
+ - `s[`i`] > 0` is `true` for all i in the range [0, rank_).
14366
+ - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
14367
+ `index_type` [[basic.fundamental]].
14368
+ - If *rank\_* is greater than 0, then there exists a permutation P of
14369
+ the integers in the range [0, rank_), such that
14370
+ `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
14371
+ range [1, rank_), where pᵢ is the iᵗʰ element of P. \[*Note 3*: For
14372
+ `layout_stride`, this condition is necessary and sufficient for
14373
+ `is_unique()` to be `true`. — *end note*]
14374
+
14375
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`, and for all
14376
+ d in the range [0, rank_), direct-non-list-initializes `strides_[`d`]`
14377
+ with `as_const(s[`d`])`.
14378
+
14379
+ ``` cpp
14380
+ template<class StridedLayoutMapping>
14381
+ constexpr explicit(see below)
14382
+ mapping(const StridedLayoutMapping& other) noexcept;
14383
+ ```
14384
+
14385
+ *Constraints:*
14386
+
14387
+ - `layout-mapping-alike<StridedLayoutMapping>` is satisfied.
14388
+ - `is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type>`
14389
+ is
14390
+ `true`.
14391
+ - `StridedLayoutMapping::is_always_unique()` is `true`.
14392
+ - `StridedLayoutMapping::is_always_strided()` is `true`.
14393
+
14394
+ *Preconditions:*
14395
+
14396
+ - `StridedLayoutMapping` meets the layout mapping
14397
+ requirements [[mdspan.layout.policy.reqmts]],
14398
+ - `other.stride(`r`) > 0` is `true` for every rank index r of
14399
+ `extents()`,
14400
+ - `other.required_span_size()` is representable as a value of type
14401
+ `index_type` [[basic.fundamental]], and
14402
+ - *`OFFSET`*`(other) == 0` is `true`.
14403
+
14404
+ *Effects:* Direct-non-list-initializes *extents\_* with
14405
+ `other.extents()`, and for all d in the range [0, rank_),
14406
+ direct-non-list-initializes *`strides_`*`[`d`]` with
14407
+ `other.stride(`d`)`.
14408
+
14409
+ Remarks: The expression inside `explicit` is equivalent to:
14410
+
14411
+ ``` cpp
14412
+ !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
14413
+ (is-mapping-of<layout_left, LayoutStrideMapping> ||
14414
+ is-mapping-of<layout_right, LayoutStrideMapping> ||
14415
+ is-mapping-of<layout_stride, LayoutStrideMapping>))
14416
+ ```
14417
+
14418
+ ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
14419
+
14420
+ ``` cpp
14421
+ constexpr index_type required_span_size() const noexcept;
14422
+ ```
14423
+
14424
+ *Returns:* *`REQUIRED-SPAN-SIZE`*`(extents(), `*`strides_`*`)`.
14425
+
14426
+ ``` cpp
14427
+ template<class... Indices>
14428
+ constexpr index_type operator()(Indices... i) const noexcept;
14429
+ ```
14430
+
14431
+ *Constraints:*
14432
+
14433
+ - `sizeof...(Indices) == `*`rank_`* is `true`,
14434
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
14435
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
14436
+
14437
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
14438
+ multidimensional index in *extents\_*[[mdspan.overview]].
14439
+
14440
+ *Effects:* Let `P` be a parameter pack such that
14441
+
14442
+ ``` cpp
14443
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
14444
+ ```
14445
+
14446
+ is `true`. Equivalent to:
14447
+
14448
+ ``` cpp
14449
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
14450
+ ```
14451
+
14452
+ ``` cpp
14453
+ constexpr bool is_exhaustive() const noexcept;
14454
+ ```
14455
+
14456
+ *Returns:*
14457
+
14458
+ - `true` if *rank\_* is 0.
14459
+ - Otherwise, `true` if there is a permutation P of the integers in the
14460
+ range [0, rank_) such that `stride(`p₀`)` equals 1, and `stride(`pᵢ`)`
14461
+ equals `stride(`pᵢ₋₁`) * extents().extent(`pᵢ₋₁`)` for i in the range
14462
+ [1, rank_), where pᵢ is the iᵗʰ element of P.
14463
+ - Otherwise, `false`.
14464
+
14465
+ ``` cpp
14466
+ template<class OtherMapping>
14467
+ friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
14468
+ ```
14469
+
14470
+ *Constraints:*
14471
+
14472
+ - `layout-mapping-alike<OtherMapping>` is satisfied.
14473
+ - *`rank_`*` == OtherMapping::extents_type::rank()` is `true`.
14474
+ - `OtherMapping::is_always_strided()` is `true`.
14475
+
14476
+ *Preconditions:* `OtherMapping` meets the layout mapping
14477
+ requirements [[mdspan.layout.policy.reqmts]].
14478
+
14479
+ *Returns:* `true` if `x.extents() == y.extents()` is `true`,
14480
+ *`OFFSET`*`(y) == 0` is `true`, and each of
14481
+ `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
14482
+ [0, `x.extents().rank()`). Otherwise, `false`.
14483
+
14484
+ #### Accessor policy <a id="mdspan.accessor">[[mdspan.accessor]]</a>
14485
+
14486
+ ##### General <a id="mdspan.accessor.general">[[mdspan.accessor.general]]</a>
14487
+
14488
+ An *accessor policy* defines types and operations by which a reference
14489
+ to a single object is created from an abstract data handle to a number
14490
+ of such objects and an index.
14491
+
14492
+ A range of indices [0, N) is an *accessible range* of a given data
14493
+ handle and an accessor if, for each i in the range, the accessor
14494
+ policy’s `access` function produces a valid reference to an object.
14495
+
14496
+ In subclause [[mdspan.accessor.reqmts]],
14497
+
14498
+ - `A` denotes an accessor policy.
14499
+ - `a` denotes a value of type `A` or `const A`.
14500
+ - `p` denotes a value of type `A::data_handle_type` or
14501
+ `const A::data_handle_type`. \[*Note 1*: The type
14502
+ `A::data_handle_type` need not be dereferenceable. — *end note*]
14503
+ - `n`, `i`, and `j` each denote values of type `size_t`.
14504
+
14505
+ ##### Requirements <a id="mdspan.accessor.reqmts">[[mdspan.accessor.reqmts]]</a>
14506
+
14507
+ A type `A` meets the accessor policy requirements if
14508
+
14509
+ - `A` models `copyable`,
14510
+ - `is_nothrow_move_constructible_v<A>` is `true`,
14511
+ - `is_nothrow_move_assignable_v<A>` is `true`,
14512
+ - `is_nothrow_swappable_v<A>` is `true`, and
14513
+ - the following types and expressions are well-formed and have the
14514
+ specified semantics.
14515
+
14516
+ ``` cpp
14517
+ typename A::element_type
14518
+ ```
14519
+
14520
+ *Result:* A complete object type that is not an abstract class type.
14521
+
14522
+ ``` cpp
14523
+ typename A::data_handle_type
14524
+ ```
14525
+
14526
+ *Result:* A type that models `copyable`, and for which
14527
+ `is_nothrow_move_constructible_v<A::data_handle_type>` is `true`,
14528
+ `is_nothrow_move_assignable_v<A::data_handle_type>` is `true`, and
14529
+ `is_nothrow_swappable_v<A::data_handle_type>` is `true`.
14530
+
14531
+ [*Note 1*: The type of `data_handle_type` need not be
14532
+ `element_type*`. — *end note*]
14533
+
14534
+ ``` cpp
14535
+ typename A::reference
14536
+ ```
14537
+
14538
+ *Result:* A type that models
14539
+ `common_reference_with<A::reference&&, A::element_type&>`.
14540
+
14541
+ [*Note 2*: The type of `reference` need not be
14542
+ `element_type&`. — *end note*]
14543
+
14544
+ ``` cpp
14545
+ typename A::offset_policy
14546
+ ```
14547
+
14548
+ *Result:* A type `OP` such that:
14549
+
14550
+ - `OP` meets the accessor policy requirements,
14551
+ - `constructible_from<OP, const A&>` is modeled, and
14552
+ - `is_same_v<typename OP::element_type, typename A::element_type>` is
14553
+ `true`.
14554
+
14555
+ ``` cpp
14556
+ a.access(p, i)
14557
+ ```
14558
+
14559
+ *Result:* `A::reference`
14560
+
14561
+ *Remarks:* The expression is equality preserving.
14562
+
14563
+ [*Note 3*: Concrete accessor policies can impose preconditions for
14564
+ their `access` function. However, they might not. For example, an
14565
+ accessor where `p` is `span<A::element_type, dynamic_extent>` and
14566
+ `access(p, i)` returns `p[i % p.size()]` does not need to impose a
14567
+ precondition on `i`. — *end note*]
14568
+
14569
+ ``` cpp
14570
+ a.offset(p, i)
14571
+ ```
14572
+
14573
+ *Result:* `A::offset_policy::data_handle_type`
14574
+
14575
+ *Returns:* `q` such that for `b` being `A::offset_policy(a)`, and any
14576
+ integer `n` for which [0, `n`) is an accessible range of `p` and `a`:
14577
+
14578
+ - [0, `n` - `i`) is an accessible range of `q` and `b`; and
14579
+ - `b.access(q, j)` provides access to the same element as
14580
+ `a.access(p, i + j)`, for every `j` in the range [0, `n` - `i`).
14581
+
14582
+ *Remarks:* The expression is equality-preserving.
14583
+
14584
+ ##### Class template `default_accessor` <a id="mdspan.accessor.default">[[mdspan.accessor.default]]</a>
14585
+
14586
+ ###### Overview <a id="mdspan.accessor.default.overview">[[mdspan.accessor.default.overview]]</a>
14587
+
14588
+ ``` cpp
14589
+ namespace std {
14590
+ template<class ElementType>
14591
+ struct default_accessor {
14592
+ using offset_policy = default_accessor;
14593
+ using element_type = ElementType;
14594
+ using reference = ElementType&;
14595
+ using data_handle_type = ElementType*;
14596
+
14597
+ constexpr default_accessor() noexcept = default;
14598
+ template<class OtherElementType>
14599
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
14600
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
14601
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
14602
+ };
14603
+ }
14604
+ ```
14605
+
14606
+ `default_accessor` meets the accessor policy requirements.
14607
+
14608
+ `ElementType` is required to be a complete object type that is neither
14609
+ an abstract class type nor an array type.
14610
+
14611
+ Each specialization of `default_accessor` is a trivially copyable type
14612
+ that models `semiregular`.
14613
+
14614
+ [0, n) is an accessible range for an object `p` of type
14615
+ `data_handle_type` and an object of type `default_accessor` if and only
14616
+ if \[`p`, `p + `n) is a valid range.
14617
+
14618
+ ###### Members <a id="mdspan.accessor.default.members">[[mdspan.accessor.default.members]]</a>
14619
+
14620
+ ``` cpp
14621
+ template<class OtherElementType>
14622
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
14623
+ ```
14624
+
14625
+ *Constraints:*
14626
+ `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is `true`.
14627
+
14628
+ ``` cpp
14629
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
14630
+ ```
14631
+
14632
+ *Effects:* Equivalent to: `return p[i];`
14633
+
14634
+ ``` cpp
14635
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
14636
+ ```
14637
+
14638
+ *Effects:* Equivalent to: `return p + i;`
14639
+
14640
+ #### Class template `mdspan` <a id="mdspan.mdspan">[[mdspan.mdspan]]</a>
14641
+
14642
+ ##### Overview <a id="mdspan.mdspan.overview">[[mdspan.mdspan.overview]]</a>
14643
+
14644
+ `mdspan` is a view of a multidimensional array of elements.
14645
+
14646
+ ``` cpp
14647
+ namespace std {
14648
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
14649
+ class AccessorPolicy = default_accessor<ElementType>>
14650
+ class mdspan {
14651
+ public:
14652
+ using extents_type = Extents;
14653
+ using layout_type = LayoutPolicy;
14654
+ using accessor_type = AccessorPolicy;
14655
+ using mapping_type = typename layout_type::template mapping<extents_type>;
14656
+ using element_type = ElementType;
14657
+ using value_type = remove_cv_t<element_type>;
14658
+ using index_type = typename extents_type::index_type;
14659
+ using size_type = typename extents_type::size_type;
14660
+ using rank_type = typename extents_type::rank_type;
14661
+ using data_handle_type = typename accessor_type::data_handle_type;
14662
+ using reference = typename accessor_type::reference;
14663
+
14664
+ static constexpr rank_type rank() noexcept { return extents_type::rank(); }
14665
+ static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
14666
+ static constexpr size_t static_extent(rank_type r) noexcept
14667
+ { return extents_type::static_extent(r); }
14668
+ constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
14669
+
14670
+ // [mdspan.mdspan.cons], constructors
14671
+ constexpr mdspan();
14672
+ constexpr mdspan(const mdspan& rhs) = default;
14673
+ constexpr mdspan(mdspan&& rhs) = default;
14674
+
14675
+ template<class... OtherIndexTypes>
14676
+ constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
14677
+ template<class OtherIndexType, size_t N>
14678
+ constexpr explicit(N != rank_dynamic())
14679
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
14680
+ template<class OtherIndexType, size_t N>
14681
+ constexpr explicit(N != rank_dynamic())
14682
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
14683
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
14684
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
14685
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
14686
+
14687
+ template<class OtherElementType, class OtherExtents,
14688
+ class OtherLayoutPolicy, class OtherAccessorPolicy>
14689
+ constexpr explicit(see below)
14690
+ mdspan(const mdspan<OtherElementType, OtherExtents,
14691
+ OtherLayoutPolicy, OtherAccessorPolicy>& other);
14692
+
14693
+ constexpr mdspan& operator=(const mdspan& rhs) = default;
14694
+ constexpr mdspan& operator=(mdspan&& rhs) = default;
14695
+
14696
+ // [mdspan.mdspan.members], members
14697
+ template<class... OtherIndexTypes>
14698
+ constexpr reference operator[](OtherIndexTypes... indices) const;
14699
+ template<class OtherIndexType>
14700
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
14701
+ template<class OtherIndexType>
14702
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
14703
+
14704
+ constexpr size_type size() const noexcept;
14705
+ [[nodiscard]] constexpr bool empty() const noexcept;
14706
+
14707
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
14708
+
14709
+ constexpr const extents_type& extents() const noexcept { return map_.extents(); }
14710
+ constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
14711
+ constexpr const mapping_type& mapping() const noexcept { return map_; }
14712
+ constexpr const accessor_type& accessor() const noexcept { return acc_; }
14713
+
14714
+ static constexpr bool is_always_unique()
14715
+ { return mapping_type::is_always_unique(); }
14716
+ static constexpr bool is_always_exhaustive()
14717
+ { return mapping_type::is_always_exhaustive(); }
14718
+ static constexpr bool is_always_strided()
14719
+ { return mapping_type::is_always_strided(); }
14720
+
14721
+ constexpr bool is_unique() const
14722
+ { return map_.is_unique(); }
14723
+ constexpr bool is_exhaustive() const
14724
+ { return map_.is_exhaustive(); }
14725
+ constexpr bool is_strided() const
14726
+ { return map_.is_strided(); }
14727
+ constexpr index_type stride(rank_type r) const
14728
+ { return map_.stride(r); }
14729
+
14730
+ private:
14731
+ accessor_type acc_; // exposition only
14732
+ mapping_type map_; // exposition only
14733
+ data_handle_type ptr_; // exposition only
14734
+ };
14735
+
14736
+ template<class CArray>
14737
+ requires(is_array_v<CArray> && rank_v<CArray> == 1)
14738
+ mdspan(CArray&)
14739
+ -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
14740
+
14741
+ template<class Pointer>
14742
+ requires(is_pointer_v<remove_reference_t<Pointer>>)
14743
+ mdspan(Pointer&&)
14744
+ -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
14745
+
14746
+ template<class ElementType, class... Integrals>
14747
+ requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
14748
+ explicit mdspan(ElementType*, Integrals...)
14749
+ -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
14750
+
14751
+ template<class ElementType, class OtherIndexType, size_t N>
14752
+ mdspan(ElementType*, span<OtherIndexType, N>)
14753
+ -> mdspan<ElementType, dextents<size_t, N>>;
14754
+
14755
+ template<class ElementType, class OtherIndexType, size_t N>
14756
+ mdspan(ElementType*, const array<OtherIndexType, N>&)
14757
+ -> mdspan<ElementType, dextents<size_t, N>>;
14758
+
14759
+ template<class ElementType, class IndexType, size_t... ExtentsPack>
14760
+ mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
14761
+ -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
14762
+
14763
+ template<class ElementType, class MappingType>
14764
+ mdspan(ElementType*, const MappingType&)
14765
+ -> mdspan<ElementType, typename MappingType::extents_type,
14766
+ typename MappingType::layout_type>;
14767
+
14768
+ template<class MappingType, class AccessorType>
14769
+ mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
14770
+ const AccessorType&)
14771
+ -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
14772
+ typename MappingType::layout_type, AccessorType>;
14773
+ }
14774
+ ```
14775
+
14776
+ *Mandates:*
14777
+
14778
+ - `ElementType` is a complete object type that is neither an abstract
14779
+ class type nor an array type,
14780
+ - `Extents` is a specialization of `extents`, and
14781
+ - `is_same_v<ElementType, typename AccessorPolicy::element_type>` is
14782
+ `true`.
14783
+
14784
+ `LayoutPolicy` shall meet the layout mapping policy requirements
14785
+ [[mdspan.layout.policy.reqmts]], and `AccessorPolicy` shall meet the
14786
+ accessor policy requirements [[mdspan.accessor.reqmts]].
14787
+
14788
+ Each specialization `MDS` of `mdspan` models `copyable` and
14789
+
14790
+ - `is_nothrow_move_constructible_v<MDS>` is `true`,
14791
+ - `is_nothrow_move_assignable_v<MDS>` is `true`, and
14792
+ - `is_nothrow_swappable_v<MDS>` is `true`.
14793
+
14794
+ A specialization of `mdspan` is a trivially copyable type if its
14795
+ `accessor_type`, `mapping_type`, and `data_handle_type` are trivially
14796
+ copyable types.
14797
+
14798
+ ##### Constructors <a id="mdspan.mdspan.cons">[[mdspan.mdspan.cons]]</a>
14799
+
14800
+ ``` cpp
14801
+ constexpr mdspan();
14802
+ ```
14803
+
14804
+ *Constraints:*
14805
+
14806
+ - `rank_dynamic() > 0` is `true`.
14807
+ - `is_default_constructible_v<data_handle_type>` is `true`.
14808
+ - `is_default_constructible_v<mapping_type>` is `true`.
14809
+ - `is_default_constructible_v<accessor_type>` is `true`.
14810
+
14811
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
14812
+ an accessible range of *ptr\_* and *acc\_* for the values of *map\_* and
14813
+ *acc\_* after the invocation of this constructor.
14814
+
14815
+ *Effects:* Value-initializes *ptr\_*, *map\_*, and *acc\_*.
14816
+
14817
+ ``` cpp
14818
+ template<class... OtherIndexTypes>
14819
+ constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts);
14820
+ ```
14821
+
14822
+ Let `N` be `sizeof...(OtherIndexTypes)`.
14823
+
14824
+ *Constraints:*
14825
+
14826
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
14827
+ - `(is_nothrow_constructible<index_type, OtherIndexTypes> && ...)` is
14828
+ `true`,
14829
+ - `N == rank() || N == rank_dynamic()` is `true`,
14830
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
14831
+ - `is_default_constructible_v<accessor_type>` is `true`.
14832
+
14833
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
14834
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
14835
+ *acc\_* after the invocation of this constructor.
14836
+
14837
+ *Effects:*
14838
+
14839
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
14840
+ - direct-non-list-initializes *map\_* with
14841
+ `extents_type(static_cast<index_type>(std::move(exts))...)`, and
14842
+ - value-initializes *acc\_*.
14843
+
14844
+ ``` cpp
14845
+ template<class OtherIndexType, size_t N>
14846
+ constexpr explicit(N != rank_dynamic())
14847
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
14848
+ template<class OtherIndexType, size_t N>
14849
+ constexpr explicit(N != rank_dynamic())
14850
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
14851
+ ```
14852
+
14853
+ *Constraints:*
14854
+
14855
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
14856
+ - `(is_nothrow_constructible<index_type, const OtherIndexType&> && ...)`
14857
+ is `true`,
14858
+ - `N == rank() || N == rank_dynamic()` is `true`,
14859
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
14860
+ - `is_default_constructible_v<accessor_type>` is `true`.
14861
+
14862
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
14863
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
14864
+ *acc\_* after the invocation of this constructor.
14865
+
14866
+ *Effects:*
14867
+
14868
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
14869
+ - direct-non-list-initializes *map\_* with `extents_type(exts)`, and
14870
+ - value-initializes *acc\_*.
14871
+
14872
+ ``` cpp
14873
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
14874
+ ```
14875
+
14876
+ *Constraints:*
14877
+
14878
+ - `is_constructible_v<mapping_type, const extents_type&>` is `true`, and
14879
+ - `is_default_constructible_v<accessor_type>` is `true`.
14880
+
14881
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
14882
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
14883
+ *acc\_* after the invocation of this constructor.
14884
+
14885
+ *Effects:*
14886
+
14887
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
14888
+ - direct-non-list-initializes *map\_* with `ext`, and
14889
+ - value-initializes *acc\_*.
14890
+
14891
+ ``` cpp
14892
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
14893
+ ```
14894
+
14895
+ *Constraints:* `is_default_constructible_v<accessor_type>` is `true`.
14896
+
14897
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
14898
+ `p` and *acc\_* for the value of *acc\_* after the invocation of this
14899
+ constructor.
14900
+
14901
+ *Effects:*
14902
+
14903
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
14904
+ - direct-non-list-initializes *map\_* with `m`, and
14905
+ - value-initializes *acc\_*.
14906
+
14907
+ ``` cpp
14908
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
14909
+ ```
14910
+
14911
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
14912
+ `p` and `a`.
14913
+
14914
+ *Effects:*
14915
+
14916
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
14917
+ - direct-non-list-initializes *map\_* with `m`, and
14918
+ - direct-non-list-initializes *acc\_* with `a`.
14919
+
14920
+ ``` cpp
14921
+ template<class OtherElementType, class OtherExtents,
14922
+ class OtherLayoutPolicy, class OtherAccessor>
14923
+ constexpr explicit(see below)
14924
+ mdspan(const mdspan<OtherElementType, OtherExtents,
14925
+ OtherLayoutPolicy, OtherAccessor>& other);
14926
+ ```
14927
+
14928
+ *Constraints:*
14929
+
14930
+ - `is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<Oth- erExtents>&>`
14931
+ is `true`, and
14932
+ - `is_constructible_v<accessor_type, const OtherAccessor&>` is `true`.
14933
+
14934
+ *Mandates:*
14935
+
14936
+ - `is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&>`
14937
+ is `true`, and
14938
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
14939
+
14940
+ *Preconditions:*
14941
+
14942
+ - For each rank index `r` of `extents_type`,
14943
+ `static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)`
14944
+ is `true`.
14945
+ - $[0, \texttt{\textit{map_}.required_span_size()})$ is an accessible
14946
+ range of *ptr\_* and *acc\_* for values of *ptr\_*, *map\_*, and
14947
+ *acc\_* after the invocation of this constructor.
14948
+
14949
+ *Effects:*
14950
+
14951
+ - Direct-non-list-initializes *ptr\_* with `other.`*`ptr_`*,
14952
+ - direct-non-list-initializes *map\_* with `other.`*`map_`*, and
14953
+ - direct-non-list-initializes *acc\_* with `other.`*`acc_`*.
14954
+
14955
+ *Remarks:* The expression inside `explicit` is equivalent to:
14956
+
14957
+ ``` cpp
14958
+ !is_convertible_v<const OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type>
14959
+ || !is_convertible_v<const OtherAccessor&, accessor_type>
14960
+ ```
14961
+
14962
+ ##### Members <a id="mdspan.mdspan.members">[[mdspan.mdspan.members]]</a>
14963
+
14964
+ ``` cpp
14965
+ template<class... OtherIndexTypes>
14966
+ constexpr reference operator[](OtherIndexTypes... indices) const;
14967
+ ```
14968
+
14969
+ *Constraints:*
14970
+
14971
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
14972
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
14973
+ `true`, and
14974
+ - `sizeof...(OtherIndexTypes) == rank()` is `true`.
14975
+
14976
+ Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
14977
+
14978
+ *Preconditions:* `I` is a multidimensional index in `extents()`.
14979
+
14980
+ [*Note 1*: This implies that
14981
+ *`map_`*`(I) < `*`map_`*`.required_span_size()` is
14982
+ `true`. — *end note*]
14983
+
14984
+ *Effects:* Equivalent to:
14985
+
14986
+ ``` cpp
14987
+ return acc_.access(ptr_, map_(static_cast<index_type>(std::move(indices))...));
14988
+ ```
14989
+
14990
+ ``` cpp
14991
+ template<class OtherIndexType>
14992
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
14993
+ template<class OtherIndexType>
14994
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
14995
+ ```
14996
+
14997
+ *Constraints:*
14998
+
14999
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
15000
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
15001
+ `true`.
15002
+
15003
+ *Effects:* Let `P` be a parameter pack such that
15004
+
15005
+ ``` cpp
15006
+ is_same_v<make_index_sequence<rank()>, index_sequence<P...>>
15007
+ ```
15008
+
15009
+ is `true`. Equivalent to:
15010
+
15011
+ ``` cpp
15012
+ return operator[](as_const(indices[P])...);
15013
+ ```
15014
+
15015
+ ``` cpp
15016
+ constexpr size_type size() const noexcept;
15017
+ ```
15018
+
15019
+ *Preconditions:* The size of the multidimensional index space
15020
+ `extents()` is representable as a value of type `size_type`
15021
+ [[basic.fundamental]].
15022
+
15023
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(rank())`.
15024
+
15025
+ ``` cpp
15026
+ [[nodiscard]] constexpr bool empty() const noexcept;
15027
+ ```
15028
+
15029
+ *Returns:* `true` if the size of the multidimensional index space
15030
+ `extents()` is 0, otherwise `false`.
15031
+
15032
+ ``` cpp
15033
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
15034
+ ```
15035
+
15036
+ *Effects:* Equivalent to:
15037
+
15038
+ ``` cpp
15039
+ swap(x.ptr_, y.ptr_);
15040
+ swap(x.map_, y.map_);
15041
+ swap(x.acc_, y.acc_);
15042
+ ```
15043
+
15044
  <!-- Link reference definitions -->
15045
+ [alg.equal]: algorithms.md#alg.equal
15046
  [alg.sorting]: algorithms.md#alg.sorting
15047
  [algorithm.stable]: library.md#algorithm.stable
15048
  [algorithms]: algorithms.md#algorithms
15049
  [algorithms.requirements]: algorithms.md#algorithms.requirements
15050
  [allocator.requirements]: library.md#allocator.requirements
15051
  [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
15052
+ [allocator.traits.members]: mem.md#allocator.traits.members
15053
+ [allocator.uses.construction]: mem.md#allocator.uses.construction
15054
  [array]: #array
15055
  [array.cons]: #array.cons
15056
  [array.creation]: #array.creation
15057
  [array.members]: #array.members
15058
  [array.overview]: #array.overview
 
15063
  [associative]: #associative
15064
  [associative.general]: #associative.general
15065
  [associative.map.syn]: #associative.map.syn
15066
  [associative.reqmts]: #associative.reqmts
15067
  [associative.reqmts.except]: #associative.reqmts.except
15068
+ [associative.reqmts.general]: #associative.reqmts.general
15069
  [associative.set.syn]: #associative.set.syn
15070
+ [basic.fundamental]: basic.md#basic.fundamental
15071
  [basic.string]: strings.md#basic.string
15072
  [class.copy.ctor]: class.md#class.copy.ctor
15073
  [class.default.ctor]: class.md#class.default.ctor
15074
  [class.dtor]: class.md#class.dtor
15075
  [container.adaptors]: #container.adaptors
15076
+ [container.adaptors.format]: #container.adaptors.format
15077
  [container.adaptors.general]: #container.adaptors.general
15078
+ [container.alloc.reqmts]: #container.alloc.reqmts
15079
+ [container.gen.reqmts]: #container.gen.reqmts
 
15080
  [container.insert.return]: #container.insert.return
15081
  [container.node]: #container.node
15082
  [container.node.compat]: #container.node.compat
15083
  [container.node.cons]: #container.node.cons
15084
  [container.node.dtor]: #container.node.dtor
15085
  [container.node.modifiers]: #container.node.modifiers
15086
  [container.node.observers]: #container.node.observers
15087
  [container.node.overview]: #container.node.overview
15088
+ [container.opt.reqmts]: #container.opt.reqmts
15089
+ [container.reqmts]: #container.reqmts
15090
  [container.requirements]: #container.requirements
15091
  [container.requirements.dataraces]: #container.requirements.dataraces
15092
  [container.requirements.general]: #container.requirements.general
15093
+ [container.requirements.pre]: #container.requirements.pre
15094
+ [container.rev.reqmts]: #container.rev.reqmts
 
15095
  [containers]: #containers
15096
  [containers.general]: #containers.general
15097
  [containers.summary]: #containers.summary
15098
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
15099
+ [defns.valid]: intro.md#defns.valid
15100
  [deque]: #deque
15101
  [deque.capacity]: #deque.capacity
15102
  [deque.cons]: #deque.cons
15103
  [deque.erasure]: #deque.erasure
15104
  [deque.modifiers]: #deque.modifiers
15105
  [deque.overview]: #deque.overview
15106
  [deque.syn]: #deque.syn
15107
+ [expr.const]: expr.md#expr.const
15108
+ [flat.map]: #flat.map
15109
+ [flat.map.access]: #flat.map.access
15110
+ [flat.map.capacity]: #flat.map.capacity
15111
+ [flat.map.cons]: #flat.map.cons
15112
+ [flat.map.defn]: #flat.map.defn
15113
+ [flat.map.erasure]: #flat.map.erasure
15114
+ [flat.map.modifiers]: #flat.map.modifiers
15115
+ [flat.map.overview]: #flat.map.overview
15116
+ [flat.map.syn]: #flat.map.syn
15117
+ [flat.multimap]: #flat.multimap
15118
+ [flat.multimap.cons]: #flat.multimap.cons
15119
+ [flat.multimap.defn]: #flat.multimap.defn
15120
+ [flat.multimap.erasure]: #flat.multimap.erasure
15121
+ [flat.multimap.overview]: #flat.multimap.overview
15122
+ [flat.multiset]: #flat.multiset
15123
+ [flat.multiset.cons]: #flat.multiset.cons
15124
+ [flat.multiset.defn]: #flat.multiset.defn
15125
+ [flat.multiset.erasure]: #flat.multiset.erasure
15126
+ [flat.multiset.modifiers]: #flat.multiset.modifiers
15127
+ [flat.multiset.overview]: #flat.multiset.overview
15128
+ [flat.set]: #flat.set
15129
+ [flat.set.cons]: #flat.set.cons
15130
+ [flat.set.defn]: #flat.set.defn
15131
+ [flat.set.erasure]: #flat.set.erasure
15132
+ [flat.set.modifiers]: #flat.set.modifiers
15133
+ [flat.set.overview]: #flat.set.overview
15134
+ [flat.set.syn]: #flat.set.syn
15135
+ [forward.iterators]: iterators.md#forward.iterators
15136
+ [forward.list]: #forward.list
15137
+ [forward.list.access]: #forward.list.access
15138
+ [forward.list.cons]: #forward.list.cons
15139
  [forward.list.erasure]: #forward.list.erasure
15140
+ [forward.list.iter]: #forward.list.iter
15141
+ [forward.list.modifiers]: #forward.list.modifiers
15142
+ [forward.list.ops]: #forward.list.ops
15143
+ [forward.list.overview]: #forward.list.overview
15144
  [forward.list.syn]: #forward.list.syn
 
 
 
 
 
 
 
15145
  [hash.requirements]: library.md#hash.requirements
15146
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
15147
+ [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
15148
  [iterator.requirements]: iterators.md#iterator.requirements
15149
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
15150
  [list]: #list
15151
  [list.capacity]: #list.capacity
15152
  [list.cons]: #list.cons
 
15159
  [map.access]: #map.access
15160
  [map.cons]: #map.cons
15161
  [map.erasure]: #map.erasure
15162
  [map.modifiers]: #map.modifiers
15163
  [map.overview]: #map.overview
15164
+ [mdspan.accessor]: #mdspan.accessor
15165
+ [mdspan.accessor.default]: #mdspan.accessor.default
15166
+ [mdspan.accessor.default.members]: #mdspan.accessor.default.members
15167
+ [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
15168
+ [mdspan.accessor.general]: #mdspan.accessor.general
15169
+ [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
15170
+ [mdspan.extents]: #mdspan.extents
15171
+ [mdspan.extents.cmp]: #mdspan.extents.cmp
15172
+ [mdspan.extents.cons]: #mdspan.extents.cons
15173
+ [mdspan.extents.dextents]: #mdspan.extents.dextents
15174
+ [mdspan.extents.expo]: #mdspan.extents.expo
15175
+ [mdspan.extents.obs]: #mdspan.extents.obs
15176
+ [mdspan.extents.overview]: #mdspan.extents.overview
15177
+ [mdspan.layout]: #mdspan.layout
15178
+ [mdspan.layout.general]: #mdspan.layout.general
15179
+ [mdspan.layout.left]: #mdspan.layout.left
15180
+ [mdspan.layout.left.cons]: #mdspan.layout.left.cons
15181
+ [mdspan.layout.left.obs]: #mdspan.layout.left.obs
15182
+ [mdspan.layout.left.overview]: #mdspan.layout.left.overview
15183
+ [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
15184
+ [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
15185
+ [mdspan.layout.reqmts]: #mdspan.layout.reqmts
15186
+ [mdspan.layout.right]: #mdspan.layout.right
15187
+ [mdspan.layout.right.cons]: #mdspan.layout.right.cons
15188
+ [mdspan.layout.right.obs]: #mdspan.layout.right.obs
15189
+ [mdspan.layout.right.overview]: #mdspan.layout.right.overview
15190
+ [mdspan.layout.stride]: #mdspan.layout.stride
15191
+ [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
15192
+ [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
15193
+ [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
15194
+ [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
15195
+ [mdspan.mdspan]: #mdspan.mdspan
15196
+ [mdspan.mdspan.cons]: #mdspan.mdspan.cons
15197
+ [mdspan.mdspan.members]: #mdspan.mdspan.members
15198
+ [mdspan.mdspan.overview]: #mdspan.mdspan.overview
15199
+ [mdspan.overview]: #mdspan.overview
15200
+ [mdspan.syn]: #mdspan.syn
15201
  [multimap]: #multimap
15202
  [multimap.cons]: #multimap.cons
15203
  [multimap.erasure]: #multimap.erasure
15204
  [multimap.modifiers]: #multimap.modifiers
15205
  [multimap.overview]: #multimap.overview
 
15215
  [priqueue.special]: #priqueue.special
15216
  [queue]: #queue
15217
  [queue.cons]: #queue.cons
15218
  [queue.cons.alloc]: #queue.cons.alloc
15219
  [queue.defn]: #queue.defn
15220
+ [queue.mod]: #queue.mod
15221
  [queue.ops]: #queue.ops
15222
  [queue.special]: #queue.special
15223
  [queue.syn]: #queue.syn
15224
  [random.access.iterators]: iterators.md#random.access.iterators
15225
  [res.on.data.races]: library.md#res.on.data.races
 
15241
  [span.syn]: #span.syn
15242
  [stack]: #stack
15243
  [stack.cons]: #stack.cons
15244
  [stack.cons.alloc]: #stack.cons.alloc
15245
  [stack.defn]: #stack.defn
15246
+ [stack.general]: #stack.general
15247
+ [stack.mod]: #stack.mod
15248
  [stack.ops]: #stack.ops
15249
  [stack.special]: #stack.special
15250
  [stack.syn]: #stack.syn
15251
  [strings]: strings.md#strings
15252
  [swappable.requirements]: library.md#swappable.requirements
 
 
 
 
 
15253
  [temp.deduct]: temp.md#temp.deduct
15254
  [temp.param]: temp.md#temp.param
15255
  [temp.type]: temp.md#temp.type
15256
+ [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
15257
  [unord]: #unord
15258
  [unord.general]: #unord.general
15259
  [unord.hash]: utilities.md#unord.hash
15260
  [unord.map]: #unord.map
15261
  [unord.map.cnstr]: #unord.map.cnstr
 
15273
  [unord.multiset.cnstr]: #unord.multiset.cnstr
15274
  [unord.multiset.erasure]: #unord.multiset.erasure
15275
  [unord.multiset.overview]: #unord.multiset.overview
15276
  [unord.req]: #unord.req
15277
  [unord.req.except]: #unord.req.except
15278
+ [unord.req.general]: #unord.req.general
15279
  [unord.set]: #unord.set
15280
  [unord.set.cnstr]: #unord.set.cnstr
15281
  [unord.set.erasure]: #unord.set.erasure
15282
  [unord.set.overview]: #unord.set.overview
15283
  [unord.set.syn]: #unord.set.syn
15284
  [vector]: #vector
15285
  [vector.bool]: #vector.bool
15286
+ [vector.bool.fmt]: #vector.bool.fmt
15287
+ [vector.bool.pspc]: #vector.bool.pspc
15288
  [vector.capacity]: #vector.capacity
15289
  [vector.cons]: #vector.cons
15290
  [vector.data]: #vector.data
15291
  [vector.erasure]: #vector.erasure
15292
  [vector.modifiers]: #vector.modifiers
15293
  [vector.overview]: #vector.overview
15294
  [vector.syn]: #vector.syn
15295
  [views]: #views
15296
+ [views.contiguous]: #views.contiguous
15297
  [views.general]: #views.general
15298
+ [views.multidim]: #views.multidim
15299
  [views.span]: #views.span
15300
 
15301
  [^1]: Equality comparison is a refinement of partitioning if no two
15302
  objects that compare equal fall into different partitions.
15303
 
 
15305
  iterators are random access iterators.
15306
 
15307
  [^3]: As specified in  [[allocator.requirements]], the requirements in
15308
  this Clause apply only to lists whose allocators compare equal.
15309
 
15310
+ [^4]: `reserve()` uses `Allocator::allocate()` which can throw an
15311
  appropriate exception.