From Jason Turner

[containers]

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

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmprvz3ahbd/{from.md → to.md} +2214 -1541
tmp/tmprvz3ahbd/{from.md → to.md} RENAMED
@@ -5,28 +5,22 @@
5
  This Clause describes components that C++ programs may use to organize
6
  collections of information.
7
 
8
  The following subclauses describe container requirements, and components
9
  for sequence containers and associative containers, as summarized in
10
- Table  [[tab:containers.lib.summary]].
11
 
12
- **Table: Containers library summary** <a id="tab:containers.lib.summary">[tab:containers.lib.summary]</a>
13
 
14
  | Subclause | | Header |
15
- | -------------------------- | -------------------------------- | ----------------- |
16
  | [[container.requirements]] | Requirements | |
17
- | [[sequences]] | Sequence containers | `<array>` |
18
- | | | `<deque>` |
19
- | | | `<forward_list>` |
20
- | | | `<list>` |
21
- | | | `<vector>` |
22
- | [[associative]] | Associative containers | `<map>` |
23
- | | | `<set>` |
24
- | [[unord]] | Unordered associative containers | `<unordered_map>` |
25
- | | | `<unordered_set>` |
26
- | [[container.adaptors]] | Container adaptors | `<queue>` |
27
- | | | `<stack>` |
28
 
29
 
30
  ## Container requirements <a id="container.requirements">[[container.requirements]]</a>
31
 
32
  ### General container requirements <a id="container.requirements.general">[[container.requirements.general]]</a>
@@ -45,31 +39,31 @@ linear complexity, even though the complexity of copying each contained
45
  For the components affected by this subclause that declare an
46
  `allocator_type`, objects stored in these components shall be
47
  constructed using the function
48
  `allocator_traits<allocator_type>::rebind_traits<U>::{}construct` and
49
  destroyed using the function
50
- `allocator_traits<allocator_type>::rebind_traits<U>::{}destroy` (
51
- [[allocator.traits.members]]), where `U` is either
52
  `allocator_type::value_type` or an internal type used by the container.
53
  These functions are called only for the container’s element type, not
54
  for internal types used by the container.
55
 
56
  [*Note 1*: This means, for example, that a node-based container might
57
  need to construct nodes containing aligned buffers and call `construct`
58
  to place the element into the buffer. — *end note*]
59
 
60
- In Tables  [[tab:containers.container.requirements]],
61
- [[tab:containers.reversible.requirements]], and
62
- [[tab:containers.optional.operations]] `X` denotes a container class
63
- containing objects of type `T`, `a` and `b` denote values of type `X`,
64
- `u` denotes an identifier, `r` denotes a non-const value of type `X`,
65
- and `rv` denotes a non-const rvalue of type `X`.
66
 
67
  Those entries marked “(Note A)” or “(Note B)” have linear complexity for
68
  `array` and have constant complexity for all other standard containers.
69
 
70
- [*Note 2*: The algorithm `equal()` is defined in Clause 
71
  [[algorithms]]. — *end note*]
72
 
73
  The member function `size()` returns the number of elements in the
74
  container. The number of elements is defined by the rules of
75
  constructors, inserts, and erases.
@@ -87,10 +81,11 @@ i == j
87
  i != j
88
  i < j
89
  i <= j
90
  i >= j
91
  i > j
 
92
  i - j
93
  ```
94
 
95
  where `i` and `j` denote objects of a container’s `iterator` type,
96
  either or both may be replaced by an object of the container’s
@@ -114,11 +109,11 @@ constructors obtain an allocator by move construction from the allocator
114
  belonging to the container being moved. Such move construction of the
115
  allocator shall not exit via an exception. All other constructors for
116
  these container types take a `const allocator_type&` argument.
117
 
118
  [*Note 4*: If an invocation of a constructor uses the default value of
119
- an optional allocator argument, then the `Allocator` type must support
120
  value-initialization. — *end note*]
121
 
122
  A copy of this allocator is used for any memory allocation and element
123
  construction performed, by these constructors and by all member
124
  functions, during the lifetime of each container object or until the
@@ -152,13 +147,13 @@ element in one container before the swap shall refer to the same element
152
  in the other container after the swap. It is unspecified whether an
153
  iterator with value `a.end()` before the swap will have value `b.end()`
154
  after the swap.
155
 
156
  If the iterator type of a container belongs to the bidirectional or
157
- random access iterator categories ([[iterator.requirements]]), the
158
- container is called *reversible* and satisfies the additional
159
- requirements in Table  [[tab:containers.reversible.requirements]].
160
 
161
  Unless otherwise specified (see  [[associative.reqmts.except]],
162
  [[unord.req.except]], [[deque.modifiers]], and [[vector.modifiers]]) all
163
  container types defined in this Clause meet the following additional
164
  requirements:
@@ -182,38 +177,40 @@ Unless otherwise specified (either explicitly or by defining a function
182
  in terms of other functions), invoking a container member function or
183
  passing a container as an argument to a library function shall not
184
  invalidate iterators to, or change the values of, objects within that
185
  container.
186
 
187
- A *contiguous container* is a container that supports random access
188
- iterators ([[random.access.iterators]]) and whose member types
189
- `iterator` and `const_iterator` are contiguous iterators (
190
- [[iterator.requirements.general]]).
191
 
192
- Table  [[tab:containers.optional.operations]] lists operations that are
193
- provided for some types of containers but not others. Those containers
194
- for which the listed operations are provided shall implement the
195
- semantics described in Table  [[tab:containers.optional.operations]]
196
- unless otherwise stated.
 
 
197
 
198
- [*Note 6*: The algorithm `lexicographical_compare()` is defined in
199
- Clause  [[algorithms]]. — *end note*]
200
 
201
  All of the containers defined in this Clause and in  [[basic.string]]
202
  except `array` meet the additional requirements of an allocator-aware
203
- container, as described in Table  [[tab:containers.allocatoraware]].
204
 
205
  Given an allocator type `A` and given a container type `X` having a
206
  `value_type` identical to `T` and an `allocator_type` identical to
207
  `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
208
  `A`, a pointer `p` of type `T*`, an expression `v` of type (possibly
209
  `const`) `T`, and an rvalue `rv` of type `T`, the following terms are
210
  defined. If `X` is not allocator-aware, the terms below are defined as
211
  if `A` were `allocator<T>` — no allocator object needs to be created and
212
  user specializations of `allocator<T>` are not instantiated:
213
 
214
- - `T` is *`DefaultInsertable` into `X`* means that the following
215
  expression is well-formed:
216
  ``` cpp
217
  allocator_traits<A>::construct(m, p)
218
  ```
219
  - An element of `X` is *default-inserted* if it is initialized by
@@ -222,71 +219,71 @@ user specializations of `allocator<T>` are not instantiated:
222
  allocator_traits<A>::construct(m, p)
223
  ```
224
 
225
  where `p` is the address of the uninitialized storage for the element
226
  allocated within `X`.
227
- - `T` is *`MoveInsertable` into `X`* means that the following expression
228
- is well-formed:
229
  ``` cpp
230
  allocator_traits<A>::construct(m, p, rv)
231
  ```
232
 
233
  and its evaluation causes the following postcondition to hold: The
234
  value of `*p` is equivalent to the value of `rv` before the
235
  evaluation.
236
  \[*Note 7*: `rv` remains a valid object. Its state is
237
  unspecified — *end note*]
238
- - `T` is *`CopyInsertable` into `X`* means that, in addition to `T`
239
- being `MoveInsertable` into `X`, the following expression is
240
  well-formed:
241
  ``` cpp
242
  allocator_traits<A>::construct(m, p, v)
243
  ```
244
 
245
  and its evaluation causes the following postcondition to hold: The
246
  value of `v` is unchanged and is equivalent to `*p`.
247
- - `T` is *`EmplaceConstructible` into `X` from `args`*, for zero or more
248
- arguments `args`, means that the following expression is well-formed:
 
249
  ``` cpp
250
  allocator_traits<A>::construct(m, p, args)
251
  ```
252
- - `T` is *`Erasable` from `X`* means that the following expression is
253
- well-formed:
254
  ``` cpp
255
  allocator_traits<A>::destroy(m, p)
256
  ```
257
 
258
  [*Note 8*: A container calls
259
  `allocator_traits<A>::construct(m, p, args)` to construct an element at
260
  `p` using `args`, with `m == get_allocator()`. The default `construct`
261
  in `allocator` will call `::new((void*)p) T(args)`, but specialized
262
  allocators may choose a different definition. — *end note*]
263
 
264
- In Table  [[tab:containers.allocatoraware]], `X` denotes an
265
- allocator-aware container class with a `value_type` of `T` using
266
- allocator of type `A`, `u` denotes a variable, `a` and `b` denote
267
- non-const lvalues of type `X`, `t` denotes an lvalue or a const rvalue
268
- of type `X`, `rv` denotes a non-const rvalue of type `X`, and `m` is a
269
- value of type `A`.
270
 
271
  The behavior of certain container member functions and deduction guides
272
  depends on whether types qualify as input iterators or allocators. The
273
  extent to which an implementation determines that a type cannot be an
274
  input iterator is unspecified, except that as a minimum integral types
275
  shall not qualify as input iterators. Likewise, the extent to which an
276
  implementation determines that a type cannot be an allocator is
277
  unspecified, except that as a minimum a type `A` shall not qualify as an
278
- allocator unless it satisfies both of the following conditions:
279
 
280
- - The *qualified-id* `A::value_type` is valid and denotes a type (
281
- [[temp.deduct]]).
282
  - The expression `declval<A&>().allocate(size_t{})` is well-formed when
283
  treated as an unevaluated operand.
284
 
285
  ### Container data races <a id="container.requirements.dataraces">[[container.requirements.dataraces]]</a>
286
 
287
- For purposes of avoiding data races ([[res.on.data.races]]),
288
  implementations shall consider the following functions to be `const`:
289
  `begin`, `end`, `rbegin`, `rend`, `front`, `back`, `data`, `find`,
290
  `lower_bound`, `upper_bound`, `equal_range`, `at` and, except in
291
  associative or unordered associative containers, `operator[]`.
292
 
@@ -312,38 +309,43 @@ which provides limited sequence operations because it has a fixed number
312
  of elements. The library also provides container adaptors that make it
313
  easy to construct abstract data types, such as `stack`s or `queue`s, out
314
  of the basic sequence container kinds (or out of other kinds of sequence
315
  containers that the user might define).
316
 
317
- The sequence containers offer the programmer different complexity
318
- trade-offs and should be used accordingly. `vector` or `array` is the
319
- type of sequence container that should be used by default. `list` or
320
- `forward_list` should be used when there are frequent insertions and
321
- deletions from the middle of the sequence. `deque` is the data structure
322
- of choice when most insertions and deletions take place at the beginning
323
- or at the end of the sequence.
 
 
 
324
 
325
- In Tables  [[tab:containers.sequence.requirements]] and
326
- [[tab:containers.sequence.optional]], `X` denotes a sequence container
327
- class, `a` denotes a value of type `X` containing elements of type `T`,
328
- `u` denotes the name of a variable being declared, `A` denotes
329
- `X::allocator_type` if the *qualified-id* `X::allocator_type` is valid
330
- and denotes a type ([[temp.deduct]]) and `allocator<T>` if it doesn’t,
331
- `i` and `j` denote iterators satisfying input iterator requirements and
332
- refer to elements implicitly convertible to `value_type`, `[i, j)`
333
- denotes a valid range, `il` designates an object of type
334
- `initializer_list<value_type>`, `n` denotes a value of type
335
- `X::size_type`, `p` denotes a valid constant iterator to `a`, `q`
336
- denotes a valid dereferenceable constant iterator to `a`, `[q1, q2)`
337
- denotes a valid range of constant iterators in `a`, `t` denotes an
338
- lvalue or a const rvalue of `X::value_type`, and `rv` denotes a
339
- non-const rvalue of `X::value_type`. `Args` denotes a template parameter
340
- pack; `args` denotes a function parameter pack with the pattern
341
- `Args&&`.
342
 
343
  The complexities of the expressions are sequence dependent.
344
 
 
 
 
345
  The iterator returned from `a.insert(p, t)` points to the copy of `t`
346
  inserted into `a`.
347
 
348
  The iterator returned from `a.insert(p, rv)` points to the copy of `rv`
349
  inserted into `a`.
@@ -366,12 +368,11 @@ element exists, `a.end()` is returned.
366
 
367
  The iterator returned by `a.erase(q1, q2)` points to the element pointed
368
  to by `q2` prior to any elements being erased. If no such element
369
  exists, `a.end()` is returned.
370
 
371
- For every sequence container defined in this Clause and in Clause 
372
- [[strings]]:
373
 
374
  - If the constructor
375
  ``` cpp
376
  template<class InputIterator>
377
  X(InputIterator first, InputIterator last,
@@ -403,32 +404,31 @@ For every sequence container defined in this Clause and in Clause 
403
  and a type that does not qualify as an input iterator is deduced for
404
  that parameter, or if it has an `Allocator` template parameter and a
405
  type that does not qualify as an allocator is deduced for that
406
  parameter.
407
 
408
- Table  [[tab:containers.sequence.optional]] lists operations that are
409
- provided for some types of sequence containers but not others. An
410
- implementation shall provide these operations for all container types
411
- shown in the “container” column, and shall implement them so as to take
412
- 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
- #### `node_handle` overview <a id="container.node.overview">[[container.node.overview]]</a>
420
 
421
  A *node handle* is an object that accepts ownership of a single element
422
- from an associative container ([[associative.reqmts]]) or an unordered
423
- associative container ([[unord.req]]). It may be used to transfer that
424
  ownership to another container with compatible nodes. Containers with
425
  compatible nodes have the same node handle type. Elements may be
426
  transferred in either direction between container types in the same row
427
- of Table  [[tab:containers.node.compat]].
428
 
429
- **Table: Container types with compatible nodes** <a id="tab:containers.node.compat">[tab:containers.node.compat]</a>
430
 
431
  | | |
432
  | -------------------------------- | ------------------------------------- |
433
  | `map<K, T, C1, A>` | `map<K, T, C2, A>` |
434
  | `map<K, T, C1, A>` | `multimap<K, T, C2, A>` |
@@ -442,122 +442,126 @@ of Table  [[tab:containers.node.compat]].
442
 
443
  If a node handle is not empty, then it contains an allocator that is
444
  equal to the allocator of the container when the element was extracted.
445
  If a node handle is empty, it contains no allocator.
446
 
447
- Class `node_handle` is for exposition only. An implementation is
448
- permitted to provide equivalent functionality without providing a class
449
- with this name.
450
 
451
  If a user-defined specialization of `pair` exists for
452
  `pair<const Key, T>` or `pair<Key, T>`, where `Key` is the container’s
453
  `key_type` and `T` is the container’s `mapped_type`, the behavior of
454
  operations involving node handles is undefined.
455
 
456
  ``` cpp
457
  template<unspecified>
458
- class node_handle {
459
  public:
460
- // These type declarations are described in Tables [tab:containers.associative.requirements] and [tab:HashRequirements].
461
  using value_type = see below; // not present for map containers
462
  using key_type = see below; // not present for set containers
463
  using mapped_type = see below; // not present for set containers
464
  using allocator_type = see below;
465
 
466
  private:
467
  using container_node_type = unspecified;
468
  using ator_traits = allocator_traits<allocator_type>;
469
 
470
- typename ator_traits::rebind_traits<container_node_type>::pointer ptr_;
471
  optional<allocator_type> alloc_;
472
 
473
  public:
474
- constexpr node_handle() noexcept : ptr_(), alloc_() {}
475
- ~node_handle();
476
- node_handle(node_handle&&) noexcept;
477
- node_handle& operator=(node_handle&&);
478
 
 
 
 
 
479
  value_type& value() const; // not present for map containers
480
  key_type& key() const; // not present for set containers
481
  mapped_type& mapped() const; // not present for set containers
482
 
483
  allocator_type get_allocator() const;
484
  explicit operator bool() const noexcept;
485
- bool empty() const noexcept;
486
 
487
- void swap(node_handle&)
 
488
  noexcept(ator_traits::propagate_on_container_swap::value ||
489
  ator_traits::is_always_equal::value);
490
 
491
- friend void swap(node_handle& x, node_handle& y) noexcept(noexcept(x.swap(y))) {
492
  x.swap(y);
493
  }
494
  };
495
  ```
496
 
497
- #### `node_handle` constructors, copy, and assignment <a id="container.node.cons">[[container.node.cons]]</a>
498
 
499
  ``` cpp
500
- node_handle(node_handle&& nh) noexcept;
501
  ```
502
 
503
- *Effects:* Constructs a *`node_handle`* object initializing `ptr_` with
504
  `nh.ptr_`. Move constructs `alloc_` with `nh.alloc_`. Assigns `nullptr`
505
  to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
506
 
507
  ``` cpp
508
- node_handle& operator=(node_handle&& nh);
509
  ```
510
 
511
- *Requires:* Either `!alloc_`, or
512
- `ator_traits::propagate_on_container_move_assignment` is `true`, or
513
- `alloc_ == nh.alloc_`.
514
 
515
  *Effects:*
516
 
517
  - If `ptr_ != nullptr`, destroys the `value_type` subobject in the
518
  `container_node_type` object pointed to by `ptr_` by calling
519
  `ator_traits::destroy`, then deallocates `ptr_` by calling
520
- `ator_traits::rebind_traits<container_node_type>::deallocate`.
521
  - Assigns `nh.ptr_` to `ptr_`.
522
- - If `!alloc` or `ator_traits::propagate_on_container_move_assignment`
523
- is `true`, move assigns `nh.alloc_` to `alloc_`.
 
524
  - Assigns `nullptr` to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
525
 
526
  *Returns:* `*this`.
527
 
528
  *Throws:* Nothing.
529
 
530
- #### `node_handle` destructor <a id="container.node.dtor">[[container.node.dtor]]</a>
531
 
532
  ``` cpp
533
- ~node_handle();
534
  ```
535
 
536
  *Effects:* If `ptr_ != nullptr`, destroys the `value_type` subobject in
537
  the `container_node_type` object pointed to by `ptr_` by calling
538
  `ator_traits::destroy`, then deallocates `ptr_` by calling
539
- `ator_traits::rebind_traits<container_node_type>::deallocate`.
540
 
541
- #### `node_handle` observers <a id="container.node.observers">[[container.node.observers]]</a>
542
 
543
  ``` cpp
544
  value_type& value() const;
545
  ```
546
 
547
- *Requires:* `empty() == false`.
548
 
549
  *Returns:* A reference to the `value_type` subobject in the
550
  `container_node_type` object pointed to by `ptr_`.
551
 
552
  *Throws:* Nothing.
553
 
554
  ``` cpp
555
  key_type& key() const;
556
  ```
557
 
558
- *Requires:* `empty() == false`.
559
 
560
  *Returns:* A non-const reference to the `key_type` member of the
561
  `value_type` subobject in the `container_node_type` object pointed to by
562
  `ptr_`.
563
 
@@ -568,22 +572,22 @@ permitted.
568
 
569
  ``` cpp
570
  mapped_type& mapped() const;
571
  ```
572
 
573
- *Requires:* `empty() == false`.
574
 
575
  *Returns:* A reference to the `mapped_type` member of the `value_type`
576
  subobject in the `container_node_type` object pointed to by `ptr_`.
577
 
578
  *Throws:* Nothing.
579
 
580
  ``` cpp
581
  allocator_type get_allocator() const;
582
  ```
583
 
584
- *Requires:* `empty() == false`.
585
 
586
  *Returns:* `*alloc_`.
587
 
588
  *Throws:* Nothing.
589
 
@@ -592,70 +596,75 @@ explicit operator bool() const noexcept;
592
  ```
593
 
594
  *Returns:* `ptr_ != nullptr`.
595
 
596
  ``` cpp
597
- bool empty() const noexcept;
598
  ```
599
 
600
  *Returns:* `ptr_ == nullptr`.
601
 
602
- #### `node_handle` modifiers <a id="container.node.modifiers">[[container.node.modifiers]]</a>
603
 
604
  ``` cpp
605
- void swap(node_handle& nh)
606
  noexcept(ator_traits::propagate_on_container_swap::value ||
607
  ator_traits::is_always_equal::value);
608
  ```
609
 
610
- *Requires:* `!alloc_`, or `!nh.alloc_`, or
611
- `ator_traits::propagate_on_container_swap` is `true`, or
612
  `alloc_ == nh.alloc_`.
613
 
614
  *Effects:* Calls `swap(ptr_, nh.ptr_)`. If `!alloc_`, or `!nh.alloc_`,
615
- or `ator_traits::propagate_on_container_swap` is `true` calls
616
  `swap(alloc_, nh.alloc_)`.
617
 
618
  ### Insert return type <a id="container.insert.return">[[container.insert.return]]</a>
619
 
620
  The associative containers with unique keys and the unordered containers
621
  with unique keys have a member function `insert` that returns a nested
622
  type `insert_return_type`. That return type is a specialization of the
623
- type specified in this subclause.
624
 
625
  ``` cpp
626
  template<class Iterator, class NodeType>
627
- struct INSERT_RETURN_TYPE
628
  {
629
  Iterator position;
630
  bool inserted;
631
  NodeType node;
632
  };
633
  ```
634
 
635
- The name `INSERT_RETURN_TYPE` is exposition only. `INSERT_RETURN_TYPE`
636
- has the template parameters, data members, and special members specified
637
- above. It has no base classes or members other than those specified.
 
638
 
639
  ### Associative containers <a id="associative.reqmts">[[associative.reqmts]]</a>
640
 
641
  Associative containers provide fast retrieval of data based on keys. The
642
  library provides four basic kinds of associative containers: `set`,
643
  `multiset`, `map` and `multimap`.
644
 
645
  Each associative container is parameterized on `Key` and an ordering
646
- relation `Compare` that induces a strict weak ordering (
647
- [[alg.sorting]]) on elements of `Key`. In addition, `map` and `multimap`
648
- associate an arbitrary *mapped type* `T` with the `Key`. The object of
649
- type `Compare` is called the *comparison object* of a container.
650
 
651
  The phrase “equivalence of keys” means the equivalence relation imposed
652
- by the comparison and *not* the `operator==` on keys. That is, two keys
653
- `k1` and `k2` are considered to be equivalent if for the comparison
654
- object `comp`, `comp(k1, k2) == false && comp(k2, k1) == false`. For any
655
- two keys `k1` and `k2` in the same container, calling `comp(k1, k2)`
656
- shall always return the same value.
 
 
 
 
657
 
658
  An associative container supports *unique keys* if it may contain at
659
  most one element for each key. Otherwise, it supports *equivalent keys*.
660
  The `set` and `map` classes support unique keys; the `multiset` and
661
  `multimap` classes support equivalent keys. For `multiset` and
@@ -671,45 +680,44 @@ of an associative container is of the bidirectional iterator category.
671
  For associative containers where the value type is the same as the key
672
  type, both `iterator` and `const_iterator` are constant iterators. It is
673
  unspecified whether or not `iterator` and `const_iterator` are the same
674
  type.
675
 
676
- [*Note 1*: `iterator` and `const_iterator` have identical semantics in
677
  this case, and `iterator` is convertible to `const_iterator`. Users can
678
  avoid violating the one-definition rule by always using `const_iterator`
679
  in their function parameter lists. — *end note*]
680
 
681
  The associative containers meet all the requirements of Allocator-aware
682
- containers ([[container.requirements.general]]), except that for `map`
683
- and `multimap`, the requirements placed on `value_type` in Table 
684
- [[tab:containers.container.requirements]] apply instead to `key_type`
685
- and `mapped_type`.
686
 
687
- [*Note 2*: For example, in some cases `key_type` and `mapped_type` are
688
- required to be `CopyAssignable` even though the associated `value_type`,
689
- `pair<const key_type, mapped_type>`, is not
690
- `CopyAssignable`. — *end note*]
691
 
692
- In Table  [[tab:containers.associative.requirements]], `X` denotes an
693
- associative container class, `a` denotes a value of type `X`, `a2`
694
- denotes a value of a type with nodes compatible with type `X` (Table 
695
- [[tab:containers.node.compat]]), `b` denotes a possibly `const` value of
696
- type `X`, `u` denotes the name of a variable being declared, `a_uniq`
697
- denotes a value of type `X` when `X` supports unique keys, `a_eq`
698
- denotes a value of type `X` when `X` supports multiple keys, `a_tran`
699
- denotes a possibly `const` value of type `X` when the *qualified-id*
700
- `X::key_compare::is_transparent` is valid and denotes a type (
701
- [[temp.deduct]]), `i` and `j` satisfy input iterator requirements and
702
- refer to elements implicitly convertible to `value_type`, \[`i`, `j`)
703
- denotes a valid range, `p` denotes a valid constant iterator to `a`, `q`
704
- denotes a valid dereferenceable constant iterator to `a`, `r` denotes a
705
- valid dereferenceable iterator to `a`, `[q1, q2)` denotes a valid range
706
- of constant iterators in `a`, `il` designates an object of type
707
  `initializer_list<value_type>`, `t` denotes a value of type
708
  `X::value_type`, `k` denotes a value of type `X::key_type` and `c`
709
  denotes a possibly `const` value of type `X::key_compare`; `kl` is a
710
- value such that `a` is partitioned ([[alg.sorting]]) with respect to
711
  `c(r, kl)`, with `r` the key value of `e` and `e` in `a`; `ku` is a
712
  value such that `a` is partitioned with respect to `!c(ku, r)`; `ke` is
713
  a value such that `a` is partitioned with respect to `c(r, ke)` and
714
  `!c(ke, r)`, with `c(r, ke)` implying `!c(ke, r)`. `A` denotes the
715
  storage allocator used by `X`, if any, or `allocator<X::value_type>`
@@ -746,19 +754,19 @@ value_comp(*i, *j) != false
746
  ```
747
 
748
  When an associative container is constructed by passing a comparison
749
  object the container shall not store a pointer or reference to the
750
  passed object, even if that object is passed by reference. When an
751
- associative container is copied, either through a copy constructor or an
752
  assignment operator, the target container shall then use the comparison
753
  object from the container being copied, as if that comparison object had
754
  been passed to the target container in its constructor.
755
 
756
- The member function templates `find`, `count`, `lower_bound`,
757
- `upper_bound`, and `equal_range` shall not participate in overload
758
- resolution unless the *qualified-id* `Compare::is_transparent` is valid
759
- and denotes a type ([[temp.deduct]]).
760
 
761
  A deduction guide for an associative container shall not participate in
762
  overload resolution if any of the following are true:
763
 
764
  - It has an `InputIterator` template parameter and a type that does not
@@ -789,31 +797,31 @@ of data based on keys. The worst-case complexity for most operations is
789
  linear, but the average case is much faster. The library provides four
790
  unordered associative containers: `unordered_set`, `unordered_map`,
791
  `unordered_multiset`, and `unordered_multimap`.
792
 
793
  Unordered associative containers conform to the requirements for
794
- Containers ([[container.requirements]]), except that the expressions
795
  `a == b` and `a != b` have different semantics than for the other
796
  container types.
797
 
798
  Each unordered associative container is parameterized by `Key`, by a
799
- function object type `Hash` that meets the `Hash` requirements (
800
- [[hash.requirements]]) and acts as a hash function for argument values
801
- of type `Key`, and by a binary predicate `Pred` that induces an
802
- equivalence relation on values of type `Key`. Additionally,
803
- `unordered_map` and `unordered_multimap` associate an arbitrary *mapped
804
- type* `T` with the `Key`.
805
 
806
  The container’s object of type `Hash` — denoted by `hash` — is called
807
  the *hash function* of the container. The container’s object of type
808
  `Pred` — denoted by `pred` — is called the *key equality predicate* of
809
  the container.
810
 
811
- Two values `k1` and `k2` of type `Key` are considered equivalent if the
812
- container’s key equality predicate returns `true` when passed those
813
- values. If `k1` and `k2` are equivalent, the container’s hash function
814
- shall return the same value for both.
815
 
816
  [*Note 1*: Thus, when an unordered associative container is
817
  instantiated with a non-default `Pred` parameter it usually needs a
818
  non-default `Hash` parameter as well. — *end note*]
819
 
@@ -858,64 +866,78 @@ changes ordering between elements, and changes which buckets elements
858
  appear in, but does not invalidate pointers or references to elements.
859
  For `unordered_multiset` and `unordered_multimap`, rehashing preserves
860
  the relative ordering of equivalent elements.
861
 
862
  The unordered associative containers meet all the requirements of
863
- Allocator-aware containers ([[container.requirements.general]]), except
864
  that for `unordered_map` and `unordered_multimap`, the requirements
865
- placed on `value_type` in Table 
866
- [[tab:containers.container.requirements]] apply instead to `key_type`
867
- and `mapped_type`.
868
 
869
  [*Note 3*: For example, `key_type` and `mapped_type` are sometimes
870
- required to be `CopyAssignable` even though the associated `value_type`,
871
- `pair<const key_type, mapped_type>`, is not
872
- `CopyAssignable`. — *end note*]
873
 
874
- In Table  [[tab:HashRequirements]]: `X` denotes an unordered associative
875
- container class, `a` denotes a value of type `X`, `a2` denotes a value
876
- of a type with nodes compatible with type `X` (Table 
877
- [[tab:containers.node.compat]]), `b` denotes a possibly const value of
878
- type `X`, `a_uniq` denotes a value of type `X` when `X` supports unique
879
- keys, `a_eq` denotes a value of type `X` when `X` supports equivalent
880
- keys, `i` and `j` denote input iterators that refer to `value_type`,
881
- `[i, j)` denotes a valid range, `p` and `q2` denote valid constant
882
- iterators to `a`, `q` and `q1` denote valid dereferenceable constant
883
- iterators to `a`, `r` denotes a valid dereferenceable iterator to `a`,
884
- `[q1, q2)` denotes a valid range in `a`, `il` denotes a value of type
885
- `initializer_list<value_type>`, `t` denotes a value of type
886
- `X::value_type`, `k` denotes a value of type `key_type`, `hf` denotes a
887
- possibly const value of type `hasher`, `eq` denotes a possibly const
888
- value of type `key_equal`, `n` denotes a value of type `size_type`, `z`
889
- denotes a value of type `float`, and `nh` denotes a non-const rvalue of
890
- type `X::node_type`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891
 
892
  Two unordered containers `a` and `b` compare equal if
893
  `a.size() == b.size()` and, for every equivalent-key group \[`Ea1`,
894
  `Ea2`) obtained from `a.equal_range(Ea1)`, there exists an
895
  equivalent-key group \[`Eb1`, `Eb2`) obtained from `b.equal_range(Ea1)`,
896
  such that `is_permutation(Ea1, Ea2, Eb1, Eb2)` returns `true`. For
897
  `unordered_set` and `unordered_map`, the complexity of `operator==`
898
  (i.e., the number of calls to the `==` operator of the `value_type`, to
899
  the predicate returned by `key_eq()`, and to the hasher returned by
900
  `hash_function()`) is proportional to N in the average case and to N² in
901
- the worst case, where N is a.size(). For `unordered_multiset` and
902
  `unordered_multimap`, the complexity of `operator==` is proportional to
903
  $\sum E_i^2$ in the average case and to N² in the worst case, where N is
904
  `a.size()`, and Eᵢ is the size of the iᵗʰ equivalent-key group in `a`.
905
  However, if the respective elements of each corresponding pair of
906
  equivalent-key groups Eaᵢ and Ebᵢ are arranged in the same order (as is
907
  commonly the case, e.g., if `a` and `b` are unmodified copies of the
908
  same container), then the average-case complexity for
909
  `unordered_multiset` and `unordered_multimap` becomes proportional to N
910
  (but worst-case complexity remains 𝑂(N^2), e.g., for a pathologically
911
  bad hash function). The behavior of a program that uses `operator==` or
912
- `operator!=` on unordered containers is undefined unless the `Hash` and
913
- `Pred` function objects respectively have the same behavior for both
914
- containers and the equality comparison function for `Key` is a
915
- refinement[^1] of the partition into equivalent-key groups produced by
916
- `Pred`.
917
 
918
  The iterator types `iterator` and `const_iterator` of an unordered
919
  associative container are of at least the forward iterator category. For
920
  unordered associative containers where the key type and value type are
921
  the same, both `iterator` and `const_iterator` are constant iterators.
@@ -938,10 +960,15 @@ pointers and references to the removed element remain valid. However,
938
  accessing the element through such pointers and references while the
939
  element is owned by a `node_type` is undefined behavior. References and
940
  pointers to an element obtained while it is owned by a `node_type` are
941
  invalidated if the element is successfully inserted.
942
 
 
 
 
 
 
943
  A deduction guide for an unordered associative container shall not
944
  participate in overload resolution if any of the following are true:
945
 
946
  - It has an `InputIterator` template parameter and a type that does not
947
  qualify as an input iterator is deduced for that parameter.
@@ -977,35 +1004,47 @@ or comparison function, the `rehash()` function has no effect.
977
 
978
  The headers `<array>`, `<deque>`, `<forward_list>`, `<list>`, and
979
  `<vector>` define class templates that meet the requirements for
980
  sequence containers.
981
 
 
 
 
 
 
 
 
 
982
  ### Header `<array>` synopsis <a id="array.syn">[[array.syn]]</a>
983
 
984
  ``` cpp
985
- #include <initializer_list>
 
986
 
987
  namespace std {
988
  // [array], class template array
989
  template<class T, size_t N> struct array;
 
990
  template<class T, size_t N>
991
- bool operator==(const array<T, N>& x, const array<T, N>& y);
992
- template <class T, size_t N>
993
- bool operator!=(const array<T, N>& x, const array<T, N>& y);
994
- template <class T, size_t N>
995
- bool operator< (const array<T, N>& x, const array<T, N>& y);
996
  template<class T, size_t N>
997
- bool operator> (const array<T, N>& x, const array<T, N>& y);
 
 
 
998
  template<class T, size_t N>
999
- bool operator<=(const array<T, N>& x, const array<T, N>& y);
 
 
1000
  template<class T, size_t N>
1001
- bool operator>=(const array<T, N>& x, const array<T, N>& y);
1002
  template<class T, size_t N>
1003
- void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
1004
 
1005
- template <class T> class tuple_size;
1006
- template <size_t I, class T> class tuple_element;
 
1007
  template<class T, size_t N>
1008
  struct tuple_size<array<T, N>>;
1009
  template<size_t I, class T, size_t N>
1010
  struct tuple_element<I, array<T, N>>;
1011
  template<size_t I, class T, size_t N>
@@ -1020,124 +1059,136 @@ namespace std {
1020
  ```
1021
 
1022
  ### Header `<deque>` synopsis <a id="deque.syn">[[deque.syn]]</a>
1023
 
1024
  ``` cpp
1025
- #include <initializer_list>
 
1026
 
1027
  namespace std {
1028
  // [deque], class template deque
1029
  template<class T, class Allocator = allocator<T>> class deque;
 
1030
  template<class T, class Allocator>
1031
  bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1032
  template<class T, class Allocator>
1033
- bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1034
- template <class T, class Allocator>
1035
- bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1036
- template <class T, class Allocator>
1037
- bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1038
- template <class T, class Allocator>
1039
- bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1040
- template <class T, class Allocator>
1041
- bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1042
  template<class T, class Allocator>
1043
  void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
1044
  noexcept(noexcept(x.swap(y)));
1045
 
 
 
 
 
 
 
 
1046
  namespace pmr {
1047
  template<class T>
1048
  using deque = std::deque<T, polymorphic_allocator<T>>;
1049
  }
1050
  }
1051
  ```
1052
 
1053
- ### Header `<forward_list>` synopsis <a id="forward_list.syn">[[forward_list.syn]]</a>
1054
 
1055
  ``` cpp
1056
- #include <initializer_list>
 
1057
 
1058
  namespace std {
1059
  // [forwardlist], class template forward_list
1060
  template<class T, class Allocator = allocator<T>> class forward_list;
 
1061
  template<class T, class Allocator>
1062
  bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1063
  template<class T, class Allocator>
1064
- bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1065
- template <class T, class Allocator>
1066
- bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1067
- template <class T, class Allocator>
1068
- bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1069
- template <class T, class Allocator>
1070
- bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1071
- template <class T, class Allocator>
1072
- bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1073
  template<class T, class Allocator>
1074
  void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
1075
  noexcept(noexcept(x.swap(y)));
1076
 
 
 
 
 
 
 
 
1077
  namespace pmr {
1078
  template<class T>
1079
  using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
1080
  }
1081
  }
1082
  ```
1083
 
1084
  ### Header `<list>` synopsis <a id="list.syn">[[list.syn]]</a>
1085
 
1086
  ``` cpp
1087
- #include <initializer_list>
 
1088
 
1089
  namespace std {
1090
  // [list], class template list
1091
  template<class T, class Allocator = allocator<T>> class list;
 
1092
  template<class T, class Allocator>
1093
  bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
1094
  template<class T, class Allocator>
1095
- bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
1096
- template <class T, class Allocator>
1097
- bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
1098
- template <class T, class Allocator>
1099
- bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
1100
- template <class T, class Allocator>
1101
- bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
1102
- template <class T, class Allocator>
1103
- bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);
1104
  template<class T, class Allocator>
1105
  void swap(list<T, Allocator>& x, list<T, Allocator>& y)
1106
  noexcept(noexcept(x.swap(y)));
1107
 
 
 
 
 
 
 
 
1108
  namespace pmr {
1109
  template<class T>
1110
  using list = std::list<T, polymorphic_allocator<T>>;
1111
  }
1112
  }
1113
  ```
1114
 
1115
  ### Header `<vector>` synopsis <a id="vector.syn">[[vector.syn]]</a>
1116
 
1117
  ``` cpp
1118
- #include <initializer_list>
 
1119
 
1120
  namespace std {
1121
  // [vector], class template vector
1122
  template<class T, class Allocator = allocator<T>> class vector;
 
1123
  template<class T, class Allocator>
1124
- bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1125
  template<class T, class Allocator>
1126
- bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
 
 
1127
  template<class T, class Allocator>
1128
- bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1129
- template <class T, class Allocator>
1130
- bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1131
- template <class T, class Allocator>
1132
- bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1133
- template <class T, class Allocator>
1134
- bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1135
- template <class T, class Allocator>
1136
- void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
1137
  noexcept(noexcept(x.swap(y)));
1138
 
 
 
 
 
 
 
 
1139
  // [vector.bool], class vector<bool>
1140
  template<class Allocator> class vector<bool, Allocator>;
1141
 
1142
  // hash support
1143
  template<class T> struct hash;
@@ -1150,35 +1201,44 @@ namespace std {
1150
  }
1151
  ```
1152
 
1153
  ### Class template `array` <a id="array">[[array]]</a>
1154
 
1155
- #### Class template `array` overview <a id="array.overview">[[array.overview]]</a>
1156
 
1157
  The header `<array>` defines a class template for storing fixed-size
1158
- sequences of objects. An `array` is a contiguous container (
1159
- [[container.requirements.general]]). An instance of `array<T, N>` stores
1160
  `N` elements of type `T`, so that `size() == N` is an invariant.
1161
 
1162
- An `array` is an aggregate ([[dcl.init.aggr]]) that can be
1163
  list-initialized with up to `N` elements whose types are convertible to
1164
  `T`.
1165
 
1166
- An `array` satisfies all of the requirements of a container and of a
1167
- reversible container ([[container.requirements]]), except that a
1168
- default constructed `array` object is not empty and that `swap` does not
1169
- have constant complexity. An `array` satisfies some of the requirements
1170
- of a sequence container ([[sequence.reqmts]]). Descriptions are
1171
- provided here only for operations on `array` that are not described in
1172
- one of these tables and for operations where there is additional
1173
- semantic information.
 
 
 
 
 
 
 
 
 
1174
 
1175
  ``` cpp
1176
  namespace std {
1177
  template<class T, size_t N>
1178
  struct array {
1179
- // types:
1180
  using value_type = T;
1181
  using pointer = T*;
1182
  using const_pointer = const T*;
1183
  using reference = T&;
1184
  using const_reference = const T&;
@@ -1189,14 +1249,14 @@ namespace std {
1189
  using reverse_iterator = std::reverse_iterator<iterator>;
1190
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1191
 
1192
  // no explicit construct/copy/destroy for aggregate type
1193
 
1194
- void fill(const T& u);
1195
- void swap(array&) noexcept(is_nothrow_swappable_v<T>);
1196
 
1197
- // iterators:
1198
  constexpr iterator begin() noexcept;
1199
  constexpr const_iterator begin() const noexcept;
1200
  constexpr iterator end() noexcept;
1201
  constexpr const_iterator end() const noexcept;
1202
 
@@ -1208,16 +1268,16 @@ namespace std {
1208
  constexpr const_iterator cbegin() const noexcept;
1209
  constexpr const_iterator cend() const noexcept;
1210
  constexpr const_reverse_iterator crbegin() const noexcept;
1211
  constexpr const_reverse_iterator crend() const noexcept;
1212
 
1213
- // capacity:
1214
- constexpr bool empty() const noexcept;
1215
  constexpr size_type size() const noexcept;
1216
  constexpr size_type max_size() const noexcept;
1217
 
1218
- // element access:
1219
  constexpr reference operator[](size_type n);
1220
  constexpr const_reference operator[](size_type n) const;
1221
  constexpr reference at(size_type n);
1222
  constexpr const_reference at(size_type n) const;
1223
  constexpr reference front();
@@ -1232,83 +1292,75 @@ namespace std {
1232
  template<class T, class... U>
1233
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
1234
  }
1235
  ```
1236
 
1237
- #### `array` constructors, copy, and assignment <a id="array.cons">[[array.cons]]</a>
1238
 
1239
- The conditions for an aggregate ([[dcl.init.aggr]]) shall be met. Class
1240
  `array` relies on the implicitly-declared special member functions (
1241
- [[class.ctor]], [[class.dtor]], and [[class.copy]]) to conform to the
1242
- container requirements table in  [[container.requirements]]. In addition
1243
- to the requirements specified in the container requirements table, the
1244
- implicit move constructor and move assignment operator for `array`
1245
- require that `T` be `MoveConstructible` or `MoveAssignable`,
1246
- respectively.
1247
 
1248
  ``` cpp
1249
  template<class T, class... U>
1250
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
1251
  ```
1252
 
1253
- *Requires:* `(is_same_v<T, U> && ...)` is `true`. Otherwise the program
1254
- is ill-formed.
1255
 
1256
- #### `array` specialized algorithms <a id="array.special">[[array.special]]</a>
1257
 
1258
  ``` cpp
1259
- template <class T, size_t N>
1260
- void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
1261
- ```
1262
-
1263
- *Remarks:* This function shall not participate in overload resolution
1264
- unless `N == 0` or `is_swappable_v<T>` is `true`.
1265
-
1266
- *Effects:* As if by `x.swap(y)`.
1267
-
1268
- *Complexity:* Linear in `N`.
1269
-
1270
- #### `array::size` <a id="array.size">[[array.size]]</a>
1271
-
1272
- ``` cpp
1273
- template <class T, size_t N> constexpr size_type array<T, N>::size() const noexcept;
1274
  ```
1275
 
1276
  *Returns:* `N`.
1277
 
1278
- #### `array::data` <a id="array.data">[[array.data]]</a>
1279
-
1280
  ``` cpp
1281
  constexpr T* data() noexcept;
1282
  constexpr const T* data() const noexcept;
1283
  ```
1284
 
1285
- *Returns:* A pointer such that `data() == addressof(front())`, and
1286
- \[`data()`, `data() + size()`) is a valid range.
1287
-
1288
- #### `array::fill` <a id="array.fill">[[array.fill]]</a>
1289
 
1290
  ``` cpp
1291
- void fill(const T& u);
1292
  ```
1293
 
1294
  *Effects:* As if by `fill_n(begin(), N, u)`.
1295
 
1296
- #### `array::swap` <a id="array.swap">[[array.swap]]</a>
1297
-
1298
  ``` cpp
1299
- void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
1300
  ```
1301
 
1302
  *Effects:* Equivalent to `swap_ranges(begin(), end(), y.begin())`.
1303
 
1304
  [*Note 1*: Unlike the `swap` function for other containers,
1305
  `array::swap` takes linear time, may exit via an exception, and does not
1306
  cause iterators to become associated with the other
1307
  container. — *end note*]
1308
 
1309
- #### Zero sized arrays <a id="array.zero">[[array.zero]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
 
1311
  `array` shall provide support for the special case `N == 0`.
1312
 
1313
  In the case that `N == 0`, `begin() == end() ==` unique value. The
1314
  return value of `data()` is unspecified.
@@ -1317,24 +1369,51 @@ The effect of calling `front()` or `back()` for a zero-sized array is
1317
  undefined.
1318
 
1319
  Member function `swap()` shall have a non-throwing exception
1320
  specification.
1321
 
1322
- #### Tuple interface to class template `array` <a id="array.tuple">[[array.tuple]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1323
 
1324
  ``` cpp
1325
  template<class T, size_t N>
1326
  struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
1327
  ```
1328
 
1329
  ``` cpp
1330
- tuple_element<I, array<T, N>>::type
 
 
 
1331
  ```
1332
 
1333
- *Requires:* `I < N`. The program is ill-formed if `I` is out of bounds.
1334
-
1335
- *Value:* The type T.
1336
 
1337
  ``` cpp
1338
  template<size_t I, class T, size_t N>
1339
  constexpr T& get(array<T, N>& a) noexcept;
1340
  template<size_t I, class T, size_t N>
@@ -1343,41 +1422,40 @@ template <size_t I, class T, size_t N>
1343
  constexpr const T& get(const array<T, N>& a) noexcept;
1344
  template<size_t I, class T, size_t N>
1345
  constexpr const T&& get(const array<T, N>&& a) noexcept;
1346
  ```
1347
 
1348
- *Requires:* `I < N`. The program is ill-formed if `I` is out of bounds.
1349
 
1350
- *Returns:* A reference to the `I`th element of `a`, where indexing is
1351
  zero-based.
1352
 
1353
  ### Class template `deque` <a id="deque">[[deque]]</a>
1354
 
1355
- #### Class template `deque` overview <a id="deque.overview">[[deque.overview]]</a>
1356
 
1357
  A `deque` is a sequence container that supports random access iterators
1358
- ([[random.access.iterators]]). In addition, it supports constant time
1359
  insert and erase operations at the beginning or the end; insert and
1360
  erase in the middle take linear time. That is, a deque is especially
1361
  optimized for pushing and popping elements at the beginning and end.
1362
  Storage management is handled automatically.
1363
 
1364
- A `deque` satisfies all of the requirements of a container, of a
1365
- reversible container (given in tables in  [[container.requirements]]),
1366
- of a sequence container, including the optional sequence container
1367
- requirements ([[sequence.reqmts]]), and of an allocator-aware container
1368
- (Table  [[tab:containers.allocatoraware]]). Descriptions are provided
1369
- here only for operations on `deque` that are not described in one of
1370
- these tables or for operations where there is additional semantic
1371
- information.
1372
 
1373
  ``` cpp
1374
  namespace std {
1375
  template<class T, class Allocator = allocator<T>>
1376
  class deque {
1377
  public:
1378
- // types:
1379
  using value_type = T;
1380
  using allocator_type = Allocator;
1381
  using pointer = typename allocator_traits<Allocator>::pointer;
1382
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
1383
  using reference = value_type&;
@@ -1411,11 +1489,11 @@ namespace std {
1411
  void assign(InputIterator first, InputIterator last);
1412
  void assign(size_type n, const T& t);
1413
  void assign(initializer_list<T>);
1414
  allocator_type get_allocator() const noexcept;
1415
 
1416
- // iterators:
1417
  iterator begin() noexcept;
1418
  const_iterator begin() const noexcept;
1419
  iterator end() noexcept;
1420
  const_iterator end() const noexcept;
1421
  reverse_iterator rbegin() noexcept;
@@ -1427,18 +1505,18 @@ namespace std {
1427
  const_iterator cend() const noexcept;
1428
  const_reverse_iterator crbegin() const noexcept;
1429
  const_reverse_iterator crend() const noexcept;
1430
 
1431
  // [deque.capacity], capacity
1432
- bool empty() const noexcept;
1433
  size_type size() const noexcept;
1434
  size_type max_size() const noexcept;
1435
  void resize(size_type sz);
1436
  void resize(size_type sz, const T& c);
1437
  void shrink_to_fit();
1438
 
1439
- // element access:
1440
  reference operator[](size_type n);
1441
  const_reference operator[](size_type n) const;
1442
  reference at(size_type n);
1443
  const_reference at(size_type n) const;
1444
  reference front();
@@ -1471,36 +1549,22 @@ namespace std {
1471
  void swap(deque&)
1472
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
1473
  void clear() noexcept;
1474
  };
1475
 
1476
- template<class InputIterator,
1477
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1478
  deque(InputIterator, InputIterator, Allocator = Allocator())
1479
- -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
1480
 
1481
- template <class T, class Allocator>
1482
- bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1483
- template <class T, class Allocator>
1484
- bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1485
- template <class T, class Allocator>
1486
- bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1487
- template <class T, class Allocator>
1488
- bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1489
- template <class T, class Allocator>
1490
- bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1491
- template <class T, class Allocator>
1492
- bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1493
-
1494
- // [deque.special], specialized algorithms
1495
  template<class T, class Allocator>
1496
  void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
1497
  noexcept(noexcept(x.swap(y)));
1498
  }
1499
  ```
1500
 
1501
- #### `deque` constructors, copy, and assignment <a id="deque.cons">[[deque.cons]]</a>
1502
 
1503
  ``` cpp
1504
  explicit deque(const Allocator&);
1505
  ```
1506
 
@@ -1513,22 +1577,22 @@ explicit deque(size_type n, const Allocator& = Allocator());
1513
  ```
1514
 
1515
  *Effects:* Constructs a `deque` with `n` default-inserted elements using
1516
  the specified allocator.
1517
 
1518
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
1519
 
1520
  *Complexity:* Linear in `n`.
1521
 
1522
  ``` cpp
1523
  deque(size_type n, const T& value, const Allocator& = Allocator());
1524
  ```
1525
 
1526
  *Effects:* Constructs a `deque` with `n` copies of `value`, using the
1527
  specified allocator.
1528
 
1529
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
1530
 
1531
  *Complexity:* Linear in `n`.
1532
 
1533
  ``` cpp
1534
  template<class InputIterator>
@@ -1538,55 +1602,57 @@ template <class InputIterator>
1538
  *Effects:* Constructs a `deque` equal to the range \[`first`, `last`),
1539
  using the specified allocator.
1540
 
1541
  *Complexity:* Linear in `distance(first, last)`.
1542
 
1543
- #### `deque` capacity <a id="deque.capacity">[[deque.capacity]]</a>
1544
 
1545
  ``` cpp
1546
  void resize(size_type sz);
1547
  ```
1548
 
 
 
 
1549
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
1550
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
1551
  to the sequence.
1552
 
1553
- *Requires:* `T` shall be `MoveInsertable` and `DefaultInsertable` into
1554
- `*this`.
1555
-
1556
  ``` cpp
1557
  void resize(size_type sz, const T& c);
1558
  ```
1559
 
 
 
1560
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
1561
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
1562
  sequence.
1563
 
1564
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
1565
-
1566
  ``` cpp
1567
  void shrink_to_fit();
1568
  ```
1569
 
1570
- *Requires:* `T` shall be `MoveInsertable` into `*this`.
1571
 
1572
  *Effects:* `shrink_to_fit` is a non-binding request to reduce memory use
1573
  but does not change the size of the sequence.
1574
 
1575
  [*Note 1*: The request is non-binding to allow latitude for
1576
  implementation-specific optimizations. — *end note*]
1577
 
1578
- If an exception is thrown other than by the move constructor of a
1579
- non-`CopyInsertable` `T` there are no effects.
 
1580
 
1581
- *Complexity:* Linear in the size of the sequence.
 
1582
 
1583
- *Remarks:* `shrink_to_fit` invalidates all the references, pointers, and
1584
- iterators referring to the elements in the sequence as well as the
1585
- past-the-end iterator.
1586
 
1587
- #### `deque` modifiers <a id="deque.modifiers">[[deque.modifiers]]</a>
1588
 
1589
  ``` cpp
1590
  iterator insert(const_iterator position, const T& x);
1591
  iterator insert(const_iterator position, T&& x);
1592
  iterator insert(const_iterator position, size_type n, const T& x);
@@ -1611,16 +1677,16 @@ has no effect on the validity of references to elements of the deque.
1611
 
1612
  *Remarks:* If an exception is thrown other than by the copy constructor,
1613
  move constructor, assignment operator, or move assignment operator of
1614
  `T` there are no effects. If an exception is thrown while inserting a
1615
  single element at either end, there are no effects. Otherwise, if an
1616
- exception is thrown by the move constructor of a non-`CopyInsertable`
1617
- `T`, the effects are unspecified.
1618
 
1619
  *Complexity:* The complexity is linear in the number of elements
1620
  inserted plus the lesser of the distances to the beginning and end of
1621
- the deque. Inserting a single element either at the beginning or end of
1622
  a deque always takes constant time and causes a single call to a
1623
  constructor of `T`.
1624
 
1625
  ``` cpp
1626
  iterator erase(const_iterator position);
@@ -1645,48 +1711,68 @@ operations. — *end note*]
1645
  as the number of elements erased, but the number of calls to the
1646
  assignment operator of `T` is no more than the lesser of the number of
1647
  elements before the erased elements and the number of elements after the
1648
  erased elements.
1649
 
1650
- *Throws:* Nothing unless an exception is thrown by the copy constructor,
1651
- move constructor, assignment operator, or move assignment operator of
1652
- `T`.
1653
 
1654
- #### `deque` specialized algorithms <a id="deque.special">[[deque.special]]</a>
1655
 
1656
  ``` cpp
1657
- template <class T, class Allocator>
1658
- void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
1659
- noexcept(noexcept(x.swap(y)));
1660
  ```
1661
 
1662
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1663
 
1664
  ### Class template `forward_list` <a id="forwardlist">[[forwardlist]]</a>
1665
 
1666
- #### Class template `forward_list` overview <a id="forwardlist.overview">[[forwardlist.overview]]</a>
1667
 
1668
  A `forward_list` is a container that supports forward iterators and
1669
  allows constant time insert and erase operations anywhere within the
1670
  sequence, with storage management handled automatically. Fast random
1671
  access to list elements is not supported.
1672
 
1673
  [*Note 1*: It is intended that `forward_list` have zero space or time
1674
  overhead relative to a hand-written C-style singly linked list. Features
1675
  that would conflict with that goal have been omitted. — *end note*]
1676
 
1677
- A `forward_list` satisfies all of the requirements of a container
1678
- (Table  [[tab:containers.container.requirements]]), except that the
1679
- `size()` member function is not provided and `operator==` has linear
1680
- complexity. A `forward_list` also satisfies all of the requirements for
1681
- an allocator-aware container (Table  [[tab:containers.allocatoraware]]).
1682
- In addition, a `forward_list` provides the `assign` member functions
1683
- (Table  [[tab:containers.sequence.requirements]]) and several of the
1684
- optional container requirements (Table 
1685
- [[tab:containers.sequence.optional]]). Descriptions are provided here
1686
- only for operations on `forward_list` that are not described in that
1687
- table or for operations where there is additional semantic information.
1688
 
1689
  [*Note 2*: Modifying any list requires access to the element preceding
1690
  the first element of interest, but in a `forward_list` there is no
1691
  constant-time way to access a preceding element. For this reason, ranges
1692
  that are modified, such as those supplied to `erase` and `splice`, must
@@ -1695,11 +1781,11 @@ be open at the beginning. — *end note*]
1695
  ``` cpp
1696
  namespace std {
1697
  template<class T, class Allocator = allocator<T>>
1698
  class forward_list {
1699
  public:
1700
- // types:
1701
  using value_type = T;
1702
  using allocator_type = Allocator;
1703
  using pointer = typename allocator_traits<Allocator>::pointer;
1704
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
1705
  using reference = value_type&;
@@ -1711,15 +1797,13 @@ namespace std {
1711
 
1712
  // [forwardlist.cons], construct/copy/destroy
1713
  forward_list() : forward_list(Allocator()) { }
1714
  explicit forward_list(const Allocator&);
1715
  explicit forward_list(size_type n, const Allocator& = Allocator());
1716
- forward_list(size_type n, const T& value,
1717
- const Allocator& = Allocator());
1718
  template<class InputIterator>
1719
- forward_list(InputIterator first, InputIterator last,
1720
- const Allocator& = Allocator());
1721
  forward_list(const forward_list& x);
1722
  forward_list(forward_list&& x);
1723
  forward_list(const forward_list& x, const Allocator&);
1724
  forward_list(forward_list&& x, const Allocator&);
1725
  forward_list(initializer_list<T>, const Allocator& = Allocator());
@@ -1744,12 +1828,12 @@ namespace std {
1744
 
1745
  const_iterator cbegin() const noexcept;
1746
  const_iterator cbefore_begin() const noexcept;
1747
  const_iterator cend() const noexcept;
1748
 
1749
- // capacity:
1750
- bool empty() const noexcept;
1751
  size_type max_size() const noexcept;
1752
 
1753
  // [forwardlist.access], element access
1754
  reference front();
1755
  const_reference front() const;
@@ -1779,24 +1863,22 @@ namespace std {
1779
  void clear() noexcept;
1780
 
1781
  // [forwardlist.ops], forward_list operations
1782
  void splice_after(const_iterator position, forward_list& x);
1783
  void splice_after(const_iterator position, forward_list&& x);
1784
- void splice_after(const_iterator position, forward_list& x,
1785
- const_iterator i);
1786
- void splice_after(const_iterator position, forward_list&& x,
1787
- const_iterator i);
1788
  void splice_after(const_iterator position, forward_list& x,
1789
  const_iterator first, const_iterator last);
1790
  void splice_after(const_iterator position, forward_list&& x,
1791
  const_iterator first, const_iterator last);
1792
 
1793
- void remove(const T& value);
1794
- template <class Predicate> void remove_if(Predicate pred);
1795
 
1796
- void unique();
1797
- template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
1798
 
1799
  void merge(forward_list& x);
1800
  void merge(forward_list&& x);
1801
  template<class Compare> void merge(forward_list& x, Compare comp);
1802
  template<class Compare> void merge(forward_list&& x, Compare comp);
@@ -1805,42 +1887,28 @@ namespace std {
1805
  template<class Compare> void sort(Compare comp);
1806
 
1807
  void reverse() noexcept;
1808
  };
1809
 
1810
- template<class InputIterator,
1811
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1812
  forward_list(InputIterator, InputIterator, Allocator = Allocator())
1813
- -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;
1814
 
1815
- template <class T, class Allocator>
1816
- bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1817
- template <class T, class Allocator>
1818
- bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1819
- template <class T, class Allocator>
1820
- bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1821
- template <class T, class Allocator>
1822
- bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1823
- template <class T, class Allocator>
1824
- bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1825
- template <class T, class Allocator>
1826
- bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
1827
-
1828
- // [forwardlist.spec], specialized algorithms
1829
  template<class T, class Allocator>
1830
  void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
1831
  noexcept(noexcept(x.swap(y)));
1832
  }
1833
  ```
1834
 
1835
  An incomplete type `T` may be used when instantiating `forward_list` if
1836
- the allocator satisfies the allocator completeness requirements (
1837
- [[allocator.requirements.completeness]]). `T` shall be complete before
1838
  any member of the resulting specialization of `forward_list` is
1839
  referenced.
1840
 
1841
- #### `forward_list` constructors, copy, assignment <a id="forwardlist.cons">[[forwardlist.cons]]</a>
1842
 
1843
  ``` cpp
1844
  explicit forward_list(const Allocator&);
1845
  ```
1846
 
@@ -1851,26 +1919,26 @@ allocator.
1851
 
1852
  ``` cpp
1853
  explicit forward_list(size_type n, const Allocator& = Allocator());
1854
  ```
1855
 
 
 
1856
  *Effects:* Constructs a `forward_list` object with `n` default-inserted
1857
  elements using the specified allocator.
1858
 
1859
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
1860
-
1861
  *Complexity:* Linear in `n`.
1862
 
1863
  ``` cpp
1864
  forward_list(size_type n, const T& value, const Allocator& = Allocator());
1865
  ```
1866
 
 
 
1867
  *Effects:* Constructs a `forward_list` object with `n` copies of `value`
1868
  using the specified allocator.
1869
 
1870
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
1871
-
1872
  *Complexity:* Linear in `n`.
1873
 
1874
  ``` cpp
1875
  template<class InputIterator>
1876
  forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
@@ -1879,11 +1947,11 @@ template <class InputIterator>
1879
  *Effects:* Constructs a `forward_list` object equal to the range
1880
  \[`first`, `last`).
1881
 
1882
  *Complexity:* Linear in `distance(first, last)`.
1883
 
1884
- #### `forward_list` iterators <a id="forwardlist.iter">[[forwardlist.iter]]</a>
1885
 
1886
  ``` cpp
1887
  iterator before_begin() noexcept;
1888
  const_iterator before_begin() const noexcept;
1889
  const_iterator cbefore_begin() const noexcept;
@@ -1895,20 +1963,20 @@ equal to the iterator returned by `begin()`.
1895
  *Effects:* `cbefore_begin()` is equivalent to
1896
  `const_cast<forward_list const&>(*this).before_begin()`.
1897
 
1898
  *Remarks:* `before_begin() == end()` shall equal `false`.
1899
 
1900
- #### `forward_list` element access <a id="forwardlist.access">[[forwardlist.access]]</a>
1901
 
1902
  ``` cpp
1903
  reference front();
1904
  const_reference front() const;
1905
  ```
1906
 
1907
  *Returns:* `*begin()`
1908
 
1909
- #### `forward_list` modifiers <a id="forwardlist.modifiers">[[forwardlist.modifiers]]</a>
1910
 
1911
  None of the overloads of `insert_after` shall affect the validity of
1912
  iterators and references, and `erase_after` shall invalidate only
1913
  iterators and references to the erased elements. If an exception is
1914
  thrown during `insert_after` there shall be no effect. Inserting `n`
@@ -1940,22 +2008,22 @@ void pop_front();
1940
  ``` cpp
1941
  iterator insert_after(const_iterator position, const T& x);
1942
  iterator insert_after(const_iterator position, T&& x);
1943
  ```
1944
 
1945
- *Requires:* `position` is `before_begin()` or is a dereferenceable
1946
  iterator in the range \[`begin()`, `end()`).
1947
 
1948
  *Effects:* Inserts a copy of `x` after `position`.
1949
 
1950
  *Returns:* An iterator pointing to the copy of `x`.
1951
 
1952
  ``` cpp
1953
  iterator insert_after(const_iterator position, size_type n, const T& x);
1954
  ```
1955
 
1956
- *Requires:* `position` is `before_begin()` or is a dereferenceable
1957
  iterator in the range \[`begin()`, `end()`).
1958
 
1959
  *Effects:* Inserts `n` copies of `x` after `position`.
1960
 
1961
  *Returns:* An iterator pointing to the last inserted copy of `x` or
@@ -1964,13 +2032,13 @@ iterator in the range \[`begin()`, `end()`).
1964
  ``` cpp
1965
  template<class InputIterator>
1966
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
1967
  ```
1968
 
1969
- *Requires:* `position` is `before_begin()` or is a dereferenceable
1970
- iterator in the range \[`begin()`, `end()`). `first` and `last` are not
1971
- iterators in `*this`.
1972
 
1973
  *Effects:* Inserts copies of elements in \[`first`, `last`) after
1974
  `position`.
1975
 
1976
  *Returns:* An iterator pointing to the last inserted element or
@@ -1988,11 +2056,11 @@ iterator insert_after(const_iterator position, initializer_list<T> il);
1988
  ``` cpp
1989
  template<class... Args>
1990
  iterator emplace_after(const_iterator position, Args&&... args);
1991
  ```
1992
 
1993
- *Requires:* `position` is `before_begin()` or is a dereferenceable
1994
  iterator in the range \[`begin()`, `end()`).
1995
 
1996
  *Effects:* Inserts an object of type `value_type` constructed with
1997
  `value_type(std::forward<Args>(args)...)` after `position`.
1998
 
@@ -2000,11 +2068,11 @@ iterator in the range \[`begin()`, `end()`).
2000
 
2001
  ``` cpp
2002
  iterator erase_after(const_iterator position);
2003
  ```
2004
 
2005
- *Requires:* The iterator following `position` is dereferenceable.
2006
 
2007
  *Effects:* Erases the element pointed to by the iterator following
2008
  `position`.
2009
 
2010
  *Returns:* An iterator pointing to the element following the one that
@@ -2014,11 +2082,11 @@ was erased, or `end()` if no such element exists.
2014
 
2015
  ``` cpp
2016
  iterator erase_after(const_iterator position, const_iterator last);
2017
  ```
2018
 
2019
- *Requires:* All iterators in the range (`position`, `last`) are
2020
  dereferenceable.
2021
 
2022
  *Effects:* Erases the elements in the range (`position`, `last`).
2023
 
2024
  *Returns:* `last`.
@@ -2027,46 +2095,52 @@ dereferenceable.
2027
 
2028
  ``` cpp
2029
  void resize(size_type sz);
2030
  ```
2031
 
 
 
2032
  *Effects:* If `sz < distance(begin(), end())`, erases the last
2033
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
2034
  inserts `sz - distance(begin(), end())` default-inserted elements at the
2035
  end of the list.
2036
 
2037
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
2038
-
2039
  ``` cpp
2040
  void resize(size_type sz, const value_type& c);
2041
  ```
2042
 
 
 
2043
  *Effects:* If `sz < distance(begin(), end())`, erases the last
2044
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
2045
  inserts `sz - distance(begin(), end())` copies of `c` at the end of the
2046
  list.
2047
 
2048
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
2049
-
2050
  ``` cpp
2051
  void clear() noexcept;
2052
  ```
2053
 
2054
  *Effects:* Erases all elements in the range \[`begin()`, `end()`).
2055
 
2056
  *Remarks:* Does not invalidate past-the-end iterators.
2057
 
2058
- #### `forward_list` operations <a id="forwardlist.ops">[[forwardlist.ops]]</a>
 
 
 
 
 
2059
 
2060
  ``` cpp
2061
  void splice_after(const_iterator position, forward_list& x);
2062
  void splice_after(const_iterator position, forward_list&& x);
2063
  ```
2064
 
2065
- *Requires:* `position` is `before_begin()` or is a dereferenceable
2066
  iterator in the range \[`begin()`, `end()`).
2067
- `get_allocator() == x.get_allocator()`. `&x != this`.
 
2068
 
2069
  *Effects:* Inserts the contents of `x` after `position`, and `x` becomes
2070
  empty. Pointers and references to the moved elements of `x` now refer to
2071
  those same elements but as members of `*this`. Iterators referring to
2072
  the moved elements will continue to refer to their elements, but they
@@ -2079,14 +2153,14 @@ now behave as iterators into `*this`, not into `x`.
2079
  ``` cpp
2080
  void splice_after(const_iterator position, forward_list& x, const_iterator i);
2081
  void splice_after(const_iterator position, forward_list&& x, const_iterator i);
2082
  ```
2083
 
2084
- *Requires:* `position` is `before_begin()` or is a dereferenceable
2085
  iterator in the range \[`begin()`, `end()`). The iterator following `i`
2086
  is a dereferenceable iterator in `x`.
2087
- `get_allocator() == x.get_allocator()`.
2088
 
2089
  *Effects:* Inserts the element following `i` into `*this`, following
2090
  `position`, and removes it from `x`. The result is unchanged if
2091
  `position == i` or `position == ++i`. Pointers and references to `*++i`
2092
  continue to refer to the same element but as a member of `*this`.
@@ -2102,15 +2176,15 @@ void splice_after(const_iterator position, forward_list& x,
2102
  const_iterator first, const_iterator last);
2103
  void splice_after(const_iterator position, forward_list&& x,
2104
  const_iterator first, const_iterator last);
2105
  ```
2106
 
2107
- *Requires:* `position` is `before_begin()` or is a dereferenceable
2108
  iterator in the range \[`begin()`, `end()`). (`first`, `last`) is a
2109
  valid range in `x`, and all iterators in the range (`first`, `last`) are
2110
  dereferenceable. `position` is not an iterator in the range (`first`,
2111
- `last`). `get_allocator() == x.get_allocator()`.
2112
 
2113
  *Effects:* Inserts elements in the range (`first`, `last`) after
2114
  `position` and removes the elements from `x`. Pointers and references to
2115
  the moved elements of `x` now refer to those same elements but as
2116
  members of `*this`. Iterators referring to the moved elements will
@@ -2118,39 +2192,43 @@ continue to refer to their elements, but they now behave as iterators
2118
  into `*this`, not into `x`.
2119
 
2120
  *Complexity:* 𝑂(`distance(first, last)`)
2121
 
2122
  ``` cpp
2123
- void remove(const T& value);
2124
- template <class Predicate> void remove_if(Predicate pred);
2125
  ```
2126
 
2127
- *Effects:* Erases all the elements in the list referred by a list
2128
  iterator `i` for which the following conditions hold: `*i == value` (for
2129
  `remove()`), `pred(*i)` is `true` (for `remove_if()`). Invalidates only
2130
  the iterators and references to the erased elements.
2131
 
 
 
2132
  *Throws:* Nothing unless an exception is thrown by the equality
2133
  comparison or the predicate.
2134
 
2135
- *Remarks:* Stable ([[algorithm.stable]]).
2136
 
2137
  *Complexity:* Exactly `distance(begin(), end())` applications of the
2138
  corresponding predicate.
2139
 
2140
  ``` cpp
2141
- void unique();
2142
- template <class BinaryPredicate> void unique(BinaryPredicate pred);
2143
  ```
2144
 
2145
  *Effects:* Erases all but the first element from every consecutive group
2146
  of equal elements referred to by the iterator `i` in the range
2147
  \[`first + 1`, `last`) for which `*i == *(i-1)` (for the version with no
2148
  arguments) or `pred(*i, *(i - 1))` (for the version with a predicate
2149
  argument) holds. Invalidates only the iterators and references to the
2150
  erased elements.
2151
 
 
 
2152
  *Throws:* Nothing unless an exception is thrown by the equality
2153
  comparison or the predicate.
2154
 
2155
  *Complexity:* If the range \[`first`, `last`) is not empty, exactly
2156
  `(last - first) - 1` applications of the corresponding predicate,
@@ -2161,44 +2239,40 @@ void merge(forward_list& x);
2161
  void merge(forward_list&& x);
2162
  template<class Compare> void merge(forward_list& x, Compare comp);
2163
  template<class Compare> void merge(forward_list&& x, Compare comp);
2164
  ```
2165
 
2166
- *Requires:* `comp` defines a strict weak ordering ([[alg.sorting]]),
2167
- and `*this` and `x` are both sorted according to this ordering.
2168
- `get_allocator() == x.get_allocator()`.
 
2169
 
2170
  *Effects:* Merges the two sorted ranges `[begin(), end())` and
2171
  `[x.begin(), x.end())`. `x` is empty after the merge. If an exception is
2172
  thrown other than by a comparison there are no effects. Pointers and
2173
  references to the moved elements of `x` now refer to those same elements
2174
  but as members of `*this`. Iterators referring to the moved elements
2175
  will continue to refer to their elements, but they now behave as
2176
  iterators into `*this`, not into `x`.
2177
 
2178
- *Remarks:* Stable ([[algorithm.stable]]). The behavior is undefined if
2179
- `get_allocator() != x.get_allocator()`.
2180
 
2181
  *Complexity:* At most
2182
  `distance(begin(), end()) + distance(x.begin(), x.end()) - 1`
2183
  comparisons.
2184
 
2185
  ``` cpp
2186
  void sort();
2187
  template<class Compare> void sort(Compare comp);
2188
  ```
2189
 
2190
- *Requires:* `operator<` (for the version with no arguments) or `comp`
2191
- (for the version with a comparison argument) defines a strict weak
2192
- ordering ([[alg.sorting]]).
2193
-
2194
  *Effects:* Sorts the list according to the `operator<` or the `comp`
2195
  function object. If an exception is thrown, the order of the elements in
2196
  `*this` is unspecified. Does not affect the validity of iterators and
2197
  references.
2198
 
2199
- *Remarks:* Stable ([[algorithm.stable]]).
2200
 
2201
  *Complexity:* Approximately N log N comparisons, where N is
2202
  `distance(begin(), end())`.
2203
 
2204
  ``` cpp
@@ -2208,48 +2282,55 @@ void reverse() noexcept;
2208
  *Effects:* Reverses the order of the elements in the list. Does not
2209
  affect the validity of iterators and references.
2210
 
2211
  *Complexity:* Linear time.
2212
 
2213
- #### `forward_list` specialized algorithms <a id="forwardlist.spec">[[forwardlist.spec]]</a>
2214
 
2215
  ``` cpp
2216
- template <class T, class Allocator>
2217
- void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
2218
- noexcept(noexcept(x.swap(y)));
2219
  ```
2220
 
2221
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
2222
 
2223
  ### Class template `list` <a id="list">[[list]]</a>
2224
 
2225
- #### Class template `list` overview <a id="list.overview">[[list.overview]]</a>
2226
 
2227
  A `list` is a sequence container that supports bidirectional iterators
2228
  and allows constant time insert and erase operations anywhere within the
2229
- sequence, with storage management handled automatically. Unlike
2230
- vectors ([[vector]]) and deques ([[deque]]), fast random access to
2231
- list elements is not supported, but many algorithms only need sequential
2232
- access anyway.
2233
 
2234
- A `list` satisfies all of the requirements of a container, of a
2235
- reversible container (given in two tables in
2236
- [[container.requirements]]), of a sequence container, including most of
2237
- the optional sequence container requirements ([[sequence.reqmts]]), and
2238
- of an allocator-aware container (Table 
2239
- [[tab:containers.allocatoraware]]). The exceptions are the `operator[]`
2240
- and `at` member functions, which are not provided.[^2] Descriptions are
2241
- provided here only for operations on `list` that are not described in
2242
- one of these tables or for operations where there is additional semantic
2243
  information.
2244
 
2245
  ``` cpp
2246
  namespace std {
2247
  template<class T, class Allocator = allocator<T>>
2248
  class list {
2249
  public:
2250
- // types:
2251
  using value_type = T;
2252
  using allocator_type = Allocator;
2253
  using pointer = typename allocator_traits<Allocator>::pointer;
2254
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
2255
  using reference = value_type&;
@@ -2282,11 +2363,11 @@ namespace std {
2282
  void assign(InputIterator first, InputIterator last);
2283
  void assign(size_type n, const T& t);
2284
  void assign(initializer_list<T>);
2285
  allocator_type get_allocator() const noexcept;
2286
 
2287
- // iterators:
2288
  iterator begin() noexcept;
2289
  const_iterator begin() const noexcept;
2290
  iterator end() noexcept;
2291
  const_iterator end() const noexcept;
2292
  reverse_iterator rbegin() noexcept;
@@ -2298,17 +2379,17 @@ namespace std {
2298
  const_iterator cend() const noexcept;
2299
  const_reverse_iterator crbegin() const noexcept;
2300
  const_reverse_iterator crend() const noexcept;
2301
 
2302
  // [list.capacity], capacity
2303
- bool empty() const noexcept;
2304
  size_type size() const noexcept;
2305
  size_type max_size() const noexcept;
2306
  void resize(size_type sz);
2307
  void resize(size_type sz, const T& c);
2308
 
2309
- // element access:
2310
  reference front();
2311
  const_reference front() const;
2312
  reference back();
2313
  const_reference back() const;
2314
 
@@ -2325,36 +2406,32 @@ namespace std {
2325
  template<class... Args> iterator emplace(const_iterator position, Args&&... args);
2326
  iterator insert(const_iterator position, const T& x);
2327
  iterator insert(const_iterator position, T&& x);
2328
  iterator insert(const_iterator position, size_type n, const T& x);
2329
  template<class InputIterator>
2330
- iterator insert(const_iterator position, InputIterator first,
2331
- InputIterator last);
2332
  iterator insert(const_iterator position, initializer_list<T> il);
2333
 
2334
  iterator erase(const_iterator position);
2335
  iterator erase(const_iterator position, const_iterator last);
2336
- void swap(list&)
2337
- noexcept(allocator_traits<Allocator>::is_always_equal::value);
2338
  void clear() noexcept;
2339
 
2340
  // [list.ops], list operations
2341
  void splice(const_iterator position, list& x);
2342
  void splice(const_iterator position, list&& x);
2343
  void splice(const_iterator position, list& x, const_iterator i);
2344
  void splice(const_iterator position, list&& x, const_iterator i);
2345
- void splice(const_iterator position, list& x,
2346
- const_iterator first, const_iterator last);
2347
- void splice(const_iterator position, list&& x,
2348
- const_iterator first, const_iterator last);
2349
 
2350
- void remove(const T& value);
2351
- template <class Predicate> void remove_if(Predicate pred);
2352
 
2353
- void unique();
2354
  template<class BinaryPredicate>
2355
- void unique(BinaryPredicate binary_pred);
2356
 
2357
  void merge(list& x);
2358
  void merge(list&& x);
2359
  template<class Compare> void merge(list& x, Compare comp);
2360
  template<class Compare> void merge(list&& x, Compare comp);
@@ -2363,41 +2440,27 @@ namespace std {
2363
  template<class Compare> void sort(Compare comp);
2364
 
2365
  void reverse() noexcept;
2366
  };
2367
 
2368
- template<class InputIterator,
2369
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
2370
  list(InputIterator, InputIterator, Allocator = Allocator())
2371
- -> list<typename iterator_traits<InputIterator>::value_type, Allocator>;
2372
 
2373
- template <class T, class Allocator>
2374
- bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
2375
- template <class T, class Allocator>
2376
- bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
2377
- template <class T, class Allocator>
2378
- bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
2379
- template <class T, class Allocator>
2380
- bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
2381
- template <class T, class Allocator>
2382
- bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
2383
- template <class T, class Allocator>
2384
- bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);
2385
-
2386
- // [list.special], specialized algorithms
2387
  template<class T, class Allocator>
2388
  void swap(list<T, Allocator>& x, list<T, Allocator>& y)
2389
  noexcept(noexcept(x.swap(y)));
2390
  }
2391
  ```
2392
 
2393
  An incomplete type `T` may be used when instantiating `list` if the
2394
- allocator satisfies the allocator completeness requirements (
2395
- [[allocator.requirements.completeness]]). `T` shall be complete before
2396
  any member of the resulting specialization of `list` is referenced.
2397
 
2398
- #### `list` constructors, copy, and assignment <a id="list.cons">[[list.cons]]</a>
2399
 
2400
  ``` cpp
2401
  explicit list(const Allocator&);
2402
  ```
2403
 
@@ -2407,26 +2470,26 @@ explicit list(const Allocator&);
2407
 
2408
  ``` cpp
2409
  explicit list(size_type n, const Allocator& = Allocator());
2410
  ```
2411
 
 
 
2412
  *Effects:* Constructs a `list` with `n` default-inserted elements using
2413
  the specified allocator.
2414
 
2415
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
2416
-
2417
  *Complexity:* Linear in `n`.
2418
 
2419
  ``` cpp
2420
  list(size_type n, const T& value, const Allocator& = Allocator());
2421
  ```
2422
 
 
 
2423
  *Effects:* Constructs a `list` with `n` copies of `value`, using the
2424
  specified allocator.
2425
 
2426
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
2427
-
2428
  *Complexity:* Linear in `n`.
2429
 
2430
  ``` cpp
2431
  template<class InputIterator>
2432
  list(InputIterator first, InputIterator last, const Allocator& = Allocator());
@@ -2434,31 +2497,33 @@ template <class InputIterator>
2434
 
2435
  *Effects:* Constructs a `list` equal to the range \[`first`, `last`).
2436
 
2437
  *Complexity:* Linear in `distance(first, last)`.
2438
 
2439
- #### `list` capacity <a id="list.capacity">[[list.capacity]]</a>
2440
 
2441
  ``` cpp
2442
  void resize(size_type sz);
2443
  ```
2444
 
 
 
2445
  *Effects:* If `size() < sz`, appends `sz - size()` default-inserted
2446
  elements to the sequence. If `sz <= size()`, equivalent to:
2447
 
2448
  ``` cpp
2449
  list<T>::iterator it = begin();
2450
  advance(it, sz);
2451
  erase(it, end());
2452
  ```
2453
 
2454
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
2455
-
2456
  ``` cpp
2457
  void resize(size_type sz, const T& c);
2458
  ```
2459
 
 
 
2460
  *Effects:* As if by:
2461
 
2462
  ``` cpp
2463
  if (sz > size())
2464
  insert(end(), sz-size(), c);
@@ -2469,13 +2534,11 @@ else if (sz < size()) {
2469
  }
2470
  else
2471
  ; // do nothing
2472
  ```
2473
 
2474
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
2475
-
2476
- #### `list` modifiers <a id="list.modifiers">[[list.modifiers]]</a>
2477
 
2478
  ``` cpp
2479
  iterator insert(const_iterator position, const T& x);
2480
  iterator insert(const_iterator position, T&& x);
2481
  iterator insert(const_iterator position, size_type n, const T& x);
@@ -2519,14 +2582,18 @@ elements.
2519
  *Complexity:* Erasing a single element is a constant time operation with
2520
  a single call to the destructor of `T`. Erasing a range in a list is
2521
  linear time in the size of the range and the number of calls to the
2522
  destructor of type `T` is exactly equal to the size of the range.
2523
 
2524
- #### `list` operations <a id="list.ops">[[list.ops]]</a>
2525
 
2526
  Since lists allow fast insertion and erasing from the middle of a list,
2527
- certain operations are provided specifically for them.[^3]
 
 
 
 
2528
 
2529
  `list` provides three splice operations that destructively move elements
2530
  from one list to another. The behavior of splice operations is undefined
2531
  if `get_allocator() !=
2532
  x.get_allocator()`.
@@ -2534,11 +2601,11 @@ x.get_allocator()`.
2534
  ``` cpp
2535
  void splice(const_iterator position, list& x);
2536
  void splice(const_iterator position, list&& x);
2537
  ```
2538
 
2539
- *Requires:* `&x != this`.
2540
 
2541
  *Effects:* Inserts the contents of `x` before `position` and `x` becomes
2542
  empty. Pointers and references to the moved elements of `x` now refer to
2543
  those same elements but as members of `*this`. Iterators referring to
2544
  the moved elements will continue to refer to their elements, but they
@@ -2551,11 +2618,11 @@ now behave as iterators into `*this`, not into `x`.
2551
  ``` cpp
2552
  void splice(const_iterator position, list& x, const_iterator i);
2553
  void splice(const_iterator position, list&& x, const_iterator i);
2554
  ```
2555
 
2556
- *Requires:* `i` is a valid dereferenceable iterator of `x`.
2557
 
2558
  *Effects:* Inserts an element pointed to by `i` from list `x` before
2559
  `position` and removes the element from `x`. The result is unchanged if
2560
  `position == i` or `position == ++i`. Pointers and references to `*i`
2561
  continue to refer to this same element but as a member of `*this`.
@@ -2571,55 +2638,59 @@ void splice(const_iterator position, list& x, const_iterator first,
2571
  const_iterator last);
2572
  void splice(const_iterator position, list&& x, const_iterator first,
2573
  const_iterator last);
2574
  ```
2575
 
2576
- *Requires:* `[first, last)` is a valid range in `x`. The program has
2577
- undefined behavior if `position` is an iterator in the range \[`first`,
2578
- `last`).
2579
 
2580
  *Effects:* Inserts elements in the range \[`first`, `last`) before
2581
  `position` and removes the elements from `x`. Pointers and references to
2582
  the moved elements of `x` now refer to those same elements but as
2583
  members of `*this`. Iterators referring to the moved elements will
2584
  continue to refer to their elements, but they now behave as iterators
2585
  into `*this`, not into `x`.
2586
 
2587
  *Throws:* Nothing.
2588
 
2589
- *Complexity:* Constant time if `&x == this`; otherwise, linear time.
 
2590
 
2591
  ``` cpp
2592
- void remove(const T& value);
2593
- template <class Predicate> void remove_if(Predicate pred);
2594
  ```
2595
 
2596
- *Effects:* Erases all the elements in the list referred by a list
2597
- iterator `i` for which the following conditions hold:
2598
- `*i == value, pred(*i) != false`. Invalidates only the iterators and
2599
- references to the erased elements.
 
 
2600
 
2601
  *Throws:* Nothing unless an exception is thrown by `*i == value` or
2602
  `pred(*i) != false`.
2603
 
2604
- *Remarks:* Stable ([[algorithm.stable]]).
2605
 
2606
  *Complexity:* Exactly `size()` applications of the corresponding
2607
  predicate.
2608
 
2609
  ``` cpp
2610
- void unique();
2611
- template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
2612
  ```
2613
 
2614
  *Effects:* Erases all but the first element from every consecutive group
2615
  of equal elements referred to by the iterator `i` in the range
2616
  \[`first + 1`, `last`) for which `*i == *(i-1)` (for the version of
2617
  `unique` with no arguments) or `pred(*i, *(i - 1))` (for the version of
2618
  `unique` with a predicate argument) holds. Invalidates only the
2619
  iterators and references to the erased elements.
2620
 
 
 
2621
  *Throws:* Nothing unless an exception is thrown by `*i == *(i-1)` or
2622
  `pred(*i, *(i - 1))`
2623
 
2624
  *Complexity:* If the range `[first, last)` is not empty, exactly
2625
  `(last - first) - 1` applications of the corresponding predicate,
@@ -2630,33 +2701,34 @@ void merge(list& x);
2630
  void merge(list&& x);
2631
  template<class Compare> void merge(list& x, Compare comp);
2632
  template<class Compare> void merge(list&& x, Compare comp);
2633
  ```
2634
 
2635
- *Requires:* `comp` shall define a strict weak
2636
- ordering ([[alg.sorting]]), and both the list and the argument list
2637
- shall be sorted according to this ordering.
 
2638
 
2639
- *Effects:* If `(&x == this)` does nothing; otherwise, merges the two
2640
- sorted ranges `[begin(), end())` and `[x.begin(), x.end())`. The result
2641
- is a range in which the elements will be sorted in non-decreasing order
2642
- according to the ordering defined by `comp`; that is, for every iterator
2643
- `i`, in the range other than the first, the condition
2644
  `comp(*i, *(i - 1))` will be `false`. Pointers and references to the
2645
  moved elements of `x` now refer to those same elements but as members of
2646
  `*this`. Iterators referring to the moved elements will continue to
2647
  refer to their elements, but they now behave as iterators into `*this`,
2648
  not into `x`.
2649
 
2650
- *Remarks:* Stable ([[algorithm.stable]]). If `(&x != this)` the range
2651
- `[x.begin(), x.end())` is empty after the merge. No elements are copied
2652
- by this operation. The behavior is undefined if
2653
- `get_allocator() != x.get_allocator()`.
2654
 
2655
  *Complexity:* At most `size() + x.size() - 1` applications of `comp` if
2656
- `(&x != this)`; otherwise, no applications of `comp` are performed. If
2657
- an exception is thrown other than by a comparison there are no effects.
 
2658
 
2659
  ``` cpp
2660
  void reverse() noexcept;
2661
  ```
2662
 
@@ -2668,59 +2740,68 @@ affect the validity of iterators and references.
2668
  ``` cpp
2669
  void sort();
2670
  template<class Compare> void sort(Compare comp);
2671
  ```
2672
 
2673
- *Requires:* `operator<` (for the first version) or `comp` (for the
2674
- second version) shall define a strict weak ordering ([[alg.sorting]]).
2675
-
2676
  *Effects:* Sorts the list according to the `operator<` or a `Compare`
2677
  function object. If an exception is thrown, the order of the elements in
2678
  `*this` is unspecified. Does not affect the validity of iterators and
2679
  references.
2680
 
2681
- *Remarks:* Stable ([[algorithm.stable]]).
2682
 
2683
  *Complexity:* Approximately N log N comparisons, where `N == size()`.
2684
 
2685
- #### `list` specialized algorithms <a id="list.special">[[list.special]]</a>
2686
 
2687
  ``` cpp
2688
- template <class T, class Allocator>
2689
- void swap(list<T, Allocator>& x, list<T, Allocator>& y)
2690
- noexcept(noexcept(x.swap(y)));
2691
  ```
2692
 
2693
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
2694
 
2695
  ### Class template `vector` <a id="vector">[[vector]]</a>
2696
 
2697
- #### Class template `vector` overview <a id="vector.overview">[[vector.overview]]</a>
2698
 
2699
  A `vector` is a sequence container that supports (amortized) constant
2700
  time insert and erase operations at the end; insert and erase in the
2701
  middle take linear time. Storage management is handled automatically,
2702
  though hints can be given to improve efficiency.
2703
 
2704
- A `vector` satisfies all of the requirements of a container and of a
2705
  reversible container (given in two tables in 
2706
  [[container.requirements]]), of a sequence container, including most of
2707
- the optional sequence container requirements ([[sequence.reqmts]]), of
2708
- an allocator-aware container (Table  [[tab:containers.allocatoraware]]),
2709
- and, for an element type other than `bool`, of a contiguous container (
2710
- [[container.requirements.general]]). The exceptions are the
2711
- `push_front`, `pop_front`, and `emplace_front` member functions, which
2712
- are not provided. Descriptions are provided here only for operations on
2713
- `vector` that are not described in one of these tables or for operations
2714
- where there is additional semantic information.
 
 
 
2715
 
2716
  ``` cpp
2717
  namespace std {
2718
  template<class T, class Allocator = allocator<T>>
2719
  class vector {
2720
  public:
2721
- // types:
2722
  using value_type = T;
2723
  using allocator_type = Allocator;
2724
  using pointer = typename allocator_traits<Allocator>::pointer;
2725
  using const_pointer = typename allocator_traits<Allocator>::const_pointer;
2726
  using reference = value_type&;
@@ -2731,159 +2812,146 @@ namespace std {
2731
  using const_iterator = implementation-defined // type of vector::const_iterator; // see [container.requirements]
2732
  using reverse_iterator = std::reverse_iterator<iterator>;
2733
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2734
 
2735
  // [vector.cons], construct/copy/destroy
2736
- vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
2737
- explicit vector(const Allocator&) noexcept;
2738
- explicit vector(size_type n, const Allocator& = Allocator());
2739
- vector(size_type n, const T& value, const Allocator& = Allocator());
2740
  template<class InputIterator>
2741
- vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
2742
- vector(const vector& x);
2743
- vector(vector&&) noexcept;
2744
- vector(const vector&, const Allocator&);
2745
- vector(vector&&, const Allocator&);
2746
- vector(initializer_list<T>, const Allocator& = Allocator());
2747
- ~vector();
2748
- vector& operator=(const vector& x);
2749
- vector& operator=(vector&& x)
2750
  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
2751
  allocator_traits<Allocator>::is_always_equal::value);
2752
- vector& operator=(initializer_list<T>);
2753
  template<class InputIterator>
2754
- void assign(InputIterator first, InputIterator last);
2755
- void assign(size_type n, const T& u);
2756
- void assign(initializer_list<T>);
2757
- allocator_type get_allocator() const noexcept;
2758
 
2759
- // iterators:
2760
- iterator begin() noexcept;
2761
- const_iterator begin() const noexcept;
2762
- iterator end() noexcept;
2763
- const_iterator end() const noexcept;
2764
- reverse_iterator rbegin() noexcept;
2765
- const_reverse_iterator rbegin() const noexcept;
2766
- reverse_iterator rend() noexcept;
2767
- const_reverse_iterator rend() const noexcept;
2768
 
2769
- const_iterator cbegin() const noexcept;
2770
- const_iterator cend() const noexcept;
2771
- const_reverse_iterator crbegin() const noexcept;
2772
- const_reverse_iterator crend() const noexcept;
2773
 
2774
  // [vector.capacity], capacity
2775
- bool empty() const noexcept;
2776
- size_type size() const noexcept;
2777
- size_type max_size() const noexcept;
2778
- size_type capacity() const noexcept;
2779
- void resize(size_type sz);
2780
- void resize(size_type sz, const T& c);
2781
- void reserve(size_type n);
2782
- void shrink_to_fit();
2783
 
2784
- // element access:
2785
- reference operator[](size_type n);
2786
- const_reference operator[](size_type n) const;
2787
- const_reference at(size_type n) const;
2788
- reference at(size_type n);
2789
- reference front();
2790
- const_reference front() const;
2791
- reference back();
2792
- const_reference back() const;
2793
 
2794
  // [vector.data], data access
2795
- T* data() noexcept;
2796
- const T* data() const noexcept;
2797
 
2798
  // [vector.modifiers], modifiers
2799
- template <class... Args> reference emplace_back(Args&&... args);
2800
- void push_back(const T& x);
2801
- void push_back(T&& x);
2802
- void pop_back();
2803
 
2804
- template <class... Args> iterator emplace(const_iterator position, Args&&... args);
2805
- iterator insert(const_iterator position, const T& x);
2806
- iterator insert(const_iterator position, T&& x);
2807
- iterator insert(const_iterator position, size_type n, const T& x);
2808
  template<class InputIterator>
2809
- iterator insert(const_iterator position, InputIterator first, InputIterator last);
2810
- iterator insert(const_iterator position, initializer_list<T> il);
2811
- iterator erase(const_iterator position);
2812
- iterator erase(const_iterator first, const_iterator last);
2813
- void swap(vector&)
 
2814
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
2815
  allocator_traits<Allocator>::is_always_equal::value);
2816
- void clear() noexcept;
2817
  };
2818
 
2819
- template<class InputIterator,
2820
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
2821
  vector(InputIterator, InputIterator, Allocator = Allocator())
2822
- -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
2823
 
 
2824
  template<class T, class Allocator>
2825
- bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2826
- template <class T, class Allocator>
2827
- bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2828
- template <class T, class Allocator>
2829
- bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2830
- template <class T, class Allocator>
2831
- bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2832
- template <class T, class Allocator>
2833
- bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2834
- template <class T, class Allocator>
2835
- bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
2836
-
2837
- // [vector.special], specialized algorithms
2838
- template <class T, class Allocator>
2839
- void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
2840
  noexcept(noexcept(x.swap(y)));
2841
  }
2842
  ```
2843
 
2844
  An incomplete type `T` may be used when instantiating `vector` if the
2845
- allocator satisfies the allocator completeness requirements (
2846
- [[allocator.requirements.completeness]]). `T` shall be complete before
2847
  any member of the resulting specialization of `vector` is referenced.
2848
 
2849
- #### `vector` constructors, copy, and assignment <a id="vector.cons">[[vector.cons]]</a>
2850
 
2851
  ``` cpp
2852
- explicit vector(const Allocator&);
2853
  ```
2854
 
2855
  *Effects:* Constructs an empty `vector`, using the specified allocator.
2856
 
2857
  *Complexity:* Constant.
2858
 
2859
  ``` cpp
2860
- explicit vector(size_type n, const Allocator& = Allocator());
2861
  ```
2862
 
 
 
2863
  *Effects:* Constructs a `vector` with `n` default-inserted elements
2864
  using the specified allocator.
2865
 
2866
- *Requires:* `T` shall be `DefaultInsertable` into `*this`.
2867
-
2868
  *Complexity:* Linear in `n`.
2869
 
2870
  ``` cpp
2871
- vector(size_type n, const T& value,
2872
  const Allocator& = Allocator());
2873
  ```
2874
 
 
 
2875
  *Effects:* Constructs a `vector` with `n` copies of `value`, using the
2876
  specified allocator.
2877
 
2878
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
2879
-
2880
  *Complexity:* Linear in `n`.
2881
 
2882
  ``` cpp
2883
  template<class InputIterator>
2884
- vector(InputIterator first, InputIterator last,
2885
  const Allocator& = Allocator());
2886
  ```
2887
 
2888
  *Effects:* Constructs a `vector` equal to the range \[`first`, `last`),
2889
  using the specified allocator.
@@ -2892,152 +2960,166 @@ using the specified allocator.
2892
  is the distance between `first` and `last`) and no reallocations if
2893
  iterators `first` and `last` are of forward, bidirectional, or random
2894
  access categories. It makes order `N` calls to the copy constructor of
2895
  `T` and order log N reallocations if they are just input iterators.
2896
 
2897
- #### `vector` capacity <a id="vector.capacity">[[vector.capacity]]</a>
2898
 
2899
  ``` cpp
2900
- size_type capacity() const noexcept;
2901
  ```
2902
 
2903
  *Returns:* The total number of elements that the vector can hold without
2904
  requiring reallocation.
2905
 
 
 
2906
  ``` cpp
2907
- void reserve(size_type n);
2908
  ```
2909
 
2910
- *Requires:* `T` shall be `MoveInsertable` into `*this`.
2911
 
2912
  *Effects:* A directive that informs a `vector` of a planned change in
2913
  size, so that it can manage the storage allocation accordingly. After
2914
  `reserve()`, `capacity()` is greater or equal to the argument of
2915
  `reserve` if reallocation happens; and equal to the previous value of
2916
  `capacity()` otherwise. Reallocation happens at this point if and only
2917
  if the current capacity is less than the argument of `reserve()`. If an
2918
  exception is thrown other than by the move constructor of a
2919
- non-`CopyInsertable` type, there are no effects.
2920
 
2921
  *Complexity:* It does not change the size of the sequence and takes at
2922
  most linear time in the size of the sequence.
2923
 
2924
  *Throws:* `length_error` if `n > max_size()`.[^4]
2925
 
2926
  *Remarks:* Reallocation invalidates all the references, pointers, and
2927
- iterators referring to the elements in the sequence. No reallocation
2928
- shall take place during insertions that happen after a call to
2929
- `reserve()` until the time when an insertion would make the size of the
2930
- vector greater than the value of `capacity()`.
 
 
 
 
 
2931
 
2932
  ``` cpp
2933
- void shrink_to_fit();
2934
  ```
2935
 
2936
- *Requires:* `T` shall be `MoveInsertable` into `*this`.
2937
 
2938
  *Effects:* `shrink_to_fit` is a non-binding request to reduce
2939
  `capacity()` to `size()`.
2940
 
2941
- [*Note 1*: The request is non-binding to allow latitude for
2942
  implementation-specific optimizations. — *end note*]
2943
 
2944
  It does not increase `capacity()`, but may reduce `capacity()` by
2945
  causing reallocation. If an exception is thrown other than by the move
2946
- constructor of a non-`CopyInsertable` `T` there are no effects.
2947
 
2948
- *Complexity:* Linear in the size of the sequence.
 
2949
 
2950
  *Remarks:* Reallocation invalidates all the references, pointers, and
2951
  iterators referring to the elements in the sequence as well as the
2952
- past-the-end iterator. If no reallocation happens, they remain valid.
 
 
 
2953
 
2954
  ``` cpp
2955
- void swap(vector& x)
2956
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
2957
  allocator_traits<Allocator>::is_always_equal::value);
2958
  ```
2959
 
2960
  *Effects:* Exchanges the contents and `capacity()` of `*this` with that
2961
  of `x`.
2962
 
2963
  *Complexity:* Constant time.
2964
 
2965
  ``` cpp
2966
- void resize(size_type sz);
2967
  ```
2968
 
 
 
 
2969
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
2970
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
2971
  to the sequence.
2972
 
2973
- *Requires:* `T` shall be `MoveInsertable` and `DefaultInsertable` into
2974
- `*this`.
2975
-
2976
  *Remarks:* If an exception is thrown other than by the move constructor
2977
- of a non-`CopyInsertable` `T` there are no effects.
2978
 
2979
  ``` cpp
2980
- void resize(size_type sz, const T& c);
2981
  ```
2982
 
 
 
2983
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
2984
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
2985
  sequence.
2986
 
2987
- *Requires:* `T` shall be `CopyInsertable` into `*this`.
2988
-
2989
  *Remarks:* If an exception is thrown there are no effects.
2990
 
2991
- #### `vector` data <a id="vector.data">[[vector.data]]</a>
2992
 
2993
  ``` cpp
2994
- T* data() noexcept;
2995
- const T* data() const noexcept;
2996
  ```
2997
 
2998
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
2999
  range. For a non-empty vector, `data()` `==` `addressof(front())`.
3000
 
3001
  *Complexity:* Constant time.
3002
 
3003
- #### `vector` modifiers <a id="vector.modifiers">[[vector.modifiers]]</a>
3004
 
3005
  ``` cpp
3006
- iterator insert(const_iterator position, const T& x);
3007
- iterator insert(const_iterator position, T&& x);
3008
- iterator insert(const_iterator position, size_type n, const T& x);
3009
  template<class InputIterator>
3010
- iterator insert(const_iterator position, InputIterator first, InputIterator last);
3011
- iterator insert(const_iterator position, initializer_list<T>);
3012
 
3013
- template <class... Args> reference emplace_back(Args&&... args);
3014
- template <class... Args> iterator emplace(const_iterator position, Args&&... args);
3015
- void push_back(const T& x);
3016
- void push_back(T&& x);
3017
  ```
3018
 
3019
  *Remarks:* Causes reallocation if the new size is greater than the old
3020
  capacity. Reallocation invalidates all the references, pointers, and
3021
- iterators referring to the elements in the sequence. If no reallocation
3022
- happens, all the iterators and references before the insertion point
3023
- remain valid. If an exception is thrown other than by the copy
3024
- constructor, move constructor, assignment operator, or move assignment
3025
- operator of `T` or by any `InputIterator` operation there are no
3026
- effects. If an exception is thrown while inserting a single element at
3027
- the end and `T` is `CopyInsertable` or
 
 
3028
  `is_nothrow_move_constructible_v<T>` is `true`, there are no effects.
3029
  Otherwise, if an exception is thrown by the move constructor of a
3030
- non-`CopyInsertable` `T`, the effects are unspecified.
3031
 
3032
- *Complexity:* The complexity is linear in the number of elements
 
3033
  inserted plus the distance to the end of the vector.
3034
 
3035
  ``` cpp
3036
- iterator erase(const_iterator position);
3037
- iterator erase(const_iterator first, const_iterator last);
3038
- void pop_back();
3039
  ```
3040
 
3041
  *Effects:* Invalidates iterators and references at or after the point of
3042
  the erase.
3043
 
@@ -3047,19 +3129,41 @@ is called the number of times equal to the number of elements in the
3047
  vector after the erased elements.
3048
 
3049
  *Throws:* Nothing unless an exception is thrown by the assignment
3050
  operator or move assignment operator of `T`.
3051
 
3052
- #### `vector` specialized algorithms <a id="vector.special">[[vector.special]]</a>
3053
 
3054
  ``` cpp
3055
- template <class T, class Allocator>
3056
- void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
3057
- noexcept(noexcept(x.swap(y)));
3058
  ```
3059
 
3060
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3061
 
3062
  ### Class `vector<bool>` <a id="vector.bool">[[vector.bool]]</a>
3063
 
3064
  To optimize space allocation, a specialization of vector for `bool`
3065
  elements is provided:
@@ -3067,11 +3171,11 @@ elements is provided:
3067
  ``` cpp
3068
  namespace std {
3069
  template<class Allocator>
3070
  class vector<bool, Allocator> {
3071
  public:
3072
- // types:
3073
  using value_type = bool;
3074
  using allocator_type = Allocator;
3075
  using pointer = implementation-defined;
3076
  using const_pointer = implementation-defined;
3077
  using const_reference = bool;
@@ -3080,107 +3184,106 @@ namespace std {
3080
  using iterator = implementation-defined // type of vector<bool>::iterator; // see [container.requirements]
3081
  using const_iterator = implementation-defined // type of vector<bool>::const_iterator; // see [container.requirements]
3082
  using reverse_iterator = std::reverse_iterator<iterator>;
3083
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3084
 
3085
- // bit reference:
3086
  class reference {
3087
  friend class vector;
3088
- reference() noexcept;
3089
  public:
3090
- ~reference();
3091
- operator bool() const noexcept;
3092
- reference& operator=(const bool x) noexcept;
3093
- reference& operator=(const reference& x) noexcept;
3094
- void flip() noexcept; // flips the bit
 
3095
  };
3096
 
3097
- // construct/copy/destroy:
3098
- vector() : vector(Allocator()) { }
3099
- explicit vector(const Allocator&);
3100
- explicit vector(size_type n, const Allocator& = Allocator());
3101
- vector(size_type n, const bool& value,
3102
- const Allocator& = Allocator());
3103
  template<class InputIterator>
3104
- vector(InputIterator first, InputIterator last,
3105
- const Allocator& = Allocator());
3106
- vector(const vector<bool, Allocator>& x);
3107
- vector(vector<bool, Allocator>&& x);
3108
- vector(const vector&, const Allocator&);
3109
- vector(vector&&, const Allocator&);
3110
- vector(initializer_list<bool>, const Allocator& = Allocator()));
3111
- ~vector();
3112
- vector<bool, Allocator>& operator=(const vector<bool, Allocator>& x);
3113
- vector<bool, Allocator>& operator=(vector<bool, Allocator>&& x);
3114
- vector& operator=(initializer_list<bool>);
3115
  template<class InputIterator>
3116
- void assign(InputIterator first, InputIterator last);
3117
- void assign(size_type n, const bool& t);
3118
- void assign(initializer_list<bool>);
3119
- allocator_type get_allocator() const noexcept;
3120
 
3121
- // iterators:
3122
- iterator begin() noexcept;
3123
- const_iterator begin() const noexcept;
3124
- iterator end() noexcept;
3125
- const_iterator end() const noexcept;
3126
- reverse_iterator rbegin() noexcept;
3127
- const_reverse_iterator rbegin() const noexcept;
3128
- reverse_iterator rend() noexcept;
3129
- const_reverse_iterator rend() const noexcept;
3130
 
3131
- const_iterator cbegin() const noexcept;
3132
- const_iterator cend() const noexcept;
3133
- const_reverse_iterator crbegin() const noexcept;
3134
- const_reverse_iterator crend() const noexcept;
3135
 
3136
- // capacity:
3137
- bool empty() const noexcept;
3138
- size_type size() const noexcept;
3139
- size_type max_size() const noexcept;
3140
- size_type capacity() const noexcept;
3141
- void resize(size_type sz, bool c = false);
3142
- void reserve(size_type n);
3143
- void shrink_to_fit();
3144
 
3145
- // element access:
3146
- reference operator[](size_type n);
3147
- const_reference operator[](size_type n) const;
3148
- const_reference at(size_type n) const;
3149
- reference at(size_type n);
3150
- reference front();
3151
- const_reference front() const;
3152
- reference back();
3153
- const_reference back() const;
3154
 
3155
- // modifiers:
3156
- template <class... Args> reference emplace_back(Args&&... args);
3157
- void push_back(const bool& x);
3158
- void pop_back();
3159
- template <class... Args> iterator emplace(const_iterator position, Args&&... args);
3160
- iterator insert(const_iterator position, const bool& x);
3161
- iterator insert(const_iterator position, size_type n, const bool& x);
3162
  template<class InputIterator>
3163
- iterator insert(const_iterator position,
3164
  InputIterator first, InputIterator last);
3165
- iterator insert(const_iterator position, initializer_list<bool> il);
3166
 
3167
- iterator erase(const_iterator position);
3168
- iterator erase(const_iterator first, const_iterator last);
3169
- void swap(vector<bool, Allocator>&);
3170
- static void swap(reference x, reference y) noexcept;
3171
- void flip() noexcept; // flips all bits
3172
- void clear() noexcept;
3173
  };
3174
  }
3175
  ```
3176
 
3177
  Unless described below, all operations have the same requirements and
3178
  semantics as the primary `vector` template, except that operations
3179
  dealing with the `bool` value type map to bit values in the container
3180
- storage and `allocator_traits::construct` (
3181
- [[allocator.traits.members]]) is not used to construct these values.
3182
 
3183
  There is no requirement that the data be stored as a contiguous
3184
  allocation of `bool` values. A space-optimized representation of bits is
3185
  recommended instead.
3186
 
@@ -3191,17 +3294,17 @@ is a class that simulates the behavior of references of a single bit in
3191
  set, and `false` otherwise. The assignment operator sets the bit when
3192
  the argument is (convertible to) `true` and clears it otherwise. `flip`
3193
  reverses the state of the bit.
3194
 
3195
  ``` cpp
3196
- void flip() noexcept;
3197
  ```
3198
 
3199
  *Effects:* Replaces each element in the container with its complement.
3200
 
3201
  ``` cpp
3202
- static void swap(reference x, reference y) noexcept;
3203
  ```
3204
 
3205
  *Effects:* Exchanges the contents of `x` and `y` as if by:
3206
 
3207
  ``` cpp
@@ -3212,11 +3315,11 @@ y = b;
3212
 
3213
  ``` cpp
3214
  template<class Allocator> struct hash<vector<bool, Allocator>>;
3215
  ```
3216
 
3217
- The specialization is enabled ([[unord.hash]]).
3218
 
3219
  ## Associative containers <a id="associative">[[associative]]</a>
3220
 
3221
  ### In general <a id="associative.general">[[associative.general]]</a>
3222
 
@@ -3226,81 +3329,75 @@ header `<set>` defines the class templates `set` and `multiset`.
3226
  The following exposition-only alias templates may appear in deduction
3227
  guides for associative containers:
3228
 
3229
  ``` cpp
3230
  template<class InputIterator>
3231
- using iter_key_t = remove_const_t<
 
 
 
3232
  typename iterator_traits<InputIterator>::value_type::first_type>; // exposition only
3233
  template<class InputIterator>
3234
- using iter_val_t
3235
- = typename iterator_traits<InputIterator>::value_type::second_type; // exposition only
3236
  template<class InputIterator>
3237
- using iter_to_alloc_t
3238
- = pair<add_const_t<typename iterator_traits<InputIterator>::value_type::first_type>,
3239
  typename iterator_traits<InputIterator>::value_type::second_type>; // exposition only
3240
  ```
3241
 
3242
  ### Header `<map>` synopsis <a id="associative.map.syn">[[associative.map.syn]]</a>
3243
 
3244
  ``` cpp
3245
- #include <initializer_list>
 
3246
 
3247
  namespace std {
3248
  // [map], class template map
3249
  template<class Key, class T, class Compare = less<Key>,
3250
  class Allocator = allocator<pair<const Key, T>>>
3251
  class map;
 
3252
  template<class Key, class T, class Compare, class Allocator>
3253
  bool operator==(const map<Key, T, Compare, Allocator>& x,
3254
  const map<Key, T, Compare, Allocator>& y);
3255
  template<class Key, class T, class Compare, class Allocator>
3256
- bool operator< (const map<Key, T, Compare, Allocator>& x,
3257
- const map<Key, T, Compare, Allocator>& y);
3258
- template <class Key, class T, class Compare, class Allocator>
3259
- bool operator!=(const map<Key, T, Compare, Allocator>& x,
3260
- const map<Key, T, Compare, Allocator>& y);
3261
- template <class Key, class T, class Compare, class Allocator>
3262
- bool operator> (const map<Key, T, Compare, Allocator>& x,
3263
- const map<Key, T, Compare, Allocator>& y);
3264
- template <class Key, class T, class Compare, class Allocator>
3265
- bool operator>=(const map<Key, T, Compare, Allocator>& x,
3266
- const map<Key, T, Compare, Allocator>& y);
3267
- template <class Key, class T, class Compare, class Allocator>
3268
- bool operator<=(const map<Key, T, Compare, Allocator>& x,
3269
  const map<Key, T, Compare, Allocator>& y);
 
3270
  template<class Key, class T, class Compare, class Allocator>
3271
  void swap(map<Key, T, Compare, Allocator>& x,
3272
  map<Key, T, Compare, Allocator>& y)
3273
  noexcept(noexcept(x.swap(y)));
3274
 
 
 
 
 
3275
  // [multimap], class template multimap
3276
  template<class Key, class T, class Compare = less<Key>,
3277
  class Allocator = allocator<pair<const Key, T>>>
3278
  class multimap;
 
3279
  template<class Key, class T, class Compare, class Allocator>
3280
  bool operator==(const multimap<Key, T, Compare, Allocator>& x,
3281
  const multimap<Key, T, Compare, Allocator>& y);
3282
  template<class Key, class T, class Compare, class Allocator>
3283
- bool operator< (const multimap<Key, T, Compare, Allocator>& x,
3284
- const multimap<Key, T, Compare, Allocator>& y);
3285
- template <class Key, class T, class Compare, class Allocator>
3286
- bool operator!=(const multimap<Key, T, Compare, Allocator>& x,
3287
- const multimap<Key, T, Compare, Allocator>& y);
3288
- template <class Key, class T, class Compare, class Allocator>
3289
- bool operator> (const multimap<Key, T, Compare, Allocator>& x,
3290
- const multimap<Key, T, Compare, Allocator>& y);
3291
- template <class Key, class T, class Compare, class Allocator>
3292
- bool operator>=(const multimap<Key, T, Compare, Allocator>& x,
3293
- const multimap<Key, T, Compare, Allocator>& y);
3294
- template <class Key, class T, class Compare, class Allocator>
3295
- bool operator<=(const multimap<Key, T, Compare, Allocator>& x,
3296
  const multimap<Key, T, Compare, Allocator>& y);
 
3297
  template<class Key, class T, class Compare, class Allocator>
3298
  void swap(multimap<Key, T, Compare, Allocator>& x,
3299
  multimap<Key, T, Compare, Allocator>& y)
3300
  noexcept(noexcept(x.swap(y)));
3301
 
 
 
 
 
3302
  namespace pmr {
3303
  template<class Key, class T, class Compare = less<Key>>
3304
  using map = std::map<Key, T, Compare,
3305
  polymorphic_allocator<pair<const Key, T>>>;
3306
 
@@ -3312,107 +3409,91 @@ namespace std {
3312
  ```
3313
 
3314
  ### Header `<set>` synopsis <a id="associative.set.syn">[[associative.set.syn]]</a>
3315
 
3316
  ``` cpp
3317
- #include <initializer_list>
 
3318
 
3319
  namespace std {
3320
  // [set], class template set
3321
- template <class Key, class Compare = less<Key>,
3322
- class Allocator = allocator<Key>>
3323
  class set;
 
3324
  template<class Key, class Compare, class Allocator>
3325
  bool operator==(const set<Key, Compare, Allocator>& x,
3326
  const set<Key, Compare, Allocator>& y);
3327
  template<class Key, class Compare, class Allocator>
3328
- bool operator< (const set<Key, Compare, Allocator>& x,
3329
- const set<Key, Compare, Allocator>& y);
3330
- template <class Key, class Compare, class Allocator>
3331
- bool operator!=(const set<Key, Compare, Allocator>& x,
3332
- const set<Key, Compare, Allocator>& y);
3333
- template <class Key, class Compare, class Allocator>
3334
- bool operator> (const set<Key, Compare, Allocator>& x,
3335
- const set<Key, Compare, Allocator>& y);
3336
- template <class Key, class Compare, class Allocator>
3337
- bool operator>=(const set<Key, Compare, Allocator>& x,
3338
- const set<Key, Compare, Allocator>& y);
3339
- template <class Key, class Compare, class Allocator>
3340
- bool operator<=(const set<Key, Compare, Allocator>& x,
3341
- const set<Key, Compare, Allocator>& y);
3342
  template<class Key, class Compare, class Allocator>
3343
  void swap(set<Key, Compare, Allocator>& x,
3344
  set<Key, Compare, Allocator>& y)
3345
  noexcept(noexcept(x.swap(y)));
3346
 
 
 
 
 
3347
  // [multiset], class template multiset
3348
- template <class Key, class Compare = less<Key>,
3349
- class Allocator = allocator<Key>>
3350
  class multiset;
 
3351
  template<class Key, class Compare, class Allocator>
3352
  bool operator==(const multiset<Key, Compare, Allocator>& x,
3353
  const multiset<Key, Compare, Allocator>& y);
3354
  template<class Key, class Compare, class Allocator>
3355
- bool operator< (const multiset<Key, Compare, Allocator>& x,
3356
- const multiset<Key, Compare, Allocator>& y);
3357
- template <class Key, class Compare, class Allocator>
3358
- bool operator!=(const multiset<Key, Compare, Allocator>& x,
3359
- const multiset<Key, Compare, Allocator>& y);
3360
- template <class Key, class Compare, class Allocator>
3361
- bool operator> (const multiset<Key, Compare, Allocator>& x,
3362
- const multiset<Key, Compare, Allocator>& y);
3363
- template <class Key, class Compare, class Allocator>
3364
- bool operator>=(const multiset<Key, Compare, Allocator>& x,
3365
- const multiset<Key, Compare, Allocator>& y);
3366
- template <class Key, class Compare, class Allocator>
3367
- bool operator<=(const multiset<Key, Compare, Allocator>& x,
3368
- const multiset<Key, Compare, Allocator>& y);
3369
  template<class Key, class Compare, class Allocator>
3370
  void swap(multiset<Key, Compare, Allocator>& x,
3371
  multiset<Key, Compare, Allocator>& y)
3372
  noexcept(noexcept(x.swap(y)));
3373
 
 
 
 
 
3374
  namespace pmr {
3375
  template<class Key, class Compare = less<Key>>
3376
- using set = std::set<Key, Compare,
3377
- polymorphic_allocator<Key>>;
3378
 
3379
  template<class Key, class Compare = less<Key>>
3380
- using multiset = std::multiset<Key, Compare,
3381
- polymorphic_allocator<Key>>;
3382
  }
3383
  }
3384
  ```
3385
 
3386
  ### Class template `map` <a id="map">[[map]]</a>
3387
 
3388
- #### Class template `map` overview <a id="map.overview">[[map.overview]]</a>
3389
 
3390
  A `map` is an associative container that supports unique keys (contains
3391
  at most one of each key value) and provides for fast retrieval of values
3392
  of another type `T` based on the keys. The `map` class supports
3393
  bidirectional iterators.
3394
 
3395
- A `map` satisfies all of the requirements of a container, of a
3396
- reversible container ([[container.requirements]]), of an associative
3397
- container ([[associative.reqmts]]), and of an allocator-aware container
3398
- (Table  [[tab:containers.allocatoraware]]). A `map` also provides most
3399
- operations described in  [[associative.reqmts]] for unique keys. This
3400
- means that a `map` supports the `a_uniq` operations in 
3401
- [[associative.reqmts]] but not the `a_eq` operations. For a `map<Key,T>`
3402
- the `key_type` is `Key` and the `value_type` is `pair<const Key,T>`.
3403
- Descriptions are provided here only for operations on `map` that are not
3404
- described in one of those tables or for operations where there is
3405
- additional semantic information.
3406
 
3407
  ``` cpp
3408
  namespace std {
3409
  template<class Key, class T, class Compare = less<Key>,
3410
  class Allocator = allocator<pair<const Key, T>>>
3411
  class map {
3412
  public:
3413
- // types:
3414
  using key_type = Key;
3415
  using mapped_type = T;
3416
  using value_type = pair<const Key, T>;
3417
  using key_compare = Compare;
3418
  using allocator_type = Allocator;
@@ -3425,11 +3506,11 @@ namespace std {
3425
  using iterator = implementation-defined // type of map::iterator; // see [container.requirements]
3426
  using const_iterator = implementation-defined // type of map::const_iterator; // see [container.requirements]
3427
  using reverse_iterator = std::reverse_iterator<iterator>;
3428
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3429
  using node_type = unspecified;
3430
- using insert_return_type = INSERT_RETURN_TYPE<iterator, node_type>;
3431
 
3432
  class value_compare {
3433
  friend class map;
3434
  protected:
3435
  Compare comp;
@@ -3465,11 +3546,11 @@ namespace std {
3465
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
3466
  is_nothrow_move_assignable_v<Compare>);
3467
  map& operator=(initializer_list<value_type>);
3468
  allocator_type get_allocator() const noexcept;
3469
 
3470
- // iterators:
3471
  iterator begin() noexcept;
3472
  const_iterator begin() const noexcept;
3473
  iterator end() noexcept;
3474
  const_iterator end() const noexcept;
3475
 
@@ -3481,20 +3562,20 @@ namespace std {
3481
  const_iterator cbegin() const noexcept;
3482
  const_iterator cend() const noexcept;
3483
  const_reverse_iterator crbegin() const noexcept;
3484
  const_reverse_iterator crend() const noexcept;
3485
 
3486
- // capacity:
3487
- bool empty() const noexcept;
3488
  size_type size() const noexcept;
3489
  size_type max_size() const noexcept;
3490
 
3491
  // [map.access], element access
3492
- T& operator[](const key_type& x);
3493
- T& operator[](key_type&& x);
3494
- T& at(const key_type& x);
3495
- const T& at(const key_type& x) const;
3496
 
3497
  // [map.modifiers], modifiers
3498
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
3499
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
3500
  pair<iterator, bool> insert(const value_type& x);
@@ -3546,23 +3627,26 @@ namespace std {
3546
  template<class C2>
3547
  void merge(multimap<Key, T, C2, Allocator>& source);
3548
  template<class C2>
3549
  void merge(multimap<Key, T, C2, Allocator>&& source);
3550
 
3551
- // observers:
3552
  key_compare key_comp() const;
3553
  value_compare value_comp() const;
3554
 
3555
- // map operations:
3556
  iterator find(const key_type& x);
3557
  const_iterator find(const key_type& x) const;
3558
  template<class K> iterator find(const K& x);
3559
  template<class K> const_iterator find(const K& x) const;
3560
 
3561
  size_type count(const key_type& x) const;
3562
  template<class K> size_type count(const K& x) const;
3563
 
 
 
 
3564
  iterator lower_bound(const key_type& x);
3565
  const_iterator lower_bound(const key_type& x) const;
3566
  template<class K> iterator lower_bound(const K& x);
3567
  template<class K> const_iterator lower_bound(const K& x) const;
3568
 
@@ -3577,56 +3661,37 @@ namespace std {
3577
  pair<iterator, iterator> equal_range(const K& x);
3578
  template<class K>
3579
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
3580
  };
3581
 
3582
- template<class InputIterator, class Compare = less<iter_key_t<InputIterator>>,
3583
- class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
3584
  map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
3585
- -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>;
3586
 
3587
  template<class Key, class T, class Compare = less<Key>,
3588
  class Allocator = allocator<pair<const Key, T>>>
3589
- map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
3590
  -> map<Key, T, Compare, Allocator>;
3591
 
3592
  template<class InputIterator, class Allocator>
3593
  map(InputIterator, InputIterator, Allocator)
3594
- -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
3595
- less<iter_key_t<InputIterator>>, Allocator>;
3596
 
3597
  template<class Key, class T, class Allocator>
3598
- map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;
3599
 
3600
- template <class Key, class T, class Compare, class Allocator>
3601
- bool operator==(const map<Key, T, Compare, Allocator>& x,
3602
- const map<Key, T, Compare, Allocator>& y);
3603
- template <class Key, class T, class Compare, class Allocator>
3604
- bool operator< (const map<Key, T, Compare, Allocator>& x,
3605
- const map<Key, T, Compare, Allocator>& y);
3606
- template <class Key, class T, class Compare, class Allocator>
3607
- bool operator!=(const map<Key, T, Compare, Allocator>& x,
3608
- const map<Key, T, Compare, Allocator>& y);
3609
- template <class Key, class T, class Compare, class Allocator>
3610
- bool operator> (const map<Key, T, Compare, Allocator>& x,
3611
- const map<Key, T, Compare, Allocator>& y);
3612
- template <class Key, class T, class Compare, class Allocator>
3613
- bool operator>=(const map<Key, T, Compare, Allocator>& x,
3614
- const map<Key, T, Compare, Allocator>& y);
3615
- template <class Key, class T, class Compare, class Allocator>
3616
- bool operator<=(const map<Key, T, Compare, Allocator>& x,
3617
- const map<Key, T, Compare, Allocator>& y);
3618
-
3619
- // [map.special], specialized algorithms
3620
  template<class Key, class T, class Compare, class Allocator>
3621
  void swap(map<Key, T, Compare, Allocator>& x,
3622
  map<Key, T, Compare, Allocator>& y)
3623
  noexcept(noexcept(x.swap(y)));
3624
  }
3625
  ```
3626
 
3627
- #### `map` constructors, copy, and assignment <a id="map.cons">[[map.cons]]</a>
3628
 
3629
  ``` cpp
3630
  explicit map(const Compare& comp, const Allocator& = Allocator());
3631
  ```
3632
 
@@ -3646,62 +3711,61 @@ object and allocator, and inserts elements from the range \[`first`,
3646
  `last`).
3647
 
3648
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
3649
  sorted using `comp` and otherwise N log N, where N is `last - first`.
3650
 
3651
- #### `map` element access <a id="map.access">[[map.access]]</a>
3652
 
3653
  ``` cpp
3654
- T& operator[](const key_type& x);
3655
  ```
3656
 
3657
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
3658
 
3659
  ``` cpp
3660
- T& operator[](key_type&& x);
3661
  ```
3662
 
3663
  *Effects:* Equivalent to: `return try_emplace(move(x)).first->second;`
3664
 
3665
  ``` cpp
3666
- T& at(const key_type& x);
3667
- const T& at(const key_type& x) const;
3668
  ```
3669
 
3670
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
3671
  `*this`.
3672
 
3673
  *Throws:* An exception object of type `out_of_range` if no such element
3674
  is present.
3675
 
3676
  *Complexity:* Logarithmic.
3677
 
3678
- #### `map` modifiers <a id="map.modifiers">[[map.modifiers]]</a>
3679
 
3680
  ``` cpp
3681
  template<class P>
3682
  pair<iterator, bool> insert(P&& x);
3683
  template<class P>
3684
  iterator insert(const_iterator position, P&& x);
3685
  ```
3686
 
 
 
3687
  *Effects:* The first form is equivalent to
3688
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
3689
  `return emplace_hint(position, std::forward<P>(x))`.
3690
 
3691
- *Remarks:* These signatures shall not participate in overload resolution
3692
- unless `is_constructible_v<value_type, P&&>` is `true`.
3693
-
3694
  ``` cpp
3695
  template<class... Args>
3696
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
3697
  template<class... Args>
3698
  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
3699
  ```
3700
 
3701
- *Requires:* `value_type` shall be `EmplaceConstructible` into `map` from
3702
- `piecewise_construct`, `forward_as_tuple(k)`,
3703
  `forward_as_tuple(std::forward<Args>(args)...)`.
3704
 
3705
  *Effects:* If the map already contains an element whose key is
3706
  equivalent to `k`, there is no effect. Otherwise inserts an object of
3707
  type `value_type` constructed with `piecewise_construct`,
@@ -3718,12 +3782,12 @@ template <class... Args>
3718
  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
3719
  template<class... Args>
3720
  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
3721
  ```
3722
 
3723
- *Requires:* `value_type` shall be `EmplaceConstructible` into `map` from
3724
- `piecewise_construct`, `forward_as_tuple(std::move(k))`,
3725
  `forward_as_tuple(std::forward<Args>(args)...)`.
3726
 
3727
  *Effects:* If the map already contains an element whose key is
3728
  equivalent to `k`, there is no effect. Otherwise inserts an object of
3729
  type `value_type` constructed with `piecewise_construct`,
@@ -3741,13 +3805,14 @@ template <class M>
3741
  pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
3742
  template<class M>
3743
  iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
3744
  ```
3745
 
3746
- *Requires:* `is_assignable_v<mapped_type&, M&&>` shall be `true`.
3747
- `value_type` shall be `EmplaceConstructible` into `map` from `k`,
3748
- `forward<M>(obj)`.
 
3749
 
3750
  *Effects:* If the map already contains an element `e` whose key is
3751
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
3752
  Otherwise inserts an object of type `value_type` constructed with `k`,
3753
  `std::forward<M>(obj)`.
@@ -3763,13 +3828,14 @@ template <class M>
3763
  pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
3764
  template<class M>
3765
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
3766
  ```
3767
 
3768
- *Requires:* `is_assignable_v<mapped_type&, M&&>` shall be `true`.
3769
- `value_type` shall be `EmplaceConstructible` into `map` from `move(k)`,
3770
- `forward<M>(obj)`.
 
3771
 
3772
  *Effects:* If the map already contains an element `e` whose key is
3773
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
3774
  Otherwise inserts an object of type `value_type` constructed with
3775
  `std::move(k)`, `std::forward<M>(obj)`.
@@ -3778,49 +3844,60 @@ Otherwise inserts an object of type `value_type` constructed with
3778
  pair is `true` if and only if the insertion took place. The returned
3779
  iterator points to the map element whose key is equivalent to `k`.
3780
 
3781
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
3782
 
3783
- #### `map` specialized algorithms <a id="map.special">[[map.special]]</a>
3784
 
3785
  ``` cpp
3786
- template <class Key, class T, class Compare, class Allocator>
3787
- void swap(map<Key, T, Compare, Allocator>& x,
3788
- map<Key, T, Compare, Allocator>& y)
3789
- noexcept(noexcept(x.swap(y)));
3790
  ```
3791
 
3792
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
3793
 
3794
  ### Class template `multimap` <a id="multimap">[[multimap]]</a>
3795
 
3796
- #### Class template `multimap` overview <a id="multimap.overview">[[multimap.overview]]</a>
3797
 
3798
  A `multimap` is an associative container that supports equivalent keys
3799
  (possibly containing multiple copies of the same key value) and provides
3800
  for fast retrieval of values of another type `T` based on the keys. The
3801
  `multimap` class supports bidirectional iterators.
3802
 
3803
- A `multimap` satisfies all of the requirements of a container and of a
3804
- reversible container ([[container.requirements]]), of an associative
3805
- container ([[associative.reqmts]]), and of an allocator-aware container
3806
- (Table  [[tab:containers.allocatoraware]]). A `multimap` also provides
3807
- most operations described in  [[associative.reqmts]] for equal keys.
3808
- This means that a `multimap` supports the `a_eq` operations in 
3809
- [[associative.reqmts]] but not the `a_uniq` operations. For a
3810
- `multimap<Key,T>` the `key_type` is `Key` and the `value_type` is
3811
- `pair<const Key,T>`. Descriptions are provided here only for operations
3812
- on `multimap` that are not described in one of those tables or for
3813
- operations where there is additional semantic information.
3814
 
3815
  ``` cpp
3816
  namespace std {
3817
  template<class Key, class T, class Compare = less<Key>,
3818
  class Allocator = allocator<pair<const Key, T>>>
3819
  class multimap {
3820
  public:
3821
- // types:
3822
  using key_type = Key;
3823
  using mapped_type = T;
3824
  using value_type = pair<const Key, T>;
3825
  using key_compare = Compare;
3826
  using allocator_type = Allocator;
@@ -3873,11 +3950,11 @@ namespace std {
3873
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
3874
  is_nothrow_move_assignable_v<Compare>);
3875
  multimap& operator=(initializer_list<value_type>);
3876
  allocator_type get_allocator() const noexcept;
3877
 
3878
- // iterators:
3879
  iterator begin() noexcept;
3880
  const_iterator begin() const noexcept;
3881
  iterator end() noexcept;
3882
  const_iterator end() const noexcept;
3883
 
@@ -3889,12 +3966,12 @@ namespace std {
3889
  const_iterator cbegin() const noexcept;
3890
  const_iterator cend() const noexcept;
3891
  const_reverse_iterator crbegin() const noexcept;
3892
  const_reverse_iterator crend() const noexcept;
3893
 
3894
- // capacity:
3895
- bool empty() const noexcept;
3896
  size_type size() const noexcept;
3897
  size_type max_size() const noexcept;
3898
 
3899
  // [multimap.modifiers], modifiers
3900
  template<class... Args> iterator emplace(Args&&... args);
@@ -3930,23 +4007,26 @@ namespace std {
3930
  template<class C2>
3931
  void merge(map<Key, T, C2, Allocator>& source);
3932
  template<class C2>
3933
  void merge(map<Key, T, C2, Allocator>&& source);
3934
 
3935
- // observers:
3936
  key_compare key_comp() const;
3937
  value_compare value_comp() const;
3938
 
3939
- // map operations:
3940
  iterator find(const key_type& x);
3941
  const_iterator find(const key_type& x) const;
3942
  template<class K> iterator find(const K& x);
3943
  template<class K> const_iterator find(const K& x) const;
3944
 
3945
  size_type count(const key_type& x) const;
3946
  template<class K> size_type count(const K& x) const;
3947
 
 
 
 
3948
  iterator lower_bound(const key_type& x);
3949
  const_iterator lower_bound(const key_type& x) const;
3950
  template<class K> iterator lower_bound(const K& x);
3951
  template<class K> const_iterator lower_bound(const K& x) const;
3952
 
@@ -3961,57 +4041,39 @@ namespace std {
3961
  pair<iterator, iterator> equal_range(const K& x);
3962
  template<class K>
3963
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
3964
  };
3965
 
3966
- template<class InputIterator, class Compare = less<iter_key_t<InputIterator>>,
3967
- class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
3968
  multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
3969
- -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>;
 
3970
 
3971
  template<class Key, class T, class Compare = less<Key>,
3972
  class Allocator = allocator<pair<const Key, T>>>
3973
- multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
3974
  -> multimap<Key, T, Compare, Allocator>;
3975
 
3976
  template<class InputIterator, class Allocator>
3977
  multimap(InputIterator, InputIterator, Allocator)
3978
- -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
3979
- less<iter_key_t<InputIterator>>, Allocator>;
3980
 
3981
  template<class Key, class T, class Allocator>
3982
- multimap(initializer_list<pair<const Key, T>>, Allocator)
3983
  -> multimap<Key, T, less<Key>, Allocator>;
3984
 
3985
- template <class Key, class T, class Compare, class Allocator>
3986
- bool operator==(const multimap<Key, T, Compare, Allocator>& x,
3987
- const multimap<Key, T, Compare, Allocator>& y);
3988
- template <class Key, class T, class Compare, class Allocator>
3989
- bool operator< (const multimap<Key, T, Compare, Allocator>& x,
3990
- const multimap<Key, T, Compare, Allocator>& y);
3991
- template <class Key, class T, class Compare, class Allocator>
3992
- bool operator!=(const multimap<Key, T, Compare, Allocator>& x,
3993
- const multimap<Key, T, Compare, Allocator>& y);
3994
- template <class Key, class T, class Compare, class Allocator>
3995
- bool operator> (const multimap<Key, T, Compare, Allocator>& x,
3996
- const multimap<Key, T, Compare, Allocator>& y);
3997
- template <class Key, class T, class Compare, class Allocator>
3998
- bool operator>=(const multimap<Key, T, Compare, Allocator>& x,
3999
- const multimap<Key, T, Compare, Allocator>& y);
4000
- template <class Key, class T, class Compare, class Allocator>
4001
- bool operator<=(const multimap<Key, T, Compare, Allocator>& x,
4002
- const multimap<Key, T, Compare, Allocator>& y);
4003
-
4004
- // [multimap.special], specialized algorithms
4005
  template<class Key, class T, class Compare, class Allocator>
4006
  void swap(multimap<Key, T, Compare, Allocator>& x,
4007
  multimap<Key, T, Compare, Allocator>& y)
4008
  noexcept(noexcept(x.swap(y)));
4009
  }
4010
  ```
4011
 
4012
- #### `multimap` constructors <a id="multimap.cons">[[multimap.cons]]</a>
4013
 
4014
  ``` cpp
4015
  explicit multimap(const Compare& comp, const Allocator& = Allocator());
4016
  ```
4017
 
@@ -4032,62 +4094,71 @@ object and allocator, and inserts elements from the range \[`first`,
4032
  `last`).
4033
 
4034
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4035
  sorted using `comp` and otherwise N log N, where N is `last - first`.
4036
 
4037
- #### `multimap` modifiers <a id="multimap.modifiers">[[multimap.modifiers]]</a>
4038
 
4039
  ``` cpp
4040
  template<class P> iterator insert(P&& x);
4041
  template<class P> iterator insert(const_iterator position, P&& x);
4042
  ```
4043
 
 
 
4044
  *Effects:* The first form is equivalent to
4045
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
4046
  `return emplace_hint(position, std::forward<P>(x))`.
4047
 
4048
- *Remarks:* These signatures shall not participate in overload resolution
4049
- unless `is_constructible_v<value_type, P&&>` is `true`.
4050
-
4051
- #### `multimap` specialized algorithms <a id="multimap.special">[[multimap.special]]</a>
4052
 
4053
  ``` cpp
4054
- template <class Key, class T, class Compare, class Allocator>
4055
- void swap(multimap<Key, T, Compare, Allocator>& x,
4056
- multimap<Key, T, Compare, Allocator>& y)
4057
- noexcept(noexcept(x.swap(y)));
4058
  ```
4059
 
4060
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
4061
 
4062
  ### Class template `set` <a id="set">[[set]]</a>
4063
 
4064
- #### Class template `set` overview <a id="set.overview">[[set.overview]]</a>
4065
 
4066
  A `set` is an associative container that supports unique keys (contains
4067
  at most one of each key value) and provides for fast retrieval of the
4068
  keys themselves. The `set` class supports bidirectional iterators.
4069
 
4070
- A `set` satisfies all of the requirements of a container, of a
4071
- reversible container ([[container.requirements]]), of an associative
4072
- container ([[associative.reqmts]]), and of an allocator-aware container
4073
- (Table  [[tab:containers.allocatoraware]]). A `set` also provides most
4074
- operations described in  [[associative.reqmts]] for unique keys. This
4075
- means that a `set` supports the `a_uniq` operations in 
4076
- [[associative.reqmts]] but not the `a_eq` operations. For a `set<Key>`
4077
- both the `key_type` and `value_type` are `Key`. Descriptions are
4078
- provided here only for operations on `set` that are not described in one
4079
- of these tables and for operations where there is additional semantic
4080
- information.
4081
 
4082
  ``` cpp
4083
  namespace std {
4084
  template<class Key, class Compare = less<Key>,
4085
  class Allocator = allocator<Key>>
4086
  class set {
4087
  public:
4088
- // types:
4089
  using key_type = Key;
4090
  using key_compare = Compare;
4091
  using value_type = Key;
4092
  using value_compare = Compare;
4093
  using allocator_type = Allocator;
@@ -4100,11 +4171,11 @@ namespace std {
4100
  using iterator = implementation-defined // type of set::iterator; // see [container.requirements]
4101
  using const_iterator = implementation-defined // type of set::const_iterator; // see [container.requirements]
4102
  using reverse_iterator = std::reverse_iterator<iterator>;
4103
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
4104
  using node_type = unspecified;
4105
- using insert_return_type = INSERT_RETURN_TYPE<iterator, node_type>;
4106
 
4107
  // [set.cons], construct/copy/destroy
4108
  set() : set(Compare()) { }
4109
  explicit set(const Compare& comp, const Allocator& = Allocator());
4110
  template<class InputIterator>
@@ -4128,11 +4199,11 @@ namespace std {
4128
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4129
  is_nothrow_move_assignable_v<Compare>);
4130
  set& operator=(initializer_list<value_type>);
4131
  allocator_type get_allocator() const noexcept;
4132
 
4133
- // iterators:
4134
  iterator begin() noexcept;
4135
  const_iterator begin() const noexcept;
4136
  iterator end() noexcept;
4137
  const_iterator end() const noexcept;
4138
 
@@ -4144,16 +4215,16 @@ namespace std {
4144
  const_iterator cbegin() const noexcept;
4145
  const_iterator cend() const noexcept;
4146
  const_reverse_iterator crbegin() const noexcept;
4147
  const_reverse_iterator crend() const noexcept;
4148
 
4149
- // capacity:
4150
- bool empty() const noexcept;
4151
  size_type size() const noexcept;
4152
  size_type max_size() const noexcept;
4153
 
4154
- // modifiers:
4155
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
4156
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
4157
  pair<iterator,bool> insert(const value_type& x);
4158
  pair<iterator,bool> insert(value_type&& x);
4159
  iterator insert(const_iterator position, const value_type& x);
@@ -4183,23 +4254,26 @@ namespace std {
4183
  template<class C2>
4184
  void merge(multiset<Key, C2, Allocator>& source);
4185
  template<class C2>
4186
  void merge(multiset<Key, C2, Allocator>&& source);
4187
 
4188
- // observers:
4189
  key_compare key_comp() const;
4190
  value_compare value_comp() const;
4191
 
4192
- // set operations:
4193
  iterator find(const key_type& x);
4194
  const_iterator find(const key_type& x) const;
4195
  template<class K> iterator find(const K& x);
4196
  template<class K> const_iterator find(const K& x) const;
4197
 
4198
  size_type count(const key_type& x) const;
4199
  template<class K> size_type count(const K& x) const;
4200
 
 
 
 
4201
  iterator lower_bound(const key_type& x);
4202
  const_iterator lower_bound(const key_type& x) const;
4203
  template<class K> iterator lower_bound(const K& x);
4204
  template<class K> const_iterator lower_bound(const K& x) const;
4205
 
@@ -4215,56 +4289,37 @@ namespace std {
4215
  template<class K>
4216
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
4217
  };
4218
 
4219
  template<class InputIterator,
4220
- class Compare = less<typename iterator_traits<InputIterator>::value_type>,
4221
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
4222
  set(InputIterator, InputIterator,
4223
  Compare = Compare(), Allocator = Allocator())
4224
- -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
4225
 
4226
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
4227
  set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
4228
  -> set<Key, Compare, Allocator>;
4229
 
4230
  template<class InputIterator, class Allocator>
4231
  set(InputIterator, InputIterator, Allocator)
4232
- -> set<typename iterator_traits<InputIterator>::value_type,
4233
- less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
4234
 
4235
  template<class Key, class Allocator>
4236
  set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>;
4237
 
4238
- template <class Key, class Compare, class Allocator>
4239
- bool operator==(const set<Key, Compare, Allocator>& x,
4240
- const set<Key, Compare, Allocator>& y);
4241
- template <class Key, class Compare, class Allocator>
4242
- bool operator< (const set<Key, Compare, Allocator>& x,
4243
- const set<Key, Compare, Allocator>& y);
4244
- template <class Key, class Compare, class Allocator>
4245
- bool operator!=(const set<Key, Compare, Allocator>& x,
4246
- const set<Key, Compare, Allocator>& y);
4247
- template <class Key, class Compare, class Allocator>
4248
- bool operator> (const set<Key, Compare, Allocator>& x,
4249
- const set<Key, Compare, Allocator>& y);
4250
- template <class Key, class Compare, class Allocator>
4251
- bool operator>=(const set<Key, Compare, Allocator>& x,
4252
- const set<Key, Compare, Allocator>& y);
4253
- template <class Key, class Compare, class Allocator>
4254
- bool operator<=(const set<Key, Compare, Allocator>& x,
4255
- const set<Key, Compare, Allocator>& y);
4256
-
4257
- // [set.special], specialized algorithms
4258
  template<class Key, class Compare, class Allocator>
4259
  void swap(set<Key, Compare, Allocator>& x,
4260
  set<Key, Compare, Allocator>& y)
4261
  noexcept(noexcept(x.swap(y)));
4262
  }
4263
  ```
4264
 
4265
- #### `set` constructors, copy, and assignment <a id="set.cons">[[set.cons]]</a>
4266
 
4267
  ``` cpp
4268
  explicit set(const Compare& comp, const Allocator& = Allocator());
4269
  ```
4270
 
@@ -4284,49 +4339,60 @@ object and allocator, and inserts elements from the range \[`first`,
4284
  `last`).
4285
 
4286
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4287
  sorted using `comp` and otherwise N log N, where N is `last - first`.
4288
 
4289
- #### `set` specialized algorithms <a id="set.special">[[set.special]]</a>
4290
 
4291
  ``` cpp
4292
- template <class Key, class Compare, class Allocator>
4293
- void swap(set<Key, Compare, Allocator>& x,
4294
- set<Key, Compare, Allocator>& y)
4295
- noexcept(noexcept(x.swap(y)));
4296
  ```
4297
 
4298
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
4299
 
4300
  ### Class template `multiset` <a id="multiset">[[multiset]]</a>
4301
 
4302
- #### Class template `multiset` overview <a id="multiset.overview">[[multiset.overview]]</a>
4303
 
4304
  A `multiset` is an associative container that supports equivalent keys
4305
  (possibly contains multiple copies of the same key value) and provides
4306
  for fast retrieval of the keys themselves. The `multiset` class supports
4307
  bidirectional iterators.
4308
 
4309
- A `multiset` satisfies all of the requirements of a container, of a
4310
- reversible container ([[container.requirements]]), of an associative
4311
- container ([[associative.reqmts]]), and of an allocator-aware container
4312
- (Table  [[tab:containers.allocatoraware]]). `multiset` also provides
4313
- most operations described in  [[associative.reqmts]] for duplicate keys.
4314
- This means that a `multiset` supports the `a_eq` operations in 
4315
- [[associative.reqmts]] but not the `a_uniq` operations. For a
4316
- `multiset<Key>` both the `key_type` and `value_type` are `Key`.
4317
- Descriptions are provided here only for operations on `multiset` that
4318
- are not described in one of these tables and for operations where there
4319
- is additional semantic information.
4320
 
4321
  ``` cpp
4322
  namespace std {
4323
  template<class Key, class Compare = less<Key>,
4324
  class Allocator = allocator<Key>>
4325
  class multiset {
4326
  public:
4327
- // types:
4328
  using key_type = Key;
4329
  using key_compare = Compare;
4330
  using value_type = Key;
4331
  using value_compare = Compare;
4332
  using allocator_type = Allocator;
@@ -4366,11 +4432,11 @@ namespace std {
4366
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4367
  is_nothrow_move_assignable_v<Compare>);
4368
  multiset& operator=(initializer_list<value_type>);
4369
  allocator_type get_allocator() const noexcept;
4370
 
4371
- // iterators:
4372
  iterator begin() noexcept;
4373
  const_iterator begin() const noexcept;
4374
  iterator end() noexcept;
4375
  const_iterator end() const noexcept;
4376
 
@@ -4382,16 +4448,16 @@ namespace std {
4382
  const_iterator cbegin() const noexcept;
4383
  const_iterator cend() const noexcept;
4384
  const_reverse_iterator crbegin() const noexcept;
4385
  const_reverse_iterator crend() const noexcept;
4386
 
4387
- // capacity:
4388
- bool empty() const noexcept;
4389
  size_type size() const noexcept;
4390
  size_type max_size() const noexcept;
4391
 
4392
- // modifiers:
4393
  template<class... Args> iterator emplace(Args&&... args);
4394
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
4395
  iterator insert(const value_type& x);
4396
  iterator insert(value_type&& x);
4397
  iterator insert(const_iterator position, const value_type& x);
@@ -4421,23 +4487,26 @@ namespace std {
4421
  template<class C2>
4422
  void merge(set<Key, C2, Allocator>& source);
4423
  template<class C2>
4424
  void merge(set<Key, C2, Allocator>&& source);
4425
 
4426
- // observers:
4427
  key_compare key_comp() const;
4428
  value_compare value_comp() const;
4429
 
4430
- // set operations:
4431
  iterator find(const key_type& x);
4432
  const_iterator find(const key_type& x) const;
4433
  template<class K> iterator find(const K& x);
4434
  template<class K> const_iterator find(const K& x) const;
4435
 
4436
  size_type count(const key_type& x) const;
4437
  template<class K> size_type count(const K& x) const;
4438
 
 
 
 
4439
  iterator lower_bound(const key_type& x);
4440
  const_iterator lower_bound(const key_type& x) const;
4441
  template<class K> iterator lower_bound(const K& x);
4442
  template<class K> const_iterator lower_bound(const K& x) const;
4443
 
@@ -4453,56 +4522,37 @@ namespace std {
4453
  template<class K>
4454
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
4455
  };
4456
 
4457
  template<class InputIterator,
4458
- class Compare = less<typename iterator_traits<InputIterator>::value_type>,
4459
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
4460
  multiset(InputIterator, InputIterator,
4461
  Compare = Compare(), Allocator = Allocator())
4462
- -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;
4463
 
4464
  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
4465
  multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
4466
  -> multiset<Key, Compare, Allocator>;
4467
 
4468
  template<class InputIterator, class Allocator>
4469
  multiset(InputIterator, InputIterator, Allocator)
4470
- -> multiset<typename iterator_traits<InputIterator>::value_type,
4471
- less<typename iterator_traits<InputIterator>::value_type>, Allocator>;
4472
 
4473
  template<class Key, class Allocator>
4474
  multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>;
4475
 
4476
- template <class Key, class Compare, class Allocator>
4477
- bool operator==(const multiset<Key, Compare, Allocator>& x,
4478
- const multiset<Key, Compare, Allocator>& y);
4479
- template <class Key, class Compare, class Allocator>
4480
- bool operator< (const multiset<Key, Compare, Allocator>& x,
4481
- const multiset<Key, Compare, Allocator>& y);
4482
- template <class Key, class Compare, class Allocator>
4483
- bool operator!=(const multiset<Key, Compare, Allocator>& x,
4484
- const multiset<Key, Compare, Allocator>& y);
4485
- template <class Key, class Compare, class Allocator>
4486
- bool operator> (const multiset<Key, Compare, Allocator>& x,
4487
- const multiset<Key, Compare, Allocator>& y);
4488
- template <class Key, class Compare, class Allocator>
4489
- bool operator>=(const multiset<Key, Compare, Allocator>& x,
4490
- const multiset<Key, Compare, Allocator>& y);
4491
- template <class Key, class Compare, class Allocator>
4492
- bool operator<=(const multiset<Key, Compare, Allocator>& x,
4493
- const multiset<Key, Compare, Allocator>& y);
4494
-
4495
- // [multiset.special], specialized algorithms
4496
  template<class Key, class Compare, class Allocator>
4497
  void swap(multiset<Key, Compare, Allocator>& x,
4498
  multiset<Key, Compare, Allocator>& y)
4499
  noexcept(noexcept(x.swap(y)));
4500
  }
4501
  ```
4502
 
4503
- #### `multiset` constructors <a id="multiset.cons">[[multiset.cons]]</a>
4504
 
4505
  ``` cpp
4506
  explicit multiset(const Compare& comp, const Allocator& = Allocator());
4507
  ```
4508
 
@@ -4522,37 +4572,50 @@ object and allocator, and inserts elements from the range \[`first`,
4522
  `last`).
4523
 
4524
  *Complexity:* Linear in N if the range \[`first`, `last`) is already
4525
  sorted using `comp` and otherwise N log N, where N is `last - first`.
4526
 
4527
- #### `multiset` specialized algorithms <a id="multiset.special">[[multiset.special]]</a>
4528
 
4529
  ``` cpp
4530
- template <class Key, class Compare, class Allocator>
4531
- void swap(multiset<Key, Compare, Allocator>& x,
4532
- multiset<Key, Compare, Allocator>& y)
4533
- noexcept(noexcept(x.swap(y)));
4534
  ```
4535
 
4536
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
4537
 
4538
  ## Unordered associative containers <a id="unord">[[unord]]</a>
4539
 
4540
  ### In general <a id="unord.general">[[unord.general]]</a>
4541
 
4542
  The header `<unordered_map>` defines the class templates `unordered_map`
4543
  and `unordered_multimap`; the header `<unordered_set>` defines the class
4544
  templates `unordered_set` and `unordered_multiset`.
4545
 
4546
- The exposition-only alias templates `iter_key_t`, `iter_val_t`, and
4547
- `iter_to_alloc_t` defined in [[associative.general]] may appear in
4548
- deduction guides for unordered containers.
 
4549
 
4550
  ### Header `<unordered_map>` synopsis <a id="unord.map.syn">[[unord.map.syn]]</a>
4551
 
4552
  ``` cpp
4553
- #include <initializer_list>
 
4554
 
4555
  namespace std {
4556
  // [unord.map], class template unordered_map
4557
  template<class Key,
4558
  class T,
@@ -4567,32 +4630,35 @@ namespace std {
4567
  class Hash = hash<Key>,
4568
  class Pred = equal_to<Key>,
4569
  class Alloc = allocator<pair<const Key, T>>>
4570
  class unordered_multimap;
4571
 
 
 
 
 
 
 
 
 
4572
  template<class Key, class T, class Hash, class Pred, class Alloc>
4573
  void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
4574
  unordered_map<Key, T, Hash, Pred, Alloc>& y)
4575
  noexcept(noexcept(x.swap(y)));
4576
 
4577
  template<class Key, class T, class Hash, class Pred, class Alloc>
4578
  void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
4579
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
4580
  noexcept(noexcept(x.swap(y)));
4581
 
4582
- template <class Key, class T, class Hash, class Pred, class Alloc>
4583
- bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
4584
- const unordered_map<Key, T, Hash, Pred, Alloc>& b);
4585
- template <class Key, class T, class Hash, class Pred, class Alloc>
4586
- bool operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
4587
- const unordered_map<Key, T, Hash, Pred, Alloc>& b);
4588
- template <class Key, class T, class Hash, class Pred, class Alloc>
4589
- bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
4590
- const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
4591
- template <class Key, class T, class Hash, class Pred, class Alloc>
4592
- bool operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
4593
- const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
4594
 
4595
  namespace pmr {
4596
  template<class Key,
4597
  class T,
4598
  class Hash = hash<Key>,
@@ -4613,11 +4679,12 @@ namespace std {
4613
  ```
4614
 
4615
  ### Header `<unordered_set>` synopsis <a id="unord.set.syn">[[unord.set.syn]]</a>
4616
 
4617
  ``` cpp
4618
- #include <initializer_list>
 
4619
 
4620
  namespace std {
4621
  // [unord.set], class template unordered_set
4622
  template<class Key,
4623
  class Hash = hash<Key>,
@@ -4630,32 +4697,35 @@ namespace std {
4630
  class Hash = hash<Key>,
4631
  class Pred = equal_to<Key>,
4632
  class Alloc = allocator<Key>>
4633
  class unordered_multiset;
4634
 
 
 
 
 
 
 
 
 
4635
  template<class Key, class Hash, class Pred, class Alloc>
4636
  void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
4637
  unordered_set<Key, Hash, Pred, Alloc>& y)
4638
  noexcept(noexcept(x.swap(y)));
4639
 
4640
  template<class Key, class Hash, class Pred, class Alloc>
4641
  void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
4642
  unordered_multiset<Key, Hash, Pred, Alloc>& y)
4643
  noexcept(noexcept(x.swap(y)));
4644
 
4645
- template <class Key, class Hash, class Pred, class Alloc>
4646
- bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
4647
- const unordered_set<Key, Hash, Pred, Alloc>& b);
4648
- template <class Key, class Hash, class Pred, class Alloc>
4649
- bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& a,
4650
- const unordered_set<Key, Hash, Pred, Alloc>& b);
4651
- template <class Key, class Hash, class Pred, class Alloc>
4652
- bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
4653
- const unordered_multiset<Key, Hash, Pred, Alloc>& b);
4654
- template <class Key, class Hash, class Pred, class Alloc>
4655
- bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
4656
- const unordered_multiset<Key, Hash, Pred, Alloc>& b);
4657
 
4658
  namespace pmr {
4659
  template<class Key,
4660
  class Hash = hash<Key>,
4661
  class Pred = equal_to<Key>>
@@ -4671,40 +4741,40 @@ namespace std {
4671
  }
4672
  ```
4673
 
4674
  ### Class template `unordered_map` <a id="unord.map">[[unord.map]]</a>
4675
 
4676
- #### Class template `unordered_map` overview <a id="unord.map.overview">[[unord.map.overview]]</a>
4677
 
4678
  An `unordered_map` is an unordered associative container that supports
4679
  unique keys (an `unordered_map` contains at most one of each key value)
4680
  and that associates values of another type `mapped_type` with the keys.
4681
  The `unordered_map` class supports forward iterators.
4682
 
4683
- An `unordered_map` satisfies all of the requirements of a container, of
4684
- an unordered associative container, and of an allocator-aware container
4685
- (Table  [[tab:containers.allocatoraware]]). It provides the operations
4686
- described in the preceding requirements table for unique keys; that is,
4687
- an `unordered_map` supports the `a_uniq` operations in that table, not
4688
- the `a_eq` operations. For an `unordered_map<Key, T>` the `key type` is
4689
  `Key`, the mapped type is `T`, and the value type is
4690
  `pair<const Key, T>`.
4691
 
4692
- This section only describes operations on `unordered_map` that are not
4693
- described in one of the requirement tables, or for which there is
4694
- additional semantic information.
4695
 
4696
  ``` cpp
4697
  namespace std {
4698
  template<class Key,
4699
  class T,
4700
  class Hash = hash<Key>,
4701
  class Pred = equal_to<Key>,
4702
  class Allocator = allocator<pair<const Key, T>>>
4703
  class unordered_map {
4704
  public:
4705
- // types:
4706
  using key_type = Key;
4707
  using mapped_type = T;
4708
  using value_type = pair<const Key, T>;
4709
  using hasher = Hash;
4710
  using key_equal = Pred;
@@ -4719,11 +4789,11 @@ namespace std {
4719
  using iterator = implementation-defined // type of unordered_map::iterator; // see [container.requirements]
4720
  using const_iterator = implementation-defined // type of unordered_map::const_iterator; // see [container.requirements]
4721
  using local_iterator = implementation-defined // type of unordered_map::local_iterator; // see [container.requirements]
4722
  using const_local_iterator = implementation-defined // type of unordered_map::const_local_iterator; // see [container.requirements]
4723
  using node_type = unspecified;
4724
- using insert_return_type = INSERT_RETURN_TYPE<iterator, node_type>;
4725
 
4726
  // [unord.map.cnstr], construct/copy/destroy
4727
  unordered_map();
4728
  explicit unordered_map(size_type n,
4729
  const hasher& hf = hasher(),
@@ -4768,20 +4838,20 @@ namespace std {
4768
  is_nothrow_move_assignable_v<Hash> &&
4769
  is_nothrow_move_assignable_v<Pred>);
4770
  unordered_map& operator=(initializer_list<value_type>);
4771
  allocator_type get_allocator() const noexcept;
4772
 
4773
- // iterators:
4774
  iterator begin() noexcept;
4775
  const_iterator begin() const noexcept;
4776
  iterator end() noexcept;
4777
  const_iterator end() const noexcept;
4778
  const_iterator cbegin() const noexcept;
4779
  const_iterator cend() const noexcept;
4780
 
4781
- // capacity:
4782
- bool empty() const noexcept;
4783
  size_type size() const noexcept;
4784
  size_type max_size() const noexcept;
4785
 
4786
  // [unord.map.modifiers], modifiers
4787
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
@@ -4834,28 +4904,42 @@ namespace std {
4834
  template<class H2, class P2>
4835
  void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
4836
  template<class H2, class P2>
4837
  void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
4838
 
4839
- // observers:
4840
  hasher hash_function() const;
4841
  key_equal key_eq() const;
4842
 
4843
- // map operations:
4844
  iterator find(const key_type& k);
4845
  const_iterator find(const key_type& k) const;
 
 
 
 
 
4846
  size_type count(const key_type& k) const;
 
 
 
 
 
4847
  pair<iterator, iterator> equal_range(const key_type& k);
4848
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
 
 
 
 
4849
 
4850
  // [unord.map.elem], element access
4851
  mapped_type& operator[](const key_type& k);
4852
  mapped_type& operator[](key_type&& k);
4853
  mapped_type& at(const key_type& k);
4854
  const mapped_type& at(const key_type& k) const;
4855
 
4856
- // bucket interface:
4857
  size_type bucket_count() const noexcept;
4858
  size_type max_bucket_count() const noexcept;
4859
  size_type bucket_size(size_type n) const;
4860
  size_type bucket(const key_type& k) const;
4861
  local_iterator begin(size_type n);
@@ -4863,73 +4947,66 @@ namespace std {
4863
  local_iterator end(size_type n);
4864
  const_local_iterator end(size_type n) const;
4865
  const_local_iterator cbegin(size_type n) const;
4866
  const_local_iterator cend(size_type n) const;
4867
 
4868
- // hash policy:
4869
  float load_factor() const noexcept;
4870
  float max_load_factor() const noexcept;
4871
  void max_load_factor(float z);
4872
  void rehash(size_type n);
4873
  void reserve(size_type n);
4874
  };
4875
 
4876
  template<class InputIterator,
4877
- class Hash = hash<iter_key_t<InputIterator>>,
4878
- class Pred = equal_to<iter_key_t<InputIterator>>,
4879
- class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
4880
  unordered_map(InputIterator, InputIterator, typename see below::size_type = see below,
4881
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
4882
- -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
4883
  Allocator>;
4884
 
4885
  template<class Key, class T, class Hash = hash<Key>,
4886
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
4887
- unordered_map(initializer_list<pair<const Key, T>>,
4888
  typename see below::size_type = see below, Hash = Hash(),
4889
  Pred = Pred(), Allocator = Allocator())
4890
  -> unordered_map<Key, T, Hash, Pred, Allocator>;
4891
 
4892
  template<class InputIterator, class Allocator>
4893
  unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator)
4894
- -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
4895
- hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>,
4896
- Allocator>;
4897
 
4898
  template<class InputIterator, class Allocator>
4899
  unordered_map(InputIterator, InputIterator, Allocator)
4900
- -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
4901
- hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>,
4902
- Allocator>;
4903
 
4904
  template<class InputIterator, class Hash, class Allocator>
4905
  unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator)
4906
- -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
4907
- equal_to<iter_key_t<InputIterator>>, Allocator>;
4908
 
4909
- template<class Key, class T, typename Allocator>
4910
- unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type,
4911
  Allocator)
4912
  -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
4913
 
4914
- template<class Key, class T, typename Allocator>
4915
- unordered_map(initializer_list<pair<const Key, T>>, Allocator)
4916
  -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
4917
 
4918
  template<class Key, class T, class Hash, class Allocator>
4919
- unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Hash,
4920
  Allocator)
4921
  -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;
4922
 
4923
- template <class Key, class T, class Hash, class Pred, class Alloc>
4924
- bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
4925
- const unordered_map<Key, T, Hash, Pred, Alloc>& b);
4926
- template <class Key, class T, class Hash, class Pred, class Alloc>
4927
- bool operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
4928
- const unordered_map<Key, T, Hash, Pred, Alloc>& b);
4929
-
4930
- // [unord.map.swap], swap
4931
  template<class Key, class T, class Hash, class Pred, class Alloc>
4932
  void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
4933
  unordered_map<Key, T, Hash, Pred, Alloc>& y)
4934
  noexcept(noexcept(x.swap(y)));
4935
  }
@@ -4937,11 +5014,11 @@ namespace std {
4937
 
4938
  A `size_type` parameter type in an `unordered_map` deduction guide
4939
  refers to the `size_type` member type of the type deduced by the
4940
  deduction guide.
4941
 
4942
- #### `unordered_map` constructors <a id="unord.map.cnstr">[[unord.map.cnstr]]</a>
4943
 
4944
  ``` cpp
4945
  unordered_map() : unordered_map(size_type(see below)) { }
4946
  explicit unordered_map(size_type n,
4947
  const hasher& hf = hasher(),
@@ -4977,11 +5054,11 @@ buckets. If `n` is not provided, the number of buckets is
4977
  `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
4978
  for the second form. `max_load_factor()` returns `1.0`.
4979
 
4980
  *Complexity:* Average case linear, worst case quadratic.
4981
 
4982
- #### `unordered_map` element access <a id="unord.map.elem">[[unord.map.elem]]</a>
4983
 
4984
  ``` cpp
4985
  mapped_type& operator[](const key_type& k);
4986
  ```
4987
 
@@ -5002,41 +5079,39 @@ const mapped_type& at(const key_type& k) const;
5002
  whose key is equivalent to `k`.
5003
 
5004
  *Throws:* An exception object of type `out_of_range` if no such element
5005
  is present.
5006
 
5007
- #### `unordered_map` modifiers <a id="unord.map.modifiers">[[unord.map.modifiers]]</a>
5008
 
5009
  ``` cpp
5010
  template<class P>
5011
  pair<iterator, bool> insert(P&& obj);
5012
  ```
5013
 
 
 
5014
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
5015
 
5016
- *Remarks:* This signature shall not participate in overload resolution
5017
- unless `is_constructible_v<value_type, P&&>` is `true`.
5018
-
5019
  ``` cpp
5020
  template<class P>
5021
  iterator insert(const_iterator hint, P&& obj);
5022
  ```
5023
 
 
 
5024
  *Effects:* Equivalent to:
5025
  `return emplace_hint(hint, std::forward<P>(obj));`
5026
 
5027
- *Remarks:* This signature shall not participate in overload resolution
5028
- unless `is_constructible_v<value_type, P&&>` is `true`.
5029
-
5030
  ``` cpp
5031
  template<class... Args>
5032
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
5033
  template<class... Args>
5034
  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
5035
  ```
5036
 
5037
- *Requires:* `value_type` shall be `EmplaceConstructible` into
5038
  `unordered_map` from `piecewise_construct`, `forward_as_tuple(k)`,
5039
  `forward_as_tuple(std::forward<Args>(args)...)`.
5040
 
5041
  *Effects:* If the map already contains an element whose key is
5042
  equivalent to `k`, there is no effect. Otherwise inserts an object of
@@ -5054,11 +5129,11 @@ template <class... Args>
5054
  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
5055
  template<class... Args>
5056
  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
5057
  ```
5058
 
5059
- *Requires:* `value_type` shall be `EmplaceConstructible` into
5060
  `unordered_map` from `piecewise_construct`,
5061
  `forward_as_tuple(std::move(k))`,
5062
  `forward_as_tuple(std::forward<Args>(args)...)`.
5063
 
5064
  *Effects:* If the map already contains an element whose key is
@@ -5078,13 +5153,14 @@ template <class M>
5078
  pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
5079
  template<class M>
5080
  iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
5081
  ```
5082
 
5083
- *Requires:* `is_assignable_v<mapped_type&, M&&>` shall be `true`.
5084
- `value_type` shall be `EmplaceConstructible` into `unordered_map` from
5085
- `k`, `std::forward<M>(obj)`.
 
5086
 
5087
  *Effects:* If the map already contains an element `e` whose key is
5088
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
5089
  Otherwise inserts an object of type `value_type` constructed with `k`,
5090
  `std::forward<M>(obj)`.
@@ -5100,13 +5176,14 @@ template <class M>
5100
  pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
5101
  template<class M>
5102
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
5103
  ```
5104
 
5105
- *Requires:* `is_assignable_v<mapped_type&, M&&>` shall be `true`.
5106
- `value_type` shall be `EmplaceConstructible` into `unordered_map` from
5107
- `std::move(k)`, `std::forward<M>(obj)`.
 
5108
 
5109
  *Effects:* If the map already contains an element `e` whose key is
5110
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
5111
  Otherwise inserts an object of type `value_type` constructed with
5112
  `std::move(k)`, `std::forward<M>(obj)`.
@@ -5115,54 +5192,65 @@ Otherwise inserts an object of type `value_type` constructed with
5115
  pair is `true` if and only if the insertion took place. The returned
5116
  iterator points to the map element whose key is equivalent to `k`.
5117
 
5118
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
5119
 
5120
- #### `unordered_map` swap <a id="unord.map.swap">[[unord.map.swap]]</a>
5121
 
5122
  ``` cpp
5123
- template <class Key, class T, class Hash, class Pred, class Alloc>
5124
- void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
5125
- unordered_map<Key, T, Hash, Pred, Alloc>& y)
5126
- noexcept(noexcept(x.swap(y)));
5127
  ```
5128
 
5129
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
5130
 
5131
  ### Class template `unordered_multimap` <a id="unord.multimap">[[unord.multimap]]</a>
5132
 
5133
- #### Class template `unordered_multimap` overview <a id="unord.multimap.overview">[[unord.multimap.overview]]</a>
5134
 
5135
  An `unordered_multimap` is an unordered associative container that
5136
  supports equivalent keys (an instance of `unordered_multimap` may
5137
  contain multiple copies of each key value) and that associates values of
5138
  another type `mapped_type` with the keys. The `unordered_multimap` class
5139
  supports forward iterators.
5140
 
5141
- An `unordered_multimap` satisfies all of the requirements of a
5142
- container, of an unordered associative container, and of an
5143
- allocator-aware container (Table  [[tab:containers.allocatoraware]]). It
5144
- provides the operations described in the preceding requirements table
5145
- for equivalent keys; that is, an `unordered_multimap` supports the
5146
- `a_eq` operations in that table, not the `a_uniq` operations. For an
5147
- `unordered_multimap<Key, T>` the `key type` is `Key`, the mapped type is
5148
- `T`, and the value type is `pair<const Key, T>`.
5149
 
5150
- This section only describes operations on `unordered_multimap` that are
5151
- not described in one of the requirement tables, or for which there is
5152
- additional semantic information.
5153
 
5154
  ``` cpp
5155
  namespace std {
5156
  template<class Key,
5157
  class T,
5158
  class Hash = hash<Key>,
5159
  class Pred = equal_to<Key>,
5160
  class Allocator = allocator<pair<const Key, T>>>
5161
  class unordered_multimap {
5162
  public:
5163
- // types:
5164
  using key_type = Key;
5165
  using mapped_type = T;
5166
  using value_type = pair<const Key, T>;
5167
  using hasher = Hash;
5168
  using key_equal = Pred;
@@ -5225,20 +5313,20 @@ namespace std {
5225
  is_nothrow_move_assignable_v<Hash> &&
5226
  is_nothrow_move_assignable_v<Pred>);
5227
  unordered_multimap& operator=(initializer_list<value_type>);
5228
  allocator_type get_allocator() const noexcept;
5229
 
5230
- // iterators:
5231
  iterator begin() noexcept;
5232
  const_iterator begin() const noexcept;
5233
  iterator end() noexcept;
5234
  const_iterator end() const noexcept;
5235
  const_iterator cbegin() const noexcept;
5236
  const_iterator cend() const noexcept;
5237
 
5238
- // capacity:
5239
- bool empty() const noexcept;
5240
  size_type size() const noexcept;
5241
  size_type max_size() const noexcept;
5242
 
5243
  // [unord.multimap.modifiers], modifiers
5244
  template<class... Args> iterator emplace(Args&&... args);
@@ -5274,22 +5362,35 @@ namespace std {
5274
  template<class H2, class P2>
5275
  void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
5276
  template<class H2, class P2>
5277
  void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
5278
 
5279
- // observers:
5280
  hasher hash_function() const;
5281
  key_equal key_eq() const;
5282
 
5283
- // map operations:
5284
  iterator find(const key_type& k);
5285
  const_iterator find(const key_type& k) const;
 
 
 
 
5286
  size_type count(const key_type& k) const;
 
 
 
 
 
5287
  pair<iterator, iterator> equal_range(const key_type& k);
5288
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
 
 
 
 
5289
 
5290
- // bucket interface:
5291
  size_type bucket_count() const noexcept;
5292
  size_type max_bucket_count() const noexcept;
5293
  size_type bucket_size(size_type n) const;
5294
  size_type bucket(const key_type& k) const;
5295
  local_iterator begin(size_type n);
@@ -5306,66 +5407,59 @@ namespace std {
5306
  void rehash(size_type n);
5307
  void reserve(size_type n);
5308
  };
5309
 
5310
  template<class InputIterator,
5311
- class Hash = hash<iter_key_t<InputIterator>>,
5312
- class Pred = equal_to<iter_key_t<InputIterator>>,
5313
- class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
5314
  unordered_multimap(InputIterator, InputIterator,
5315
  typename see below::size_type = see below,
5316
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5317
- -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
5318
- Allocator>;
5319
 
5320
  template<class Key, class T, class Hash = hash<Key>,
5321
  class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
5322
- unordered_multimap(initializer_list<pair<const Key, T>>,
5323
  typename see below::size_type = see below,
5324
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5325
  -> unordered_multimap<Key, T, Hash, Pred, Allocator>;
5326
 
5327
  template<class InputIterator, class Allocator>
5328
  unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator)
5329
- -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
5330
- hash<iter_key_t<InputIterator>>,
5331
- equal_to<iter_key_t<InputIterator>>, Allocator>;
5332
 
5333
  template<class InputIterator, class Allocator>
5334
  unordered_multimap(InputIterator, InputIterator, Allocator)
5335
- -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
5336
- hash<iter_key_t<InputIterator>>,
5337
- equal_to<iter_key_t<InputIterator>>, Allocator>;
5338
 
5339
  template<class InputIterator, class Hash, class Allocator>
5340
  unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash,
5341
  Allocator)
5342
- -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
5343
- equal_to<iter_key_t<InputIterator>>, Allocator>;
5344
 
5345
- template<class Key, class T, typename Allocator>
5346
- unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
5347
  Allocator)
5348
  -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
5349
 
5350
- template<class Key, class T, typename Allocator>
5351
- unordered_multimap(initializer_list<pair<const Key, T>>, Allocator)
5352
  -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
5353
 
5354
  template<class Key, class T, class Hash, class Allocator>
5355
- unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
5356
  Hash, Allocator)
5357
  -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;
5358
 
5359
- template <class Key, class T, class Hash, class Pred, class Alloc>
5360
- bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
5361
- const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
5362
- template <class Key, class T, class Hash, class Pred, class Alloc>
5363
- bool operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
5364
- const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
5365
-
5366
- // [unord.multimap.swap], swap
5367
  template<class Key, class T, class Hash, class Pred, class Alloc>
5368
  void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
5369
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
5370
  noexcept(noexcept(x.swap(y)));
5371
  }
@@ -5373,11 +5467,11 @@ namespace std {
5373
 
5374
  A `size_type` parameter type in an `unordered_multimap` deduction guide
5375
  refers to the `size_type` member type of the type deduced by the
5376
  deduction guide.
5377
 
5378
- #### `unordered_multimap` constructors <a id="unord.multimap.cnstr">[[unord.multimap.cnstr]]</a>
5379
 
5380
  ``` cpp
5381
  unordered_multimap() : unordered_multimap(size_type(see below)) { }
5382
  explicit unordered_multimap(size_type n,
5383
  const hasher& hf = hasher(),
@@ -5413,76 +5507,85 @@ hash function, key equality predicate, and allocator, and using at least
5413
  `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
5414
  for the second form. `max_load_factor()` returns `1.0`.
5415
 
5416
  *Complexity:* Average case linear, worst case quadratic.
5417
 
5418
- #### `unordered_multimap` modifiers <a id="unord.multimap.modifiers">[[unord.multimap.modifiers]]</a>
5419
 
5420
  ``` cpp
5421
  template<class P>
5422
  iterator insert(P&& obj);
5423
  ```
5424
 
 
 
5425
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
5426
 
5427
- *Remarks:* This signature shall not participate in overload resolution
5428
- unless `is_constructible_v<value_type, P&&>` is `true`.
5429
-
5430
  ``` cpp
5431
  template<class P>
5432
  iterator insert(const_iterator hint, P&& obj);
5433
  ```
5434
 
 
 
5435
  *Effects:* Equivalent to:
5436
  `return emplace_hint(hint, std::forward<P>(obj));`
5437
 
5438
- *Remarks:* This signature shall not participate in overload resolution
5439
- unless `is_constructible_v<value_type, P&&>` is `true`.
5440
-
5441
- #### `unordered_multimap` swap <a id="unord.multimap.swap">[[unord.multimap.swap]]</a>
5442
 
5443
  ``` cpp
5444
- template <class Key, class T, class Hash, class Pred, class Alloc>
5445
- void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
5446
- unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
5447
- noexcept(noexcept(x.swap(y)));
5448
  ```
5449
 
5450
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
5451
 
5452
  ### Class template `unordered_set` <a id="unord.set">[[unord.set]]</a>
5453
 
5454
- #### Class template `unordered_set` overview <a id="unord.set.overview">[[unord.set.overview]]</a>
5455
 
5456
  An `unordered_set` is an unordered associative container that supports
5457
  unique keys (an `unordered_set` contains at most one of each key value)
5458
  and in which the elements’ keys are the elements themselves. The
5459
  `unordered_set` class supports forward iterators.
5460
 
5461
- An `unordered_set` satisfies all of the requirements of a container, of
5462
- an unordered associative container, and of an allocator-aware container
5463
- (Table  [[tab:containers.allocatoraware]]). It provides the operations
5464
- described in the preceding requirements table for unique keys; that is,
5465
- an `unordered_set` supports the `a_uniq` operations in that table, not
5466
- the `a_eq` operations. For an `unordered_set<Key>` the `key type` and
5467
- the value type are both `Key`. The `iterator` and `const_iterator` types
5468
- are both constant iterator types. It is unspecified whether they are the
5469
  same type.
5470
 
5471
- This section only describes operations on `unordered_set` that are not
5472
- described in one of the requirement tables, or for which there is
5473
- additional semantic information.
5474
 
5475
  ``` cpp
5476
  namespace std {
5477
  template<class Key,
5478
  class Hash = hash<Key>,
5479
  class Pred = equal_to<Key>,
5480
  class Allocator = allocator<Key>>
5481
  class unordered_set {
5482
  public:
5483
- // types:
5484
  using key_type = Key;
5485
  using value_type = Key;
5486
  using hasher = Hash;
5487
  using key_equal = Pred;
5488
  using allocator_type = Allocator;
@@ -5496,11 +5599,11 @@ namespace std {
5496
  using iterator = implementation-defined // type of unordered_set::iterator; // see [container.requirements]
5497
  using const_iterator = implementation-defined // type of unordered_set::const_iterator; // see [container.requirements]
5498
  using local_iterator = implementation-defined // type of unordered_set::local_iterator; // see [container.requirements]
5499
  using const_local_iterator = implementation-defined // type of unordered_set::const_local_iterator; // see [container.requirements]
5500
  using node_type = unspecified;
5501
- using insert_return_type = INSERT_RETURN_TYPE<iterator, node_type>;
5502
 
5503
  // [unord.set.cnstr], construct/copy/destroy
5504
  unordered_set();
5505
  explicit unordered_set(size_type n,
5506
  const hasher& hf = hasher(),
@@ -5545,24 +5648,24 @@ namespace std {
5545
  is_nothrow_move_assignable_v<Hash> &&
5546
  is_nothrow_move_assignable_v<Pred>);
5547
  unordered_set& operator=(initializer_list<value_type>);
5548
  allocator_type get_allocator() const noexcept;
5549
 
5550
- // iterators:
5551
  iterator begin() noexcept;
5552
  const_iterator begin() const noexcept;
5553
  iterator end() noexcept;
5554
  const_iterator end() const noexcept;
5555
  const_iterator cbegin() const noexcept;
5556
  const_iterator cend() const noexcept;
5557
 
5558
- // capacity:
5559
- bool empty() const noexcept;
5560
  size_type size() const noexcept;
5561
  size_type max_size() const noexcept;
5562
 
5563
- // modifiers:
5564
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
5565
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
5566
  pair<iterator, bool> insert(const value_type& obj);
5567
  pair<iterator, bool> insert(value_type&& obj);
5568
  iterator insert(const_iterator hint, const value_type& obj);
@@ -5592,22 +5695,35 @@ namespace std {
5592
  template<class H2, class P2>
5593
  void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
5594
  template<class H2, class P2>
5595
  void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
5596
 
5597
- // observers:
5598
  hasher hash_function() const;
5599
  key_equal key_eq() const;
5600
 
5601
- // set operations:
5602
  iterator find(const key_type& k);
5603
  const_iterator find(const key_type& k) const;
 
 
 
 
5604
  size_type count(const key_type& k) const;
 
 
 
 
 
5605
  pair<iterator, iterator> equal_range(const key_type& k);
5606
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
 
 
 
 
5607
 
5608
- // bucket interface:
5609
  size_type bucket_count() const noexcept;
5610
  size_type max_bucket_count() const noexcept;
5611
  size_type bucket_size(size_type n) const;
5612
  size_type bucket(const key_type& k) const;
5613
  local_iterator begin(size_type n);
@@ -5615,75 +5731,68 @@ namespace std {
5615
  local_iterator end(size_type n);
5616
  const_local_iterator end(size_type n) const;
5617
  const_local_iterator cbegin(size_type n) const;
5618
  const_local_iterator cend(size_type n) const;
5619
 
5620
- // hash policy:
5621
  float load_factor() const noexcept;
5622
  float max_load_factor() const noexcept;
5623
  void max_load_factor(float z);
5624
  void rehash(size_type n);
5625
  void reserve(size_type n);
5626
  };
5627
 
5628
  template<class InputIterator,
5629
- class Hash = hash<typename iterator_traits<InputIterator>::value_type>,
5630
- class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>,
5631
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
5632
  unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
5633
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5634
- -> unordered_set<typename iterator_traits<InputIterator>::value_type,
5635
  Hash, Pred, Allocator>;
5636
 
5637
  template<class T, class Hash = hash<T>,
5638
  class Pred = equal_to<T>, class Allocator = allocator<T>>
5639
  unordered_set(initializer_list<T>, typename see below::size_type = see below,
5640
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5641
  -> unordered_set<T, Hash, Pred, Allocator>;
5642
 
5643
  template<class InputIterator, class Allocator>
5644
  unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator)
5645
- -> unordered_set<typename iterator_traits<InputIterator>::value_type,
5646
- hash<typename iterator_traits<InputIterator>::value_type>,
5647
- equal_to<typename iterator_traits<InputIterator>::value_type>,
5648
  Allocator>;
5649
 
5650
  template<class InputIterator, class Hash, class Allocator>
5651
  unordered_set(InputIterator, InputIterator, typename see below::size_type,
5652
  Hash, Allocator)
5653
- -> unordered_set<typename iterator_traits<InputIterator>::value_type, Hash,
5654
- equal_to<typename iterator_traits<InputIterator>::value_type>,
5655
  Allocator>;
5656
 
5657
  template<class T, class Allocator>
5658
  unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
5659
  -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;
5660
 
5661
  template<class T, class Hash, class Allocator>
5662
  unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
5663
  -> unordered_set<T, Hash, equal_to<T>, Allocator>;
5664
 
5665
- template <class Key, class Hash, class Pred, class Alloc>
5666
- bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
5667
- const unordered_set<Key, Hash, Pred, Alloc>& b);
5668
- template <class Key, class Hash, class Pred, class Alloc>
5669
- bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& a,
5670
- const unordered_set<Key, Hash, Pred, Alloc>& b);
5671
-
5672
- // [unord.set.swap], swap
5673
  template<class Key, class Hash, class Pred, class Alloc>
5674
  void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
5675
  unordered_set<Key, Hash, Pred, Alloc>& y)
5676
  noexcept(noexcept(x.swap(y)));
5677
  }
5678
  ```
5679
 
5680
  A `size_type` parameter type in an `unordered_set` deduction guide
5681
- refers to the `size_type` member type of the primary `unordered_set`
5682
- template.
5683
 
5684
- #### `unordered_set` constructors <a id="unord.set.cnstr">[[unord.set.cnstr]]</a>
5685
 
5686
  ``` cpp
5687
  unordered_set() : unordered_set(size_type(see below)) { }
5688
  explicit unordered_set(size_type n,
5689
  const hasher& hf = hasher(),
@@ -5719,54 +5828,65 @@ buckets. If `n` is not provided, the number of buckets is
5719
  `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
5720
  for the second form. `max_load_factor()` returns `1.0`.
5721
 
5722
  *Complexity:* Average case linear, worst case quadratic.
5723
 
5724
- #### `unordered_set` swap <a id="unord.set.swap">[[unord.set.swap]]</a>
5725
 
5726
  ``` cpp
5727
- template <class Key, class Hash, class Pred, class Alloc>
5728
- void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
5729
- unordered_set<Key, Hash, Pred, Alloc>& y)
5730
- noexcept(noexcept(x.swap(y)));
5731
  ```
5732
 
5733
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
5734
 
5735
  ### Class template `unordered_multiset` <a id="unord.multiset">[[unord.multiset]]</a>
5736
 
5737
- #### Class template `unordered_multiset` overview <a id="unord.multiset.overview">[[unord.multiset.overview]]</a>
5738
 
5739
  An `unordered_multiset` is an unordered associative container that
5740
  supports equivalent keys (an instance of `unordered_multiset` may
5741
  contain multiple copies of the same key value) and in which each
5742
  element’s key is the element itself. The `unordered_multiset` class
5743
  supports forward iterators.
5744
 
5745
- An `unordered_multiset` satisfies all of the requirements of a
5746
- container, of an unordered associative container, and of an
5747
- allocator-aware container (Table  [[tab:containers.allocatoraware]]). It
5748
- provides the operations described in the preceding requirements table
5749
- for equivalent keys; that is, an `unordered_multiset` supports the
5750
- `a_eq` operations in that table, not the `a_uniq` operations. For an
5751
- `unordered_multiset<Key>` the `key type` and the value type are both
5752
- `Key`. The `iterator` and `const_iterator` types are both constant
5753
- iterator types. It is unspecified whether they are the same type.
5754
 
5755
- This section only describes operations on `unordered_multiset` that are
5756
- not described in one of the requirement tables, or for which there is
5757
- additional semantic information.
5758
 
5759
  ``` cpp
5760
  namespace std {
5761
  template<class Key,
5762
  class Hash = hash<Key>,
5763
  class Pred = equal_to<Key>,
5764
  class Allocator = allocator<Key>>
5765
  class unordered_multiset {
5766
  public:
5767
- // types:
5768
  using key_type = Key;
5769
  using value_type = Key;
5770
  using hasher = Hash;
5771
  using key_equal = Pred;
5772
  using allocator_type = Allocator;
@@ -5828,24 +5948,24 @@ namespace std {
5828
  is_nothrow_move_assignable_v<Hash> &&
5829
  is_nothrow_move_assignable_v<Pred>);
5830
  unordered_multiset& operator=(initializer_list<value_type>);
5831
  allocator_type get_allocator() const noexcept;
5832
 
5833
- // iterators:
5834
  iterator begin() noexcept;
5835
  const_iterator begin() const noexcept;
5836
  iterator end() noexcept;
5837
  const_iterator end() const noexcept;
5838
  const_iterator cbegin() const noexcept;
5839
  const_iterator cend() const noexcept;
5840
 
5841
- // capacity:
5842
- bool empty() const noexcept;
5843
  size_type size() const noexcept;
5844
  size_type max_size() const noexcept;
5845
 
5846
- // modifiers:
5847
  template<class... Args> iterator emplace(Args&&... args);
5848
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
5849
  iterator insert(const value_type& obj);
5850
  iterator insert(value_type&& obj);
5851
  iterator insert(const_iterator hint, const value_type& obj);
@@ -5875,22 +5995,35 @@ namespace std {
5875
  template<class H2, class P2>
5876
  void merge(unordered_set<Key, H2, P2, Allocator>& source);
5877
  template<class H2, class P2>
5878
  void merge(unordered_set<Key, H2, P2, Allocator>&& source);
5879
 
5880
- // observers:
5881
  hasher hash_function() const;
5882
  key_equal key_eq() const;
5883
 
5884
- // set operations:
5885
  iterator find(const key_type& k);
5886
  const_iterator find(const key_type& k) const;
 
 
 
 
5887
  size_type count(const key_type& k) const;
 
 
 
 
 
5888
  pair<iterator, iterator> equal_range(const key_type& k);
5889
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
 
 
 
 
5890
 
5891
- // bucket interface:
5892
  size_type bucket_count() const noexcept;
5893
  size_type max_bucket_count() const noexcept;
5894
  size_type bucket_size(size_type n) const;
5895
  size_type bucket(const key_type& k) const;
5896
  local_iterator begin(size_type n);
@@ -5898,75 +6031,68 @@ namespace std {
5898
  local_iterator end(size_type n);
5899
  const_local_iterator end(size_type n) const;
5900
  const_local_iterator cbegin(size_type n) const;
5901
  const_local_iterator cend(size_type n) const;
5902
 
5903
- // hash policy:
5904
  float load_factor() const noexcept;
5905
  float max_load_factor() const noexcept;
5906
  void max_load_factor(float z);
5907
  void rehash(size_type n);
5908
  void reserve(size_type n);
5909
  };
5910
 
5911
  template<class InputIterator,
5912
- class Hash = hash<typename iterator_traits<InputIterator>::value_type>,
5913
- class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>,
5914
- class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
5915
  unordered_multiset(InputIterator, InputIterator, see below::size_type = see below,
5916
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5917
- -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
5918
  Hash, Pred, Allocator>;
5919
 
5920
  template<class T, class Hash = hash<T>,
5921
  class Pred = equal_to<T>, class Allocator = allocator<T>>
5922
  unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
5923
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
5924
  -> unordered_multiset<T, Hash, Pred, Allocator>;
5925
 
5926
  template<class InputIterator, class Allocator>
5927
  unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator)
5928
- -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
5929
- hash<typename iterator_traits<InputIterator>::value_type>,
5930
- equal_to<typename iterator_traits<InputIterator>::value_type>,
5931
  Allocator>;
5932
 
5933
  template<class InputIterator, class Hash, class Allocator>
5934
  unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
5935
  Hash, Allocator)
5936
- -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash,
5937
- equal_to<typename iterator_traits<InputIterator>::value_type>,
5938
  Allocator>;
5939
 
5940
  template<class T, class Allocator>
5941
  unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
5942
  -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;
5943
 
5944
  template<class T, class Hash, class Allocator>
5945
  unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
5946
  -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;
5947
 
5948
- template <class Key, class Hash, class Pred, class Alloc>
5949
- bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
5950
- const unordered_multiset<Key, Hash, Pred, Alloc>& b);
5951
- template <class Key, class Hash, class Pred, class Alloc>
5952
- bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
5953
- const unordered_multiset<Key, Hash, Pred, Alloc>& b);
5954
-
5955
- // [unord.multiset.swap], swap
5956
  template<class Key, class Hash, class Pred, class Alloc>
5957
  void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
5958
  unordered_multiset<Key, Hash, Pred, Alloc>& y)
5959
  noexcept(noexcept(x.swap(y)));
5960
  }
5961
  ```
5962
 
5963
  A `size_type` parameter type in an `unordered_multiset` deduction guide
5964
- refers to the `size_type` member type of the primary
5965
- `unordered_multiset` template.
5966
 
5967
- #### `unordered_multiset` constructors <a id="unord.multiset.cnstr">[[unord.multiset.cnstr]]</a>
5968
 
5969
  ``` cpp
5970
  unordered_multiset() : unordered_multiset(size_type(see below)) { }
5971
  explicit unordered_multiset(size_type n,
5972
  const hasher& hf = hasher(),
@@ -6002,20 +6128,31 @@ hash function, key equality predicate, and allocator, and using at least
6002
  `l`) for the first form, or from the range \[`il.begin()`, `il.end()`)
6003
  for the second form. `max_load_factor()` returns `1.0`.
6004
 
6005
  *Complexity:* Average case linear, worst case quadratic.
6006
 
6007
- #### `unordered_multiset` swap <a id="unord.multiset.swap">[[unord.multiset.swap]]</a>
6008
 
6009
  ``` cpp
6010
- template <class Key, class Hash, class Pred, class Alloc>
6011
- void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
6012
- unordered_multiset<Key, Hash, Pred, Alloc>& y)
6013
- noexcept(noexcept(x.swap(y)));
6014
  ```
6015
 
6016
- *Effects:* As if by `x.swap(y)`.
 
 
 
 
 
 
 
 
 
 
 
 
6017
 
6018
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
6019
 
6020
  ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
6021
 
@@ -6050,70 +6187,88 @@ overload resolution if any of the following are true:
6050
  `uses_allocator_v<Container, Allocator>` is `false`.
6051
 
6052
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
6053
 
6054
  ``` cpp
6055
- #include <initializer_list>
 
6056
 
6057
  namespace std {
6058
  template<class T, class Container = deque<T>> class queue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6059
  template<class T, class Container = vector<T>,
6060
  class Compare = less<typename Container::value_type>>
6061
  class priority_queue;
6062
 
6063
- template <class T, class Container>
6064
- bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
6065
- template <class T, class Container>
6066
- bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
6067
- template <class T, class Container>
6068
- bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
6069
- template <class T, class Container>
6070
- bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
6071
- template <class T, class Container>
6072
- bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
6073
- template <class T, class Container>
6074
- bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
6075
-
6076
- template <class T, class Container>
6077
- void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
6078
  template<class T, class Container, class Compare>
6079
  void swap(priority_queue<T, Container, Compare>& x,
6080
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
 
 
6081
  }
6082
  ```
6083
 
6084
  ### Header `<stack>` synopsis <a id="stack.syn">[[stack.syn]]</a>
6085
 
6086
  ``` cpp
6087
- #include <initializer_list>
 
6088
 
6089
  namespace std {
6090
  template<class T, class Container = deque<T>> class stack;
 
6091
  template<class T, class Container>
6092
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
6093
- template <class T, class Container>
6094
- bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
6095
  template<class T, class Container>
6096
  bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
 
 
6097
  template<class T, class Container>
6098
  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
6099
- template <class T, class Container>
6100
- bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
6101
  template<class T, class Container>
6102
  bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
 
 
 
 
 
 
6103
  template<class T, class Container>
6104
  void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
 
6105
  }
6106
  ```
6107
 
6108
  ### Class template `queue` <a id="queue">[[queue]]</a>
6109
 
6110
- #### `queue` definition <a id="queue.defn">[[queue.defn]]</a>
6111
 
6112
  Any sequence container supporting operations `front()`, `back()`,
6113
  `push_back()` and `pop_front()` can be used to instantiate `queue`. In
6114
- particular, `list` ([[list]]) and `deque` ([[deque]]) can be used.
6115
 
6116
  ``` cpp
6117
  namespace std {
6118
  template<class T, class Container = deque<T>>
6119
  class queue {
@@ -6126,28 +6281,30 @@ namespace std {
6126
 
6127
  protected:
6128
  Container c;
6129
 
6130
  public:
 
6131
  explicit queue(const Container&);
6132
- explicit queue(Container&& = Container());
6133
  template<class Alloc> explicit queue(const Alloc&);
6134
  template<class Alloc> queue(const Container&, const Alloc&);
6135
  template<class Alloc> queue(Container&&, const Alloc&);
6136
  template<class Alloc> queue(const queue&, const Alloc&);
6137
  template<class Alloc> queue(queue&&, const Alloc&);
6138
 
6139
- bool empty() const { return c.empty(); }
6140
  size_type size() const { return c.size(); }
6141
  reference front() { return c.front(); }
6142
  const_reference front() const { return c.front(); }
6143
  reference back() { return c.back(); }
6144
  const_reference back() const { return c.back(); }
6145
  void push(const value_type& x) { c.push_back(x); }
6146
  void push(value_type&& x) { c.push_back(std::move(x)); }
6147
  template<class... Args>
6148
- reference emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); }
 
6149
  void pop() { c.pop_front(); }
6150
  void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
6151
  { using std::swap; swap(c, q.c); }
6152
  };
6153
 
@@ -6155,86 +6312,73 @@ namespace std {
6155
  queue(Container) -> queue<typename Container::value_type, Container>;
6156
 
6157
  template<class Container, class Allocator>
6158
  queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
6159
 
6160
- template <class T, class Container>
6161
- bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
6162
- template <class T, class Container>
6163
- bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
6164
- template <class T, class Container>
6165
- bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
6166
- template <class T, class Container>
6167
- bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
6168
- template <class T, class Container>
6169
- bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
6170
- template <class T, class Container>
6171
- bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
6172
-
6173
  template<class T, class Container>
6174
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
6175
 
6176
  template<class T, class Container, class Alloc>
6177
  struct uses_allocator<queue<T, Container>, Alloc>
6178
  : uses_allocator<Container, Alloc>::type { };
6179
  }
6180
  ```
6181
 
6182
- #### `queue` constructors <a id="queue.cons">[[queue.cons]]</a>
6183
 
6184
  ``` cpp
6185
  explicit queue(const Container& cont);
6186
  ```
6187
 
6188
- *Effects:*  Initializes `c` with `cont`.
6189
 
6190
  ``` cpp
6191
- explicit queue(Container&& cont = Container());
6192
  ```
6193
 
6194
- *Effects:*  Initializes `c` with `std::move(cont)`.
6195
 
6196
- #### `queue` constructors with allocators <a id="queue.cons.alloc">[[queue.cons.alloc]]</a>
6197
 
6198
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6199
  in this subclause shall not participate in overload resolution.
6200
 
6201
  ``` cpp
6202
  template<class Alloc> explicit queue(const Alloc& a);
6203
  ```
6204
 
6205
- *Effects:*  Initializes `c` with `a`.
6206
 
6207
  ``` cpp
6208
  template<class Alloc> queue(const container_type& cont, const Alloc& a);
6209
  ```
6210
 
6211
- *Effects:*  Initializes `c` with `cont` as the first argument and `a` as
6212
  the second argument.
6213
 
6214
  ``` cpp
6215
  template<class Alloc> queue(container_type&& cont, const Alloc& a);
6216
  ```
6217
 
6218
- *Effects:*  Initializes `c` with `std::move(cont)` as the first argument
6219
  and `a` as the second argument.
6220
 
6221
  ``` cpp
6222
  template<class Alloc> queue(const queue& q, const Alloc& a);
6223
  ```
6224
 
6225
- *Effects:*  Initializes `c` with `q.c` as the first argument and `a` as
6226
  the second argument.
6227
 
6228
  ``` cpp
6229
  template<class Alloc> queue(queue&& q, const Alloc& a);
6230
  ```
6231
 
6232
- *Effects:*  Initializes `c` with `std::move(q.c)` as the first argument
6233
  and `a` as the second argument.
6234
 
6235
- #### `queue` operators <a id="queue.ops">[[queue.ops]]</a>
6236
 
6237
  ``` cpp
6238
  template<class T, class Container>
6239
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
6240
  ```
@@ -6253,53 +6397,62 @@ template <class T, class Container>
6253
  bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
6254
  ```
6255
 
6256
  *Returns:* `x.c < y.c`.
6257
 
6258
- ``` cpp
6259
- template <class T, class Container>
6260
- bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
6261
- ```
6262
-
6263
- *Returns:* `x.c <= y.c`.
6264
-
6265
  ``` cpp
6266
  template<class T, class Container>
6267
  bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
6268
  ```
6269
 
6270
  *Returns:* `x.c > y.c`.
6271
 
 
 
 
 
 
 
 
6272
  ``` cpp
6273
  template<class T, class Container>
6274
  bool operator>=(const queue<T, Container>& x,
6275
  const queue<T, Container>& y);
6276
  ```
6277
 
6278
  *Returns:* `x.c >= y.c`.
6279
 
6280
- #### `queue` specialized algorithms <a id="queue.special">[[queue.special]]</a>
 
 
 
 
 
 
 
 
6281
 
6282
  ``` cpp
6283
  template<class T, class Container>
6284
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
6285
  ```
6286
 
6287
- *Remarks:* This function shall not participate in overload resolution
6288
- unless `is_swappable_v<Container>` is `true`.
6289
 
6290
  *Effects:* As if by `x.swap(y)`.
6291
 
6292
  ### Class template `priority_queue` <a id="priority.queue">[[priority.queue]]</a>
6293
 
 
 
6294
  Any sequence container with random access iterator and supporting
6295
  operations `front()`, `push_back()` and `pop_back()` can be used to
6296
- instantiate `priority_queue`. In particular, `vector` ([[vector]]) and
6297
- `deque` ([[deque]]) can be used. Instantiating `priority_queue` also
6298
  involves supplying a function or function object for making priority
6299
  comparisons; the library assumes that the function or function object
6300
- defines a strict weak ordering ([[alg.sorting]]).
6301
 
6302
  ``` cpp
6303
  namespace std {
6304
  template<class T, class Container = vector<T>,
6305
  class Compare = less<typename Container::value_type>>
@@ -6315,26 +6468,28 @@ namespace std {
6315
  protected:
6316
  Container c;
6317
  Compare comp;
6318
 
6319
  public:
 
 
6320
  priority_queue(const Compare& x, const Container&);
6321
- explicit priority_queue(const Compare& x = Compare(), Container&& = Container());
6322
  template<class InputIterator>
6323
- priority_queue(InputIterator first, InputIterator last,
6324
- const Compare& x, const Container&);
6325
  template<class InputIterator>
6326
  priority_queue(InputIterator first, InputIterator last,
6327
  const Compare& x = Compare(), Container&& = Container());
6328
  template<class Alloc> explicit priority_queue(const Alloc&);
6329
  template<class Alloc> priority_queue(const Compare&, const Alloc&);
6330
  template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
6331
  template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
6332
  template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
6333
  template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
6334
 
6335
- bool empty() const { return c.empty(); }
6336
  size_type size() const { return c.size(); }
6337
  const_reference top() const { return c.front(); }
6338
  void push(const value_type& x);
6339
  void push(value_type&& x);
6340
  template<class... Args> void emplace(Args&&... args);
@@ -6368,93 +6523,90 @@ namespace std {
6368
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
6369
  : uses_allocator<Container, Alloc>::type { };
6370
  }
6371
  ```
6372
 
6373
- #### `priority_queue` constructors <a id="priqueue.cons">[[priqueue.cons]]</a>
6374
 
6375
  ``` cpp
6376
  priority_queue(const Compare& x, const Container& y);
6377
- explicit priority_queue(const Compare& x = Compare(), Container&& y = Container());
6378
  ```
6379
 
6380
- *Requires:* `x` shall define a strict weak ordering ([[alg.sorting]]).
6381
 
6382
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
6383
  constructing or move constructing as appropriate); calls
6384
  `make_heap(c.begin(), c.end(), comp)`.
6385
 
6386
  ``` cpp
6387
  template<class InputIterator>
6388
- priority_queue(InputIterator first, InputIterator last,
6389
- const Compare& x,
6390
- const Container& y);
6391
  template<class InputIterator>
6392
- priority_queue(InputIterator first, InputIterator last,
6393
- const Compare& x = Compare(),
6394
  Container&& y = Container());
6395
  ```
6396
 
6397
- *Requires:* `x` shall define a strict weak ordering ([[alg.sorting]]).
6398
 
6399
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
6400
  constructing or move constructing as appropriate); calls
6401
  `c.insert(c.end(), first, last)`; and finally calls
6402
  `make_heap(c.begin(), c.end(), comp)`.
6403
 
6404
- #### `priority_queue` constructors with allocators <a id="priqueue.cons.alloc">[[priqueue.cons.alloc]]</a>
6405
 
6406
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6407
  in this subclause shall not participate in overload resolution.
6408
 
6409
  ``` cpp
6410
  template<class Alloc> explicit priority_queue(const Alloc& a);
6411
  ```
6412
 
6413
- *Effects:*  Initializes `c` with `a` and value-initializes `comp`.
6414
 
6415
  ``` cpp
6416
  template<class Alloc> priority_queue(const Compare& compare, const Alloc& a);
6417
  ```
6418
 
6419
- *Effects:*  Initializes `c` with `a` and initializes `comp` with
6420
  `compare`.
6421
 
6422
  ``` cpp
6423
  template<class Alloc>
6424
  priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
6425
  ```
6426
 
6427
- *Effects:*  Initializes `c` with `cont` as the first argument and `a` as
6428
  the second argument, and initializes `comp` with `compare`; calls
6429
  `make_heap(c.begin(), c.end(), comp)`.
6430
 
6431
  ``` cpp
6432
  template<class Alloc>
6433
  priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
6434
  ```
6435
 
6436
- *Effects:*  Initializes `c` with `std::move(cont)` as the first argument
6437
  and `a` as the second argument, and initializes `comp` with `compare`;
6438
  calls `make_heap(c.begin(), c.end(), comp)`.
6439
 
6440
  ``` cpp
6441
  template<class Alloc> priority_queue(const priority_queue& q, const Alloc& a);
6442
  ```
6443
 
6444
- *Effects:*  Initializes `c` with `q.c` as the first argument and `a` as
6445
  the second argument, and initializes `comp` with `q.comp`.
6446
 
6447
  ``` cpp
6448
  template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
6449
  ```
6450
 
6451
- *Effects:*  Initializes `c` with `std::move(q.c)` as the first argument
6452
  and `a` as the second argument, and initializes `comp` with
6453
  `std::move(q.comp)`.
6454
 
6455
- #### `priority_queue` members <a id="priqueue.members">[[priqueue.members]]</a>
6456
 
6457
  ``` cpp
6458
  void push(const value_type& x);
6459
  ```
6460
 
@@ -6475,11 +6627,11 @@ void push(value_type&& x);
6475
  c.push_back(std::move(x));
6476
  push_heap(c.begin(), c.end(), comp);
6477
  ```
6478
 
6479
  ``` cpp
6480
- template <class... Args> void emplace(Args&&... args)
6481
  ```
6482
 
6483
  *Effects:* As if by:
6484
 
6485
  ``` cpp
@@ -6496,32 +6648,30 @@ void pop();
6496
  ``` cpp
6497
  pop_heap(c.begin(), c.end(), comp);
6498
  c.pop_back();
6499
  ```
6500
 
6501
- #### `priority_queue` specialized algorithms <a id="priqueue.special">[[priqueue.special]]</a>
6502
 
6503
  ``` cpp
6504
  template<class T, class Container, class Compare>
6505
  void swap(priority_queue<T, Container, Compare>& x,
6506
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
6507
  ```
6508
 
6509
- *Remarks:* This function shall not participate in overload resolution
6510
- unless `is_swappable_v<Container>` is `true` and
6511
  `is_swappable_v<Compare>` is `true`.
6512
 
6513
  *Effects:* As if by `x.swap(y)`.
6514
 
6515
  ### Class template `stack` <a id="stack">[[stack]]</a>
6516
 
6517
  Any sequence container supporting operations `back()`, `push_back()` and
6518
- `pop_back()` can be used to instantiate `stack`. In particular,
6519
- `vector` ([[vector]]), `list` ([[list]]) and `deque` ([[deque]]) can
6520
- be used.
6521
 
6522
- #### `stack` definition <a id="stack.defn">[[stack.defn]]</a>
6523
 
6524
  ``` cpp
6525
  namespace std {
6526
  template<class T, class Container = deque<T>>
6527
  class stack {
@@ -6534,26 +6684,28 @@ namespace std {
6534
 
6535
  protected:
6536
  Container c;
6537
 
6538
  public:
 
6539
  explicit stack(const Container&);
6540
- explicit stack(Container&& = Container());
6541
  template<class Alloc> explicit stack(const Alloc&);
6542
  template<class Alloc> stack(const Container&, const Alloc&);
6543
  template<class Alloc> stack(Container&&, const Alloc&);
6544
  template<class Alloc> stack(const stack&, const Alloc&);
6545
  template<class Alloc> stack(stack&&, const Alloc&);
6546
 
6547
- bool empty() const { return c.empty(); }
6548
  size_type size() const { return c.size(); }
6549
  reference top() { return c.back(); }
6550
  const_reference top() const { return c.back(); }
6551
  void push(const value_type& x) { c.push_back(x); }
6552
  void push(value_type&& x) { c.push_back(std::move(x)); }
6553
  template<class... Args>
6554
- reference emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); }
 
6555
  void pop() { c.pop_back(); }
6556
  void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
6557
  { using std::swap; swap(c, s.c); }
6558
  };
6559
 
@@ -6561,85 +6713,70 @@ namespace std {
6561
  stack(Container) -> stack<typename Container::value_type, Container>;
6562
 
6563
  template<class Container, class Allocator>
6564
  stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
6565
 
6566
- template <class T, class Container>
6567
- bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
6568
- template <class T, class Container>
6569
- bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
6570
- template <class T, class Container>
6571
- bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
6572
- template <class T, class Container>
6573
- bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
6574
- template <class T, class Container>
6575
- bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
6576
- template <class T, class Container>
6577
- bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
6578
- template <class T, class Container>
6579
- void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
6580
-
6581
  template<class T, class Container, class Alloc>
6582
  struct uses_allocator<stack<T, Container>, Alloc>
6583
  : uses_allocator<Container, Alloc>::type { };
6584
  }
6585
  ```
6586
 
6587
- #### `stack` constructors <a id="stack.cons">[[stack.cons]]</a>
6588
 
6589
  ``` cpp
6590
  explicit stack(const Container& cont);
6591
  ```
6592
 
6593
  *Effects:* Initializes `c` with `cont`.
6594
 
6595
  ``` cpp
6596
- explicit stack(Container&& cont = Container());
6597
  ```
6598
 
6599
  *Effects:* Initializes `c` with `std::move(cont)`.
6600
 
6601
- #### `stack` constructors with allocators <a id="stack.cons.alloc">[[stack.cons.alloc]]</a>
6602
 
6603
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
6604
  in this subclause shall not participate in overload resolution.
6605
 
6606
  ``` cpp
6607
  template<class Alloc> explicit stack(const Alloc& a);
6608
  ```
6609
 
6610
- *Effects:*  Initializes `c` with `a`.
6611
 
6612
  ``` cpp
6613
  template<class Alloc> stack(const container_type& cont, const Alloc& a);
6614
  ```
6615
 
6616
- *Effects:*  Initializes `c` with `cont` as the first argument and `a` as
6617
  the second argument.
6618
 
6619
  ``` cpp
6620
  template<class Alloc> stack(container_type&& cont, const Alloc& a);
6621
  ```
6622
 
6623
- *Effects:*  Initializes `c` with `std::move(cont)` as the first argument
6624
  and `a` as the second argument.
6625
 
6626
  ``` cpp
6627
  template<class Alloc> stack(const stack& s, const Alloc& a);
6628
  ```
6629
 
6630
- *Effects:*  Initializes `c` with `s.c` as the first argument and `a` as
6631
  the second argument.
6632
 
6633
  ``` cpp
6634
  template<class Alloc> stack(stack&& s, const Alloc& a);
6635
  ```
6636
 
6637
- *Effects:*  Initializes `c` with `std::move(s.c)` as the first argument
6638
  and `a` as the second argument.
6639
 
6640
- #### `stack` operators <a id="stack.ops">[[stack.ops]]</a>
6641
 
6642
  ``` cpp
6643
  template<class T, class Container>
6644
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
6645
  ```
@@ -6658,133 +6795,660 @@ template <class T, class Container>
6658
  bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
6659
  ```
6660
 
6661
  *Returns:* `x.c < y.c`.
6662
 
6663
- ``` cpp
6664
- template <class T, class Container>
6665
- bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
6666
- ```
6667
-
6668
- *Returns:* `x.c <= y.c`.
6669
-
6670
  ``` cpp
6671
  template<class T, class Container>
6672
  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
6673
  ```
6674
 
6675
  *Returns:* `x.c > y.c`.
6676
 
 
 
 
 
 
 
 
6677
  ``` cpp
6678
  template<class T, class Container>
6679
  bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
6680
  ```
6681
 
6682
  *Returns:* `x.c >= y.c`.
6683
 
6684
- #### `stack` specialized algorithms <a id="stack.special">[[stack.special]]</a>
 
 
 
 
 
 
 
 
6685
 
6686
  ``` cpp
6687
  template<class T, class Container>
6688
  void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
6689
  ```
6690
 
6691
- *Remarks:* This function shall not participate in overload resolution
6692
- unless `is_swappable_v<Container>` is `true`.
6693
 
6694
  *Effects:* As if by `x.swap(y)`.
6695
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6696
  <!-- Link reference definitions -->
6697
  [alg.sorting]: algorithms.md#alg.sorting
6698
  [algorithm.stable]: library.md#algorithm.stable
6699
  [algorithms]: algorithms.md#algorithms
 
6700
  [allocator.requirements]: library.md#allocator.requirements
6701
  [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
6702
  [allocator.traits.members]: utilities.md#allocator.traits.members
6703
  [array]: #array
6704
  [array.cons]: #array.cons
6705
- [array.data]: #array.data
6706
- [array.fill]: #array.fill
6707
  [array.overview]: #array.overview
6708
- [array.size]: #array.size
6709
  [array.special]: #array.special
6710
- [array.swap]: #array.swap
6711
  [array.syn]: #array.syn
6712
  [array.tuple]: #array.tuple
6713
  [array.zero]: #array.zero
6714
  [associative]: #associative
6715
  [associative.general]: #associative.general
6716
  [associative.map.syn]: #associative.map.syn
6717
  [associative.reqmts]: #associative.reqmts
6718
  [associative.reqmts.except]: #associative.reqmts.except
6719
  [associative.set.syn]: #associative.set.syn
6720
  [basic.string]: strings.md#basic.string
6721
- [class.copy]: special.md#class.copy
6722
- [class.ctor]: special.md#class.ctor
6723
- [class.dtor]: special.md#class.dtor
6724
  [container.adaptors]: #container.adaptors
6725
  [container.adaptors.general]: #container.adaptors.general
 
 
 
6726
  [container.insert.return]: #container.insert.return
6727
  [container.node]: #container.node
 
6728
  [container.node.cons]: #container.node.cons
6729
  [container.node.dtor]: #container.node.dtor
6730
  [container.node.modifiers]: #container.node.modifiers
6731
  [container.node.observers]: #container.node.observers
6732
  [container.node.overview]: #container.node.overview
 
 
6733
  [container.requirements]: #container.requirements
6734
  [container.requirements.dataraces]: #container.requirements.dataraces
6735
  [container.requirements.general]: #container.requirements.general
 
 
 
6736
  [containers]: #containers
6737
  [containers.general]: #containers.general
 
6738
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
6739
  [deque]: #deque
6740
  [deque.capacity]: #deque.capacity
6741
  [deque.cons]: #deque.cons
 
6742
  [deque.modifiers]: #deque.modifiers
6743
  [deque.overview]: #deque.overview
6744
- [deque.special]: #deque.special
6745
  [deque.syn]: #deque.syn
6746
- [forward.iterators]: iterators.md#forward.iterators
6747
- [forward_list.syn]: #forward_list.syn
6748
  [forwardlist]: #forwardlist
6749
  [forwardlist.access]: #forwardlist.access
6750
  [forwardlist.cons]: #forwardlist.cons
6751
  [forwardlist.iter]: #forwardlist.iter
6752
  [forwardlist.modifiers]: #forwardlist.modifiers
6753
  [forwardlist.ops]: #forwardlist.ops
6754
  [forwardlist.overview]: #forwardlist.overview
6755
- [forwardlist.spec]: #forwardlist.spec
6756
  [hash.requirements]: library.md#hash.requirements
 
6757
  [iterator.requirements]: iterators.md#iterator.requirements
6758
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
6759
  [list]: #list
6760
  [list.capacity]: #list.capacity
6761
  [list.cons]: #list.cons
 
6762
  [list.modifiers]: #list.modifiers
6763
  [list.ops]: #list.ops
6764
  [list.overview]: #list.overview
6765
- [list.special]: #list.special
6766
  [list.syn]: #list.syn
6767
  [map]: #map
6768
  [map.access]: #map.access
6769
  [map.cons]: #map.cons
 
6770
  [map.modifiers]: #map.modifiers
6771
  [map.overview]: #map.overview
6772
- [map.special]: #map.special
6773
  [multimap]: #multimap
6774
  [multimap.cons]: #multimap.cons
 
6775
  [multimap.modifiers]: #multimap.modifiers
6776
  [multimap.overview]: #multimap.overview
6777
- [multimap.special]: #multimap.special
6778
  [multiset]: #multiset
6779
  [multiset.cons]: #multiset.cons
 
6780
  [multiset.overview]: #multiset.overview
6781
- [multiset.special]: #multiset.special
6782
  [priority.queue]: #priority.queue
6783
  [priqueue.cons]: #priqueue.cons
6784
  [priqueue.cons.alloc]: #priqueue.cons.alloc
6785
  [priqueue.members]: #priqueue.members
 
6786
  [priqueue.special]: #priqueue.special
6787
  [queue]: #queue
6788
  [queue.cons]: #queue.cons
6789
  [queue.cons.alloc]: #queue.cons.alloc
6790
  [queue.defn]: #queue.defn
@@ -6796,67 +7460,76 @@ unless `is_swappable_v<Container>` is `true`.
6796
  [sequence.reqmts]: #sequence.reqmts
6797
  [sequences]: #sequences
6798
  [sequences.general]: #sequences.general
6799
  [set]: #set
6800
  [set.cons]: #set.cons
 
6801
  [set.overview]: #set.overview
6802
- [set.special]: #set.special
 
 
 
 
 
 
 
 
6803
  [stack]: #stack
6804
  [stack.cons]: #stack.cons
6805
  [stack.cons.alloc]: #stack.cons.alloc
6806
  [stack.defn]: #stack.defn
6807
  [stack.ops]: #stack.ops
6808
  [stack.special]: #stack.special
6809
  [stack.syn]: #stack.syn
6810
  [strings]: strings.md#strings
6811
  [swappable.requirements]: library.md#swappable.requirements
6812
- [tab:HashRequirements]: #tab:HashRequirements
6813
- [tab:containers.allocatoraware]: #tab:containers.allocatoraware
6814
- [tab:containers.associative.requirements]: #tab:containers.associative.requirements
6815
- [tab:containers.container.requirements]: #tab:containers.container.requirements
6816
- [tab:containers.lib.summary]: #tab:containers.lib.summary
6817
- [tab:containers.node.compat]: #tab:containers.node.compat
6818
- [tab:containers.optional.operations]: #tab:containers.optional.operations
6819
- [tab:containers.reversible.requirements]: #tab:containers.reversible.requirements
6820
- [tab:containers.sequence.optional]: #tab:containers.sequence.optional
6821
- [tab:containers.sequence.requirements]: #tab:containers.sequence.requirements
6822
  [temp.deduct]: temp.md#temp.deduct
 
 
6823
  [unord]: #unord
6824
  [unord.general]: #unord.general
6825
  [unord.hash]: utilities.md#unord.hash
6826
  [unord.map]: #unord.map
6827
  [unord.map.cnstr]: #unord.map.cnstr
6828
  [unord.map.elem]: #unord.map.elem
 
6829
  [unord.map.modifiers]: #unord.map.modifiers
6830
  [unord.map.overview]: #unord.map.overview
6831
- [unord.map.swap]: #unord.map.swap
6832
  [unord.map.syn]: #unord.map.syn
6833
  [unord.multimap]: #unord.multimap
6834
  [unord.multimap.cnstr]: #unord.multimap.cnstr
 
6835
  [unord.multimap.modifiers]: #unord.multimap.modifiers
6836
  [unord.multimap.overview]: #unord.multimap.overview
6837
- [unord.multimap.swap]: #unord.multimap.swap
6838
  [unord.multiset]: #unord.multiset
6839
  [unord.multiset.cnstr]: #unord.multiset.cnstr
 
6840
  [unord.multiset.overview]: #unord.multiset.overview
6841
- [unord.multiset.swap]: #unord.multiset.swap
6842
  [unord.req]: #unord.req
6843
  [unord.req.except]: #unord.req.except
6844
  [unord.set]: #unord.set
6845
  [unord.set.cnstr]: #unord.set.cnstr
 
6846
  [unord.set.overview]: #unord.set.overview
6847
- [unord.set.swap]: #unord.set.swap
6848
  [unord.set.syn]: #unord.set.syn
6849
  [vector]: #vector
6850
  [vector.bool]: #vector.bool
6851
  [vector.capacity]: #vector.capacity
6852
  [vector.cons]: #vector.cons
6853
  [vector.data]: #vector.data
 
6854
  [vector.modifiers]: #vector.modifiers
6855
  [vector.overview]: #vector.overview
6856
- [vector.special]: #vector.special
6857
  [vector.syn]: #vector.syn
 
 
 
6858
 
6859
  [^1]: Equality comparison is a refinement of partitioning if no two
6860
  objects that compare equal fall into different partitions.
6861
 
6862
  [^2]: These member functions are only provided by containers whose
 
5
  This Clause describes components that C++ programs may use to organize
6
  collections of information.
7
 
8
  The following subclauses describe container requirements, and components
9
  for sequence containers and associative containers, as summarized in
10
+ [[containers.summary]].
11
 
12
+ **Table: Containers library summary** <a id="containers.summary">[containers.summary]</a>
13
 
14
  | Subclause | | Header |
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>
 
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.
 
81
  i != j
82
  i < j
83
  i <= j
84
  i >= j
85
  i > j
86
+ i <=> j
87
  i - j
88
  ```
89
 
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
 
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
 
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:
 
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
180
  container.
181
 
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)
215
  ```
216
  - An element of `X` is *default-inserted* if it is initialized by
 
219
  allocator_traits<A>::construct(m, p)
220
  ```
221
 
222
  where `p` is the address of the uninitialized storage for the element
223
  allocated within `X`.
224
+ - `T` is **Cpp17MoveInsertable* into `X`* means that the following
225
+ expression is well-formed:
226
  ``` cpp
227
  allocator_traits<A>::construct(m, p, rv)
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
239
  allocator_traits<A>::construct(m, p, v)
240
  ```
241
 
242
  and its evaluation causes the following postcondition to hold: The
243
  value of `v` is unchanged and is equivalent to `*p`.
244
+ - `T` is **Cpp17EmplaceConstructible* into `X` from `args`*, for zero or
245
+ more arguments `args`, means that the following expression is
246
+ well-formed:
247
  ``` cpp
248
  allocator_traits<A>::construct(m, p, args)
249
  ```
250
+ - `T` is **Cpp17Erasable* from `X`* means that the following expression
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`:
286
  `begin`, `end`, `rbegin`, `rend`, `front`, `back`, `data`, `find`,
287
  `lower_bound`, `upper_bound`, `equal_range`, `at` and, except in
288
  associative or unordered associative containers, `operator[]`.
289
 
 
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`.
 
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
377
  template<class InputIterator>
378
  X(InputIterator first, InputIterator last,
 
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
 
421
  A *node handle* is an object that accepts ownership of a single element
422
+ from an associative container [[associative.reqmts]] or an unordered
423
+ associative container [[unord.req]]. It may be used to transfer that
424
  ownership to another container with compatible nodes. Containers with
425
  compatible nodes have the same node handle type. Elements may be
426
  transferred in either direction between container types in the same row
427
+ of [[container.node.compat]].
428
 
429
+ **Table: Container types with compatible nodes** <a id="container.node.compat">[container.node.compat]</a>
430
 
431
  | | |
432
  | -------------------------------- | ------------------------------------- |
433
  | `map<K, T, C1, A>` | `map<K, T, C2, A>` |
434
  | `map<K, T, C1, A>` | `multimap<K, T, C2, A>` |
 
442
 
443
  If a node handle is not empty, then it contains an allocator that is
444
  equal to the allocator of the container when the element was extracted.
445
  If a node handle is empty, it contains no allocator.
446
 
447
+ Class *`node-handle`* is for exposition only.
 
 
448
 
449
  If a user-defined specialization of `pair` exists for
450
  `pair<const Key, T>` or `pair<Key, T>`, where `Key` is the container’s
451
  `key_type` and `T` is the container’s `mapped_type`, the behavior of
452
  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;
475
+ node-handle& operator=(node-handle&&);
476
 
477
+ // [container.node.dtor], destructor
478
+ ~node-handle();
479
+
480
+ // [container.node.observers], observers
481
  value_type& value() const; // not present for map containers
482
  key_type& key() const; // not present for set containers
483
  mapped_type& mapped() const; // not present for set containers
484
 
485
  allocator_type get_allocator() const;
486
  explicit operator bool() const noexcept;
487
+ [[nodiscard]] bool empty() const noexcept;
488
 
489
+ // [container.node.modifiers], modifiers
490
+ void swap(node-handle&)
491
  noexcept(ator_traits::propagate_on_container_swap::value ||
492
  ator_traits::is_always_equal::value);
493
 
494
+ friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
495
  x.swap(y);
496
  }
497
  };
498
  ```
499
 
500
+ #### Constructors, copy, and assignment <a id="container.node.cons">[[container.node.cons]]</a>
501
 
502
  ``` cpp
503
+ node-handle(node-handle&& nh) noexcept;
504
  ```
505
 
506
+ *Effects:* Constructs a *node-handle* object initializing `ptr_` with
507
  `nh.ptr_`. Move constructs `alloc_` with `nh.alloc_`. Assigns `nullptr`
508
  to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
509
 
510
  ``` cpp
511
+ node-handle& operator=(node-handle&& nh);
512
  ```
513
 
514
+ *Preconditions:* Either `!alloc_`, or
515
+ `ator_traits::propagate_on_container_move_assignment::value` is `true`,
516
+ or `alloc_ == nh.alloc_`.
517
 
518
  *Effects:*
519
 
520
  - If `ptr_ != nullptr`, destroys the `value_type` subobject in the
521
  `container_node_type` object pointed to by `ptr_` by calling
522
  `ator_traits::destroy`, then deallocates `ptr_` by calling
523
+ `ator_traits::template rebind_traits<container_node_type>::deallocate`.
524
  - Assigns `nh.ptr_` to `ptr_`.
525
+ - If `!alloc` or
526
+ `ator_traits::propagate_on_container_move_assignment::value` is
527
+ `true`, move assigns `nh.alloc_` to `alloc_`.
528
  - Assigns `nullptr` to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
529
 
530
  *Returns:* `*this`.
531
 
532
  *Throws:* Nothing.
533
 
534
+ #### Destructor <a id="container.node.dtor">[[container.node.dtor]]</a>
535
 
536
  ``` cpp
537
+ ~node-handle();
538
  ```
539
 
540
  *Effects:* If `ptr_ != nullptr`, destroys the `value_type` subobject in
541
  the `container_node_type` object pointed to by `ptr_` by calling
542
  `ator_traits::destroy`, then deallocates `ptr_` by calling
543
+ `ator_traits::template rebind_traits<container_node_type>::deallocate`.
544
 
545
+ #### Observers <a id="container.node.observers">[[container.node.observers]]</a>
546
 
547
  ``` cpp
548
  value_type& value() const;
549
  ```
550
 
551
+ *Preconditions:* `empty() == false`.
552
 
553
  *Returns:* A reference to the `value_type` subobject in the
554
  `container_node_type` object pointed to by `ptr_`.
555
 
556
  *Throws:* Nothing.
557
 
558
  ``` cpp
559
  key_type& key() const;
560
  ```
561
 
562
+ *Preconditions:* `empty() == false`.
563
 
564
  *Returns:* A non-const reference to the `key_type` member of the
565
  `value_type` subobject in the `container_node_type` object pointed to by
566
  `ptr_`.
567
 
 
572
 
573
  ``` cpp
574
  mapped_type& mapped() const;
575
  ```
576
 
577
+ *Preconditions:* `empty() == false`.
578
 
579
  *Returns:* A reference to the `mapped_type` member of the `value_type`
580
  subobject in the `container_node_type` object pointed to by `ptr_`.
581
 
582
  *Throws:* Nothing.
583
 
584
  ``` cpp
585
  allocator_type get_allocator() const;
586
  ```
587
 
588
+ *Preconditions:* `empty() == false`.
589
 
590
  *Returns:* `*alloc_`.
591
 
592
  *Throws:* Nothing.
593
 
 
596
  ```
597
 
598
  *Returns:* `ptr_ != nullptr`.
599
 
600
  ``` cpp
601
+ [[nodiscard]] bool empty() const noexcept;
602
  ```
603
 
604
  *Returns:* `ptr_ == nullptr`.
605
 
606
+ #### Modifiers <a id="container.node.modifiers">[[container.node.modifiers]]</a>
607
 
608
  ``` cpp
609
+ void swap(node-handle& nh)
610
  noexcept(ator_traits::propagate_on_container_swap::value ||
611
  ator_traits::is_always_equal::value);
612
  ```
613
 
614
+ *Preconditions:* `!alloc_`, or `!nh.alloc_`, or
615
+ `ator_traits::propagate_on_container_swap::value` is `true`, or
616
  `alloc_ == nh.alloc_`.
617
 
618
  *Effects:* Calls `swap(ptr_, nh.ptr_)`. If `!alloc_`, or `!nh.alloc_`,
619
+ or `ator_traits::propagate_on_container_swap::value` is `true` calls
620
  `swap(alloc_, nh.alloc_)`.
621
 
622
  ### Insert return type <a id="container.insert.return">[[container.insert.return]]</a>
623
 
624
  The associative containers with unique keys and the unordered containers
625
  with unique keys have a member function `insert` that returns a nested
626
  type `insert_return_type`. That return type is a specialization of the
627
+ template specified in this subclause.
628
 
629
  ``` cpp
630
  template<class Iterator, class NodeType>
631
+ struct insert-return-type
632
  {
633
  Iterator position;
634
  bool inserted;
635
  NodeType node;
636
  };
637
  ```
638
 
639
+ The name *`insert-return-type`* is exposition only.
640
+ *`insert-return-type`* has the template parameters, data members, and
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`
654
+ is called the *comparison object* of a container.
655
 
656
  The phrase “equivalence of keys” means the equivalence relation imposed
657
+ by the comparison object. That is, two keys `k1` and `k2` are considered
658
+ to be equivalent if for the comparison object `comp`,
659
+ `comp(k1, k2) == false && comp(k2, k1) == false`.
660
+
661
+ [*Note 1*: This is not necessarily the same as the result of
662
+ `k1 == k2`. — *end note*]
663
+
664
+ For any two keys `k1` and `k2` in the same container, calling
665
+ `comp(k1, k2)` shall always return the same value.
666
 
667
  An associative container supports *unique keys* if it may contain at
668
  most one element for each key. Otherwise, it supports *equivalent keys*.
669
  The `set` and `map` classes support unique keys; the `multiset` and
670
  `multimap` classes support equivalent keys. For `multiset` and
 
680
  For associative containers where the value type is the same as the key
681
  type, both `iterator` and `const_iterator` are constant iterators. It is
682
  unspecified whether or not `iterator` and `const_iterator` are the same
683
  type.
684
 
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>`
 
754
  ```
755
 
756
  When an associative container is constructed by passing a comparison
757
  object the container shall not store a pointer or reference to the
758
  passed object, even if that object is passed by reference. When an
759
+ 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
 
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`.
800
 
801
  Unordered associative containers conform to the requirements for
802
+ Containers [[container.requirements]], except that the expressions
803
  `a == b` and `a != b` have different semantics than for the other
804
  container types.
805
 
806
  Each unordered associative container is parameterized by `Key`, by a
807
+ function object type `Hash` that meets the *Cpp17Hash* requirements
808
+ [[hash.requirements]] and acts as a hash function for argument values of
809
+ type `Key`, and by a binary predicate `Pred` that induces an equivalence
810
+ relation on values of type `Key`. Additionally, `unordered_map` and
811
+ `unordered_multimap` associate an arbitrary *mapped type* `T` with the
812
+ `Key`.
813
 
814
  The container’s object of type `Hash` — denoted by `hash` — is called
815
  the *hash function* of the container. The container’s object of type
816
  `Pred` — denoted by `pred` — is called the *key equality predicate* of
817
  the container.
818
 
819
+ Two values `k1` and `k2` are considered equivalent if the container’s
820
+ key equality predicate `pred(k1, k2)` is valid and returns `true` when
821
+ passed those values. If `k1` and `k2` are equivalent, the container’s
822
+ hash function shall return the same value for both.
823
 
824
  [*Note 1*: Thus, when an unordered associative container is
825
  instantiated with a non-default `Pred` parameter it usually needs a
826
  non-default `Hash` parameter as well. — *end note*]
827
 
 
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)`,
919
  such that `is_permutation(Ea1, Ea2, Eb1, Eb2)` returns `true`. For
920
  `unordered_set` and `unordered_map`, the complexity of `operator==`
921
  (i.e., the number of calls to the `==` operator of the `value_type`, to
922
  the predicate returned by `key_eq()`, and to the hasher returned by
923
  `hash_function()`) is proportional to N in the average case and to N² in
924
+ the worst case, where N is `a.size()`. For `unordered_multiset` and
925
  `unordered_multimap`, the complexity of `operator==` is proportional to
926
  $\sum E_i^2$ in the average case and to N² in the worst case, where N is
927
  `a.size()`, and Eᵢ is the size of the iᵗʰ equivalent-key group in `a`.
928
  However, if the respective elements of each corresponding pair of
929
  equivalent-key groups Eaᵢ and Ebᵢ are arranged in the same order (as is
930
  commonly the case, e.g., if `a` and `b` are unmodified copies of the
931
  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.
 
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
974
  qualify as an input iterator is deduced for that parameter.
 
1004
 
1005
  The headers `<array>`, `<deque>`, `<forward_list>`, `<list>`, and
1006
  `<vector>` define class templates that meet the requirements for
1007
  sequence containers.
1008
 
1009
+ The following exposition-only alias template may appear in deduction
1010
+ guides for sequence containers:
1011
+
1012
+ ``` cpp
1013
+ template<class InputIterator>
1014
+ using iter-value-type = typename iterator_traits<InputIterator>::value_type; // exposition only
1015
+ ```
1016
+
1017
  ### Header `<array>` synopsis <a id="array.syn">[[array.syn]]</a>
1018
 
1019
  ``` cpp
1020
+ #include <compare> // see [compare.syn]
1021
+ #include <initializer_list> // see [initializer.list.syn]
1022
 
1023
  namespace std {
1024
  // [array], class template array
1025
  template<class T, size_t N> struct array;
1026
+
1027
  template<class T, size_t N>
1028
+ constexpr bool operator==(const array<T, N>& x, const array<T, N>& y);
 
 
 
 
1029
  template<class T, size_t N>
1030
+ constexpr synth-three-way-result<T>
1031
+ operator<=>(const array<T, N>& x, const array<T, N>& y);
1032
+
1033
+ // [array.special], specialized algorithms
1034
  template<class T, size_t N>
1035
+ constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
1036
+
1037
+ // [array.creation], array creation functions
1038
  template<class T, size_t N>
1039
+ constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
1040
  template<class T, size_t N>
1041
+ constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
1042
 
1043
+ // [array.tuple], tuple interface
1044
+ template<class T> struct tuple_size;
1045
+ template<size_t I, class T> struct tuple_element;
1046
  template<class T, size_t N>
1047
  struct tuple_size<array<T, N>>;
1048
  template<size_t I, class T, size_t N>
1049
  struct tuple_element<I, array<T, N>>;
1050
  template<size_t I, class T, size_t N>
 
1059
  ```
1060
 
1061
  ### Header `<deque>` synopsis <a id="deque.syn">[[deque.syn]]</a>
1062
 
1063
  ``` cpp
1064
+ #include <compare> // see [compare.syn]
1065
+ #include <initializer_list> // see [initializer.list.syn]
1066
 
1067
  namespace std {
1068
  // [deque], class template deque
1069
  template<class T, class Allocator = allocator<T>> class deque;
1070
+
1071
  template<class T, class Allocator>
1072
  bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
1073
  template<class T, class Allocator>
1074
+ synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
1075
+ \itcorr const deque<T, Allocator>& y);
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
1086
+ erase_if(deque<T, Allocator>& c, Predicate pred);
1087
+
1088
  namespace pmr {
1089
  template<class T>
1090
  using deque = std::deque<T, polymorphic_allocator<T>>;
1091
  }
1092
  }
1093
  ```
1094
 
1095
+ ### Header `<forward_list>` synopsis <a id="forward.list.syn">[[forward.list.syn]]</a>
1096
 
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>
1108
+ synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
1109
+ \itcorr const forward_list<T, Allocator>& y);
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
1120
+ erase_if(forward_list<T, Allocator>& c, Predicate pred);
1121
+
1122
  namespace pmr {
1123
  template<class T>
1124
  using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
1125
  }
1126
  }
1127
  ```
1128
 
1129
  ### Header `<list>` synopsis <a id="list.syn">[[list.syn]]</a>
1130
 
1131
  ``` cpp
1132
+ #include <compare> // see [compare.syn]
1133
+ #include <initializer_list> // see [initializer.list.syn]
1134
 
1135
  namespace std {
1136
  // [list], class template list
1137
  template<class T, class Allocator = allocator<T>> class list;
1138
+
1139
  template<class T, class Allocator>
1140
  bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
1141
  template<class T, class Allocator>
1142
+ synth-three-way-result<T> operator<=>(const list<T, Allocator>& x,
1143
+ \itcorr const list<T, Allocator>& y);
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
1154
+ erase_if(list<T, Allocator>& c, Predicate pred);
1155
+
1156
  namespace pmr {
1157
  template<class T>
1158
  using list = std::list<T, polymorphic_allocator<T>>;
1159
  }
1160
  }
1161
  ```
1162
 
1163
  ### Header `<vector>` synopsis <a id="vector.syn">[[vector.syn]]</a>
1164
 
1165
  ``` cpp
1166
+ #include <compare> // see [compare.syn]
1167
+ #include <initializer_list> // see [initializer.list.syn]
1168
 
1169
  namespace std {
1170
  // [vector], class template vector
1171
  template<class T, class Allocator = allocator<T>> class vector;
1172
+
1173
  template<class T, class Allocator>
1174
+ constexpr bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
1175
  template<class T, class Allocator>
1176
+ constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x,
1177
+ \itcorr const vector<T, Allocator>& y);
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;
 
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
1230
+ template-argument-equivalent.
1231
+
1232
+ The types `iterator` and `const_iterator` meet the constexpr iterator
1233
+ requirements [[iterator.requirements.general]].
1234
 
1235
  ``` cpp
1236
  namespace std {
1237
  template<class T, size_t N>
1238
  struct array {
1239
+ // types
1240
  using value_type = T;
1241
  using pointer = T*;
1242
  using const_pointer = const T*;
1243
  using reference = T&;
1244
  using const_reference = const T&;
 
1249
  using reverse_iterator = std::reverse_iterator<iterator>;
1250
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1251
 
1252
  // no explicit construct/copy/destroy for aggregate type
1253
 
1254
+ constexpr void fill(const T& u);
1255
+ constexpr void swap(array&) noexcept(is_nothrow_swappable_v<T>);
1256
 
1257
+ // iterators
1258
  constexpr iterator begin() noexcept;
1259
  constexpr const_iterator begin() const noexcept;
1260
  constexpr iterator end() noexcept;
1261
  constexpr const_iterator end() const noexcept;
1262
 
 
1268
  constexpr const_iterator cbegin() const noexcept;
1269
  constexpr const_iterator cend() const noexcept;
1270
  constexpr const_reverse_iterator crbegin() const noexcept;
1271
  constexpr const_reverse_iterator crend() const noexcept;
1272
 
1273
+ // capacity
1274
+ [[nodiscard]] constexpr bool empty() const noexcept;
1275
  constexpr size_type size() const noexcept;
1276
  constexpr size_type max_size() const noexcept;
1277
 
1278
+ // element access
1279
  constexpr reference operator[](size_type n);
1280
  constexpr const_reference operator[](size_type n) const;
1281
  constexpr reference at(size_type n);
1282
  constexpr const_reference at(size_type n) const;
1283
  constexpr reference front();
 
1292
  template<class T, class... U>
1293
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
1294
  }
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
  ```
1312
 
1313
+ *Mandates:* `(is_same_v<T, U> && ...)` is `true`.
 
1314
 
1315
+ #### Member functions <a id="array.members">[[array.members]]</a>
1316
 
1317
  ``` cpp
1318
+ constexpr size_type size() const noexcept;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1319
  ```
1320
 
1321
  *Returns:* `N`.
1322
 
 
 
1323
  ``` cpp
1324
  constexpr T* data() noexcept;
1325
  constexpr const T* data() const noexcept;
1326
  ```
1327
 
1328
+ *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
1329
+ range. For a non-empty array, `data()` `==` `addressof(front())`.
 
 
1330
 
1331
  ``` cpp
1332
+ constexpr void fill(const T& u);
1333
  ```
1334
 
1335
  *Effects:* As if by `fill_n(begin(), N, u)`.
1336
 
 
 
1337
  ``` cpp
1338
+ 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
+
1350
+ ``` cpp
1351
+ template<class T, size_t N>
1352
+ constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
1353
+ ```
1354
+
1355
+ *Constraints:* `N == 0` or `is_swappable_v<T>` is `true`.
1356
+
1357
+ *Effects:* As if by `x.swap(y)`.
1358
+
1359
+ *Complexity:* Linear in `N`.
1360
+
1361
+ #### Zero-sized arrays <a id="array.zero">[[array.zero]]</a>
1362
 
1363
  `array` shall provide support for the special case `N == 0`.
1364
 
1365
  In the case that `N == 0`, `begin() == end() ==` unique value. The
1366
  return value of `data()` is unspecified.
 
1369
  undefined.
1370
 
1371
  Member function `swap()` shall have a non-throwing exception
1372
  specification.
1373
 
1374
+ #### Array creation functions <a id="array.creation">[[array.creation]]</a>
1375
+
1376
+ ``` cpp
1377
+ template<class T, size_t N>
1378
+ constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
1379
+ ```
1380
+
1381
+ *Mandates:* `is_array_v<T>` is `false` and `is_constructible_v<T, T&>`
1382
+ is `true`.
1383
+
1384
+ *Preconditions:* `T` meets the *Cpp17CopyConstructible* requirements.
1385
+
1386
+ *Returns:* `{{ a[0], `…`, a[N - 1] }}`.
1387
+
1388
+ ``` cpp
1389
+ template<class T, size_t N>
1390
+ constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
1391
+ ```
1392
+
1393
+ *Mandates:* `is_array_v<T>` is `false` and `is_move_constructible_v<T>`
1394
+ is `true`.
1395
+
1396
+ *Preconditions:* `T` meets the *Cpp17MoveConstructible* requirements.
1397
+
1398
+ *Returns:* `{{ std::move(a[0]), `…`, std::move(a[N - 1]) }}`.
1399
+
1400
+ #### Tuple interface <a id="array.tuple">[[array.tuple]]</a>
1401
 
1402
  ``` cpp
1403
  template<class T, size_t N>
1404
  struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
1405
  ```
1406
 
1407
  ``` cpp
1408
+ template<size_t I, class T, size_t N>
1409
+ struct tuple_element<I, array<T, N>> {
1410
+ using type = T;
1411
+ };
1412
  ```
1413
 
1414
+ *Mandates:* `I < N` is `true`.
 
 
1415
 
1416
  ``` cpp
1417
  template<size_t I, class T, size_t N>
1418
  constexpr T& get(array<T, N>& a) noexcept;
1419
  template<size_t I, class T, size_t N>
 
1422
  constexpr const T& get(const array<T, N>& a) noexcept;
1423
  template<size_t I, class T, size_t N>
1424
  constexpr const T&& get(const array<T, N>&& a) noexcept;
1425
  ```
1426
 
1427
+ *Mandates:* `I < N` is `true`.
1428
 
1429
+ *Returns:* A reference to the `I`ᵗʰ element of `a`, where indexing is
1430
  zero-based.
1431
 
1432
  ### Class template `deque` <a id="deque">[[deque]]</a>
1433
 
1434
+ #### Overview <a id="deque.overview">[[deque.overview]]</a>
1435
 
1436
  A `deque` is a sequence container that supports random access iterators
1437
+ [[random.access.iterators]]. In addition, it supports constant time
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 {
1455
  public:
1456
+ // types
1457
  using value_type = T;
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&;
 
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
1495
  iterator begin() noexcept;
1496
  const_iterator begin() const noexcept;
1497
  iterator end() noexcept;
1498
  const_iterator end() const noexcept;
1499
  reverse_iterator rbegin() noexcept;
 
1505
  const_iterator cend() const noexcept;
1506
  const_reverse_iterator crbegin() const noexcept;
1507
  const_reverse_iterator crend() const noexcept;
1508
 
1509
  // [deque.capacity], capacity
1510
+ [[nodiscard]] bool empty() const noexcept;
1511
  size_type size() const noexcept;
1512
  size_type max_size() const noexcept;
1513
  void resize(size_type sz);
1514
  void resize(size_type sz, const T& c);
1515
  void shrink_to_fit();
1516
 
1517
+ // element access
1518
  reference operator[](size_type n);
1519
  const_reference operator[](size_type n) const;
1520
  reference at(size_type n);
1521
  const_reference at(size_type n) const;
1522
  reference front();
 
1549
  void swap(deque&)
1550
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
1551
  void clear() noexcept;
1552
  };
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
 
1567
  ``` cpp
1568
  explicit deque(const Allocator&);
1569
  ```
1570
 
 
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>
 
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
  ```
1612
 
1613
+ *Preconditions:* `T` is *Cpp17MoveInsertable* and
1614
+ *Cpp17DefaultInsertable* into `*this`.
1615
+
1616
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
1617
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
1618
  to the sequence.
1619
 
 
 
 
1620
  ``` cpp
1621
  void resize(size_type sz, const T& c);
1622
  ```
1623
 
1624
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
1625
+
1626
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
1627
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
1628
  sequence.
1629
 
 
 
1630
  ``` cpp
1631
  void shrink_to_fit();
1632
  ```
1633
 
1634
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
1635
 
1636
  *Effects:* `shrink_to_fit` is a non-binding request to reduce memory use
1637
  but does not change the size of the sequence.
1638
 
1639
  [*Note 1*: The request is non-binding to allow latitude for
1640
  implementation-specific optimizations. — *end note*]
1641
 
1642
+ If the size is equal to the old capacity, or if an exception is thrown
1643
+ other than by the move constructor of a non-*Cpp17CopyInsertable* `T`,
1644
+ then there are no effects.
1645
 
1646
+ *Complexity:* If the size is not equal to the old capacity, linear in
1647
+ the size of the sequence; otherwise constant.
1648
 
1649
+ *Remarks:* If the size is not equal to the old capacity, then
1650
+ invalidates all the references, pointers, and iterators referring to the
1651
+ elements in the sequence, as well as the past-the-end iterator.
1652
 
1653
+ #### Modifiers <a id="deque.modifiers">[[deque.modifiers]]</a>
1654
 
1655
  ``` cpp
1656
  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);
 
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);
 
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
1724
+ erase(deque<T, Allocator>& c, const U& value);
1725
  ```
1726
 
1727
+ *Effects:* Equivalent to:
1728
+
1729
+ ``` cpp
1730
+ auto it = remove(c.begin(), c.end(), value);
1731
+ auto r = distance(it, c.end());
1732
+ c.erase(it, c.end());
1733
+ return r;
1734
+ ```
1735
+
1736
+ ``` cpp
1737
+ template<class T, class Allocator, class Predicate>
1738
+ typename deque<T, Allocator>::size_type
1739
+ erase_if(deque<T, Allocator>& c, Predicate pred);
1740
+ ```
1741
+
1742
+ *Effects:* Equivalent to:
1743
+
1744
+ ``` cpp
1745
+ 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
 
1781
  ``` cpp
1782
  namespace std {
1783
  template<class T, class Allocator = allocator<T>>
1784
  class forward_list {
1785
  public:
1786
+ // types
1787
  using value_type = T;
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&;
 
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());
 
1828
 
1829
  const_iterator cbegin() const noexcept;
1830
  const_iterator cbefore_begin() const noexcept;
1831
  const_iterator cend() const noexcept;
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;
 
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,
1871
  const_iterator first, const_iterator last);
1872
  void splice_after(const_iterator position, forward_list&& x,
1873
  const_iterator first, const_iterator last);
1874
 
1875
+ size_type remove(const T& value);
1876
+ template<class Predicate> size_type remove_if(Predicate pred);
1877
 
1878
+ size_type unique();
1879
+ template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
1880
 
1881
  void merge(forward_list& x);
1882
  void merge(forward_list&& x);
1883
  template<class Compare> void merge(forward_list& x, Compare comp);
1884
  template<class Compare> void merge(forward_list&& x, Compare comp);
 
1887
  template<class Compare> void sort(Compare comp);
1888
 
1889
  void reverse() noexcept;
1890
  };
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
 
 
1919
 
1920
  ``` cpp
1921
  explicit forward_list(size_type n, const Allocator& = Allocator());
1922
  ```
1923
 
1924
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
1925
+
1926
  *Effects:* Constructs a `forward_list` object with `n` default-inserted
1927
  elements using the specified allocator.
1928
 
 
 
1929
  *Complexity:* Linear in `n`.
1930
 
1931
  ``` cpp
1932
  forward_list(size_type n, const T& value, const Allocator& = Allocator());
1933
  ```
1934
 
1935
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
1936
+
1937
  *Effects:* Constructs a `forward_list` object with `n` copies of `value`
1938
  using the specified allocator.
1939
 
 
 
1940
  *Complexity:* Linear in `n`.
1941
 
1942
  ``` cpp
1943
  template<class InputIterator>
1944
  forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
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;
 
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`
 
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
 
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
 
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
 
 
2068
 
2069
  ``` cpp
2070
  iterator erase_after(const_iterator position);
2071
  ```
2072
 
2073
+ *Preconditions:* The iterator following `position` is dereferenceable.
2074
 
2075
  *Effects:* Erases the element pointed to by the iterator following
2076
  `position`.
2077
 
2078
  *Returns:* An iterator pointing to the element following the one that
 
2082
 
2083
  ``` cpp
2084
  iterator erase_after(const_iterator position, const_iterator last);
2085
  ```
2086
 
2087
+ *Preconditions:* All iterators in the range (`position`, `last`) are
2088
  dereferenceable.
2089
 
2090
  *Effects:* Erases the elements in the range (`position`, `last`).
2091
 
2092
  *Returns:* `last`.
 
2095
 
2096
  ``` cpp
2097
  void resize(size_type sz);
2098
  ```
2099
 
2100
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
2101
+
2102
  *Effects:* If `sz < distance(begin(), end())`, erases the last
2103
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
2104
  inserts `sz - distance(begin(), end())` default-inserted elements at the
2105
  end of the list.
2106
 
 
 
2107
  ``` cpp
2108
  void resize(size_type sz, const value_type& c);
2109
  ```
2110
 
2111
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
2112
+
2113
  *Effects:* If `sz < distance(begin(), end())`, erases the last
2114
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
2115
  inserts `sz - distance(begin(), end())` copies of `c` at the end of the
2116
  list.
2117
 
 
 
2118
  ``` cpp
2119
  void clear() noexcept;
2120
  ```
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
  ```
2137
 
2138
+ *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2139
  iterator in the range \[`begin()`, `end()`).
2140
+ `get_allocator() == x.get_allocator()` is `true`. `addressof(x) != this`
2141
+ is `true`.
2142
 
2143
  *Effects:* Inserts the contents of `x` after `position`, and `x` becomes
2144
  empty. Pointers and references to the moved elements of `x` now refer to
2145
  those same elements but as members of `*this`. Iterators referring to
2146
  the moved elements will continue to refer to their elements, but they
 
2153
  ``` cpp
2154
  void splice_after(const_iterator position, forward_list& x, const_iterator i);
2155
  void splice_after(const_iterator position, forward_list&& x, const_iterator i);
2156
  ```
2157
 
2158
+ *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2159
  iterator in the range \[`begin()`, `end()`). The iterator following `i`
2160
  is a dereferenceable iterator in `x`.
2161
+ `get_allocator() == x.get_allocator()` is `true`.
2162
 
2163
  *Effects:* Inserts the element following `i` into `*this`, following
2164
  `position`, and removes it from `x`. The result is unchanged if
2165
  `position == i` or `position == ++i`. Pointers and references to `*++i`
2166
  continue to refer to the same element but as a member of `*this`.
 
2176
  const_iterator first, const_iterator last);
2177
  void splice_after(const_iterator position, forward_list&& x,
2178
  const_iterator first, const_iterator last);
2179
  ```
2180
 
2181
+ *Preconditions:* `position` is `before_begin()` or is a dereferenceable
2182
  iterator in the range \[`begin()`, `end()`). (`first`, `last`) is a
2183
  valid range in `x`, and all iterators in the range (`first`, `last`) are
2184
  dereferenceable. `position` is not an iterator in the range (`first`,
2185
+ `last`). `get_allocator() == x.get_allocator()` is `true`.
2186
 
2187
  *Effects:* Inserts elements in the range (`first`, `last`) after
2188
  `position` and removes the elements from `x`. Pointers and references to
2189
  the moved elements of `x` now refer to those same elements but as
2190
  members of `*this`. Iterators referring to the moved elements will
 
2192
  into `*this`, not into `x`.
2193
 
2194
  *Complexity:* 𝑂(`distance(first, last)`)
2195
 
2196
  ``` cpp
2197
+ size_type remove(const T& value);
2198
+ template<class Predicate> size_type remove_if(Predicate pred);
2199
  ```
2200
 
2201
+ *Effects:* Erases all the elements in the list referred to by a list
2202
  iterator `i` for which the following conditions hold: `*i == value` (for
2203
  `remove()`), `pred(*i)` is `true` (for `remove_if()`). Invalidates only
2204
  the iterators and references to the erased elements.
2205
 
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,
 
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
  ```
2267
 
 
 
 
 
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
 
2282
  *Effects:* Reverses the order of the elements in the list. Does not
2283
  affect the validity of iterators and references.
2284
 
2285
  *Complexity:* Linear time.
2286
 
2287
+ #### Erasure <a id="forward.list.erasure">[[forward.list.erasure]]</a>
2288
 
2289
  ``` cpp
2290
+ template<class T, class Allocator, class U>
2291
+ typename forward_list<T, Allocator>::size_type
2292
+ erase(forward_list<T, Allocator>& c, const U& value);
2293
  ```
2294
 
2295
+ *Effects:* Equivalent to:
2296
+ `return erase_if(c, [&](auto& elem) { return elem == value; });`
2297
+
2298
+ ``` cpp
2299
+ template<class T, class Allocator, class Predicate>
2300
+ typename forward_list<T, Allocator>::size_type
2301
+ erase_if(forward_list<T, Allocator>& c, Predicate pred);
2302
+ ```
2303
+
2304
+ *Effects:* Equivalent to: `return c.remove_if(pred);`
2305
 
2306
  ### Class template `list` <a id="list">[[list]]</a>
2307
 
2308
+ #### Overview <a id="list.overview">[[list.overview]]</a>
2309
 
2310
  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 {
2330
  public:
2331
+ // types
2332
  using value_type = T;
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&;
 
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
2369
  iterator begin() noexcept;
2370
  const_iterator begin() const noexcept;
2371
  iterator end() noexcept;
2372
  const_iterator end() const noexcept;
2373
  reverse_iterator rbegin() noexcept;
 
2379
  const_iterator cend() const noexcept;
2380
  const_reverse_iterator crbegin() const noexcept;
2381
  const_reverse_iterator crend() const noexcept;
2382
 
2383
  // [list.capacity], capacity
2384
+ [[nodiscard]] bool empty() const noexcept;
2385
  size_type size() const noexcept;
2386
  size_type max_size() const noexcept;
2387
  void resize(size_type sz);
2388
  void resize(size_type sz, const T& c);
2389
 
2390
+ // element access
2391
  reference front();
2392
  const_reference front() const;
2393
  reference back();
2394
  const_reference back() const;
2395
 
 
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);
 
2417
  void clear() noexcept;
2418
 
2419
  // [list.ops], list operations
2420
  void splice(const_iterator position, list& x);
2421
  void splice(const_iterator position, list&& x);
2422
  void splice(const_iterator position, list& x, const_iterator i);
2423
  void splice(const_iterator position, list&& x, const_iterator i);
2424
+ void splice(const_iterator position, list& x, const_iterator first, const_iterator last);
2425
+ void splice(const_iterator position, list&& x, const_iterator first, const_iterator last);
 
 
2426
 
2427
+ size_type remove(const T& value);
2428
+ template<class Predicate> size_type remove_if(Predicate pred);
2429
 
2430
+ size_type unique();
2431
  template<class BinaryPredicate>
2432
+ size_type unique(BinaryPredicate binary_pred);
2433
 
2434
  void merge(list& x);
2435
  void merge(list&& x);
2436
  template<class Compare> void merge(list& x, Compare comp);
2437
  template<class Compare> void merge(list&& x, Compare comp);
 
2440
  template<class Compare> void sort(Compare comp);
2441
 
2442
  void reverse() noexcept;
2443
  };
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
2458
+ [[allocator.requirements.completeness]]. `T` shall be complete before
2459
  any member of the resulting specialization of `list` is referenced.
2460
 
2461
+ #### Constructors, copy, and assignment <a id="list.cons">[[list.cons]]</a>
2462
 
2463
  ``` cpp
2464
  explicit list(const Allocator&);
2465
  ```
2466
 
 
2470
 
2471
  ``` cpp
2472
  explicit list(size_type n, const Allocator& = Allocator());
2473
  ```
2474
 
2475
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
2476
+
2477
  *Effects:* Constructs a `list` with `n` default-inserted elements using
2478
  the specified allocator.
2479
 
 
 
2480
  *Complexity:* Linear in `n`.
2481
 
2482
  ``` cpp
2483
  list(size_type n, const T& value, const Allocator& = Allocator());
2484
  ```
2485
 
2486
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
2487
+
2488
  *Effects:* Constructs a `list` with `n` copies of `value`, using the
2489
  specified allocator.
2490
 
 
 
2491
  *Complexity:* Linear in `n`.
2492
 
2493
  ``` cpp
2494
  template<class InputIterator>
2495
  list(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
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
  ```
2507
 
2508
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
2509
+
2510
  *Effects:* If `size() < sz`, appends `sz - size()` default-inserted
2511
  elements to the sequence. If `sz <= size()`, equivalent to:
2512
 
2513
  ``` cpp
2514
  list<T>::iterator it = begin();
2515
  advance(it, sz);
2516
  erase(it, end());
2517
  ```
2518
 
 
 
2519
  ``` cpp
2520
  void resize(size_type sz, const T& c);
2521
  ```
2522
 
2523
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
2524
+
2525
  *Effects:* As if by:
2526
 
2527
  ``` cpp
2528
  if (sz > size())
2529
  insert(end(), sz-size(), c);
 
2534
  }
2535
  else
2536
  ; // do nothing
2537
  ```
2538
 
2539
+ #### Modifiers <a id="list.modifiers">[[list.modifiers]]</a>
 
 
2540
 
2541
  ``` cpp
2542
  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);
 
2582
  *Complexity:* Erasing a single element is a constant time operation with
2583
  a single call to the destructor of `T`. Erasing a range in a list is
2584
  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()`.
 
2601
  ``` cpp
2602
  void splice(const_iterator position, list& x);
2603
  void splice(const_iterator position, list&& x);
2604
  ```
2605
 
2606
+ *Preconditions:* `addressof(x) != this` is `true`.
2607
 
2608
  *Effects:* Inserts the contents of `x` before `position` and `x` becomes
2609
  empty. Pointers and references to the moved elements of `x` now refer to
2610
  those same elements but as members of `*this`. Iterators referring to
2611
  the moved elements will continue to refer to their elements, but they
 
2618
  ``` cpp
2619
  void splice(const_iterator position, list& x, const_iterator i);
2620
  void splice(const_iterator position, list&& x, const_iterator i);
2621
  ```
2622
 
2623
+ *Preconditions:* `i` is a valid dereferenceable iterator of `x`.
2624
 
2625
  *Effects:* Inserts an element pointed to by `i` from list `x` before
2626
  `position` and removes the element from `x`. The result is unchanged if
2627
  `position == i` or `position == ++i`. Pointers and references to `*i`
2628
  continue to refer to this same element but as a member of `*this`.
 
2638
  const_iterator last);
2639
  void splice(const_iterator position, list&& x, const_iterator first,
2640
  const_iterator last);
2641
  ```
2642
 
2643
+ *Preconditions:* `[first, last)` is a valid range in `x`. `position` is
2644
+ not an iterator in the range \[`first`, `last`).
 
2645
 
2646
  *Effects:* Inserts elements in the range \[`first`, `last`) before
2647
  `position` and removes the elements from `x`. Pointers and references to
2648
  the moved elements of `x` now refer to those same elements but as
2649
  members of `*this`. Iterators referring to the moved elements will
2650
  continue to refer to their elements, but they now behave as iterators
2651
  into `*this`, not into `x`.
2652
 
2653
  *Throws:* Nothing.
2654
 
2655
+ *Complexity:* Constant time if `addressof(x) == this`; otherwise, linear
2656
+ time.
2657
 
2658
  ``` cpp
2659
+ size_type remove(const T& value);
2660
+ template<class Predicate> size_type remove_if(Predicate pred);
2661
  ```
2662
 
2663
+ *Effects:* Erases all the elements in the list referred to by a list
2664
+ iterator `i` for which the following conditions hold: `*i == value`,
2665
+ `pred(*i) != false`. Invalidates only the iterators and references to
2666
+ the erased elements.
2667
+
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,
 
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
 
 
2740
  ``` cpp
2741
  void sort();
2742
  template<class Compare> void sort(Compare comp);
2743
  ```
2744
 
 
 
 
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
2759
+ erase(list<T, Allocator>& c, const U& value);
2760
  ```
2761
 
2762
+ *Effects:* Equivalent to:
2763
+ `return erase_if(c, [&](auto& elem) { return elem == value; });`
2764
+
2765
+ ``` cpp
2766
+ template<class T, class Allocator, class Predicate>
2767
+ typename list<T, Allocator>::size_type
2768
+ erase_if(list<T, Allocator>& c, Predicate pred);
2769
+ ```
2770
+
2771
+ *Effects:* Equivalent to: `return c.remove_if(pred);`
2772
 
2773
  ### Class template `vector` <a id="vector">[[vector]]</a>
2774
 
2775
+ #### Overview <a id="vector.overview">[[vector.overview]]</a>
2776
 
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
2798
  namespace std {
2799
  template<class T, class Allocator = allocator<T>>
2800
  class vector {
2801
  public:
2802
+ // types
2803
  using value_type = T;
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&;
 
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
 
2816
  // [vector.cons], construct/copy/destroy
2817
+ constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
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
2841
+ constexpr iterator begin() noexcept;
2842
+ constexpr const_iterator begin() const noexcept;
2843
+ constexpr iterator end() noexcept;
2844
+ constexpr const_iterator end() const noexcept;
2845
+ constexpr reverse_iterator rbegin() noexcept;
2846
+ constexpr const_reverse_iterator rbegin() const noexcept;
2847
+ constexpr reverse_iterator rend() noexcept;
2848
+ constexpr const_reverse_iterator rend() const noexcept;
2849
 
2850
+ constexpr const_iterator cbegin() const noexcept;
2851
+ constexpr const_iterator cend() const noexcept;
2852
+ constexpr const_reverse_iterator crbegin() const noexcept;
2853
+ constexpr const_reverse_iterator crend() const noexcept;
2854
 
2855
  // [vector.capacity], capacity
2856
+ [[nodiscard]] constexpr bool empty() const noexcept;
2857
+ constexpr size_type size() const noexcept;
2858
+ constexpr size_type max_size() const noexcept;
2859
+ constexpr size_type capacity() const noexcept;
2860
+ constexpr void resize(size_type sz);
2861
+ constexpr void resize(size_type sz, const T& c);
2862
+ constexpr void reserve(size_type n);
2863
+ constexpr void shrink_to_fit();
2864
 
2865
+ // element access
2866
+ constexpr reference operator[](size_type n);
2867
+ constexpr const_reference operator[](size_type n) const;
2868
+ constexpr const_reference at(size_type n) const;
2869
+ constexpr reference at(size_type n);
2870
+ constexpr reference front();
2871
+ constexpr const_reference front() const;
2872
+ constexpr reference back();
2873
+ constexpr const_reference back() const;
2874
 
2875
  // [vector.data], data access
2876
+ constexpr T* data() noexcept;
2877
+ constexpr const T* data() const noexcept;
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 ||
2897
  allocator_traits<Allocator>::is_always_equal::value);
2898
+ constexpr void clear() noexcept;
2899
  };
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
 
2923
  *Effects:* Constructs an empty `vector`, using the specified allocator.
2924
 
2925
  *Complexity:* Constant.
2926
 
2927
  ``` cpp
2928
+ constexpr explicit vector(size_type n, const Allocator& = Allocator());
2929
  ```
2930
 
2931
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
2932
+
2933
  *Effects:* Constructs a `vector` with `n` default-inserted elements
2934
  using the specified allocator.
2935
 
 
 
2936
  *Complexity:* Linear in `n`.
2937
 
2938
  ``` cpp
2939
+ constexpr vector(size_type n, const T& value,
2940
  const Allocator& = Allocator());
2941
  ```
2942
 
2943
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
2944
+
2945
  *Effects:* Constructs a `vector` with `n` copies of `value`, using the
2946
  specified allocator.
2947
 
 
 
2948
  *Complexity:* Linear in `n`.
2949
 
2950
  ``` cpp
2951
  template<class InputIterator>
2952
+ constexpr vector(InputIterator first, InputIterator last,
2953
  const Allocator& = Allocator());
2954
  ```
2955
 
2956
  *Effects:* Constructs a `vector` equal to the range \[`first`, `last`),
2957
  using the specified allocator.
 
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;
2969
  ```
2970
 
2971
  *Returns:* The total number of elements that the vector can hold without
2972
  requiring reallocation.
2973
 
2974
+ *Complexity:* Constant time.
2975
+
2976
  ``` cpp
2977
+ constexpr void reserve(size_type n);
2978
  ```
2979
 
2980
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
2981
 
2982
  *Effects:* A directive that informs a `vector` of a planned change in
2983
  size, so that it can manage the storage allocation accordingly. After
2984
  `reserve()`, `capacity()` is greater or equal to the argument of
2985
  `reserve` if reallocation happens; and equal to the previous value of
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
3001
+ valid. — *end note*]
3002
+
3003
+ No reallocation shall take place during insertions that happen after a
3004
+ call to `reserve()` until an insertion would make the size of the vector
3005
+ greater than the value of `capacity()`.
3006
 
3007
  ``` cpp
3008
+ constexpr void shrink_to_fit();
3009
  ```
3010
 
3011
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
3012
 
3013
  *Effects:* `shrink_to_fit` is a non-binding request to reduce
3014
  `capacity()` to `size()`.
3015
 
3016
+ [*Note 2*: The request is non-binding to allow latitude for
3017
  implementation-specific optimizations. — *end note*]
3018
 
3019
  It does not increase `capacity()`, but may reduce `capacity()` by
3020
  causing reallocation. If an exception is thrown other than by the move
3021
+ constructor of a non-*Cpp17CopyInsertable* `T` there are no effects.
3022
 
3023
+ *Complexity:* If reallocation happens, linear in the size of the
3024
+ sequence.
3025
 
3026
  *Remarks:* Reallocation invalidates all the references, pointers, and
3027
  iterators referring to the elements in the sequence as well as the
3028
+ past-the-end iterator.
3029
+
3030
+ [*Note 3*: If no reallocation happens, they remain
3031
+ valid. — *end note*]
3032
 
3033
  ``` cpp
3034
+ constexpr void swap(vector& x)
3035
  noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
3036
  allocator_traits<Allocator>::is_always_equal::value);
3037
  ```
3038
 
3039
  *Effects:* Exchanges the contents and `capacity()` of `*this` with that
3040
  of `x`.
3041
 
3042
  *Complexity:* Constant time.
3043
 
3044
  ``` cpp
3045
+ constexpr void resize(size_type sz);
3046
  ```
3047
 
3048
+ *Preconditions:* `T` is *Cpp17MoveInsertable* and
3049
+ *Cpp17DefaultInsertable* into `*this`.
3050
+
3051
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
3052
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
3053
  to the sequence.
3054
 
 
 
 
3055
  *Remarks:* If an exception is thrown other than by the move constructor
3056
+ of a non-*Cpp17CopyInsertable* `T` there are no effects.
3057
 
3058
  ``` cpp
3059
+ constexpr void resize(size_type sz, const T& c);
3060
  ```
3061
 
3062
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
3063
+
3064
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
3065
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
3066
  sequence.
3067
 
 
 
3068
  *Remarks:* If an exception is thrown there are no effects.
3069
 
3070
+ #### Data <a id="vector.data">[[vector.data]]</a>
3071
 
3072
  ``` cpp
3073
+ constexpr T* data() noexcept;
3074
+ constexpr const T* data() const noexcept;
3075
  ```
3076
 
3077
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
3078
  range. For a non-empty vector, `data()` `==` `addressof(front())`.
3079
 
3080
  *Complexity:* Constant time.
3081
 
3082
+ #### Modifiers <a id="vector.modifiers">[[vector.modifiers]]</a>
3083
 
3084
  ``` cpp
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
3103
+ those at or after the insertion point, including the past-the-end
3104
+ iterator, are invalidated. If an exception is thrown other than by the
3105
+ copy constructor, move constructor, assignment operator, or move
3106
+ assignment operator of `T` or by any `InputIterator` operation there are
3107
+ 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
 
 
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
3139
+ erase(vector<T, Allocator>& c, const U& value);
3140
  ```
3141
 
3142
+ *Effects:* Equivalent to:
3143
+
3144
+ ``` cpp
3145
+ auto it = remove(c.begin(), c.end(), value);
3146
+ auto r = distance(it, c.end());
3147
+ c.erase(it, c.end());
3148
+ return r;
3149
+ ```
3150
+
3151
+ ``` cpp
3152
+ template<class T, class Allocator, class Predicate>
3153
+ constexpr typename vector<T, Allocator>::size_type
3154
+ erase_if(vector<T, Allocator>& c, Predicate pred);
3155
+ ```
3156
+
3157
+ *Effects:* Equivalent to:
3158
+
3159
+ ``` cpp
3160
+ 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:
 
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;
 
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
3225
+ constexpr iterator begin() noexcept;
3226
+ constexpr const_iterator begin() const noexcept;
3227
+ constexpr iterator end() noexcept;
3228
+ constexpr const_iterator end() const noexcept;
3229
+ constexpr reverse_iterator rbegin() noexcept;
3230
+ constexpr const_reverse_iterator rbegin() const noexcept;
3231
+ constexpr reverse_iterator rend() noexcept;
3232
+ constexpr const_reverse_iterator rend() const noexcept;
3233
 
3234
+ constexpr const_iterator cbegin() const noexcept;
3235
+ constexpr const_iterator cend() const noexcept;
3236
+ constexpr const_reverse_iterator crbegin() const noexcept;
3237
+ constexpr const_reverse_iterator crend() const noexcept;
3238
 
3239
+ // capacity
3240
+ [[nodiscard]] constexpr bool empty() const noexcept;
3241
+ constexpr size_type size() const noexcept;
3242
+ constexpr size_type max_size() const noexcept;
3243
+ constexpr size_type capacity() const noexcept;
3244
+ constexpr void resize(size_type sz, bool c = false);
3245
+ constexpr void reserve(size_type n);
3246
+ constexpr void shrink_to_fit();
3247
 
3248
+ // element access
3249
+ constexpr reference operator[](size_type n);
3250
+ constexpr const_reference operator[](size_type n) const;
3251
+ constexpr const_reference at(size_type n) const;
3252
+ constexpr reference at(size_type n);
3253
+ constexpr reference front();
3254
+ constexpr const_reference front() const;
3255
+ constexpr reference back();
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
  ```
3279
 
3280
  Unless described below, all operations have the same requirements and
3281
  semantics as the primary `vector` template, except that operations
3282
  dealing with the `bool` value type map to bit values in the container
3283
+ storage and `allocator_traits::construct` [[allocator.traits.members]]
3284
+ is not used to construct these values.
3285
 
3286
  There is no requirement that the data be stored as a contiguous
3287
  allocation of `bool` values. A space-optimized representation of bits is
3288
  recommended instead.
3289
 
 
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
 
3315
 
3316
  ``` cpp
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
 
 
3329
  The following exposition-only alias templates may appear in deduction
3330
  guides for associative containers:
3331
 
3332
  ``` cpp
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
3351
+ #include <compare> // see [compare.syn]
3352
+ #include <initializer_list> // see [initializer.list.syn]
3353
 
3354
  namespace std {
3355
  // [map], class template map
3356
  template<class Key, class T, class Compare = less<Key>,
3357
  class Allocator = allocator<pair<const Key, T>>>
3358
  class map;
3359
+
3360
  template<class Key, class T, class Compare, class Allocator>
3361
  bool operator==(const map<Key, T, Compare, Allocator>& x,
3362
  const map<Key, T, Compare, Allocator>& y);
3363
  template<class Key, class T, class Compare, class Allocator>
3364
+ synth-three-way-result<pair<const Key, T>>
3365
+ operator<=>(const map<Key, T, Compare, Allocator>& x,
 
 
 
 
 
 
 
 
 
 
 
3366
  const map<Key, T, Compare, Allocator>& y);
3367
+
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
3378
  template<class Key, class T, class Compare = less<Key>,
3379
  class Allocator = allocator<pair<const Key, T>>>
3380
  class multimap;
3381
+
3382
  template<class Key, class T, class Compare, class Allocator>
3383
  bool operator==(const multimap<Key, T, Compare, Allocator>& x,
3384
  const multimap<Key, T, Compare, Allocator>& y);
3385
  template<class Key, class T, class Compare, class Allocator>
3386
+ synth-three-way-result<pair<const Key, T>>
3387
+ operator<=>(const multimap<Key, T, Compare, Allocator>& x,
 
 
 
 
 
 
 
 
 
 
 
3388
  const multimap<Key, T, Compare, Allocator>& y);
3389
+
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 {
3400
  template<class Key, class T, class Compare = less<Key>>
3401
  using map = std::map<Key, T, Compare,
3402
  polymorphic_allocator<pair<const Key, T>>>;
3403
 
 
3409
  ```
3410
 
3411
  ### Header `<set>` synopsis <a id="associative.set.syn">[[associative.set.syn]]</a>
3412
 
3413
  ``` cpp
3414
+ #include <compare> // see [compare.syn]
3415
+ #include <initializer_list> // see [initializer.list.syn]
3416
 
3417
  namespace std {
3418
  // [set], class template set
3419
+ template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
 
3420
  class set;
3421
+
3422
  template<class Key, class Compare, class Allocator>
3423
  bool operator==(const set<Key, Compare, Allocator>& x,
3424
  const set<Key, Compare, Allocator>& y);
3425
  template<class Key, class Compare, class Allocator>
3426
+ synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
3427
+ \itcorr const set<Key, Compare, Allocator>& y);
3428
+
 
 
 
 
 
 
 
 
 
 
 
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
3439
+ template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
 
3440
  class multiset;
3441
+
3442
  template<class Key, class Compare, class Allocator>
3443
  bool operator==(const multiset<Key, Compare, Allocator>& x,
3444
  const multiset<Key, Compare, Allocator>& y);
3445
  template<class Key, class Compare, class Allocator>
3446
+ synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
3447
+ \itcorr const multiset<Key, Compare, Allocator>& y);
3448
+
 
 
 
 
 
 
 
 
 
 
 
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 {
3459
  template<class Key, class Compare = less<Key>>
3460
+ using set = std::set<Key, Compare, polymorphic_allocator<Key>>;
 
3461
 
3462
  template<class Key, class Compare = less<Key>>
3463
+ using multiset = std::multiset<Key, Compare, polymorphic_allocator<Key>>;
 
3464
  }
3465
  }
3466
  ```
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>>>
3492
  class map {
3493
  public:
3494
+ // types
3495
  using key_type = Key;
3496
  using mapped_type = T;
3497
  using value_type = pair<const Key, T>;
3498
  using key_compare = Compare;
3499
  using allocator_type = Allocator;
 
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;
3511
+ using insert_return_type = insert-return-type<iterator, node_type>;
3512
 
3513
  class value_compare {
3514
  friend class map;
3515
  protected:
3516
  Compare comp;
 
3546
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
3547
  is_nothrow_move_assignable_v<Compare>);
3548
  map& operator=(initializer_list<value_type>);
3549
  allocator_type get_allocator() const noexcept;
3550
 
3551
+ // iterators
3552
  iterator begin() noexcept;
3553
  const_iterator begin() const noexcept;
3554
  iterator end() noexcept;
3555
  const_iterator end() const noexcept;
3556
 
 
3562
  const_iterator cbegin() const noexcept;
3563
  const_iterator cend() const noexcept;
3564
  const_reverse_iterator crbegin() const noexcept;
3565
  const_reverse_iterator crend() const noexcept;
3566
 
3567
+ // capacity
3568
+ [[nodiscard]] bool empty() const noexcept;
3569
  size_type size() const noexcept;
3570
  size_type max_size() const noexcept;
3571
 
3572
  // [map.access], element access
3573
+ mapped_type& operator[](const key_type& x);
3574
+ mapped_type& operator[](key_type&& x);
3575
+ mapped_type& at(const key_type& x);
3576
+ const mapped_type& at(const key_type& x) const;
3577
 
3578
  // [map.modifiers], modifiers
3579
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
3580
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
3581
  pair<iterator, bool> insert(const value_type& x);
 
3627
  template<class C2>
3628
  void merge(multimap<Key, T, C2, Allocator>& source);
3629
  template<class C2>
3630
  void merge(multimap<Key, T, C2, Allocator>&& source);
3631
 
3632
+ // observers
3633
  key_compare key_comp() const;
3634
  value_compare value_comp() const;
3635
 
3636
+ // map operations
3637
  iterator find(const key_type& x);
3638
  const_iterator find(const key_type& x) const;
3639
  template<class K> iterator find(const K& x);
3640
  template<class K> const_iterator find(const K& x) const;
3641
 
3642
  size_type count(const key_type& x) const;
3643
  template<class K> size_type count(const K& x) const;
3644
 
3645
+ bool contains(const key_type& x) const;
3646
+ template<class K> bool contains(const K& x) const;
3647
+
3648
  iterator lower_bound(const key_type& x);
3649
  const_iterator lower_bound(const key_type& x) const;
3650
  template<class K> iterator lower_bound(const K& x);
3651
  template<class K> const_iterator lower_bound(const K& x) const;
3652
 
 
3661
  pair<iterator, iterator> equal_range(const K& x);
3662
  template<class K>
3663
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
3664
  };
3665
 
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
 
3694
  ``` cpp
3695
  explicit map(const Compare& comp, const Allocator& = Allocator());
3696
  ```
3697
 
 
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);
3720
  ```
3721
 
3722
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
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
  ```
3734
 
3735
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
3736
  `*this`.
3737
 
3738
  *Throws:* An exception object of type `out_of_range` if no such element
3739
  is present.
3740
 
3741
  *Complexity:* Logarithmic.
3742
 
3743
+ #### Modifiers <a id="map.modifiers">[[map.modifiers]]</a>
3744
 
3745
  ``` cpp
3746
  template<class P>
3747
  pair<iterator, bool> insert(P&& x);
3748
  template<class P>
3749
  iterator insert(const_iterator position, P&& x);
3750
  ```
3751
 
3752
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
3753
+
3754
  *Effects:* The first form is equivalent to
3755
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
3756
  `return emplace_hint(position, std::forward<P>(x))`.
3757
 
 
 
 
3758
  ``` cpp
3759
  template<class... Args>
3760
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
3761
  template<class... Args>
3762
  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
3763
  ```
3764
 
3765
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
3766
+ from `piecewise_construct`, `forward_as_tuple(k)`,
3767
  `forward_as_tuple(std::forward<Args>(args)...)`.
3768
 
3769
  *Effects:* If the map already contains an element whose key is
3770
  equivalent to `k`, there is no effect. Otherwise inserts an object of
3771
  type `value_type` constructed with `piecewise_construct`,
 
3782
  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
3783
  template<class... Args>
3784
  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
3785
  ```
3786
 
3787
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
3788
+ from `piecewise_construct`, `forward_as_tuple(std::move(k))`,
3789
  `forward_as_tuple(std::forward<Args>(args)...)`.
3790
 
3791
  *Effects:* If the map already contains an element whose key is
3792
  equivalent to `k`, there is no effect. Otherwise inserts an object of
3793
  type `value_type` constructed with `piecewise_construct`,
 
3805
  pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
3806
  template<class M>
3807
  iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
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)`.
 
3828
  pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
3829
  template<class M>
3830
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
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)`.
 
3844
  pair is `true` if and only if the insertion took place. The returned
3845
  iterator points to the map element whose key is equivalent to `k`.
3846
 
3847
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
3848
 
3849
+ #### Erasure <a id="map.erasure">[[map.erasure]]</a>
3850
 
3851
  ``` cpp
3852
+ template<class Key, class T, class Compare, class Allocator, class Predicate>
3853
+ typename map<Key, T, Compare, Allocator>::size_type
3854
+ erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
 
3855
  ```
3856
 
3857
+ *Effects:* Equivalent to:
3858
+
3859
+ ``` cpp
3860
+ auto original_size = c.size();
3861
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
3862
+ if (pred(*i)) {
3863
+ i = c.erase(i);
3864
+ } else {
3865
+ ++i;
3866
+ }
3867
+ }
3868
+ return original_size - c.size();
3869
+ ```
3870
 
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
3889
+ in one of those tables or for operations where there is additional
3890
+ semantic information.
3891
 
3892
  ``` cpp
3893
  namespace std {
3894
  template<class Key, class T, class Compare = less<Key>,
3895
  class Allocator = allocator<pair<const Key, T>>>
3896
  class multimap {
3897
  public:
3898
+ // types
3899
  using key_type = Key;
3900
  using mapped_type = T;
3901
  using value_type = pair<const Key, T>;
3902
  using key_compare = Compare;
3903
  using allocator_type = Allocator;
 
3950
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
3951
  is_nothrow_move_assignable_v<Compare>);
3952
  multimap& operator=(initializer_list<value_type>);
3953
  allocator_type get_allocator() const noexcept;
3954
 
3955
+ // iterators
3956
  iterator begin() noexcept;
3957
  const_iterator begin() const noexcept;
3958
  iterator end() noexcept;
3959
  const_iterator end() const noexcept;
3960
 
 
3966
  const_iterator cbegin() const noexcept;
3967
  const_iterator cend() const noexcept;
3968
  const_reverse_iterator crbegin() const noexcept;
3969
  const_reverse_iterator crend() const noexcept;
3970
 
3971
+ // capacity
3972
+ [[nodiscard]] bool empty() const noexcept;
3973
  size_type size() const noexcept;
3974
  size_type max_size() const noexcept;
3975
 
3976
  // [multimap.modifiers], modifiers
3977
  template<class... Args> iterator emplace(Args&&... args);
 
4007
  template<class C2>
4008
  void merge(map<Key, T, C2, Allocator>& source);
4009
  template<class C2>
4010
  void merge(map<Key, T, C2, Allocator>&& source);
4011
 
4012
+ // observers
4013
  key_compare key_comp() const;
4014
  value_compare value_comp() const;
4015
 
4016
+ // map operations
4017
  iterator find(const key_type& x);
4018
  const_iterator find(const key_type& x) const;
4019
  template<class K> iterator find(const K& x);
4020
  template<class K> const_iterator find(const K& x) const;
4021
 
4022
  size_type count(const key_type& x) const;
4023
  template<class K> size_type count(const K& x) const;
4024
 
4025
+ bool contains(const key_type& x) const;
4026
+ template<class K> bool contains(const K& x) const;
4027
+
4028
  iterator lower_bound(const key_type& x);
4029
  const_iterator lower_bound(const key_type& x) const;
4030
  template<class K> iterator lower_bound(const K& x);
4031
  template<class K> const_iterator lower_bound(const K& x) const;
4032
 
 
4041
  pair<iterator, iterator> equal_range(const K& x);
4042
  template<class K>
4043
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
4044
  };
4045
 
4046
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
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
 
4076
  ``` cpp
4077
  explicit multimap(const Compare& comp, const Allocator& = Allocator());
4078
  ```
4079
 
 
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);
4103
  template<class P> iterator insert(const_iterator position, P&& x);
4104
  ```
4105
 
4106
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
4107
+
4108
  *Effects:* The first form is equivalent to
4109
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
4110
  `return emplace_hint(position, std::forward<P>(x))`.
4111
 
4112
+ #### Erasure <a id="multimap.erasure">[[multimap.erasure]]</a>
 
 
 
4113
 
4114
  ``` cpp
4115
+ template<class Key, class T, class Compare, class Allocator, class Predicate>
4116
+ typename multimap<Key, T, Compare, Allocator>::size_type
4117
+ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
 
4118
  ```
4119
 
4120
+ *Effects:* Equivalent to:
4121
+
4122
+ ``` cpp
4123
+ auto original_size = c.size();
4124
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
4125
+ if (pred(*i)) {
4126
+ i = c.erase(i);
4127
+ } else {
4128
+ ++i;
4129
+ }
4130
+ }
4131
+ return original_size - c.size();
4132
+ ```
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>>
4157
  class set {
4158
  public:
4159
+ // types
4160
  using key_type = Key;
4161
  using key_compare = Compare;
4162
  using value_type = Key;
4163
  using value_compare = Compare;
4164
  using allocator_type = Allocator;
 
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;
4176
+ using insert_return_type = insert-return-type<iterator, node_type>;
4177
 
4178
  // [set.cons], construct/copy/destroy
4179
  set() : set(Compare()) { }
4180
  explicit set(const Compare& comp, const Allocator& = Allocator());
4181
  template<class InputIterator>
 
4199
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4200
  is_nothrow_move_assignable_v<Compare>);
4201
  set& operator=(initializer_list<value_type>);
4202
  allocator_type get_allocator() const noexcept;
4203
 
4204
+ // iterators
4205
  iterator begin() noexcept;
4206
  const_iterator begin() const noexcept;
4207
  iterator end() noexcept;
4208
  const_iterator end() const noexcept;
4209
 
 
4215
  const_iterator cbegin() const noexcept;
4216
  const_iterator cend() const noexcept;
4217
  const_reverse_iterator crbegin() const noexcept;
4218
  const_reverse_iterator crend() const noexcept;
4219
 
4220
+ // capacity
4221
+ [[nodiscard]] bool empty() const noexcept;
4222
  size_type size() const noexcept;
4223
  size_type max_size() const noexcept;
4224
 
4225
+ // modifiers
4226
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
4227
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
4228
  pair<iterator,bool> insert(const value_type& x);
4229
  pair<iterator,bool> insert(value_type&& x);
4230
  iterator insert(const_iterator position, const value_type& x);
 
4254
  template<class C2>
4255
  void merge(multiset<Key, C2, Allocator>& source);
4256
  template<class C2>
4257
  void merge(multiset<Key, C2, Allocator>&& source);
4258
 
4259
+ // observers
4260
  key_compare key_comp() const;
4261
  value_compare value_comp() const;
4262
 
4263
+ // set operations
4264
  iterator find(const key_type& x);
4265
  const_iterator find(const key_type& x) const;
4266
  template<class K> iterator find(const K& x);
4267
  template<class K> const_iterator find(const K& x) const;
4268
 
4269
  size_type count(const key_type& x) const;
4270
  template<class K> size_type count(const K& x) const;
4271
 
4272
+ bool contains(const key_type& x) const;
4273
+ template<class K> bool contains(const K& x) const;
4274
+
4275
  iterator lower_bound(const key_type& x);
4276
  const_iterator lower_bound(const key_type& x) const;
4277
  template<class K> iterator lower_bound(const K& x);
4278
  template<class K> const_iterator lower_bound(const K& x) const;
4279
 
 
4289
  template<class K>
4290
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
4291
  };
4292
 
4293
  template<class InputIterator,
4294
+ class Compare = less<iter-value-type<InputIterator>>,
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
 
 
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>
4348
+ typename set<Key, Compare, Allocator>::size_type
4349
+ erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
 
4350
  ```
4351
 
4352
+ *Effects:* Equivalent to:
4353
+
4354
+ ``` cpp
4355
+ auto original_size = c.size();
4356
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
4357
+ if (pred(*i)) {
4358
+ i = c.erase(i);
4359
+ } else {
4360
+ ++i;
4361
+ }
4362
+ }
4363
+ return original_size - c.size();
4364
+ ```
4365
 
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
4384
+ tables and for operations where there is additional semantic
4385
+ information.
4386
 
4387
  ``` cpp
4388
  namespace std {
4389
  template<class Key, class Compare = less<Key>,
4390
  class Allocator = allocator<Key>>
4391
  class multiset {
4392
  public:
4393
+ // types
4394
  using key_type = Key;
4395
  using key_compare = Compare;
4396
  using value_type = Key;
4397
  using value_compare = Compare;
4398
  using allocator_type = Allocator;
 
4432
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
4433
  is_nothrow_move_assignable_v<Compare>);
4434
  multiset& operator=(initializer_list<value_type>);
4435
  allocator_type get_allocator() const noexcept;
4436
 
4437
+ // iterators
4438
  iterator begin() noexcept;
4439
  const_iterator begin() const noexcept;
4440
  iterator end() noexcept;
4441
  const_iterator end() const noexcept;
4442
 
 
4448
  const_iterator cbegin() const noexcept;
4449
  const_iterator cend() const noexcept;
4450
  const_reverse_iterator crbegin() const noexcept;
4451
  const_reverse_iterator crend() const noexcept;
4452
 
4453
+ // capacity
4454
+ [[nodiscard]] bool empty() const noexcept;
4455
  size_type size() const noexcept;
4456
  size_type max_size() const noexcept;
4457
 
4458
+ // modifiers
4459
  template<class... Args> iterator emplace(Args&&... args);
4460
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
4461
  iterator insert(const value_type& x);
4462
  iterator insert(value_type&& x);
4463
  iterator insert(const_iterator position, const value_type& x);
 
4487
  template<class C2>
4488
  void merge(set<Key, C2, Allocator>& source);
4489
  template<class C2>
4490
  void merge(set<Key, C2, Allocator>&& source);
4491
 
4492
+ // observers
4493
  key_compare key_comp() const;
4494
  value_compare value_comp() const;
4495
 
4496
+ // set operations
4497
  iterator find(const key_type& x);
4498
  const_iterator find(const key_type& x) const;
4499
  template<class K> iterator find(const K& x);
4500
  template<class K> const_iterator find(const K& x) const;
4501
 
4502
  size_type count(const key_type& x) const;
4503
  template<class K> size_type count(const K& x) const;
4504
 
4505
+ bool contains(const key_type& x) const;
4506
+ template<class K> bool contains(const K& x) const;
4507
+
4508
  iterator lower_bound(const key_type& x);
4509
  const_iterator lower_bound(const key_type& x) const;
4510
  template<class K> iterator lower_bound(const K& x);
4511
  template<class K> const_iterator lower_bound(const K& x) const;
4512
 
 
4522
  template<class K>
4523
  pair<const_iterator, const_iterator> equal_range(const K& x) const;
4524
  };
4525
 
4526
  template<class InputIterator,
4527
+ class Compare = less<iter-value-type<InputIterator>>,
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
 
4555
  ``` cpp
4556
  explicit multiset(const Compare& comp, const Allocator& = Allocator());
4557
  ```
4558
 
 
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>
4581
+ typename multiset<Key, Compare, Allocator>::size_type
4582
+ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
 
4583
  ```
4584
 
4585
+ *Effects:* Equivalent to:
4586
+
4587
+ ``` cpp
4588
+ auto original_size = c.size();
4589
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
4590
+ if (pred(*i)) {
4591
+ i = c.erase(i);
4592
+ } else {
4593
+ ++i;
4594
+ }
4595
+ }
4596
+ return original_size - c.size();
4597
+ ```
4598
 
4599
  ## Unordered associative containers <a id="unord">[[unord]]</a>
4600
 
4601
  ### In general <a id="unord.general">[[unord.general]]</a>
4602
 
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
 
4614
  ``` cpp
4615
+ #include <compare> // see [compare.syn]
4616
+ #include <initializer_list> // see [initializer.list.syn]
4617
 
4618
  namespace std {
4619
  // [unord.map], class template unordered_map
4620
  template<class Key,
4621
  class T,
 
4630
  class Hash = hash<Key>,
4631
  class Pred = equal_to<Key>,
4632
  class Alloc = allocator<pair<const Key, T>>>
4633
  class unordered_multimap;
4634
 
4635
+ template<class Key, class T, class Hash, class Pred, class Alloc>
4636
+ bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
4637
+ const unordered_map<Key, T, Hash, Pred, Alloc>& b);
4638
+
4639
+ template<class Key, class T, class Hash, class Pred, class Alloc>
4640
+ bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
4641
+ const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
4642
+
4643
  template<class Key, class T, class Hash, class Pred, class Alloc>
4644
  void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
4645
  unordered_map<Key, T, Hash, Pred, Alloc>& y)
4646
  noexcept(noexcept(x.swap(y)));
4647
 
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 {
4662
  template<class Key,
4663
  class T,
4664
  class Hash = hash<Key>,
 
4679
  ```
4680
 
4681
  ### Header `<unordered_set>` synopsis <a id="unord.set.syn">[[unord.set.syn]]</a>
4682
 
4683
  ``` cpp
4684
+ #include <compare> // see [compare.syn]
4685
+ #include <initializer_list> // see [initializer.list.syn]
4686
 
4687
  namespace std {
4688
  // [unord.set], class template unordered_set
4689
  template<class Key,
4690
  class Hash = hash<Key>,
 
4697
  class Hash = hash<Key>,
4698
  class Pred = equal_to<Key>,
4699
  class Alloc = allocator<Key>>
4700
  class unordered_multiset;
4701
 
4702
+ template<class Key, class Hash, class Pred, class Alloc>
4703
+ bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
4704
+ const unordered_set<Key, Hash, Pred, Alloc>& b);
4705
+
4706
+ template<class Key, class Hash, class Pred, class Alloc>
4707
+ bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
4708
+ const unordered_multiset<Key, Hash, Pred, Alloc>& b);
4709
+
4710
  template<class Key, class Hash, class Pred, class Alloc>
4711
  void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
4712
  unordered_set<Key, Hash, Pred, Alloc>& y)
4713
  noexcept(noexcept(x.swap(y)));
4714
 
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 {
4729
  template<class Key,
4730
  class Hash = hash<Key>,
4731
  class Pred = equal_to<Key>>
 
4741
  }
4742
  ```
4743
 
4744
  ### Class template `unordered_map` <a id="unord.map">[[unord.map]]</a>
4745
 
4746
+ #### Overview <a id="unord.map.overview">[[unord.map.overview]]</a>
4747
 
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
 
4766
  ``` cpp
4767
  namespace std {
4768
  template<class Key,
4769
  class T,
4770
  class Hash = hash<Key>,
4771
  class Pred = equal_to<Key>,
4772
  class Allocator = allocator<pair<const Key, T>>>
4773
  class unordered_map {
4774
  public:
4775
+ // types
4776
  using key_type = Key;
4777
  using mapped_type = T;
4778
  using value_type = pair<const Key, T>;
4779
  using hasher = Hash;
4780
  using key_equal = Pred;
 
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]
4793
  using node_type = unspecified;
4794
+ using insert_return_type = insert-return-type<iterator, node_type>;
4795
 
4796
  // [unord.map.cnstr], construct/copy/destroy
4797
  unordered_map();
4798
  explicit unordered_map(size_type n,
4799
  const hasher& hf = hasher(),
 
4838
  is_nothrow_move_assignable_v<Hash> &&
4839
  is_nothrow_move_assignable_v<Pred>);
4840
  unordered_map& operator=(initializer_list<value_type>);
4841
  allocator_type get_allocator() const noexcept;
4842
 
4843
+ // iterators
4844
  iterator begin() noexcept;
4845
  const_iterator begin() const noexcept;
4846
  iterator end() noexcept;
4847
  const_iterator end() const noexcept;
4848
  const_iterator cbegin() const noexcept;
4849
  const_iterator cend() const noexcept;
4850
 
4851
+ // capacity
4852
+ [[nodiscard]] bool empty() const noexcept;
4853
  size_type size() const noexcept;
4854
  size_type max_size() const noexcept;
4855
 
4856
  // [unord.map.modifiers], modifiers
4857
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
 
4904
  template<class H2, class P2>
4905
  void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
4906
  template<class H2, class P2>
4907
  void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
4908
 
4909
+ // observers
4910
  hasher hash_function() const;
4911
  key_equal key_eq() const;
4912
 
4913
+ // map operations
4914
  iterator find(const key_type& k);
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>
4926
+ bool contains(const K& k) const;
4927
  pair<iterator, iterator> equal_range(const key_type& k);
4928
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
4929
+ template<class K>
4930
+ pair<iterator, iterator> equal_range(const K& k);
4931
+ template<class K>
4932
+ pair<const_iterator, const_iterator> equal_range(const K& k) const;
4933
 
4934
  // [unord.map.elem], element access
4935
  mapped_type& operator[](const key_type& k);
4936
  mapped_type& operator[](key_type&& k);
4937
  mapped_type& at(const key_type& k);
4938
  const mapped_type& at(const key_type& k) const;
4939
 
4940
+ // bucket interface
4941
  size_type bucket_count() const noexcept;
4942
  size_type max_bucket_count() const noexcept;
4943
  size_type bucket_size(size_type n) const;
4944
  size_type bucket(const key_type& k) const;
4945
  local_iterator begin(size_type n);
 
4947
  local_iterator end(size_type n);
4948
  const_local_iterator end(size_type n) const;
4949
  const_local_iterator cbegin(size_type n) const;
4950
  const_local_iterator cend(size_type n) const;
4951
 
4952
+ // hash policy
4953
  float load_factor() const noexcept;
4954
  float max_load_factor() const noexcept;
4955
  void max_load_factor(float z);
4956
  void rehash(size_type n);
4957
  void reserve(size_type n);
4958
  };
4959
 
4960
  template<class InputIterator,
4961
+ class Hash = hash<iter-key-type<InputIterator>>,
4962
+ class Pred = equal_to<iter-key-type<InputIterator>>,
4963
+ class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
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())
4974
  -> unordered_map<Key, T, Hash, Pred, Allocator>;
4975
 
4976
  template<class InputIterator, class Allocator>
4977
  unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator)
4978
+ -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
4979
+ hash<iter-key-type<InputIterator>>,
4980
+ equal_to<iter-key-type<InputIterator>>, Allocator>;
4981
 
4982
  template<class InputIterator, class Allocator>
4983
  unordered_map(InputIterator, InputIterator, Allocator)
4984
+ -> unordered_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
4985
+ hash<iter-key-type<InputIterator>>,
4986
+ equal_to<iter-key-type<InputIterator>>, Allocator>;
4987
 
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
 
4998
+ template<class Key, class T, class Allocator>
4999
+ unordered_map(initializer_list<pair<Key, T>>, Allocator)
5000
  -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;
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
  }
 
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
5017
  deduction guide.
5018
 
5019
+ #### Constructors <a id="unord.map.cnstr">[[unord.map.cnstr]]</a>
5020
 
5021
  ``` cpp
5022
  unordered_map() : unordered_map(size_type(see below)) { }
5023
  explicit unordered_map(size_type n,
5024
  const hasher& hf = hasher(),
 
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
 
5061
  ``` cpp
5062
  mapped_type& operator[](const key_type& k);
5063
  ```
5064
 
 
5079
  whose key is equivalent to `k`.
5080
 
5081
  *Throws:* An exception object of type `out_of_range` if no such element
5082
  is present.
5083
 
5084
+ #### Modifiers <a id="unord.map.modifiers">[[unord.map.modifiers]]</a>
5085
 
5086
  ``` cpp
5087
  template<class P>
5088
  pair<iterator, bool> insert(P&& obj);
5089
  ```
5090
 
5091
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
5092
+
5093
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
5094
 
 
 
 
5095
  ``` cpp
5096
  template<class P>
5097
  iterator insert(const_iterator hint, P&& obj);
5098
  ```
5099
 
5100
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
5101
+
5102
  *Effects:* Equivalent to:
5103
  `return emplace_hint(hint, std::forward<P>(obj));`
5104
 
 
 
 
5105
  ``` cpp
5106
  template<class... Args>
5107
  pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
5108
  template<class... Args>
5109
  iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
5110
  ```
5111
 
5112
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
5113
  `unordered_map` from `piecewise_construct`, `forward_as_tuple(k)`,
5114
  `forward_as_tuple(std::forward<Args>(args)...)`.
5115
 
5116
  *Effects:* If the map already contains an element whose key is
5117
  equivalent to `k`, there is no effect. Otherwise inserts an object of
 
5129
  pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
5130
  template<class... Args>
5131
  iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
5132
  ```
5133
 
5134
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
5135
  `unordered_map` from `piecewise_construct`,
5136
  `forward_as_tuple(std::move(k))`,
5137
  `forward_as_tuple(std::forward<Args>(args)...)`.
5138
 
5139
  *Effects:* If the map already contains an element whose key is
 
5153
  pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
5154
  template<class M>
5155
  iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
5156
  ```
5157
 
5158
+ *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
5159
+
5160
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
5161
+ `unordered_map` from `k`, `std::forward<M>(obj)`.
5162
 
5163
  *Effects:* If the map already contains an element `e` whose key is
5164
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
5165
  Otherwise inserts an object of type `value_type` constructed with `k`,
5166
  `std::forward<M>(obj)`.
 
5176
  pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
5177
  template<class M>
5178
  iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
5179
  ```
5180
 
5181
+ *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
5182
+
5183
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
5184
+ `unordered_map` from `std::move(k)`, `std::forward<M>(obj)`.
5185
 
5186
  *Effects:* If the map already contains an element `e` whose key is
5187
  equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
5188
  Otherwise inserts an object of type `value_type` constructed with
5189
  `std::move(k)`, `std::forward<M>(obj)`.
 
5192
  pair is `true` if and only if the insertion took place. The returned
5193
  iterator points to the map element whose key is equivalent to `k`.
5194
 
5195
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
5196
 
5197
+ #### Erasure <a id="unord.map.erasure">[[unord.map.erasure]]</a>
5198
 
5199
  ``` cpp
5200
+ template<class K, class T, class H, class P, class A, class Predicate>
5201
+ typename unordered_map<K, T, H, P, A>::size_type
5202
+ erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
 
5203
  ```
5204
 
5205
+ *Effects:* Equivalent to:
5206
+
5207
+ ``` cpp
5208
+ auto original_size = c.size();
5209
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
5210
+ if (pred(*i)) {
5211
+ i = c.erase(i);
5212
+ } else {
5213
+ ++i;
5214
+ }
5215
+ }
5216
+ return original_size - c.size();
5217
+ ```
5218
 
5219
  ### Class template `unordered_multimap` <a id="unord.multimap">[[unord.multimap]]</a>
5220
 
5221
+ #### Overview <a id="unord.multimap.overview">[[unord.multimap.overview]]</a>
5222
 
5223
  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
 
5242
  ``` cpp
5243
  namespace std {
5244
  template<class Key,
5245
  class T,
5246
  class Hash = hash<Key>,
5247
  class Pred = equal_to<Key>,
5248
  class Allocator = allocator<pair<const Key, T>>>
5249
  class unordered_multimap {
5250
  public:
5251
+ // types
5252
  using key_type = Key;
5253
  using mapped_type = T;
5254
  using value_type = pair<const Key, T>;
5255
  using hasher = Hash;
5256
  using key_equal = Pred;
 
5313
  is_nothrow_move_assignable_v<Hash> &&
5314
  is_nothrow_move_assignable_v<Pred>);
5315
  unordered_multimap& operator=(initializer_list<value_type>);
5316
  allocator_type get_allocator() const noexcept;
5317
 
5318
+ // iterators
5319
  iterator begin() noexcept;
5320
  const_iterator begin() const noexcept;
5321
  iterator end() noexcept;
5322
  const_iterator end() const noexcept;
5323
  const_iterator cbegin() const noexcept;
5324
  const_iterator cend() const noexcept;
5325
 
5326
+ // capacity
5327
+ [[nodiscard]] bool empty() const noexcept;
5328
  size_type size() const noexcept;
5329
  size_type max_size() const noexcept;
5330
 
5331
  // [unord.multimap.modifiers], modifiers
5332
  template<class... Args> iterator emplace(Args&&... args);
 
5362
  template<class H2, class P2>
5363
  void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
5364
  template<class H2, class P2>
5365
  void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
5366
 
5367
+ // observers
5368
  hasher hash_function() const;
5369
  key_equal key_eq() const;
5370
 
5371
+ // map operations
5372
  iterator find(const key_type& k);
5373
  const_iterator find(const key_type& k) const;
5374
+ template<class K>
5375
+ iterator find(const K& k);
5376
+ template<class K>
5377
+ const_iterator find(const K& k) const;
5378
  size_type count(const key_type& k) const;
5379
+ template<class K>
5380
+ size_type count(const K& k) const;
5381
+ bool contains(const key_type& k) const;
5382
+ template<class K>
5383
+ bool contains(const K& k) const;
5384
  pair<iterator, iterator> equal_range(const key_type& k);
5385
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
5386
+ template<class K>
5387
+ pair<iterator, iterator> equal_range(const K& k);
5388
+ template<class K>
5389
+ pair<const_iterator, const_iterator> equal_range(const K& k) const;
5390
 
5391
+ // bucket interface
5392
  size_type bucket_count() const noexcept;
5393
  size_type max_bucket_count() const noexcept;
5394
  size_type bucket_size(size_type n) const;
5395
  size_type bucket(const key_type& k) const;
5396
  local_iterator begin(size_type n);
 
5407
  void rehash(size_type n);
5408
  void reserve(size_type n);
5409
  };
5410
 
5411
  template<class InputIterator,
5412
+ class Hash = hash<iter-key-type<InputIterator>>,
5413
+ class Pred = equal_to<iter-key-type<InputIterator>>,
5414
+ class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
5415
  unordered_multimap(InputIterator, InputIterator,
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())
5426
  -> unordered_multimap<Key, T, Hash, Pred, Allocator>;
5427
 
5428
  template<class InputIterator, class Allocator>
5429
  unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator)
5430
+ -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
5431
+ hash<iter-key-type<InputIterator>>,
5432
+ equal_to<iter-key-type<InputIterator>>, Allocator>;
5433
 
5434
  template<class InputIterator, class Allocator>
5435
  unordered_multimap(InputIterator, InputIterator, Allocator)
5436
+ -> unordered_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>,
5437
+ hash<iter-key-type<InputIterator>>,
5438
+ equal_to<iter-key-type<InputIterator>>, Allocator>;
5439
 
5440
  template<class InputIterator, class Hash, class Allocator>
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
 
5451
+ template<class Key, class T, class Allocator>
5452
+ unordered_multimap(initializer_list<pair<Key, T>>, Allocator)
5453
  -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;
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
  }
 
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
5470
  deduction guide.
5471
 
5472
+ #### Constructors <a id="unord.multimap.cnstr">[[unord.multimap.cnstr]]</a>
5473
 
5474
  ``` cpp
5475
  unordered_multimap() : unordered_multimap(size_type(see below)) { }
5476
  explicit unordered_multimap(size_type n,
5477
  const hasher& hf = hasher(),
 
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
 
5514
  ``` cpp
5515
  template<class P>
5516
  iterator insert(P&& obj);
5517
  ```
5518
 
5519
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
5520
+
5521
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
5522
 
 
 
 
5523
  ``` cpp
5524
  template<class P>
5525
  iterator insert(const_iterator hint, P&& obj);
5526
  ```
5527
 
5528
+ *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
5529
+
5530
  *Effects:* Equivalent to:
5531
  `return emplace_hint(hint, std::forward<P>(obj));`
5532
 
5533
+ #### Erasure <a id="unord.multimap.erasure">[[unord.multimap.erasure]]</a>
 
 
 
5534
 
5535
  ``` cpp
5536
+ template<class K, class T, class H, class P, class A, class Predicate>
5537
+ typename unordered_multimap<K, T, H, P, A>::size_type
5538
+ erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
 
5539
  ```
5540
 
5541
+ *Effects:* Equivalent to:
5542
+
5543
+ ``` cpp
5544
+ auto original_size = c.size();
5545
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
5546
+ if (pred(*i)) {
5547
+ i = c.erase(i);
5548
+ } else {
5549
+ ++i;
5550
+ }
5551
+ }
5552
+ return original_size - c.size();
5553
+ ```
5554
 
5555
  ### Class template `unordered_set` <a id="unord.set">[[unord.set]]</a>
5556
 
5557
+ #### Overview <a id="unord.set.overview">[[unord.set.overview]]</a>
5558
 
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
 
5578
  ``` cpp
5579
  namespace std {
5580
  template<class Key,
5581
  class Hash = hash<Key>,
5582
  class Pred = equal_to<Key>,
5583
  class Allocator = allocator<Key>>
5584
  class unordered_set {
5585
  public:
5586
+ // types
5587
  using key_type = Key;
5588
  using value_type = Key;
5589
  using hasher = Hash;
5590
  using key_equal = Pred;
5591
  using allocator_type = Allocator;
 
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]
5603
  using node_type = unspecified;
5604
+ using insert_return_type = insert-return-type<iterator, node_type>;
5605
 
5606
  // [unord.set.cnstr], construct/copy/destroy
5607
  unordered_set();
5608
  explicit unordered_set(size_type n,
5609
  const hasher& hf = hasher(),
 
5648
  is_nothrow_move_assignable_v<Hash> &&
5649
  is_nothrow_move_assignable_v<Pred>);
5650
  unordered_set& operator=(initializer_list<value_type>);
5651
  allocator_type get_allocator() const noexcept;
5652
 
5653
+ // iterators
5654
  iterator begin() noexcept;
5655
  const_iterator begin() const noexcept;
5656
  iterator end() noexcept;
5657
  const_iterator end() const noexcept;
5658
  const_iterator cbegin() const noexcept;
5659
  const_iterator cend() const noexcept;
5660
 
5661
+ // capacity
5662
+ [[nodiscard]] bool empty() const noexcept;
5663
  size_type size() const noexcept;
5664
  size_type max_size() const noexcept;
5665
 
5666
+ // modifiers
5667
  template<class... Args> pair<iterator, bool> emplace(Args&&... args);
5668
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
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);
 
5695
  template<class H2, class P2>
5696
  void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
5697
  template<class H2, class P2>
5698
  void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
5699
 
5700
+ // observers
5701
  hasher hash_function() const;
5702
  key_equal key_eq() const;
5703
 
5704
+ // set operations
5705
  iterator find(const key_type& k);
5706
  const_iterator find(const key_type& k) const;
5707
+ template<class K>
5708
+ iterator find(const K& k);
5709
+ template<class K>
5710
+ const_iterator find(const K& k) const;
5711
  size_type count(const key_type& k) const;
5712
+ template<class K>
5713
+ size_type count(const K& k) const;
5714
+ bool contains(const key_type& k) const;
5715
+ template<class K>
5716
+ bool contains(const K& k) const;
5717
  pair<iterator, iterator> equal_range(const key_type& k);
5718
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
5719
+ template<class K>
5720
+ pair<iterator, iterator> equal_range(const K& k);
5721
+ template<class K>
5722
+ pair<const_iterator, const_iterator> equal_range(const K& k) const;
5723
 
5724
+ // bucket interface
5725
  size_type bucket_count() const noexcept;
5726
  size_type max_bucket_count() const noexcept;
5727
  size_type bucket_size(size_type n) const;
5728
  size_type bucket(const key_type& k) const;
5729
  local_iterator begin(size_type n);
 
5731
  local_iterator end(size_type n);
5732
  const_local_iterator end(size_type n) const;
5733
  const_local_iterator cbegin(size_type n) const;
5734
  const_local_iterator cend(size_type n) const;
5735
 
5736
+ // hash policy
5737
  float load_factor() const noexcept;
5738
  float max_load_factor() const noexcept;
5739
  void max_load_factor(float z);
5740
  void rehash(size_type n);
5741
  void reserve(size_type n);
5742
  };
5743
 
5744
  template<class InputIterator,
5745
+ class Hash = hash<iter-value-type<InputIterator>>,
5746
+ class Pred = equal_to<iter-value-type<InputIterator>>,
5747
+ class Allocator = allocator<iter-value-type<InputIterator>>>
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>;
5758
 
5759
  template<class InputIterator, class Allocator>
5760
  unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator)
5761
+ -> unordered_set<iter-value-type<InputIterator>,
5762
+ hash<iter-value-type<InputIterator>>,
5763
+ equal_to<iter-value-type<InputIterator>>,
5764
  Allocator>;
5765
 
5766
  template<class InputIterator, class Hash, class Allocator>
5767
  unordered_set(InputIterator, InputIterator, typename see below::size_type,
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
5791
+ deduction guide.
5792
 
5793
+ #### Constructors <a id="unord.set.cnstr">[[unord.set.cnstr]]</a>
5794
 
5795
  ``` cpp
5796
  unordered_set() : unordered_set(size_type(see below)) { }
5797
  explicit unordered_set(size_type n,
5798
  const hasher& hf = hasher(),
 
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
 
5835
  ``` cpp
5836
+ template<class K, class H, class P, class A, class Predicate>
5837
+ typename unordered_set<K, H, P, A>::size_type
5838
+ erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
 
5839
  ```
5840
 
5841
+ *Effects:* Equivalent to:
5842
+
5843
+ ``` cpp
5844
+ auto original_size = c.size();
5845
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
5846
+ if (pred(*i)) {
5847
+ i = c.erase(i);
5848
+ } else {
5849
+ ++i;
5850
+ }
5851
+ }
5852
+ return original_size - c.size();
5853
+ ```
5854
 
5855
  ### Class template `unordered_multiset` <a id="unord.multiset">[[unord.multiset]]</a>
5856
 
5857
+ #### Overview <a id="unord.multiset.overview">[[unord.multiset.overview]]</a>
5858
 
5859
  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
 
5879
  ``` cpp
5880
  namespace std {
5881
  template<class Key,
5882
  class Hash = hash<Key>,
5883
  class Pred = equal_to<Key>,
5884
  class Allocator = allocator<Key>>
5885
  class unordered_multiset {
5886
  public:
5887
+ // types
5888
  using key_type = Key;
5889
  using value_type = Key;
5890
  using hasher = Hash;
5891
  using key_equal = Pred;
5892
  using allocator_type = Allocator;
 
5948
  is_nothrow_move_assignable_v<Hash> &&
5949
  is_nothrow_move_assignable_v<Pred>);
5950
  unordered_multiset& operator=(initializer_list<value_type>);
5951
  allocator_type get_allocator() const noexcept;
5952
 
5953
+ // iterators
5954
  iterator begin() noexcept;
5955
  const_iterator begin() const noexcept;
5956
  iterator end() noexcept;
5957
  const_iterator end() const noexcept;
5958
  const_iterator cbegin() const noexcept;
5959
  const_iterator cend() const noexcept;
5960
 
5961
+ // capacity
5962
+ [[nodiscard]] bool empty() const noexcept;
5963
  size_type size() const noexcept;
5964
  size_type max_size() const noexcept;
5965
 
5966
+ // modifiers
5967
  template<class... Args> iterator emplace(Args&&... args);
5968
  template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
5969
  iterator insert(const value_type& obj);
5970
  iterator insert(value_type&& obj);
5971
  iterator insert(const_iterator hint, const value_type& obj);
 
5995
  template<class H2, class P2>
5996
  void merge(unordered_set<Key, H2, P2, Allocator>& source);
5997
  template<class H2, class P2>
5998
  void merge(unordered_set<Key, H2, P2, Allocator>&& source);
5999
 
6000
+ // observers
6001
  hasher hash_function() const;
6002
  key_equal key_eq() const;
6003
 
6004
+ // set operations
6005
  iterator find(const key_type& k);
6006
  const_iterator find(const key_type& k) const;
6007
+ template<class K>
6008
+ iterator find(const K& k);
6009
+ template<class K>
6010
+ const_iterator find(const K& k) const;
6011
  size_type count(const key_type& k) const;
6012
+ template<class K>
6013
+ size_type count(const K& k) const;
6014
+ bool contains(const key_type& k) const;
6015
+ template<class K>
6016
+ bool contains(const K& k) const;
6017
  pair<iterator, iterator> equal_range(const key_type& k);
6018
  pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
6019
+ template<class K>
6020
+ pair<iterator, iterator> equal_range(const K& k);
6021
+ template<class K>
6022
+ pair<const_iterator, const_iterator> equal_range(const K& k) const;
6023
 
6024
+ // bucket interface
6025
  size_type bucket_count() const noexcept;
6026
  size_type max_bucket_count() const noexcept;
6027
  size_type bucket_size(size_type n) const;
6028
  size_type bucket(const key_type& k) const;
6029
  local_iterator begin(size_type n);
 
6031
  local_iterator end(size_type n);
6032
  const_local_iterator end(size_type n) const;
6033
  const_local_iterator cbegin(size_type n) const;
6034
  const_local_iterator cend(size_type n) const;
6035
 
6036
+ // hash policy
6037
  float load_factor() const noexcept;
6038
  float max_load_factor() const noexcept;
6039
  void max_load_factor(float z);
6040
  void rehash(size_type n);
6041
  void reserve(size_type n);
6042
  };
6043
 
6044
  template<class InputIterator,
6045
+ class Hash = hash<iter-value-type<InputIterator>>,
6046
+ class Pred = equal_to<iter-value-type<InputIterator>>,
6047
+ class Allocator = allocator<iter-value-type<InputIterator>>>
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>;
6058
 
6059
  template<class InputIterator, class Allocator>
6060
  unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator)
6061
+ -> unordered_multiset<iter-value-type<InputIterator>,
6062
+ hash<iter-value-type<InputIterator>>,
6063
+ equal_to<iter-value-type<InputIterator>>,
6064
  Allocator>;
6065
 
6066
  template<class InputIterator, class Hash, class Allocator>
6067
  unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
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
6091
+ deduction guide.
6092
 
6093
+ #### Constructors <a id="unord.multiset.cnstr">[[unord.multiset.cnstr]]</a>
6094
 
6095
  ``` cpp
6096
  unordered_multiset() : unordered_multiset(size_type(see below)) { }
6097
  explicit unordered_multiset(size_type n,
6098
  const hasher& hf = hasher(),
 
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
 
6135
  ``` cpp
6136
+ template<class K, class H, class P, class A, class Predicate>
6137
+ typename unordered_multiset<K, H, P, A>::size_type
6138
+ erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
 
6139
  ```
6140
 
6141
+ *Effects:* Equivalent to:
6142
+
6143
+ ``` cpp
6144
+ auto original_size = c.size();
6145
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
6146
+ if (pred(*i)) {
6147
+ i = c.erase(i);
6148
+ } else {
6149
+ ++i;
6150
+ }
6151
+ }
6152
+ return original_size - c.size();
6153
+ ```
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
 
 
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>
6201
+ bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
6202
+ template<class T, class Container>
6203
+ bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
6204
+ template<class T, class Container>
6205
+ bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
6206
+ template<class T, class Container>
6207
+ bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
6208
+ template<class T, class Container>
6209
+ bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
6210
+ template<class T, three_way_comparable Container>
6211
+ compare_three_way_result_t<Container>
6212
+ operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
6213
+
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>
6224
  void swap(priority_queue<T, Container, Compare>& x,
6225
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
6226
+ template<class T, class Container, class Compare, class Alloc>
6227
+ struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>;
6228
  }
6229
  ```
6230
 
6231
  ### Header `<stack>` synopsis <a id="stack.syn">[[stack.syn]]</a>
6232
 
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>
6243
  bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
6244
+ template<class T, class Container>
6245
+ bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
6246
  template<class T, class Container>
6247
  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
 
 
6248
  template<class T, class Container>
6249
  bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
6250
+ template<class T, class Container>
6251
+ bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
6252
+ template<class T, three_way_comparable Container>
6253
+ compare_three_way_result_t<Container>
6254
+ operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
6255
+
6256
  template<class T, class Container>
6257
  void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
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()`,
6268
  `push_back()` and `pop_front()` can be used to instantiate `queue`. In
6269
+ particular, `list` [[list]] and `deque` [[deque]] can be used.
6270
 
6271
  ``` cpp
6272
  namespace std {
6273
  template<class T, class Container = deque<T>>
6274
  class queue {
 
6281
 
6282
  protected:
6283
  Container c;
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>)
6308
  { using std::swap; swap(c, q.c); }
6309
  };
6310
 
 
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
  }
6324
  ```
6325
 
6326
+ #### Constructors <a id="queue.cons">[[queue.cons]]</a>
6327
 
6328
  ``` cpp
6329
  explicit queue(const Container& cont);
6330
  ```
6331
 
6332
+ *Effects:* Initializes `c` with `cont`.
6333
 
6334
  ``` cpp
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
 
6345
  ``` cpp
6346
  template<class Alloc> explicit queue(const Alloc& a);
6347
  ```
6348
 
6349
+ *Effects:* Initializes `c` with `a`.
6350
 
6351
  ``` cpp
6352
  template<class Alloc> queue(const container_type& cont, const Alloc& a);
6353
  ```
6354
 
6355
+ *Effects:* Initializes `c` with `cont` as the first argument and `a` as
6356
  the second argument.
6357
 
6358
  ``` cpp
6359
  template<class Alloc> queue(container_type&& cont, const Alloc& a);
6360
  ```
6361
 
6362
+ *Effects:* Initializes `c` with `std::move(cont)` as the first argument
6363
  and `a` as the second argument.
6364
 
6365
  ``` cpp
6366
  template<class Alloc> queue(const queue& q, const Alloc& a);
6367
  ```
6368
 
6369
+ *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
6370
  the second argument.
6371
 
6372
  ``` cpp
6373
  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);
6384
  ```
 
6397
  bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
6398
  ```
6399
 
6400
  *Returns:* `x.c < y.c`.
6401
 
 
 
 
 
 
 
 
6402
  ``` cpp
6403
  template<class T, class Container>
6404
  bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
6405
  ```
6406
 
6407
  *Returns:* `x.c > y.c`.
6408
 
6409
+ ``` cpp
6410
+ template<class T, class Container>
6411
+ bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
6412
+ ```
6413
+
6414
+ *Returns:* `x.c <= y.c`.
6415
+
6416
  ``` cpp
6417
  template<class T, class Container>
6418
  bool operator>=(const queue<T, Container>& x,
6419
  const queue<T, Container>& y);
6420
  ```
6421
 
6422
  *Returns:* `x.c >= y.c`.
6423
 
6424
+ ``` cpp
6425
+ template<class T, three_way_comparable Container>
6426
+ compare_three_way_result_t<Container>
6427
+ operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
6428
+ ```
6429
+
6430
+ *Returns:* `x.c <=> y.c`.
6431
+
6432
+ #### Specialized algorithms <a id="queue.special">[[queue.special]]</a>
6433
 
6434
  ``` cpp
6435
  template<class T, class Container>
6436
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
6437
  ```
6438
 
6439
+ *Constraints:* `is_swappable_v<Container>` is `true`.
 
6440
 
6441
  *Effects:* As if by `x.swap(y)`.
6442
 
6443
  ### Class template `priority_queue` <a id="priority.queue">[[priority.queue]]</a>
6444
 
6445
+ #### Overview <a id="priqueue.overview">[[priqueue.overview]]</a>
6446
+
6447
  Any sequence container with random access iterator and supporting
6448
  operations `front()`, `push_back()` and `pop_back()` can be used to
6449
+ instantiate `priority_queue`. In particular, `vector` [[vector]] and
6450
+ `deque` [[deque]] can be used. Instantiating `priority_queue` also
6451
  involves supplying a function or function object for making priority
6452
  comparisons; the library assumes that the function or function object
6453
+ defines a strict weak ordering [[alg.sorting]].
6454
 
6455
  ``` cpp
6456
  namespace std {
6457
  template<class T, class Container = vector<T>,
6458
  class Compare = less<typename Container::value_type>>
 
6468
  protected:
6469
  Container c;
6470
  Compare comp;
6471
 
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);
 
6523
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
6524
  : uses_allocator<Container, Alloc>::type { };
6525
  }
6526
  ```
6527
 
6528
+ #### Constructors <a id="priqueue.cons">[[priqueue.cons]]</a>
6529
 
6530
  ``` cpp
6531
  priority_queue(const Compare& x, const Container& y);
6532
+ priority_queue(const Compare& x, Container&& y);
6533
  ```
6534
 
6535
+ *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
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
 
6561
  ``` cpp
6562
  template<class Alloc> explicit priority_queue(const Alloc& a);
6563
  ```
6564
 
6565
+ *Effects:* Initializes `c` with `a` and value-initializes `comp`.
6566
 
6567
  ``` cpp
6568
  template<class Alloc> priority_queue(const Compare& compare, const Alloc& a);
6569
  ```
6570
 
6571
+ *Effects:* Initializes `c` with `a` and initializes `comp` with
6572
  `compare`.
6573
 
6574
  ``` cpp
6575
  template<class Alloc>
6576
  priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
6577
  ```
6578
 
6579
+ *Effects:* Initializes `c` with `cont` as the first argument and `a` as
6580
  the second argument, and initializes `comp` with `compare`; calls
6581
  `make_heap(c.begin(), c.end(), comp)`.
6582
 
6583
  ``` cpp
6584
  template<class Alloc>
6585
  priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
6586
  ```
6587
 
6588
+ *Effects:* Initializes `c` with `std::move(cont)` as the first argument
6589
  and `a` as the second argument, and initializes `comp` with `compare`;
6590
  calls `make_heap(c.begin(), c.end(), comp)`.
6591
 
6592
  ``` cpp
6593
  template<class Alloc> priority_queue(const priority_queue& q, const Alloc& a);
6594
  ```
6595
 
6596
+ *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
6597
  the second argument, and initializes `comp` with `q.comp`.
6598
 
6599
  ``` cpp
6600
  template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
6601
  ```
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
  ```
6612
 
 
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:
6636
 
6637
  ``` cpp
 
6648
  ``` cpp
6649
  pop_heap(c.begin(), c.end(), comp);
6650
  c.pop_back();
6651
  ```
6652
 
6653
+ #### Specialized algorithms <a id="priqueue.special">[[priqueue.special]]</a>
6654
 
6655
  ``` cpp
6656
  template<class T, class Container, class Compare>
6657
  void swap(priority_queue<T, Container, Compare>& x,
6658
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
6659
  ```
6660
 
6661
+ *Constraints:* `is_swappable_v<Container>` is `true` and
 
6662
  `is_swappable_v<Compare>` is `true`.
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>
6673
 
6674
  ``` cpp
6675
  namespace std {
6676
  template<class T, class Container = deque<T>>
6677
  class stack {
 
6684
 
6685
  protected:
6686
  Container c;
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>)
6709
  { using std::swap; swap(c, s.c); }
6710
  };
6711
 
 
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
  ```
6723
 
6724
+ #### Constructors <a id="stack.cons">[[stack.cons]]</a>
6725
 
6726
  ``` cpp
6727
  explicit stack(const Container& cont);
6728
  ```
6729
 
6730
  *Effects:* Initializes `c` with `cont`.
6731
 
6732
  ``` cpp
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
 
6743
  ``` cpp
6744
  template<class Alloc> explicit stack(const Alloc& a);
6745
  ```
6746
 
6747
+ *Effects:* Initializes `c` with `a`.
6748
 
6749
  ``` cpp
6750
  template<class Alloc> stack(const container_type& cont, const Alloc& a);
6751
  ```
6752
 
6753
+ *Effects:* Initializes `c` with `cont` as the first argument and `a` as
6754
  the second argument.
6755
 
6756
  ``` cpp
6757
  template<class Alloc> stack(container_type&& cont, const Alloc& a);
6758
  ```
6759
 
6760
+ *Effects:* Initializes `c` with `std::move(cont)` as the first argument
6761
  and `a` as the second argument.
6762
 
6763
  ``` cpp
6764
  template<class Alloc> stack(const stack& s, const Alloc& a);
6765
  ```
6766
 
6767
+ *Effects:* Initializes `c` with `s.c` as the first argument and `a` as
6768
  the second argument.
6769
 
6770
  ``` cpp
6771
  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);
6782
  ```
 
6795
  bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
6796
  ```
6797
 
6798
  *Returns:* `x.c < y.c`.
6799
 
 
 
 
 
 
 
 
6800
  ``` cpp
6801
  template<class T, class Container>
6802
  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
6803
  ```
6804
 
6805
  *Returns:* `x.c > y.c`.
6806
 
6807
+ ``` cpp
6808
+ template<class T, class Container>
6809
+ bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
6810
+ ```
6811
+
6812
+ *Returns:* `x.c <= y.c`.
6813
+
6814
  ``` cpp
6815
  template<class T, class Container>
6816
  bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
6817
  ```
6818
 
6819
  *Returns:* `x.c >= y.c`.
6820
 
6821
+ ``` cpp
6822
+ template<class T, three_way_comparable Container>
6823
+ compare_three_way_result_t<Container>
6824
+ operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
6825
+ ```
6826
+
6827
+ *Returns:* `x.c <=> y.c`.
6828
+
6829
+ #### Specialized algorithms <a id="stack.special">[[stack.special]]</a>
6830
 
6831
  ``` cpp
6832
  template<class T, class Container>
6833
  void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
6834
  ```
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();
6852
+
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;
6867
+
6868
+ template<class ElementType, size_t Extent>
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.
6882
+
6883
+ ``` cpp
6884
+ namespace std {
6885
+ template<class ElementType, size_t Extent = dynamic_extent>
6886
+ class span {
6887
+ public:
6888
+ // constants and types
6889
+ using element_type = ElementType;
6890
+ using value_type = remove_cv_t<ElementType>;
6891
+ using size_type = size_t;
6892
+ using difference_type = ptrdiff_t;
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>
6904
+ constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
6905
+ template<class It, class End>
6906
+ constexpr explicit(extent != dynamic_extent) span(It first, End last);
6907
+ template<size_t N>
6908
+ constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
6909
+ template<class T, size_t N>
6910
+ constexpr span(array<T, N>& arr) noexcept;
6911
+ template<class T, size_t N>
6912
+ constexpr span(const array<T, N>& arr) noexcept;
6913
+ template<class R>
6914
+ constexpr explicit(extent != dynamic_extent) span(R&& r);
6915
+ constexpr span(const span& other) noexcept = default;
6916
+ template<class OtherElementType, size_t OtherExtent>
6917
+ constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
6918
+
6919
+ ~span() noexcept = default;
6920
+
6921
+ constexpr span& operator=(const span& other) noexcept = default;
6922
+
6923
+ // [span.sub], subviews
6924
+ template<size_t Count>
6925
+ constexpr span<element_type, Count> first() const;
6926
+ template<size_t Count>
6927
+ constexpr span<element_type, Count> last() const;
6928
+ template<size_t Offset, size_t Count = dynamic_extent>
6929
+ constexpr span<element_type, see below> subspan() const;
6930
+
6931
+ constexpr span<element_type, dynamic_extent> first(size_type count) const;
6932
+ constexpr span<element_type, dynamic_extent> last(size_type count) const;
6933
+ constexpr span<element_type, dynamic_extent> subspan(
6934
+ size_type offset, size_type count = dynamic_extent) const;
6935
+
6936
+ // [span.obs], observers
6937
+ constexpr size_type size() const noexcept;
6938
+ constexpr size_type size_bytes() const noexcept;
6939
+ [[nodiscard]] constexpr bool empty() const noexcept;
6940
+
6941
+ // [span.elem], element access
6942
+ constexpr reference operator[](size_type idx) const;
6943
+ constexpr reference front() const;
6944
+ constexpr reference back() const;
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
+ };
6957
+
6958
+ template<class It, class EndOrSize>
6959
+ span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
6960
+ template<class T, size_t N>
6961
+ span(T (&)[N]) -> span<T, N>;
6962
+ template<class T, size_t N>
6963
+ span(array<T, N>&) -> span<T, N>;
6964
+ template<class T, size_t N>
6965
+ span(const array<T, N>&) -> span<const T, N>;
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
+
6980
+ *Constraints:* `Extent == dynamic_extent || Extent == 0` is `true`.
6981
+
6982
+ *Ensures:* `size() == 0 && data() == nullptr`.
6983
+
6984
+ ``` cpp
6985
+ template<class It>
6986
+ constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
6987
+ ```
6988
+
6989
+ *Constraints:* Let `U` be `remove_reference_t<iter_reference_t<It>>`.
6990
+
6991
+ - `It` satisfies `contiguous_iterator`.
6992
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
6993
+ \[*Note 1*: The intent is to allow only qualification conversions of
6994
+ the iterator reference type to `element_type`. — *end note*]
6995
+
6996
+ *Preconditions:*
6997
+
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>
7010
+ constexpr explicit(extent != dynamic_extent) span(It first, End last);
7011
+ ```
7012
+
7013
+ *Constraints:* Let `U` be `remove_reference_t<iter_reference_t<It>>`.
7014
+
7015
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
7016
+ \[*Note 2*: The intent is to allow only qualification conversions of
7017
+ the iterator reference type to `element_type`. — *end note*]
7018
+ - `It` satisfies `contiguous_iterator`.
7019
+ - `End` satisfies `sized_sentinel_for<It>`.
7020
+ - `is_convertible_v<End, size_t>` is `false`.
7021
+
7022
+ *Preconditions:*
7023
+
7024
+ - If `extent` is not equal to `dynamic_extent`, then `last - first` is
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;
7037
+ template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
7038
+ template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
7039
+ ```
7040
+
7041
+ *Constraints:* Let `U` be `remove_pointer_t<decltype(data(arr))>`.
7042
+
7043
+ - `extent == dynamic_extent || N == extent` is `true`, and
7044
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
7045
+ \[*Note 3*: The intent is to allow only qualification conversions of
7046
+ the array element type to `element_type`. — *end note*]
7047
+
7048
+ *Effects:* Constructs a `span` that is a view over the supplied array.
7049
+
7050
+ [*Note 1*: `type_identity_t` affects class template argument
7051
+ deduction. — *end note*]
7052
+
7053
+ *Ensures:* `size() == N && data() == data(arr)` is `true`.
7054
+
7055
+ ``` cpp
7056
+ template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
7057
+ ```
7058
+
7059
+ *Constraints:* Let `U` be
7060
+ `remove_reference_t<ranges::range_reference_t<R>>`.
7061
+
7062
+ - `R` satisfies `ranges::contiguous_range` and `ranges::sized_range`.
7063
+ - Either `R` satisfies `ranges::borrowed_range` or
7064
+ `is_const_v<element_type>` is `true`.
7065
+ - `remove_cvref_t<R>` is not a specialization of `span`.
7066
+ - `remove_cvref_t<R>` is not a specialization of `array`.
7067
+ - `is_array_v<remove_cvref_t<R>>` is `false`.
7068
+ - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
7069
+ \[*Note 4*: The intent is to allow only qualification conversions of
7070
+ the range reference type to `element_type`. — *end note*]
7071
+
7072
+ *Preconditions:*
7073
+
7074
+ - If `extent` is not equal to `dynamic_extent`, then `ranges::size(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;
7087
+ ```
7088
+
7089
+ *Ensures:* `other.size() == size() && other.data() == data()`.
7090
+
7091
+ ``` cpp
7092
+ template<class OtherElementType, size_t OtherExtent>
7093
+ constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
7094
+ ```
7095
+
7096
+ *Constraints:*
7097
+
7098
+ - `extent == dynamic_extent` `||` `OtherExtent == dynamic_extent` `||`
7099
+ `extent == OtherExtent` is `true`, and
7100
+ - `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is
7101
+ `true`. \[*Note 5*: The intent is to allow only qualification
7102
+ conversions of the `OtherElementType` to
7103
+ `element_type`. — *end note*]
7104
+
7105
+ *Preconditions:* If `extent` is not equal to `dynamic_extent`, then
7106
+ `s.size()` is equal to `extent`.
7107
+
7108
+ *Effects:* Constructs a `span` that is a view over the range
7109
+ \[`s.data()`, `s.data() + s.size()`).
7110
+
7111
+ *Ensures:* `size() == s.size() && data() == s.data()`.
7112
+
7113
+ *Remarks:* The expression inside `explicit` is equivalent to:
7114
+
7115
+ ``` cpp
7116
+ extent != dynamic_extent && OtherExtent == dynamic_extent
7117
+ ```
7118
+
7119
+ ``` cpp
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
+ ```
7131
+
7132
+ *Constraints:* `It` satisfies `contiguous_iterator`.
7133
+
7134
+ ``` cpp
7135
+ 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
+
7147
+ *Mandates:* `Count <= Extent` is `true`.
7148
+
7149
+ *Preconditions:* `Count <= size()` is `true`.
7150
+
7151
+ *Effects:* Equivalent to: `return R{data(), Count};` where `R` is the
7152
+ return type.
7153
+
7154
+ ``` cpp
7155
+ template<size_t Count> constexpr span<element_type, Count> last() const;
7156
+ ```
7157
+
7158
+ *Mandates:* `Count <= Extent` is `true`.
7159
+
7160
+ *Preconditions:* `Count <= size()` is `true`.
7161
+
7162
+ *Effects:* Equivalent to: `return R{data() + (size() - Count), Count};`
7163
+ where `R` is the return type.
7164
+
7165
+ ``` cpp
7166
+ template<size_t Offset, size_t Count = dynamic_extent>
7167
+ constexpr span<element_type, see below> subspan() const;
7168
+ ```
7169
+
7170
+ *Mandates:*
7171
+
7172
+ ``` cpp
7173
+ Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset)
7174
+ ```
7175
+
7176
+ is `true`.
7177
+
7178
+ *Preconditions:*
7179
+
7180
+ ``` cpp
7181
+ Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)
7182
+ ```
7183
+
7184
+ is `true`.
7185
+
7186
+ *Effects:* Equivalent to:
7187
+
7188
+ ``` cpp
7189
+ return span<ElementType, see below>(
7190
+ data() + Offset, Count != dynamic_extent ? Count : size() - Offset);
7191
+ ```
7192
+
7193
+ *Remarks:* The second template argument of the returned `span` type is:
7194
+
7195
+ ``` cpp
7196
+ Count != dynamic_extent ? Count
7197
+ : (Extent != dynamic_extent ? Extent - Offset
7198
+ : dynamic_extent)
7199
+ ```
7200
+
7201
+ ``` cpp
7202
+ constexpr span<element_type, dynamic_extent> first(size_type count) const;
7203
+ ```
7204
+
7205
+ *Preconditions:* `count <= size()` is `true`.
7206
+
7207
+ *Effects:* Equivalent to: `return {data(), count};`
7208
+
7209
+ ``` cpp
7210
+ constexpr span<element_type, dynamic_extent> last(size_type count) const;
7211
+ ```
7212
+
7213
+ *Preconditions:* `count <= size()` is `true`.
7214
+
7215
+ *Effects:* Equivalent to: `return {data() + (size() - count), count};`
7216
+
7217
+ ``` cpp
7218
+ constexpr span<element_type, dynamic_extent> subspan(
7219
+ size_type offset, size_type count = dynamic_extent) const;
7220
+ ```
7221
+
7222
+ *Preconditions:*
7223
+
7224
+ ``` cpp
7225
+ offset <= size() && (count == dynamic_extent || count <= size() - offset)
7226
+ ```
7227
+
7228
+ is `true`.
7229
+
7230
+ *Effects:* Equivalent to:
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
+
7248
+ *Effects:* Equivalent to: `return size() * sizeof(element_type);`
7249
+
7250
+ ``` cpp
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
+
7262
+ *Preconditions:* `idx < size()` is `true`.
7263
+
7264
+ *Effects:* Equivalent to: `return *(data() + idx);`
7265
+
7266
+ ``` cpp
7267
+ constexpr reference front() const;
7268
+ ```
7269
+
7270
+ *Preconditions:* `empty()` is `false`.
7271
+
7272
+ *Effects:* Equivalent to: `return *data();`
7273
+
7274
+ ``` cpp
7275
+ constexpr reference back() const;
7276
+ ```
7277
+
7278
+ *Preconditions:* `empty()` is `false`.
7279
+
7280
+ *Effects:* Equivalent to: `return *(data() + (size() - 1));`
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
+ ```
7304
+
7305
+ *Returns:* An iterator referring to the first element in the span. If
7306
+ `empty()` is `true`, then it returns the same value as `end()`.
7307
+
7308
+ ``` cpp
7309
+ constexpr iterator end() const noexcept;
7310
+ ```
7311
+
7312
+ *Returns:* An iterator which is the past-the-end value.
7313
+
7314
+ ``` cpp
7315
+ constexpr reverse_iterator rbegin() const noexcept;
7316
+ ```
7317
+
7318
+ *Effects:* Equivalent to: `return reverse_iterator(end());`
7319
+
7320
+ ``` cpp
7321
+ constexpr reverse_iterator rend() const noexcept;
7322
+ ```
7323
+
7324
+ *Effects:* Equivalent to: `return reverse_iterator(begin());`
7325
+
7326
+ #### Views of object representation <a id="span.objectrep">[[span.objectrep]]</a>
7327
+
7328
+ ``` cpp
7329
+ template<class ElementType, size_t Extent>
7330
+ span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
7331
+ as_bytes(span<ElementType, Extent> s) noexcept;
7332
+ ```
7333
+
7334
+ *Effects:* Equivalent to:
7335
+ `return R{reinterpret_cast<const byte*>(s.data()), s.size_bytes()};`
7336
+ where `R` is the return type.
7337
+
7338
+ ``` cpp
7339
+ template<class ElementType, size_t Extent>
7340
+ span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
7341
+ as_writable_bytes(span<ElementType, Extent> s) noexcept;
7342
+ ```
7343
+
7344
+ *Constraints:* `is_const_v<ElementType>` is `false`.
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
 
7363
  [array.special]: #array.special
 
7364
  [array.syn]: #array.syn
7365
  [array.tuple]: #array.tuple
7366
  [array.zero]: #array.zero
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
7425
+ [list.erasure]: #list.erasure
7426
  [list.modifiers]: #list.modifiers
7427
  [list.ops]: #list.ops
7428
  [list.overview]: #list.overview
 
7429
  [list.syn]: #list.syn
7430
  [map]: #map
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
 
7441
  [multiset]: #multiset
7442
  [multiset.cons]: #multiset.cons
7443
+ [multiset.erasure]: #multiset.erasure
7444
  [multiset.overview]: #multiset.overview
 
7445
  [priority.queue]: #priority.queue
7446
  [priqueue.cons]: #priqueue.cons
7447
  [priqueue.cons.alloc]: #priqueue.cons.alloc
7448
  [priqueue.members]: #priqueue.members
7449
+ [priqueue.overview]: #priqueue.overview
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
 
7460
  [sequence.reqmts]: #sequence.reqmts
7461
  [sequences]: #sequences
7462
  [sequences.general]: #sequences.general
7463
  [set]: #set
7464
  [set.cons]: #set.cons
7465
+ [set.erasure]: #set.erasure
7466
  [set.overview]: #set.overview
7467
+ [span.cons]: #span.cons
7468
+ [span.deduct]: #span.deduct
7469
+ [span.elem]: #span.elem
7470
+ [span.iterators]: #span.iterators
7471
+ [span.objectrep]: #span.objectrep
7472
+ [span.obs]: #span.obs
7473
+ [span.overview]: #span.overview
7474
+ [span.sub]: #span.sub
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
7498
  [unord.map.elem]: #unord.map.elem
7499
+ [unord.map.erasure]: #unord.map.erasure
7500
  [unord.map.modifiers]: #unord.map.modifiers
7501
  [unord.map.overview]: #unord.map.overview
 
7502
  [unord.map.syn]: #unord.map.syn
7503
  [unord.multimap]: #unord.multimap
7504
  [unord.multimap.cnstr]: #unord.multimap.cnstr
7505
+ [unord.multimap.erasure]: #unord.multimap.erasure
7506
  [unord.multimap.modifiers]: #unord.multimap.modifiers
7507
  [unord.multimap.overview]: #unord.multimap.overview
 
7508
  [unord.multiset]: #unord.multiset
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
 
7535
  [^2]: These member functions are only provided by containers whose