From Jason Turner

[containers]

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

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpldpya7hb/{from.md → to.md} +6677 -3046
tmp/tmpldpya7hb/{from.md → to.md} RENAMED
@@ -10,13 +10,13 @@ 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>`, `<flat_map>`, `<flat_set>` |
21
  | [[views]] | Views | `<span>`, `<mdspan>` |
22
 
@@ -48,15 +48,15 @@ for internal types used by the container.
48
 
49
  [*Note 1*: This means, for example, that a node-based container would
50
  need to construct nodes containing aligned buffers and call `construct`
51
  to place the element into the buffer. — *end note*]
52
 
53
- ### General containers <a id="container.gen.reqmts">[[container.gen.reqmts]]</a>
54
 
55
- #### General <a id="container.requirements.general">[[container.requirements.general]]</a>
56
 
57
- In subclause [[container.gen.reqmts]],
58
 
59
  - `X` denotes a container class containing objects of type `T`,
60
  - `a` denotes a value of type `X`,
61
  - `b` and `c` denote values of type (possibly const) `X`,
62
  - `i` and `j` denote values of type (possibly const) `X::iterator`,
@@ -73,11 +73,11 @@ containers:
73
  template<class R, class T>
74
  concept container-compatible-range = // exposition only
75
  ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;
76
  ```
77
 
78
- #### Containers <a id="container.reqmts">[[container.reqmts]]</a>
79
 
80
  A type `X` meets the *container* requirements if the following types,
81
  statements, and expressions are well-formed and have the specified
82
  semantics.
83
 
@@ -157,15 +157,15 @@ X u = rv;
157
  ```
158
 
159
  *Ensures:* `u` is equal to the value that `rv` had before this
160
  construction.
161
 
162
- *Complexity:* Linear for `array` and constant for all other standard
163
- containers.
164
 
165
  ``` cpp
166
- t = v;
167
  ```
168
 
169
  *Result:* `X&`.
170
 
171
  *Ensures:* `t == v`.
@@ -278,12 +278,12 @@ t.swap(s)
278
 
279
  *Result:* `void`.
280
 
281
  *Effects:* Exchanges the contents of `t` and `s`.
282
 
283
- *Complexity:* Linear for `array` and constant for all other standard
284
- containers.
285
 
286
  ``` cpp
287
  swap(t, s)
288
  ```
289
 
@@ -365,11 +365,11 @@ these container types take a `const allocator_type&` argument.
365
  [*Note 2*: If an invocation of a constructor uses the default value of
366
  an optional allocator argument, then the allocator type must support
367
  value-initialization. — *end note*]
368
 
369
  A copy of this allocator is used for any memory allocation and element
370
- construction performed, by these constructors and by all member
371
  functions, during the lifetime of each container object or until the
372
  allocator is replaced. The allocator may be replaced only via assignment
373
  or `swap()`. Allocator replacement is performed by copy assignment, move
374
  assignment, or swapping of the allocator only if
375
 
@@ -383,15 +383,15 @@ operation. In all container types defined in this Clause, the member
383
  `get_allocator()` returns a copy of the allocator used to construct the
384
  container or, if that allocator has been replaced, a copy of the most
385
  recent replacement.
386
 
387
  The expression `a.swap(b)`, for containers `a` and `b` of a standard
388
- container type other than `array`, shall exchange the values of `a` and
389
- `b` without invoking any move, copy, or swap operations on the
390
- individual container elements. Any `Compare`, `Pred`, or `Hash` types
391
- belonging to `a` and `b` shall meet the *Cpp17Swappable* requirements
392
- and shall be exchanged by calling `swap` as described in 
393
  [[swappable.requirements]]. If
394
  `allocator_traits<allocator_type>::propagate_on_container_swap::value`
395
  is `true`, then `allocator_type` shall meet the *Cpp17Swappable*
396
  requirements and the allocators of `a` and `b` shall also be exchanged
397
  by calling `swap` as described in  [[swappable.requirements]].
@@ -401,13 +401,13 @@ iterator referring to an element in one container before the swap shall
401
  refer to the same element in the other container after the swap. It is
402
  unspecified whether an iterator with value `a.end()` before the swap
403
  will have value `b.end()` after the swap.
404
 
405
  Unless otherwise specified (see  [[associative.reqmts.except]],
406
- [[unord.req.except]], [[deque.modifiers]], and [[vector.modifiers]]) all
407
- container types defined in this Clause meet the following additional
408
- requirements:
409
 
410
  - If an exception is thrown by an `insert()` or `emplace()` function
411
  while inserting a single element, that function has no effects.
412
  - If an exception is thrown by a `push_back()`, `push_front()`,
413
  `emplace_back()`, or `emplace_front()` function, that function has no
@@ -523,13 +523,13 @@ are implemented by constexpr functions.
523
  a <=> b
524
  ```
525
 
526
  *Result:* *`synth-three-way-result`*`<X::value_type>`.
527
 
528
- *Preconditions:* Either `<=>` is defined for values of type (possibly
529
- const) `T`, or `<` is defined for values of type (possibly const) `T`
530
- and `<` is a total ordering relationship.
531
 
532
  *Returns:*
533
  `lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(), `*`synth-three-way`*`)`
534
 
535
  [*Note 1*: The algorithm `lexicographical_compare_three_way` is defined
@@ -537,23 +537,25 @@ in [[algorithms]]. — *end note*]
537
 
538
  *Complexity:* Linear.
539
 
540
  #### Allocator-aware containers <a id="container.alloc.reqmts">[[container.alloc.reqmts]]</a>
541
 
542
- All of the containers defined in [[containers]] and in  [[basic.string]]
543
- except `array` meet the additional requirements of an
 
544
  *allocator-aware container*, as described below.
545
 
546
  Given an allocator type `A` and given a container type `X` having a
547
  `value_type` identical to `T` and an `allocator_type` identical to
548
  `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
549
- `A`, a pointer `p` of type `T*`, an expression `v` of type `T` or
550
- `const T`, and an rvalue `rv` of type `T`, the following terms are
551
- defined. If `X` is not allocator-aware or is a specialization of
552
- `basic_string`, the terms below are defined as if `A` were
553
- `allocator<T>` — no allocator object needs to be created and user
554
- specializations of `allocator<T>` are not instantiated:
 
555
 
556
  - `T` is **Cpp17DefaultInsertable* into `X`* means that the following
557
  expression is well-formed:
558
  ``` cpp
559
  allocator_traits<A>::construct(m, p)
@@ -574,11 +576,11 @@ specializations of `allocator<T>` are not instantiated:
574
 
575
  and its evaluation causes the following postcondition to hold: The
576
  value of `*p` is equivalent to the value of `rv` before the
577
  evaluation.
578
  \[*Note 1*: `rv` remains a valid object. Its state is
579
- unspecified — *end note*]
580
  - `T` is **Cpp17CopyInsertable* into `X`* means that, in addition to `T`
581
  being *Cpp17MoveInsertable* into `X`, the following expression is
582
  well-formed:
583
  ``` cpp
584
  allocator_traits<A>::construct(m, p, v)
@@ -658,11 +660,11 @@ X u(m);
658
  X u(t, m);
659
  ```
660
 
661
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
662
 
663
- *Ensures:* `u == t`, `u.get_allocator() == m`
664
 
665
  *Complexity:* Linear.
666
 
667
  ``` cpp
668
  X u(rv);
@@ -748,29 +750,22 @@ can result in a data race. As an exception to the general rule, for a
748
  `y[1] = true`. — *end note*]
749
 
750
  ### Sequence containers <a id="sequence.reqmts">[[sequence.reqmts]]</a>
751
 
752
  A sequence container organizes a finite set of objects, all of the same
753
- type, into a strictly linear arrangement. The library provides four
754
- basic kinds of sequence containers: `vector`, `forward_list`, `list`,
755
- and `deque`. In addition, `array` is provided as a sequence container
756
- which provides limited sequence operations because it has a fixed number
757
- of elements. The library also provides container adaptors that make it
 
 
758
  easy to construct abstract data types, such as `stack`s, `queue`s,
759
  `flat_map`s, `flat_multimap`s, `flat_set`s, or `flat_multiset`s, out of
760
  the basic sequence container kinds (or out of other program-defined
761
  sequence containers).
762
 
763
- [*Note 1*: The sequence containers offer the programmer different
764
- complexity trade-offs. `vector` is appropriate in most circumstances.
765
- `array` has a fixed size known during translation. `list` or
766
- `forward_list` support frequent insertions and deletions from the middle
767
- of the sequence. `deque` supports efficient insertions and deletions
768
- taking place at the beginning or at the end of the sequence. When
769
- choosing a container, remember `vector` is best; leave a comment to
770
- explain if you choose from the rest! — *end note*]
771
-
772
  In this subclause,
773
 
774
  - `X` denotes a sequence container class,
775
  - `a` denotes a value of type `X` containing elements of type `T`,
776
  - `u` denotes the name of a variable being declared,
@@ -778,18 +773,18 @@ In this subclause,
778
  `X::allocator_type` is valid and denotes a type [[temp.deduct]] and
779
  `allocator<T>` if it doesn’t,
780
  - `i` and `j` denote iterators that meet the *Cpp17InputIterator*
781
  requirements and refer to elements implicitly convertible to
782
  `value_type`,
783
- - `[i, j)` denotes a valid range,
784
  - `rg` denotes a value of a type `R` that models
785
  `container-compatible-range<T>`,
786
  - `il` designates an object of type `initializer_list<value_type>`,
787
  - `n` denotes a value of type `X::size_type`,
788
  - `p` denotes a valid constant iterator to `a`,
789
  - `q` denotes a valid dereferenceable constant iterator to `a`,
790
- - `[q1, q2)` denotes a valid range of constant iterators in `a`,
791
  - `t` denotes an lvalue or a const rvalue of `X::value_type`, and
792
  - `rv` denotes a non-const rvalue of `X::value_type`.
793
  - `Args` denotes a template parameter pack;
794
  - `args` denotes a function parameter pack with the pattern `Args&&`.
795
 
@@ -816,27 +811,34 @@ X u(i, j);
816
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
817
  For `vector`, if the iterator does not meet the *Cpp17ForwardIterator*
818
  requirements [[forward.iterators]], `T` is also *Cpp17MoveInsertable*
819
  into `X`.
820
 
821
- *Effects:* Constructs a sequence container equal to the range `[i, j)`.
822
- Each iterator in the range \[`i`, `j`) is dereferenced exactly once.
 
823
 
824
  *Ensures:* `distance(u.begin(), u.end()) == distance(i, j)` is `true`.
825
 
826
  ``` cpp
827
  X(from_range, rg)
828
  ```
829
 
830
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
831
- `*ranges::begin(rg)`. For `vector`, if `R` models neither
832
- `ranges::sized_range` nor `ranges::forward_range`, `T` is also
833
- *Cpp17MoveInsertable* into `X`.
 
834
 
835
  *Effects:* Constructs a sequence container equal to the range `rg`. Each
836
  iterator in the range `rg` is dereferenced exactly once.
837
 
 
 
 
 
 
838
  *Ensures:* `distance(begin(), end()) == ranges::distance(rg)` is `true`.
839
 
840
  ``` cpp
841
  X(il)
842
  ```
@@ -862,30 +864,29 @@ a.emplace(p, args)
862
  ```
863
 
864
  *Result:* `iterator`.
865
 
866
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
867
- `args`. For `vector` and `deque`, `T` is also *Cpp17MoveInsertable* into
868
- `X` and *Cpp17MoveAssignable*.
869
 
870
  *Effects:* Inserts an object of type `T` constructed with
871
  `std::forward<Args>(args)...` before `p`.
872
 
873
  [*Note 1*: `args` can directly or indirectly refer to a value in
874
  `a`. — *end note*]
875
 
876
- *Returns:* An iterator that points to the new element constructed from
877
- `args` into `a`.
878
 
879
  ``` cpp
880
  a.insert(p, t)
881
  ```
882
 
883
  *Result:* `iterator`.
884
 
885
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`. For `vector` and
886
- `deque`, `T` is also *Cpp17CopyAssignable*.
887
 
888
  *Effects:* Inserts a copy of `t` before `p`.
889
 
890
  *Returns:* An iterator that points to the copy of `t` inserted into `a`.
891
 
@@ -893,12 +894,12 @@ a.insert(p, t)
893
  a.insert(p, rv)
894
  ```
895
 
896
  *Result:* `iterator`.
897
 
898
- *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`. For `vector` and
899
- `deque`, `T` is also *Cpp17MoveAssignable*.
900
 
901
  *Effects:* Inserts a copy of `rv` before `p`.
902
 
903
  *Returns:* An iterator that points to the copy of `rv` inserted into
904
  `a`.
@@ -922,16 +923,17 @@ a.insert(p, i, j)
922
  ```
923
 
924
  *Result:* `iterator`.
925
 
926
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
927
- For `vector` and `deque`, `T` is also *Cpp17MoveInsertable* into `X`,
928
- and `T` meets the *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
 
929
  *Cpp17Swappable*[[swappable.requirements]] requirements. Neither `i` nor
930
  `j` are iterators into `a`.
931
 
932
- *Effects:* Inserts copies of elements in `[i, j)` before `p`. Each
933
  iterator in the range \[`i`, `j`) shall be dereferenced exactly once.
934
 
935
  *Returns:* An iterator that points to the copy of the first element
936
  inserted into `a`, or `p` if `i == j`.
937
 
@@ -940,12 +942,12 @@ a.insert_range(p, rg)
940
  ```
941
 
942
  *Result:* `iterator`.
943
 
944
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
945
- `*ranges::begin(rg)`. For `vector` and `deque`, `T` is also
946
- *Cpp17MoveInsertable* into `X`, and `T` meets the
947
  *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
948
  *Cpp17Swappable*[[swappable.requirements]] requirements. `rg` and `a` do
949
  not overlap.
950
 
951
  *Effects:* Inserts copies of elements in `rg` before `p`. Each iterator
@@ -964,11 +966,12 @@ a.insert(p, il)
964
  a.erase(q)
965
  ```
966
 
967
  *Result:* `iterator`.
968
 
969
- *Preconditions:* For `vector` and `deque`, `T` is *Cpp17MoveAssignable*.
 
970
 
971
  *Effects:* Erases the element pointed to by `q`.
972
 
973
  *Returns:* An iterator that points to the element immediately following
974
  `q` prior to the element being erased. If no such element exists,
@@ -978,13 +981,14 @@ a.erase(q)
978
  a.erase(q1, q2)
979
  ```
980
 
981
  *Result:* `iterator`.
982
 
983
- *Preconditions:* For `vector` and `deque`, `T` is *Cpp17MoveAssignable*.
 
984
 
985
- *Effects:* Erases the elements in the range `[q1, q2)`.
986
 
987
  *Returns:* An iterator that points to the element pointed to by `q2`
988
  prior to any elements being erased. If no such element exists, `a.end()`
989
  is returned.
990
 
@@ -1012,14 +1016,15 @@ a.assign(i, j)
1012
  and assignable from `*i`. For `vector`, if the iterator does not meet
1013
  the forward iterator requirements [[forward.iterators]], `T` is also
1014
  *Cpp17MoveInsertable* into `X`. Neither `i` nor `j` are iterators into
1015
  `a`.
1016
 
1017
- *Effects:* Replaces elements in `a` with a copy of `[i, j)`. Invalidates
1018
- all references, pointers and iterators referring to the elements of `a`.
1019
- For `vector` and `deque`, also invalidates the past-the-end iterator.
1020
- Each iterator in the range \[`i`, `j`) is dereferenced exactly once.
 
1021
 
1022
  ``` cpp
1023
  a.assign_range(rg)
1024
  ```
1025
 
@@ -1027,20 +1032,26 @@ a.assign_range(rg)
1027
 
1028
  *Mandates:* `assignable_from<T&, ranges::range_reference_t<R>>` is
1029
  modeled.
1030
 
1031
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1032
- `*ranges::begin(rg)`. For `vector`, if `R` models neither
1033
- `ranges::sized_range` nor `ranges::forward_range`, `T` is also
1034
- *Cpp17MoveInsertable* into `X`. `rg` and `a` do not overlap.
 
1035
 
1036
  *Effects:* Replaces elements in `a` with a copy of each element in `rg`.
1037
  Invalidates all references, pointers, and iterators referring to the
1038
  elements of `a`. For `vector` and `deque`, also invalidates the
1039
  past-the-end iterator. Each iterator in the range `rg` is dereferenced
1040
  exactly once.
1041
 
 
 
 
 
 
1042
  ``` cpp
1043
  a.assign(il)
1044
  ```
1045
 
1046
  *Effects:* Equivalent to `a.assign(il.begin(), il.end())`.
@@ -1102,31 +1113,35 @@ containers but not others. Operations other than `prepend_range` and
1102
  a.front()
1103
  ```
1104
 
1105
  *Result:* `reference; const_reference` for constant `a`.
1106
 
 
 
1107
  *Returns:* `*a.begin()`
1108
 
1109
  *Remarks:* Required for `basic_string`, `array`, `deque`,
1110
- `forward_list`, `list`, and `vector`.
1111
 
1112
  ``` cpp
1113
  a.back()
1114
  ```
1115
 
1116
  *Result:* `reference; const_reference` for constant `a`.
1117
 
 
 
1118
  *Effects:* Equivalent to:
1119
 
1120
  ``` cpp
1121
  auto tmp = a.end();
1122
  --tmp;
1123
  return *tmp;
1124
  ```
1125
 
1126
- *Remarks:* Required for `basic_string`, `array`, `deque`, `list`, and
1127
- `vector`.
1128
 
1129
  ``` cpp
1130
  a.emplace_front(args)
1131
  ```
1132
 
@@ -1154,11 +1169,11 @@ a.emplace_back(args)
1154
  *Effects:* Appends an object of type `T` constructed with
1155
  `std::forward<Args>(args)...`.
1156
 
1157
  *Returns:* `a.back()`.
1158
 
1159
- *Remarks:* Required for `deque`, `list`, and `vector`.
1160
 
1161
  ``` cpp
1162
  a.push_front(t)
1163
  ```
1164
 
@@ -1210,11 +1225,12 @@ a.push_back(t)
1210
 
1211
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
1212
 
1213
  *Effects:* Appends a copy of `t`.
1214
 
1215
- *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
 
1216
 
1217
  ``` cpp
1218
  a.push_back(rv)
1219
  ```
1220
 
@@ -1222,11 +1238,12 @@ a.push_back(rv)
1222
 
1223
  *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
1224
 
1225
  *Effects:* Appends a copy of `rv`.
1226
 
1227
- *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
 
1228
 
1229
  ``` cpp
1230
  a.append_range(rg)
1231
  ```
1232
 
@@ -1237,19 +1254,19 @@ a.append_range(rg)
1237
  into `X`.
1238
 
1239
  *Effects:* Inserts copies of elements in `rg` before `end()`. Each
1240
  iterator in the range `rg` is dereferenced exactly once.
1241
 
1242
- *Remarks:* Required for `deque`, `list`, and `vector`.
1243
 
1244
  ``` cpp
1245
  a.pop_front()
1246
  ```
1247
 
1248
  *Result:* `void`
1249
 
1250
- *Preconditions:* `a.empty()` is `false`.
1251
 
1252
  *Effects:* Destroys the first element.
1253
 
1254
  *Remarks:* Required for `deque`, `forward_list`, and `list`.
1255
 
@@ -1257,37 +1274,42 @@ a.pop_front()
1257
  a.pop_back()
1258
  ```
1259
 
1260
  *Result:* `void`
1261
 
1262
- *Preconditions:* `a.empty()` is `false`.
1263
 
1264
  *Effects:* Destroys the last element.
1265
 
1266
- *Remarks:* Required for `basic_string`, `deque`, `list`, and `vector`.
 
1267
 
1268
  ``` cpp
1269
  a[n]
1270
  ```
1271
 
1272
- *Result:* `reference; const_reference` for constant `a`
1273
 
1274
- *Returns:* `*(a.begin() + n)`
1275
 
1276
- *Remarks:* Required for `basic_string`, `array`, `deque`, and `vector`.
 
 
 
1277
 
1278
  ``` cpp
1279
  a.at(n)
1280
  ```
1281
 
1282
- *Result:* `reference; const_reference` for constant `a`
1283
 
1284
  *Returns:* `*(a.begin() + n)`
1285
 
1286
  *Throws:* `out_of_range` if `n >= a.size()`.
1287
 
1288
- *Remarks:* Required for `basic_string`, `array`, `deque`, and `vector`.
 
1289
 
1290
  ### Node handles <a id="container.node">[[container.node]]</a>
1291
 
1292
  #### Overview <a id="container.node.overview">[[container.node.overview]]</a>
1293
 
@@ -1333,167 +1355,170 @@ public:
1333
  using key_type = see below; // not present for set containers
1334
  using mapped_type = see below; // not present for set containers
1335
  using allocator_type = see below;
1336
 
1337
  private:
1338
- using container_node_type = unspecified; // exposition only
1339
- using ator_traits = allocator_traits<allocator_type>; // exposition only
1340
 
1341
- typename ator_traits::template
1342
- rebind_traits<container_node_type>::pointer ptr_; // exposition only
1343
  optional<allocator_type> alloc_; // exposition only
1344
 
1345
  public:
1346
  // [container.node.cons], constructors, copy, and assignment
1347
  constexpr node-handle() noexcept : ptr_(), alloc_() {}
1348
- node-handle(node-handle&&) noexcept;
1349
- node-handle& operator=(node-handle&&);
1350
 
1351
  // [container.node.dtor], destructor
1352
- ~node-handle();
1353
 
1354
  // [container.node.observers], observers
1355
- value_type& value() const; // not present for map containers
1356
  key_type& key() const; // not present for set containers
1357
- mapped_type& mapped() const; // not present for set containers
1358
 
1359
- allocator_type get_allocator() const;
1360
- explicit operator bool() const noexcept;
1361
- [[nodiscard]] bool empty() const noexcept;
1362
 
1363
  // [container.node.modifiers], modifiers
1364
- void swap(node-handle&)
1365
- noexcept(ator_traits::propagate_on_container_swap::value ||
1366
- ator_traits::is_always_equal::value);
1367
 
1368
- friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
1369
  x.swap(y);
1370
  }
1371
  };
1372
  ```
1373
 
1374
  #### Constructors, copy, and assignment <a id="container.node.cons">[[container.node.cons]]</a>
1375
 
1376
  ``` cpp
1377
- node-handle(node-handle&& nh) noexcept;
1378
  ```
1379
 
1380
- *Effects:* Constructs a *node-handle* object initializing `ptr_` with
1381
- `nh.ptr_`. Move constructs `alloc_` with `nh.alloc_`. Assigns `nullptr`
1382
- to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
1383
 
1384
  ``` cpp
1385
- node-handle& operator=(node-handle&& nh);
1386
  ```
1387
 
1388
- *Preconditions:* Either `!alloc_`, or
1389
- `ator_traits::propagate_on_container_move_assignment::value` is `true`,
1390
- or `alloc_ == nh.alloc_`.
1391
 
1392
  *Effects:*
1393
 
1394
- - If `ptr_ != nullptr`, destroys the `value_type` subobject in the
1395
- `container_node_type` object pointed to by `ptr_` by calling
1396
- `ator_traits::destroy`, then deallocates `ptr_` by calling
1397
- `ator_traits::template rebind_traits<container_node_type>::deallocate`.
1398
- - Assigns `nh.ptr_` to `ptr_`.
1399
- - If `!alloc` or
1400
- `ator_traits::propagate_on_container_move_assignment::value` is
1401
- `true`, move assigns `nh.alloc_` to `alloc_`.
1402
- - Assigns `nullptr` to `nh.ptr_` and assigns `nullopt` to `nh.alloc_`.
 
 
1403
 
1404
  *Returns:* `*this`.
1405
 
1406
  *Throws:* Nothing.
1407
 
1408
  #### Destructor <a id="container.node.dtor">[[container.node.dtor]]</a>
1409
 
1410
  ``` cpp
1411
- ~node-handle();
1412
  ```
1413
 
1414
- *Effects:* If `ptr_ != nullptr`, destroys the `value_type` subobject in
1415
- the `container_node_type` object pointed to by `ptr_` by calling
1416
- `ator_traits::destroy`, then deallocates `ptr_` by calling
1417
- `ator_traits::template rebind_traits<container_node_type>::deallocate`.
1418
 
1419
  #### Observers <a id="container.node.observers">[[container.node.observers]]</a>
1420
 
1421
  ``` cpp
1422
- value_type& value() const;
1423
  ```
1424
 
1425
  *Preconditions:* `empty() == false`.
1426
 
1427
  *Returns:* A reference to the `value_type` subobject in the
1428
- `container_node_type` object pointed to by `ptr_`.
1429
 
1430
  *Throws:* Nothing.
1431
 
1432
  ``` cpp
1433
  key_type& key() const;
1434
  ```
1435
 
1436
  *Preconditions:* `empty() == false`.
1437
 
1438
  *Returns:* A non-const reference to the `key_type` member of the
1439
- `value_type` subobject in the `container_node_type` object pointed to by
1440
- `ptr_`.
1441
 
1442
  *Throws:* Nothing.
1443
 
1444
  *Remarks:* Modifying the key through the returned reference is
1445
  permitted.
1446
 
1447
  ``` cpp
1448
- mapped_type& mapped() const;
1449
  ```
1450
 
1451
  *Preconditions:* `empty() == false`.
1452
 
1453
  *Returns:* A reference to the `mapped_type` member of the `value_type`
1454
- subobject in the `container_node_type` object pointed to by `ptr_`.
1455
 
1456
  *Throws:* Nothing.
1457
 
1458
  ``` cpp
1459
- allocator_type get_allocator() const;
1460
  ```
1461
 
1462
  *Preconditions:* `empty() == false`.
1463
 
1464
- *Returns:* `*alloc_`.
1465
 
1466
  *Throws:* Nothing.
1467
 
1468
  ``` cpp
1469
- explicit operator bool() const noexcept;
1470
  ```
1471
 
1472
- *Returns:* `ptr_ != nullptr`.
1473
 
1474
  ``` cpp
1475
- [[nodiscard]] bool empty() const noexcept;
1476
  ```
1477
 
1478
- *Returns:* `ptr_ == nullptr`.
1479
 
1480
  #### Modifiers <a id="container.node.modifiers">[[container.node.modifiers]]</a>
1481
 
1482
  ``` cpp
1483
- void swap(node-handle& nh)
1484
- noexcept(ator_traits::propagate_on_container_swap::value ||
1485
- ator_traits::is_always_equal::value);
1486
  ```
1487
 
1488
- *Preconditions:* `!alloc_`, or `!nh.alloc_`, or
1489
- `ator_traits::propagate_on_container_swap::value` is `true`, or
1490
- `alloc_ == nh.alloc_`.
1491
 
1492
- *Effects:* Calls `swap(ptr_, nh.ptr_)`. If `!alloc_`, or `!nh.alloc_`,
1493
- or `ator_traits::propagate_on_container_swap::value` is `true` calls
1494
- `swap(alloc_, nh.alloc_)`.
 
1495
 
1496
  ### Insert return type <a id="container.insert.return">[[container.insert.return]]</a>
1497
 
1498
  The associative containers with unique keys and the unordered containers
1499
  with unique keys have a member function `insert` that returns a nested
@@ -1508,11 +1533,11 @@ struct insert-return-type
1508
  bool inserted;
1509
  NodeType node;
1510
  };
1511
  ```
1512
 
1513
- The name *`insert-return-type`* is exposition only.
1514
  *`insert-return-type`* has the template parameters, data members, and
1515
  special members specified above. It has no base classes or members other
1516
  than those specified.
1517
 
1518
  ### Associative containers <a id="associative.reqmts">[[associative.reqmts]]</a>
@@ -1571,14 +1596,14 @@ In this subclause,
1571
 
1572
  - `X` denotes an associative container class,
1573
  - `a` denotes a value of type `X`,
1574
  - `a2` denotes a value of a type with nodes compatible with type `X` (
1575
  [[container.node.compat]]),
1576
- - `b` denotes a value or type `X` or `const X`,
1577
  - `u` denotes the name of a variable being declared,
1578
  - `a_uniq` denotes a value of type `X` when `X` supports unique keys,
1579
- - `a_eq` denotes a value of type `X` when `X` supports multiple keys,
1580
  - `a_tran` denotes a value of type `X` or `const X` when the
1581
  *qualified-id* `X::key_compare::is_transparent` is valid and denotes a
1582
  type [[temp.deduct]],
1583
  - `i` and `j` meet the *Cpp17InputIterator* requirements and refer to
1584
  elements implicitly convertible to `value_type`,
@@ -1586,11 +1611,11 @@ In this subclause,
1586
  - `rg` denotes a value of a type `R` that models
1587
  `container-compatible-range<value_type>`,
1588
  - `p` denotes a valid constant iterator to `a`,
1589
  - `q` denotes a valid dereferenceable constant iterator to `a`,
1590
  - `r` denotes a valid dereferenceable iterator to `a`,
1591
- - `[q1, q2)` denotes a valid range of constant iterators in `a`,
1592
  - `il` designates an object of type `initializer_list<value_type>`,
1593
  - `t` denotes a value of type `X::value_type`,
1594
  - `k` denotes a value of type `X::key_type`, and
1595
  - `c` denotes a value of type `X::key_compare` or
1596
  `const X::key_compare`;
@@ -1612,19 +1637,18 @@ In this subclause,
1612
  - `m` denotes an allocator of a type convertible to `A`, and `nh`
1613
  denotes a non-const rvalue of type `X::node_type`.
1614
 
1615
  A type `X` meets the *associative container* requirements if `X` meets
1616
  all the requirements of an allocator-aware container
1617
- [[container.requirements.general]] and the following types, statements,
1618
- and expressions are well-formed and have the specified semantics, except
1619
  that for `map` and `multimap`, the requirements placed on `value_type`
1620
- in [[container.alloc.reqmts]] apply instead to `key_type` and
1621
- `mapped_type`.
1622
 
1623
- [*Note 3*: For example, in some cases `key_type` and `mapped_type` are
1624
- required to be *Cpp17CopyAssignable* even though the associated
1625
- `value_type`, `pair<const key_type, mapped_type>`, is not
1626
  *Cpp17CopyAssignable*. — *end note*]
1627
 
1628
  ``` cpp
1629
  typename X::key_type
1630
  ```
@@ -1843,12 +1867,11 @@ a.emplace_hint(p, args)
1843
 
1844
  *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`,
1845
  except that the element is inserted as close as possible to the position
1846
  just prior to `p`.
1847
 
1848
- *Returns:* An iterator pointing to the element with the key equivalent
1849
- to the newly inserted element.
1850
 
1851
  *Complexity:* Logarithmic in general, but amortized constant if the
1852
  element is inserted right before `p`.
1853
 
1854
  ``` cpp
@@ -2057,21 +2080,22 @@ a.extract(q)
2057
  a.merge(a2)
2058
  ```
2059
 
2060
  *Result:* `void`
2061
 
2062
- *Preconditions:* `a.get_allocator() == a2.get_allocator()`.
2063
 
2064
  *Effects:* Attempts to extract each element in `a2` and insert it into
2065
  `a` using the comparison object of `a`. In containers with unique keys,
2066
  if there is an element in `a` with key equivalent to the key of an
2067
  element from `a2`, then that element is not extracted from `a2`.
2068
 
2069
  *Ensures:* Pointers and references to the transferred elements of `a2`
2070
- refer to those same elements but as members of `a`. Iterators referring
2071
- to the transferred elements will continue to refer to their elements,
2072
- but they now behave as iterators into `a`, not into `a2`.
 
2073
 
2074
  *Throws:* Nothing unless the comparison object throws.
2075
 
2076
  *Complexity:* N log(`a.size()+` N), where N has the value `a2.size()`.
2077
 
@@ -2243,11 +2267,11 @@ b.upper_bound(k)
2243
  *Result:* `iterator`; `const_iterator` for constant `b`.
2244
 
2245
  *Returns:* An iterator pointing to the first element with key greater
2246
  than `k`, or `b.end()` if such an element is not found.
2247
 
2248
- *Complexity:* Logarithmic,
2249
 
2250
  ``` cpp
2251
  a_tran.upper_bound(ku)
2252
  ```
2253
 
@@ -2445,17 +2469,17 @@ In this subclause,
2445
  - `a_tran` denotes a value of type `X` or `const X` when the
2446
  *qualified-id*s `X::key_equal::is_transparent` and
2447
  `X::hasher::is_transparent` are both valid and denote types
2448
  [[temp.deduct]],
2449
  - `i` and `j` denote input iterators that refer to `value_type`,
2450
- - `[i, j)` denotes a valid range,
2451
  - `rg` denotes a value of a type `R` that models
2452
  `container-compatible-range<value_type>`,
2453
  - `p` and `q2` denote valid constant iterators to `a`,
2454
  - `q` and `q1` denote valid dereferenceable constant iterators to `a`,
2455
  - `r` denotes a valid dereferenceable iterator to `a`,
2456
- - `[q1, q2)` denotes a valid range in `a`,
2457
  - `il` denotes a value of type `initializer_list<value_type>`,
2458
  - `t` denotes a value of type `X::value_type`,
2459
  - `k` denotes a value of type `key_type`,
2460
  - `hf` denotes a value of type `hasher` or `const hasher`,
2461
  - `eq` denotes a value of type `key_equal` or `const key_equal`,
@@ -2478,19 +2502,19 @@ In this subclause,
2478
  - `z` denotes a value of type `float`, and
2479
  - `nh` denotes an rvalue of type `X::node_type`.
2480
 
2481
  A type `X` meets the *unordered associative container* requirements if
2482
  `X` meets all the requirements of an allocator-aware container
2483
- [[container.requirements.general]] and the following types, statements,
2484
- and expressions are well-formed and have the specified semantics, except
2485
  that for `unordered_map` and `unordered_multimap`, the requirements
2486
- placed on `value_type` in [[container.alloc.reqmts]] apply instead to
2487
  `key_type` and `mapped_type`.
2488
 
2489
- [*Note 3*: For example, `key_type` and `mapped_type` are sometimes
2490
- required to be *Cpp17CopyAssignable* even though the associated
2491
- `value_type`, `pair<const key_type, mapped_type>`, is not
2492
  *Cpp17CopyAssignable*. — *end note*]
2493
 
2494
  ``` cpp
2495
  typename X::key_type
2496
  ```
@@ -2757,12 +2781,12 @@ X(il, n, hf, eq)
2757
  ``` cpp
2758
  X(b)
2759
  ```
2760
 
2761
  *Effects:* In addition to the container
2762
- requirements [[container.requirements.general]], copies the hash
2763
- function, predicate, and maximum load factor.
2764
 
2765
  *Complexity:* Average case linear in `b.size()`, worst case quadratic.
2766
 
2767
  ``` cpp
2768
  a = b
@@ -2848,21 +2872,15 @@ from `args`.
2848
  a.emplace_hint(p, args)
2849
  ```
2850
 
2851
  *Result:* `iterator`
2852
 
2853
- *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2854
- from `args`.
 
2855
 
2856
- *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`.
2857
-
2858
- *Returns:* An iterator pointing to the element with the key equivalent
2859
- to the newly inserted element. The `const_iterator` `p` is a hint
2860
- pointing to where the search should start. Implementations are permitted
2861
- to ignore the hint.
2862
-
2863
- *Complexity:* Average case 𝑂(1), worst case 𝑂(`a.size()`).
2864
 
2865
  ``` cpp
2866
  a_uniq.insert(t)
2867
  ```
2868
 
@@ -2923,11 +2941,11 @@ a.insert(i, j)
2923
  *Result:* `void`
2924
 
2925
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2926
  from `*i`. Neither `i` nor `j` are iterators into `a`.
2927
 
2928
- *Effects:* Equivalent to `a.insert(t)` for each element in `[i,j)`.
2929
 
2930
  *Complexity:* Average case 𝑂(N), where N is `distance(i, j)`, worst case
2931
  𝑂(N(`a.size()` + 1)).
2932
 
2933
  ``` cpp
@@ -3129,11 +3147,11 @@ a.erase(r)
3129
  a.erase(q1, q2)
3130
  ```
3131
 
3132
  *Result:* `iterator`
3133
 
3134
- *Effects:* Erases all elements in the range `[q1, q2)`.
3135
 
3136
  *Returns:* The iterator immediately following the erased elements prior
3137
  to the erasure.
3138
 
3139
  *Complexity:* Average case linear in `distance(q1, q2)`, worst case
@@ -3261,21 +3279,37 @@ b.bucket(k)
3261
 
3262
  *Preconditions:* `b.bucket_count() > 0`.
3263
 
3264
  *Returns:* The index of the bucket in which elements with keys
3265
  equivalent to `k` would be found, if any such element existed. The
3266
- return value is in the range `[0, b.bucket_count())`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3267
 
3268
  *Complexity:* Constant.
3269
 
3270
  ``` cpp
3271
  b.bucket_size(n)
3272
  ```
3273
 
3274
  *Result:* `size_type`
3275
 
3276
- *Preconditions:* `n` shall be in the range `[0, b.bucket_count())`.
3277
 
3278
  *Returns:* The number of elements in the `n`ᵗʰ bucket.
3279
 
3280
  *Complexity:* 𝑂(`b.bucket_size(n)`)
3281
 
@@ -3283,11 +3317,11 @@ b.bucket_size(n)
3283
  b.begin(n)
3284
  ```
3285
 
3286
  *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3287
 
3288
- *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3289
 
3290
  *Returns:* An iterator referring to the first element in the bucket. If
3291
  the bucket is empty, then `b.begin(n) == b.end(n)`.
3292
 
3293
  *Complexity:* Constant.
@@ -3296,11 +3330,11 @@ the bucket is empty, then `b.begin(n) == b.end(n)`.
3296
  b.end(n)
3297
  ```
3298
 
3299
  *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3300
 
3301
- *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3302
 
3303
  *Returns:* An iterator which is the past-the-end value for the bucket.
3304
 
3305
  *Complexity:* Constant.
3306
 
@@ -3308,11 +3342,11 @@ b.end(n)
3308
  b.cbegin(n)
3309
  ```
3310
 
3311
  *Result:* `const_local_iterator`
3312
 
3313
- *Preconditions:* `n` shall be in the range `[0, b.bucket_count())`.
3314
 
3315
  *Returns:* An iterator referring to the first element in the bucket. If
3316
  the bucket is empty, then `b.cbegin(n) == b.cend(n)`.
3317
 
3318
  *Complexity:* Constant.
@@ -3321,11 +3355,11 @@ the bucket is empty, then `b.cbegin(n) == b.cend(n)`.
3321
  b.cend(n)
3322
  ```
3323
 
3324
  *Result:* `const_local_iterator`
3325
 
3326
- *Preconditions:* `n` is in the range `[0, b.bucket_count())`.
3327
 
3328
  *Returns:* An iterator which is the past-the-end value for the bucket.
3329
 
3330
  *Complexity:* Constant.
3331
 
@@ -3430,15 +3464,15 @@ accessing the element through such pointers and references while the
3430
  element is owned by a `node_type` is undefined behavior. References and
3431
  pointers to an element obtained while it is owned by a `node_type` are
3432
  invalidated if the element is successfully inserted.
3433
 
3434
  The member function templates `find`, `count`, `equal_range`,
3435
- `contains`, `extract`, and `erase` shall not participate in overload
3436
- resolution unless the *qualified-id*s `Pred::is_transparent` and
3437
- `Hash::is_transparent` are both valid and denote types [[temp.deduct]].
3438
- Additionally, the member function templates `extract` and `erase` shall
3439
- not participate in overload resolution if
3440
  `is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator>`
3441
  is `true`, where `K` is the type substituted as the first template
3442
  argument.
3443
 
3444
  A deduction guide for an unordered associative container shall not
@@ -3472,33 +3506,34 @@ For unordered associative containers, if an exception is thrown from
3472
  within a `rehash()` function other than by the container’s hash function
3473
  or comparison function, the `rehash()` function has no effect.
3474
 
3475
  ## Sequence containers <a id="sequences">[[sequences]]</a>
3476
 
3477
- ### In general <a id="sequences.general">[[sequences.general]]</a>
3478
 
3479
- The headers `<array>`, `<deque>`, `<forward_list>`, `<list>`, and
3480
- `<vector>` define class templates that meet the requirements for
3481
- sequence containers.
3482
 
3483
  The following exposition-only alias template may appear in deduction
3484
  guides for sequence containers:
3485
 
3486
  ``` cpp
3487
  template<class InputIterator>
3488
- using iter-value-type = typename iterator_traits<InputIterator>::value_type; // exposition only
3489
  ```
3490
 
3491
  ### Header `<array>` synopsis <a id="array.syn">[[array.syn]]</a>
3492
 
3493
  ``` cpp
 
3494
  #include <compare> // see [compare.syn]
3495
  #include <initializer_list> // see [initializer.list.syn]
3496
 
3497
  namespace std {
3498
  // [array], class template array
3499
- template<class T, size_t N> struct array;
3500
 
3501
  template<class T, size_t N>
3502
  constexpr bool operator==(const array<T, N>& x, const array<T, N>& y);
3503
  template<class T, size_t N>
3504
  constexpr synth-three-way-result<T>
@@ -3530,166 +3565,10 @@ namespace std {
3530
  template<size_t I, class T, size_t N>
3531
  constexpr const T&& get(const array<T, N>&&) noexcept;
3532
  }
3533
  ```
3534
 
3535
- ### Header `<deque>` synopsis <a id="deque.syn">[[deque.syn]]</a>
3536
-
3537
- ``` cpp
3538
- #include <compare> // see [compare.syn]
3539
- #include <initializer_list> // see [initializer.list.syn]
3540
-
3541
- namespace std {
3542
- // [deque], class template deque
3543
- template<class T, class Allocator = allocator<T>> class deque;
3544
-
3545
- template<class T, class Allocator>
3546
- bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
3547
- template<class T, class Allocator>
3548
- synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x,
3549
- \itcorr const deque<T, Allocator>& y);
3550
-
3551
- template<class T, class Allocator>
3552
- void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
3553
- noexcept(noexcept(x.swap(y)));
3554
-
3555
- // [deque.erasure], erasure
3556
- template<class T, class Allocator, class U>
3557
- typename deque<T, Allocator>::size_type
3558
- erase(deque<T, Allocator>& c, const U& value);
3559
- template<class T, class Allocator, class Predicate>
3560
- typename deque<T, Allocator>::size_type
3561
- erase_if(deque<T, Allocator>& c, Predicate pred);
3562
-
3563
- namespace pmr {
3564
- template<class T>
3565
- using deque = std::deque<T, polymorphic_allocator<T>>;
3566
- }
3567
- }
3568
- ```
3569
-
3570
- ### Header `<forward_list>` synopsis <a id="forward.list.syn">[[forward.list.syn]]</a>
3571
-
3572
- ``` cpp
3573
- #include <compare> // see [compare.syn]
3574
- #include <initializer_list> // see [initializer.list.syn]
3575
-
3576
- namespace std {
3577
- // [forward.list], class template forward_list
3578
- template<class T, class Allocator = allocator<T>> class forward_list;
3579
-
3580
- template<class T, class Allocator>
3581
- bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
3582
- template<class T, class Allocator>
3583
- synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x,
3584
- \itcorr const forward_list<T, Allocator>& y);
3585
-
3586
- template<class T, class Allocator>
3587
- void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
3588
- noexcept(noexcept(x.swap(y)));
3589
-
3590
- // [forward.list.erasure], erasure
3591
- template<class T, class Allocator, class U>
3592
- typename forward_list<T, Allocator>::size_type
3593
- erase(forward_list<T, Allocator>& c, const U& value);
3594
- template<class T, class Allocator, class Predicate>
3595
- typename forward_list<T, Allocator>::size_type
3596
- erase_if(forward_list<T, Allocator>& c, Predicate pred);
3597
-
3598
- namespace pmr {
3599
- template<class T>
3600
- using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
3601
- }
3602
- }
3603
- ```
3604
-
3605
- ### Header `<list>` synopsis <a id="list.syn">[[list.syn]]</a>
3606
-
3607
- ``` cpp
3608
- #include <compare> // see [compare.syn]
3609
- #include <initializer_list> // see [initializer.list.syn]
3610
-
3611
- namespace std {
3612
- // [list], class template list
3613
- template<class T, class Allocator = allocator<T>> class list;
3614
-
3615
- template<class T, class Allocator>
3616
- bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
3617
- template<class T, class Allocator>
3618
- synth-three-way-result<T> operator<=>(const list<T, Allocator>& x,
3619
- \itcorr const list<T, Allocator>& y);
3620
-
3621
- template<class T, class Allocator>
3622
- void swap(list<T, Allocator>& x, list<T, Allocator>& y)
3623
- noexcept(noexcept(x.swap(y)));
3624
-
3625
- // [list.erasure], erasure
3626
- template<class T, class Allocator, class U>
3627
- typename list<T, Allocator>::size_type
3628
- erase(list<T, Allocator>& c, const U& value);
3629
- template<class T, class Allocator, class Predicate>
3630
- typename list<T, Allocator>::size_type
3631
- erase_if(list<T, Allocator>& c, Predicate pred);
3632
-
3633
- namespace pmr {
3634
- template<class T>
3635
- using list = std::list<T, polymorphic_allocator<T>>;
3636
- }
3637
- }
3638
- ```
3639
-
3640
- ### Header `<vector>` synopsis <a id="vector.syn">[[vector.syn]]</a>
3641
-
3642
- ``` cpp
3643
- #include <compare> // see [compare.syn]
3644
- #include <initializer_list> // see [initializer.list.syn]
3645
-
3646
- namespace std {
3647
- // [vector], class template vector
3648
- template<class T, class Allocator = allocator<T>> class vector;
3649
-
3650
- template<class T, class Allocator>
3651
- constexpr bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
3652
- template<class T, class Allocator>
3653
- constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x,
3654
- \itcorr const vector<T, Allocator>& y);
3655
-
3656
- template<class T, class Allocator>
3657
- constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
3658
- noexcept(noexcept(x.swap(y)));
3659
-
3660
- // [vector.erasure], erasure
3661
- template<class T, class Allocator, class U>
3662
- constexpr typename vector<T, Allocator>::size_type
3663
- erase(vector<T, Allocator>& c, const U& value);
3664
- template<class T, class Allocator, class Predicate>
3665
- constexpr typename vector<T, Allocator>::size_type
3666
- erase_if(vector<T, Allocator>& c, Predicate pred);
3667
-
3668
- namespace pmr {
3669
- template<class T>
3670
- using vector = std::vector<T, polymorphic_allocator<T>>;
3671
- }
3672
-
3673
- // [vector.bool], specialization of vector for bool
3674
- // [vector.bool.pspc], partial class template specialization vector<bool, Allocator>
3675
- template<class Allocator>
3676
- class vector<bool, Allocator>;
3677
-
3678
- template<class T>
3679
- constexpr bool is-vector-bool-reference = see below; // exposition only
3680
-
3681
- // hash support
3682
- template<class T> struct hash;
3683
- template<class Allocator> struct hash<vector<bool, Allocator>>;
3684
-
3685
- // [vector.bool.fmt], formatter specialization for vector<bool>
3686
- template<class T, class charT> requires is-vector-bool-reference<T>
3687
- struct formatter<T, charT>;
3688
- }
3689
- ```
3690
-
3691
  ### Class template `array` <a id="array">[[array]]</a>
3692
 
3693
  #### Overview <a id="array.overview">[[array.overview]]</a>
3694
 
3695
  The header `<array>` defines a class template for storing fixed-size
@@ -3708,12 +3587,12 @@ object is not empty if `N` > 0. An `array` meets some of the
3708
  requirements of a sequence container [[sequence.reqmts]]. Descriptions
3709
  are provided here only for operations on `array` that are not described
3710
  in one of these tables and for operations where there is additional
3711
  semantic information.
3712
 
3713
- `array<T, N>` is a structural type [[temp.param]] if `T` is a structural
3714
- type. Two values `a1` and `a2` of type `array<T, N>` are
3715
  template-argument-equivalent [[temp.type]] if and only if each pair of
3716
  corresponding elements in `a1` and `a2` are
3717
  template-argument-equivalent.
3718
 
3719
  The types `iterator` and `const_iterator` meet the constexpr iterator
@@ -3756,19 +3635,19 @@ namespace std {
3756
  constexpr const_iterator cend() const noexcept;
3757
  constexpr const_reverse_iterator crbegin() const noexcept;
3758
  constexpr const_reverse_iterator crend() const noexcept;
3759
 
3760
  // capacity
3761
- [[nodiscard]] constexpr bool empty() const noexcept;
3762
  constexpr size_type size() const noexcept;
3763
  constexpr size_type max_size() const noexcept;
3764
 
3765
  // element access
3766
  constexpr reference operator[](size_type n);
3767
  constexpr const_reference operator[](size_type n) const;
3768
- constexpr reference at(size_type n);
3769
- constexpr const_reference at(size_type n) const;
3770
  constexpr reference front();
3771
  constexpr const_reference front() const;
3772
  constexpr reference back();
3773
  constexpr const_reference back() const;
3774
 
@@ -3781,17 +3660,16 @@ namespace std {
3781
  }
3782
  ```
3783
 
3784
  #### Constructors, copy, and assignment <a id="array.cons">[[array.cons]]</a>
3785
 
3786
- The conditions for an aggregate [[dcl.init.aggr]] shall be met. Class
3787
- `array` relies on the implicitly-declared special member functions
3788
  [[class.default.ctor]], [[class.dtor]], [[class.copy.ctor]] to conform
3789
  to the container requirements table in  [[container.requirements]]. In
3790
  addition to the requirements specified in the container requirements
3791
- table, the implicit move constructor and move assignment operator for
3792
- `array` require that `T` be *Cpp17MoveConstructible* or
3793
  *Cpp17MoveAssignable*, respectively.
3794
 
3795
  ``` cpp
3796
  template<class T, class... U>
3797
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
@@ -3811,11 +3689,11 @@ constexpr size_type size() const noexcept;
3811
  constexpr T* data() noexcept;
3812
  constexpr const T* data() const noexcept;
3813
  ```
3814
 
3815
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
3816
- range. For a non-empty array, `data()` `==` `addressof(front())`.
3817
 
3818
  ``` cpp
3819
  constexpr void fill(const T& u);
3820
  ```
3821
 
@@ -3863,24 +3741,24 @@ specification.
3863
  ``` cpp
3864
  template<class T, size_t N>
3865
  constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
3866
  ```
3867
 
3868
- *Mandates:* `is_array_v<T>` is `false` and `is_constructible_v<T, T&>`
3869
- is `true`.
3870
 
3871
  *Preconditions:* `T` meets the *Cpp17CopyConstructible* requirements.
3872
 
3873
  *Returns:* `{{ a[0], `…`, a[N - 1] }}`.
3874
 
3875
  ``` cpp
3876
  template<class T, size_t N>
3877
  constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
3878
  ```
3879
 
3880
- *Mandates:* `is_array_v<T>` is `false` and `is_move_constructible_v<T>`
3881
- is `true`.
3882
 
3883
  *Preconditions:* `T` meets the *Cpp17MoveConstructible* requirements.
3884
 
3885
  *Returns:* `{{ std::move(a[0]), `…`, std::move(a[N - 1]) }}`.
3886
 
@@ -3914,10 +3792,45 @@ template<size_t I, class T, size_t N>
3914
  *Mandates:* `I < N` is `true`.
3915
 
3916
  *Returns:* A reference to the `I`ᵗʰ element of `a`, where indexing is
3917
  zero-based.
3918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3919
  ### Class template `deque` <a id="deque">[[deque]]</a>
3920
 
3921
  #### Overview <a id="deque.overview">[[deque.overview]]</a>
3922
 
3923
  A `deque` is a sequence container that supports random access iterators
@@ -3934,121 +3847,125 @@ A `deque` meets all of the requirements of a container
3934
  optional sequence container requirements [[sequence.reqmts]].
3935
  Descriptions are provided here only for operations on `deque` that are
3936
  not described in one of these tables or for operations where there is
3937
  additional semantic information.
3938
 
 
 
 
3939
  ``` cpp
3940
  namespace std {
3941
  template<class T, class Allocator = allocator<T>>
3942
  class deque {
3943
  public:
3944
  // types
3945
  using value_type = T;
3946
  using allocator_type = Allocator;
3947
- using pointer = typename allocator_traits<Allocator>::pointer;
3948
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
3949
  using reference = value_type&;
3950
  using const_reference = const value_type&;
3951
  using size_type = implementation-defined // type of deque::size_type; // see [container.requirements]
3952
  using difference_type = implementation-defined // type of deque::difference_type; // see [container.requirements]
3953
  using iterator = implementation-defined // type of deque::iterator; // see [container.requirements]
3954
  using const_iterator = implementation-defined // type of deque::const_iterator; // see [container.requirements]
3955
  using reverse_iterator = std::reverse_iterator<iterator>;
3956
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3957
 
3958
  // [deque.cons], construct/copy/destroy
3959
- deque() : deque(Allocator()) { }
3960
- explicit deque(const Allocator&);
3961
- explicit deque(size_type n, const Allocator& = Allocator());
3962
- deque(size_type n, const T& value, const Allocator& = Allocator());
3963
  template<class InputIterator>
3964
- deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
3965
  template<container-compatible-range<T> R>
3966
- deque(from_range_t, R&& rg, const Allocator& = Allocator());
3967
- deque(const deque& x);
3968
- deque(deque&&);
3969
- deque(const deque&, const type_identity_t<Allocator>&);
3970
- deque(deque&&, const type_identity_t<Allocator>&);
3971
- deque(initializer_list<T>, const Allocator& = Allocator());
3972
 
3973
- ~deque();
3974
- deque& operator=(const deque& x);
3975
- deque& operator=(deque&& x)
3976
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
3977
- deque& operator=(initializer_list<T>);
3978
  template<class InputIterator>
3979
- void assign(InputIterator first, InputIterator last);
3980
  template<container-compatible-range<T> R>
3981
- void assign_range(R&& rg);
3982
- void assign(size_type n, const T& t);
3983
- void assign(initializer_list<T>);
3984
- allocator_type get_allocator() const noexcept;
3985
 
3986
  // iterators
3987
- iterator begin() noexcept;
3988
- const_iterator begin() const noexcept;
3989
- iterator end() noexcept;
3990
- const_iterator end() const noexcept;
3991
- reverse_iterator rbegin() noexcept;
3992
- const_reverse_iterator rbegin() const noexcept;
3993
- reverse_iterator rend() noexcept;
3994
- const_reverse_iterator rend() const noexcept;
3995
 
3996
- const_iterator cbegin() const noexcept;
3997
- const_iterator cend() const noexcept;
3998
- const_reverse_iterator crbegin() const noexcept;
3999
- const_reverse_iterator crend() const noexcept;
4000
 
4001
  // [deque.capacity], capacity
4002
- [[nodiscard]] bool empty() const noexcept;
4003
- size_type size() const noexcept;
4004
- size_type max_size() const noexcept;
4005
- void resize(size_type sz);
4006
- void resize(size_type sz, const T& c);
4007
- void shrink_to_fit();
4008
 
4009
  // element access
4010
- reference operator[](size_type n);
4011
- const_reference operator[](size_type n) const;
4012
- reference at(size_type n);
4013
- const_reference at(size_type n) const;
4014
- reference front();
4015
- const_reference front() const;
4016
- reference back();
4017
- const_reference back() const;
4018
 
4019
  // [deque.modifiers], modifiers
4020
- template<class... Args> reference emplace_front(Args&&... args);
4021
- template<class... Args> reference emplace_back(Args&&... args);
4022
- template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4023
 
4024
- void push_front(const T& x);
4025
- void push_front(T&& x);
4026
  template<container-compatible-range<T> R>
4027
- void prepend_range(R&& rg);
4028
- void push_back(const T& x);
4029
- void push_back(T&& x);
4030
  template<container-compatible-range<T> R>
4031
- void append_range(R&& rg);
4032
 
4033
- iterator insert(const_iterator position, const T& x);
4034
- iterator insert(const_iterator position, T&& x);
4035
- iterator insert(const_iterator position, size_type n, const T& x);
4036
  template<class InputIterator>
4037
- iterator insert(const_iterator position, InputIterator first, InputIterator last);
 
4038
  template<container-compatible-range<T> R>
4039
- iterator insert_range(const_iterator position, R&& rg);
4040
- iterator insert(const_iterator position, initializer_list<T>);
4041
 
4042
- void pop_front();
4043
- void pop_back();
4044
 
4045
- iterator erase(const_iterator position);
4046
- iterator erase(const_iterator first, const_iterator last);
4047
- void swap(deque&)
4048
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4049
- void clear() noexcept;
4050
  };
4051
 
4052
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
4053
  deque(InputIterator, InputIterator, Allocator = Allocator())
4054
  -> deque<iter-value-type<InputIterator>, Allocator>;
@@ -4060,87 +3977,87 @@ namespace std {
4060
  ```
4061
 
4062
  #### Constructors, copy, and assignment <a id="deque.cons">[[deque.cons]]</a>
4063
 
4064
  ``` cpp
4065
- explicit deque(const Allocator&);
4066
  ```
4067
 
4068
  *Effects:* Constructs an empty `deque`, using the specified allocator.
4069
 
4070
  *Complexity:* Constant.
4071
 
4072
  ``` cpp
4073
- explicit deque(size_type n, const Allocator& = Allocator());
4074
  ```
4075
 
4076
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
4077
 
4078
  *Effects:* Constructs a `deque` with `n` default-inserted elements using
4079
  the specified allocator.
4080
 
4081
  *Complexity:* Linear in `n`.
4082
 
4083
  ``` cpp
4084
- deque(size_type n, const T& value, const Allocator& = Allocator());
4085
  ```
4086
 
4087
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
4088
 
4089
  *Effects:* Constructs a `deque` with `n` copies of `value`, using the
4090
  specified allocator.
4091
 
4092
  *Complexity:* Linear in `n`.
4093
 
4094
  ``` cpp
4095
  template<class InputIterator>
4096
- deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
4097
  ```
4098
 
4099
  *Effects:* Constructs a `deque` equal to the range \[`first`, `last`),
4100
  using the specified allocator.
4101
 
4102
  *Complexity:* Linear in `distance(first, last)`.
4103
 
4104
  ``` cpp
4105
  template<container-compatible-range<T> R>
4106
- deque(from_range_t, R&& rg, const Allocator& = Allocator());
4107
  ```
4108
 
4109
  *Effects:* Constructs a `deque` with the elements of the range `rg`,
4110
  using the specified allocator.
4111
 
4112
  *Complexity:* Linear in `ranges::distance(rg)`.
4113
 
4114
  #### Capacity <a id="deque.capacity">[[deque.capacity]]</a>
4115
 
4116
  ``` cpp
4117
- void resize(size_type sz);
4118
  ```
4119
 
4120
  *Preconditions:* `T` is *Cpp17MoveInsertable* and
4121
- *Cpp17DefaultInsertable* into `*this`.
4122
 
4123
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
4124
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
4125
  to the sequence.
4126
 
4127
  ``` cpp
4128
- void resize(size_type sz, const T& c);
4129
  ```
4130
 
4131
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
4132
 
4133
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
4134
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
4135
  sequence.
4136
 
4137
  ``` cpp
4138
- void shrink_to_fit();
4139
  ```
4140
 
4141
- *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
4142
 
4143
  *Effects:* `shrink_to_fit` is a non-binding request to reduce memory use
4144
  but does not change the size of the sequence.
4145
 
4146
  [*Note 1*: The request is non-binding to allow latitude for
@@ -4158,31 +4075,31 @@ invalidates all the references, pointers, and iterators referring to the
4158
  elements in the sequence, as well as the past-the-end iterator.
4159
 
4160
  #### Modifiers <a id="deque.modifiers">[[deque.modifiers]]</a>
4161
 
4162
  ``` cpp
4163
- iterator insert(const_iterator position, const T& x);
4164
- iterator insert(const_iterator position, T&& x);
4165
- iterator insert(const_iterator position, size_type n, const T& x);
4166
  template<class InputIterator>
4167
- iterator insert(const_iterator position,
4168
  InputIterator first, InputIterator last);
4169
  template<container-compatible-range<T> R>
4170
- iterator insert_range(const_iterator position, R&& rg);
4171
- iterator insert(const_iterator position, initializer_list<T>);
4172
 
4173
- template<class... Args> reference emplace_front(Args&&... args);
4174
- template<class... Args> reference emplace_back(Args&&... args);
4175
- template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4176
- void push_front(const T& x);
4177
- void push_front(T&& x);
4178
  template<container-compatible-range<T> R>
4179
- void prepend_range(R&& rg);
4180
- void push_back(const T& x);
4181
- void push_back(T&& x);
4182
  template<container-compatible-range<T> R>
4183
- void append_range(R&& rg);
4184
  ```
4185
 
4186
  *Effects:* An insertion in the middle of the deque invalidates all the
4187
  iterators and references to elements of the deque. An insertion at
4188
  either end of the deque invalidates all the iterators to the deque, but
@@ -4194,20 +4111,20 @@ the deque. Inserting a single element at either the beginning or end of
4194
  a deque always takes constant time and causes a single call to a
4195
  constructor of `T`.
4196
 
4197
  *Remarks:* If an exception is thrown other than by the copy constructor,
4198
  move constructor, assignment operator, or move assignment operator of
4199
- `T` there are no effects. If an exception is thrown while inserting a
4200
  single element at either end, there are no effects. Otherwise, if an
4201
  exception is thrown by the move constructor of a
4202
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
4203
 
4204
  ``` cpp
4205
- iterator erase(const_iterator position);
4206
- iterator erase(const_iterator first, const_iterator last);
4207
- void pop_front();
4208
- void pop_back();
4209
  ```
4210
 
4211
  *Effects:* An erase operation that erases the last element of a deque
4212
  invalidates only the past-the-end iterator and all iterators and
4213
  references to the erased elements. An erase operation that erases the
@@ -4230,12 +4147,12 @@ elements before the erased elements and the number of elements after the
4230
  erased elements.
4231
 
4232
  #### Erasure <a id="deque.erasure">[[deque.erasure]]</a>
4233
 
4234
  ``` cpp
4235
- template<class T, class Allocator, class U>
4236
- typename deque<T, Allocator>::size_type
4237
  erase(deque<T, Allocator>& c, const U& value);
4238
  ```
4239
 
4240
  *Effects:* Equivalent to:
4241
 
@@ -4246,11 +4163,11 @@ c.erase(it, c.end());
4246
  return r;
4247
  ```
4248
 
4249
  ``` cpp
4250
  template<class T, class Allocator, class Predicate>
4251
- typename deque<T, Allocator>::size_type
4252
  erase_if(deque<T, Allocator>& c, Predicate pred);
4253
  ```
4254
 
4255
  *Effects:* Equivalent to:
4256
 
@@ -4259,10 +4176,47 @@ auto it = remove_if(c.begin(), c.end(), pred);
4259
  auto r = distance(it, c.end());
4260
  c.erase(it, c.end());
4261
  return r;
4262
  ```
4263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4264
  ### Class template `forward_list` <a id="forward.list">[[forward.list]]</a>
4265
 
4266
  #### Overview <a id="forward.list.overview">[[forward.list.overview]]</a>
4267
 
4268
  A `forward_list` is a container that supports forward iterators and
@@ -4274,11 +4228,11 @@ access to list elements is not supported.
4274
  overhead relative to a hand-written C-style singly linked list. Features
4275
  that would conflict with that goal have been omitted. — *end note*]
4276
 
4277
  A `forward_list` meets all of the requirements of a container
4278
  [[container.reqmts]], except that the `size()` member function is not
4279
- provided and `operator==` has linear complexity, A `forward_list` also
4280
  meets all of the requirements for an allocator-aware container
4281
  [[container.alloc.reqmts]]. In addition, a `forward_list` provides the
4282
  `assign` member functions and several of the optional sequence container
4283
  requirements [[sequence.reqmts]]. Descriptions are provided here only
4284
  for operations on `forward_list` that are not described in that table or
@@ -4288,127 +4242,133 @@ for operations where there is additional semantic information.
4288
  the first element of interest, but in a `forward_list` there is no
4289
  constant-time way to access a preceding element. For this reason,
4290
  `erase_after` and `splice_after` take fully-open ranges, not semi-open
4291
  ranges. — *end note*]
4292
 
 
 
 
4293
  ``` cpp
4294
  namespace std {
4295
  template<class T, class Allocator = allocator<T>>
4296
  class forward_list {
4297
  public:
4298
  // types
4299
  using value_type = T;
4300
  using allocator_type = Allocator;
4301
- using pointer = typename allocator_traits<Allocator>::pointer;
4302
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4303
  using reference = value_type&;
4304
  using const_reference = const value_type&;
4305
  using size_type = implementation-defined // type of forward_list::size_type; // see [container.requirements]
4306
  using difference_type = implementation-defined // type of forward_list::difference_type; // see [container.requirements]
4307
  using iterator = implementation-defined // type of forward_list::iterator; // see [container.requirements]
4308
  using const_iterator = implementation-defined // type of forward_list::const_iterator; // see [container.requirements]
4309
 
4310
  // [forward.list.cons], construct/copy/destroy
4311
- forward_list() : forward_list(Allocator()) { }
4312
- explicit forward_list(const Allocator&);
4313
- explicit forward_list(size_type n, const Allocator& = Allocator());
4314
- forward_list(size_type n, const T& value, const Allocator& = Allocator());
4315
  template<class InputIterator>
4316
- forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
 
4317
  template<container-compatible-range<T> R>
4318
- forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4319
- forward_list(const forward_list& x);
4320
- forward_list(forward_list&& x);
4321
- forward_list(const forward_list& x, const type_identity_t<Allocator>&);
4322
- forward_list(forward_list&& x, const type_identity_t<Allocator>&);
4323
- forward_list(initializer_list<T>, const Allocator& = Allocator());
4324
- ~forward_list();
4325
- forward_list& operator=(const forward_list& x);
4326
- forward_list& operator=(forward_list&& x)
4327
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4328
- forward_list& operator=(initializer_list<T>);
4329
  template<class InputIterator>
4330
- void assign(InputIterator first, InputIterator last);
4331
  template<container-compatible-range<T> R>
4332
- void assign_range(R&& rg);
4333
- void assign(size_type n, const T& t);
4334
- void assign(initializer_list<T>);
4335
- allocator_type get_allocator() const noexcept;
4336
 
4337
  // [forward.list.iter], iterators
4338
- iterator before_begin() noexcept;
4339
- const_iterator before_begin() const noexcept;
4340
- iterator begin() noexcept;
4341
- const_iterator begin() const noexcept;
4342
- iterator end() noexcept;
4343
- const_iterator end() const noexcept;
4344
 
4345
- const_iterator cbegin() const noexcept;
4346
- const_iterator cbefore_begin() const noexcept;
4347
- const_iterator cend() const noexcept;
4348
 
4349
  // capacity
4350
- [[nodiscard]] bool empty() const noexcept;
4351
- size_type max_size() const noexcept;
4352
 
4353
  // [forward.list.access], element access
4354
- reference front();
4355
- const_reference front() const;
4356
 
4357
  // [forward.list.modifiers], modifiers
4358
- template<class... Args> reference emplace_front(Args&&... args);
4359
- void push_front(const T& x);
4360
- void push_front(T&& x);
4361
  template<container-compatible-range<T> R>
4362
- void prepend_range(R&& rg);
4363
- void pop_front();
4364
 
4365
- template<class... Args> iterator emplace_after(const_iterator position, Args&&... args);
4366
- iterator insert_after(const_iterator position, const T& x);
4367
- iterator insert_after(const_iterator position, T&& x);
 
4368
 
4369
- iterator insert_after(const_iterator position, size_type n, const T& x);
4370
  template<class InputIterator>
4371
- iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
4372
- iterator insert_after(const_iterator position, initializer_list<T> il);
 
4373
  template<container-compatible-range<T> R>
4374
- iterator insert_range_after(const_iterator position, R&& rg);
4375
 
4376
- iterator erase_after(const_iterator position);
4377
- iterator erase_after(const_iterator position, const_iterator last);
4378
- void swap(forward_list&)
4379
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4380
 
4381
- void resize(size_type sz);
4382
- void resize(size_type sz, const value_type& c);
4383
- void clear() noexcept;
4384
 
4385
  // [forward.list.ops], forward_list operations
4386
- void splice_after(const_iterator position, forward_list& x);
4387
- void splice_after(const_iterator position, forward_list&& x);
4388
- void splice_after(const_iterator position, forward_list& x, const_iterator i);
4389
- void splice_after(const_iterator position, forward_list&& x, const_iterator i);
4390
- void splice_after(const_iterator position, forward_list& x,
4391
  const_iterator first, const_iterator last);
4392
- void splice_after(const_iterator position, forward_list&& x,
4393
  const_iterator first, const_iterator last);
4394
 
4395
- size_type remove(const T& value);
4396
- template<class Predicate> size_type remove_if(Predicate pred);
4397
 
4398
  size_type unique();
4399
- template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
4400
 
4401
- void merge(forward_list& x);
4402
- void merge(forward_list&& x);
4403
- template<class Compare> void merge(forward_list& x, Compare comp);
4404
- template<class Compare> void merge(forward_list&& x, Compare comp);
4405
 
4406
- void sort();
4407
- template<class Compare> void sort(Compare comp);
4408
 
4409
- void reverse() noexcept;
4410
  };
4411
 
4412
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
4413
  forward_list(InputIterator, InputIterator, Allocator = Allocator())
4414
  -> forward_list<iter-value-type<InputIterator>, Allocator>;
@@ -4426,66 +4386,66 @@ any member of the resulting specialization of `forward_list` is
4426
  referenced.
4427
 
4428
  #### Constructors, copy, and assignment <a id="forward.list.cons">[[forward.list.cons]]</a>
4429
 
4430
  ``` cpp
4431
- explicit forward_list(const Allocator&);
4432
  ```
4433
 
4434
  *Effects:* Constructs an empty `forward_list` object using the specified
4435
  allocator.
4436
 
4437
  *Complexity:* Constant.
4438
 
4439
  ``` cpp
4440
- explicit forward_list(size_type n, const Allocator& = Allocator());
4441
  ```
4442
 
4443
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
4444
 
4445
  *Effects:* Constructs a `forward_list` object with `n` default-inserted
4446
  elements using the specified allocator.
4447
 
4448
  *Complexity:* Linear in `n`.
4449
 
4450
  ``` cpp
4451
- forward_list(size_type n, const T& value, const Allocator& = Allocator());
4452
  ```
4453
 
4454
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
4455
 
4456
  *Effects:* Constructs a `forward_list` object with `n` copies of `value`
4457
  using the specified allocator.
4458
 
4459
  *Complexity:* Linear in `n`.
4460
 
4461
  ``` cpp
4462
  template<class InputIterator>
4463
- forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
4464
  ```
4465
 
4466
  *Effects:* Constructs a `forward_list` object equal to the range
4467
  \[`first`, `last`).
4468
 
4469
  *Complexity:* Linear in `distance(first, last)`.
4470
 
4471
  ``` cpp
4472
  template<container-compatible-range<T> R>
4473
- forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4474
  ```
4475
 
4476
  *Effects:* Constructs a `forward_list` object with the elements of the
4477
  range `rg`.
4478
 
4479
  *Complexity:* Linear in `ranges::distance(rg)`.
4480
 
4481
  #### Iterators <a id="forward.list.iter">[[forward.list.iter]]</a>
4482
 
4483
  ``` cpp
4484
- iterator before_begin() noexcept;
4485
- const_iterator before_begin() const noexcept;
4486
- const_iterator cbefore_begin() const noexcept;
4487
  ```
4488
 
4489
  *Effects:* `cbefore_begin()` is equivalent to
4490
  `const_cast<forward_list const&>(*this).before_begin()`.
4491
 
@@ -4495,59 +4455,60 @@ equal to the iterator returned by `begin()`.
4495
  *Remarks:* `before_begin() == end()` shall equal `false`.
4496
 
4497
  #### Element access <a id="forward.list.access">[[forward.list.access]]</a>
4498
 
4499
  ``` cpp
4500
- reference front();
4501
- const_reference front() const;
4502
  ```
4503
 
4504
  *Returns:* `*begin()`
4505
 
4506
  #### Modifiers <a id="forward.list.modifiers">[[forward.list.modifiers]]</a>
4507
 
4508
- None of the overloads of `insert_after` shall affect the validity of
4509
- iterators and references, and `erase_after` shall invalidate only
4510
- iterators and references to the erased elements. If an exception is
4511
- thrown during `insert_after` there shall be no effect. Inserting `n`
4512
- elements into a `forward_list` is linear in `n`, and the number of calls
4513
- to the copy or move constructor of `T` is exactly equal to `n`. Erasing
4514
- `n` elements from a `forward_list` is linear in `n` and the number of
4515
- calls to the destructor of type `T` is exactly equal to `n`.
 
4516
 
4517
  ``` cpp
4518
- template<class... Args> reference emplace_front(Args&&... args);
4519
  ```
4520
 
4521
  *Effects:* Inserts an object of type `value_type` constructed with
4522
  `value_type(std::forward<Args>(args)...)` at the beginning of the list.
4523
 
4524
  ``` cpp
4525
- void push_front(const T& x);
4526
- void push_front(T&& x);
4527
  ```
4528
 
4529
  *Effects:* Inserts a copy of `x` at the beginning of the list.
4530
 
4531
  ``` cpp
4532
  template<container-compatible-range<T> R>
4533
- void prepend_range(R&& rg);
4534
  ```
4535
 
4536
  *Effects:* Inserts a copy of each element of `rg` at the beginning of
4537
  the list.
4538
 
4539
  [*Note 1*: The order of elements is not reversed. — *end note*]
4540
 
4541
  ``` cpp
4542
- void pop_front();
4543
  ```
4544
 
4545
  *Effects:* As if by `erase_after(before_begin())`.
4546
 
4547
  ``` cpp
4548
- iterator insert_after(const_iterator position, const T& x);
4549
  ```
4550
 
4551
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4552
  `position` is `before_begin()` or is a dereferenceable iterator in the
4553
  range \[`begin()`, `end()`).
@@ -4555,11 +4516,11 @@ range \[`begin()`, `end()`).
4555
  *Effects:* Inserts a copy of `x` after `position`.
4556
 
4557
  *Returns:* An iterator pointing to the copy of `x`.
4558
 
4559
  ``` cpp
4560
- iterator insert_after(const_iterator position, T&& x);
4561
  ```
4562
 
4563
  *Preconditions:* `T` is *Cpp17MoveInsertable* into `forward_list`.
4564
  `position` is `before_begin()` or is a dereferenceable iterator in the
4565
  range \[`begin()`, `end()`).
@@ -4567,11 +4528,11 @@ range \[`begin()`, `end()`).
4567
  *Effects:* Inserts a copy of `x` after `position`.
4568
 
4569
  *Returns:* An iterator pointing to the copy of `x`.
4570
 
4571
  ``` cpp
4572
- iterator insert_after(const_iterator position, size_type n, const T& x);
4573
  ```
4574
 
4575
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4576
  `position` is `before_begin()` or is a dereferenceable iterator in the
4577
  range \[`begin()`, `end()`).
@@ -4581,11 +4542,12 @@ range \[`begin()`, `end()`).
4581
  *Returns:* An iterator pointing to the last inserted copy of `x`, or
4582
  `position` if `n == 0` is `true`.
4583
 
4584
  ``` cpp
4585
  template<class InputIterator>
4586
- iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
 
4587
  ```
4588
 
4589
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4590
  from `*first`. `position` is `before_begin()` or is a dereferenceable
4591
  iterator in the range \[`begin()`, `end()`). Neither `first` nor `last`
@@ -4597,11 +4559,11 @@ are iterators in `*this`.
4597
  *Returns:* An iterator pointing to the last inserted element, or
4598
  `position` if `first == last` is `true`.
4599
 
4600
  ``` cpp
4601
  template<container-compatible-range<T> R>
4602
- iterator insert_range_after(const_iterator position, R&& rg);
4603
  ```
4604
 
4605
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4606
  from `*ranges::begin(rg)`. `position` is `before_begin()` or is a
4607
  dereferenceable iterator in the range \[`begin()`, `end()`). `rg` and
@@ -4612,19 +4574,19 @@ dereferenceable iterator in the range \[`begin()`, `end()`). `rg` and
4612
 
4613
  *Returns:* An iterator pointing to the last inserted element, or
4614
  `position` if `rg` is empty.
4615
 
4616
  ``` cpp
4617
- iterator insert_after(const_iterator position, initializer_list<T> il);
4618
  ```
4619
 
4620
  *Effects:* Equivalent to:
4621
  `return insert_after(position, il.begin(), il.end());`
4622
 
4623
  ``` cpp
4624
  template<class... Args>
4625
- iterator emplace_after(const_iterator position, Args&&... args);
4626
  ```
4627
 
4628
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4629
  from `std::forward<Args>(args)...`. `position` is `before_begin()` or is
4630
  a dereferenceable iterator in the range \[`begin()`, `end()`).
@@ -4634,11 +4596,11 @@ direct-non-list-initialized with `std::forward<Args>(args)...` after
4634
  `position`.
4635
 
4636
  *Returns:* An iterator pointing to the new object.
4637
 
4638
  ``` cpp
4639
- iterator erase_after(const_iterator position);
4640
  ```
4641
 
4642
  *Preconditions:* The iterator following `position` is dereferenceable.
4643
 
4644
  *Effects:* Erases the element pointed to by the iterator following
@@ -4648,11 +4610,11 @@ iterator erase_after(const_iterator position);
4648
  was erased, or `end()` if no such element exists.
4649
 
4650
  *Throws:* Nothing.
4651
 
4652
  ``` cpp
4653
- iterator erase_after(const_iterator position, const_iterator last);
4654
  ```
4655
 
4656
  *Preconditions:* All iterators in the range (`position`, `last`) are
4657
  dereferenceable.
4658
 
@@ -4661,33 +4623,33 @@ dereferenceable.
4661
  *Returns:* `last`.
4662
 
4663
  *Throws:* Nothing.
4664
 
4665
  ``` cpp
4666
- void resize(size_type sz);
4667
  ```
4668
 
4669
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
4670
 
4671
  *Effects:* If `sz < distance(begin(), end())`, erases the last
4672
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
4673
  inserts `sz - distance(begin(), end())` default-inserted elements at the
4674
  end of the list.
4675
 
4676
  ``` cpp
4677
- void resize(size_type sz, const value_type& c);
4678
  ```
4679
 
4680
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
4681
 
4682
  *Effects:* If `sz < distance(begin(), end())`, erases the last
4683
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
4684
  inserts `sz - distance(begin(), end())` copies of `c` at the end of the
4685
  list.
4686
 
4687
  ``` cpp
4688
- void clear() noexcept;
4689
  ```
4690
 
4691
  *Effects:* Erases all elements in the range \[`begin()`, `end()`).
4692
 
4693
  *Remarks:* Does not invalidate past-the-end iterators.
@@ -4702,12 +4664,12 @@ iterator into the list and `n` is an integer, are the same as those of
4702
  list and `n` is an integer, means an iterator `j` such that `j + n == i`
4703
  is `true`. For `merge` and `sort`, the definitions and requirements in
4704
  [[alg.sorting]] apply.
4705
 
4706
  ``` cpp
4707
- void splice_after(const_iterator position, forward_list& x);
4708
- void splice_after(const_iterator position, forward_list&& x);
4709
  ```
4710
 
4711
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4712
  iterator in the range \[`begin()`, `end()`).
4713
  `get_allocator() == x.get_allocator()` is `true`. `addressof(x) != this`
@@ -4722,12 +4684,12 @@ now behave as iterators into `*this`, not into `x`.
4722
  *Throws:* Nothing.
4723
 
4724
  *Complexity:* 𝑂(`distance(x.begin(), x.end())`)
4725
 
4726
  ``` cpp
4727
- void splice_after(const_iterator position, forward_list& x, const_iterator i);
4728
- void splice_after(const_iterator position, forward_list&& x, const_iterator i);
4729
  ```
4730
 
4731
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4732
  iterator in the range \[`begin()`, `end()`). The iterator following `i`
4733
  is a dereferenceable iterator in `x`.
@@ -4743,13 +4705,13 @@ behave as iterators into `*this`, not into `x`.
4743
  *Throws:* Nothing.
4744
 
4745
  *Complexity:* 𝑂(1)
4746
 
4747
  ``` cpp
4748
- void splice_after(const_iterator position, forward_list& x,
4749
  const_iterator first, const_iterator last);
4750
- void splice_after(const_iterator position, forward_list&& x,
4751
  const_iterator first, const_iterator last);
4752
  ```
4753
 
4754
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4755
  iterator in the range \[`begin()`, `end()`). (`first`, `last`) is a
@@ -4765,12 +4727,12 @@ continue to refer to their elements, but they now behave as iterators
4765
  into `*this`, not into `x`.
4766
 
4767
  *Complexity:* 𝑂(`distance(first, last)`)
4768
 
4769
  ``` cpp
4770
- size_type remove(const T& value);
4771
- template<class Predicate> size_type remove_if(Predicate pred);
4772
  ```
4773
 
4774
  *Effects:* Erases all the elements in the list referred to by a list
4775
  iterator `i` for which the following conditions hold: `*i == value` (for
4776
  `remove()`), `pred(*i)` is `true` (for `remove_if()`). Invalidates only
@@ -4785,12 +4747,12 @@ comparison or the predicate.
4785
  corresponding predicate.
4786
 
4787
  *Remarks:* Stable [[algorithm.stable]].
4788
 
4789
  ``` cpp
4790
- size_type unique();
4791
- template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
4792
  ```
4793
 
4794
  Let `binary_pred` be `equal_to<>{}` for the first overload.
4795
 
4796
  *Preconditions:* `binary_pred` is an equivalence relation.
@@ -4808,14 +4770,14 @@ only the iterators and references to the erased elements.
4808
  *Complexity:* If `empty()` is `false`, exactly
4809
  `distance(begin(), end()) - 1` applications of the corresponding
4810
  predicate, otherwise no applications of the predicate.
4811
 
4812
  ``` cpp
4813
- void merge(forward_list& x);
4814
- void merge(forward_list&& x);
4815
- template<class Compare> void merge(forward_list& x, Compare comp);
4816
- template<class Compare> void merge(forward_list&& x, Compare comp);
4817
  ```
4818
 
4819
  Let `comp` be `less<>` for the first two overloads.
4820
 
4821
  *Preconditions:* `*this` and `x` are both sorted with respect to the
@@ -4837,12 +4799,12 @@ performed.
4837
  *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
4838
  is empty after the merge. No elements are copied by this operation. If
4839
  an exception is thrown other than by a comparison, there are no effects.
4840
 
4841
  ``` cpp
4842
- void sort();
4843
- template<class Compare> void sort(Compare comp);
4844
  ```
4845
 
4846
  *Effects:* Sorts the list according to the `operator<` or the `comp`
4847
  function object. If an exception is thrown, the order of the elements in
4848
  `*this` is unspecified. Does not affect the validity of iterators and
@@ -4852,37 +4814,847 @@ references.
4852
  `distance(begin(), end())`.
4853
 
4854
  *Remarks:* Stable [[algorithm.stable]].
4855
 
4856
  ``` cpp
4857
- void reverse() noexcept;
4858
  ```
4859
 
4860
  *Effects:* Reverses the order of the elements in the list. Does not
4861
  affect the validity of iterators and references.
4862
 
4863
  *Complexity:* Linear time.
4864
 
4865
  #### Erasure <a id="forward.list.erasure">[[forward.list.erasure]]</a>
4866
 
4867
  ``` cpp
4868
- template<class T, class Allocator, class U>
4869
- typename forward_list<T, Allocator>::size_type
4870
  erase(forward_list<T, Allocator>& c, const U& value);
4871
  ```
4872
 
4873
  *Effects:* Equivalent to:
4874
- `return erase_if(c, [&](auto& elem) { return elem == value; });`
 
 
 
4875
 
4876
  ``` cpp
4877
  template<class T, class Allocator, class Predicate>
4878
- typename forward_list<T, Allocator>::size_type
4879
  erase_if(forward_list<T, Allocator>& c, Predicate pred);
4880
  ```
4881
 
4882
  *Effects:* Equivalent to: `return c.remove_if(pred);`
4883
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4884
  ### Class template `list` <a id="list">[[list]]</a>
4885
 
4886
  #### Overview <a id="list.overview">[[list.overview]]</a>
4887
 
4888
  A `list` is a sequence container that supports bidirectional iterators
@@ -4901,137 +5673,143 @@ provided.[^2]
4901
 
4902
  Descriptions are provided here only for operations on `list` that are
4903
  not described in one of these tables or for operations where there is
4904
  additional semantic information.
4905
 
 
 
 
4906
  ``` cpp
4907
  namespace std {
4908
  template<class T, class Allocator = allocator<T>>
4909
  class list {
4910
  public:
4911
  // types
4912
  using value_type = T;
4913
  using allocator_type = Allocator;
4914
- using pointer = typename allocator_traits<Allocator>::pointer;
4915
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
4916
  using reference = value_type&;
4917
  using const_reference = const value_type&;
4918
  using size_type = implementation-defined // type of list::size_type; // see [container.requirements]
4919
  using difference_type = implementation-defined // type of list::difference_type; // see [container.requirements]
4920
  using iterator = implementation-defined // type of list::iterator; // see [container.requirements]
4921
  using const_iterator = implementation-defined // type of list::const_iterator; // see [container.requirements]
4922
  using reverse_iterator = std::reverse_iterator<iterator>;
4923
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
4924
 
4925
  // [list.cons], construct/copy/destroy
4926
- list() : list(Allocator()) { }
4927
- explicit list(const Allocator&);
4928
- explicit list(size_type n, const Allocator& = Allocator());
4929
- list(size_type n, const T& value, const Allocator& = Allocator());
4930
  template<class InputIterator>
4931
- list(InputIterator first, InputIterator last, const Allocator& = Allocator());
4932
  template<container-compatible-range<T> R>
4933
- list(from_range_t, R&& rg, const Allocator& = Allocator());
4934
- list(const list& x);
4935
- list(list&& x);
4936
- list(const list&, const type_identity_t<Allocator>&);
4937
- list(list&&, const type_identity_t<Allocator>&);
4938
- list(initializer_list<T>, const Allocator& = Allocator());
4939
- ~list();
4940
- list& operator=(const list& x);
4941
- list& operator=(list&& x)
4942
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4943
- list& operator=(initializer_list<T>);
4944
  template<class InputIterator>
4945
- void assign(InputIterator first, InputIterator last);
4946
  template<container-compatible-range<T> R>
4947
- void assign_range(R&& rg);
4948
- void assign(size_type n, const T& t);
4949
- void assign(initializer_list<T>);
4950
- allocator_type get_allocator() const noexcept;
4951
 
4952
  // iterators
4953
- iterator begin() noexcept;
4954
- const_iterator begin() const noexcept;
4955
- iterator end() noexcept;
4956
- const_iterator end() const noexcept;
4957
- reverse_iterator rbegin() noexcept;
4958
- const_reverse_iterator rbegin() const noexcept;
4959
- reverse_iterator rend() noexcept;
4960
- const_reverse_iterator rend() const noexcept;
4961
 
4962
- const_iterator cbegin() const noexcept;
4963
- const_iterator cend() const noexcept;
4964
- const_reverse_iterator crbegin() const noexcept;
4965
- const_reverse_iterator crend() const noexcept;
4966
 
4967
  // [list.capacity], capacity
4968
- [[nodiscard]] bool empty() const noexcept;
4969
- size_type size() const noexcept;
4970
- size_type max_size() const noexcept;
4971
- void resize(size_type sz);
4972
- void resize(size_type sz, const T& c);
4973
 
4974
  // element access
4975
- reference front();
4976
- const_reference front() const;
4977
- reference back();
4978
- const_reference back() const;
4979
 
4980
  // [list.modifiers], modifiers
4981
- template<class... Args> reference emplace_front(Args&&... args);
4982
- template<class... Args> reference emplace_back(Args&&... args);
4983
- void push_front(const T& x);
4984
- void push_front(T&& x);
4985
  template<container-compatible-range<T> R>
4986
- void prepend_range(R&& rg);
4987
- void pop_front();
4988
- void push_back(const T& x);
4989
- void push_back(T&& x);
4990
  template<container-compatible-range<T> R>
4991
- void append_range(R&& rg);
4992
- void pop_back();
4993
 
4994
- template<class... Args> iterator emplace(const_iterator position, Args&&... args);
4995
- iterator insert(const_iterator position, const T& x);
4996
- iterator insert(const_iterator position, T&& x);
4997
- iterator insert(const_iterator position, size_type n, const T& x);
4998
  template<class InputIterator>
4999
- iterator insert(const_iterator position, InputIterator first, InputIterator last);
 
5000
  template<container-compatible-range<T> R>
5001
- iterator insert_range(const_iterator position, R&& rg);
5002
- iterator insert(const_iterator position, initializer_list<T> il);
5003
 
5004
- iterator erase(const_iterator position);
5005
- iterator erase(const_iterator position, const_iterator last);
5006
- void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value);
5007
- void clear() noexcept;
5008
 
5009
  // [list.ops], list operations
5010
- void splice(const_iterator position, list& x);
5011
- void splice(const_iterator position, list&& x);
5012
- void splice(const_iterator position, list& x, const_iterator i);
5013
- void splice(const_iterator position, list&& x, const_iterator i);
5014
- void splice(const_iterator position, list& x, const_iterator first, const_iterator last);
5015
- void splice(const_iterator position, list&& x, const_iterator first, const_iterator last);
 
 
5016
 
5017
- size_type remove(const T& value);
5018
- template<class Predicate> size_type remove_if(Predicate pred);
5019
 
5020
- size_type unique();
5021
  template<class BinaryPredicate>
5022
- size_type unique(BinaryPredicate binary_pred);
5023
 
5024
- void merge(list& x);
5025
- void merge(list&& x);
5026
- template<class Compare> void merge(list& x, Compare comp);
5027
- template<class Compare> void merge(list&& x, Compare comp);
5028
 
5029
- void sort();
5030
- template<class Compare> void sort(Compare comp);
5031
 
5032
- void reverse() noexcept;
5033
  };
5034
 
5035
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5036
  list(InputIterator, InputIterator, Allocator = Allocator())
5037
  -> list<iter-value-type<InputIterator>, Allocator>;
@@ -5048,65 +5826,65 @@ allocator meets the allocator completeness requirements
5048
  any member of the resulting specialization of `list` is referenced.
5049
 
5050
  #### Constructors, copy, and assignment <a id="list.cons">[[list.cons]]</a>
5051
 
5052
  ``` cpp
5053
- explicit list(const Allocator&);
5054
  ```
5055
 
5056
  *Effects:* Constructs an empty list, using the specified allocator.
5057
 
5058
  *Complexity:* Constant.
5059
 
5060
  ``` cpp
5061
- explicit list(size_type n, const Allocator& = Allocator());
5062
  ```
5063
 
5064
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
5065
 
5066
  *Effects:* Constructs a `list` with `n` default-inserted elements using
5067
  the specified allocator.
5068
 
5069
  *Complexity:* Linear in `n`.
5070
 
5071
  ``` cpp
5072
- list(size_type n, const T& value, const Allocator& = Allocator());
5073
  ```
5074
 
5075
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
5076
 
5077
  *Effects:* Constructs a `list` with `n` copies of `value`, using the
5078
  specified allocator.
5079
 
5080
  *Complexity:* Linear in `n`.
5081
 
5082
  ``` cpp
5083
  template<class InputIterator>
5084
- list(InputIterator first, InputIterator last, const Allocator& = Allocator());
5085
  ```
5086
 
5087
  *Effects:* Constructs a `list` equal to the range \[`first`, `last`).
5088
 
5089
  *Complexity:* Linear in `distance(first, last)`.
5090
 
5091
  ``` cpp
5092
  template<container-compatible-range<T> R>
5093
- list(from_range_t, R&& rg, const Allocator& = Allocator());
5094
  ```
5095
 
5096
  *Effects:* Constructs a `list` object with the elements of the range
5097
  `rg`.
5098
 
5099
  *Complexity:* Linear in `ranges::distance(rg)`.
5100
 
5101
  #### Capacity <a id="list.capacity">[[list.capacity]]</a>
5102
 
5103
  ``` cpp
5104
- void resize(size_type sz);
5105
  ```
5106
 
5107
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
5108
 
5109
  *Effects:* If `size() < sz`, appends `sz - size()` default-inserted
5110
  elements to the sequence. If `sz <= size()`, equivalent to:
5111
 
5112
  ``` cpp
@@ -5114,14 +5892,14 @@ list<T>::iterator it = begin();
5114
  advance(it, sz);
5115
  erase(it, end());
5116
  ```
5117
 
5118
  ``` cpp
5119
- void resize(size_type sz, const T& c);
5120
  ```
5121
 
5122
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
5123
 
5124
  *Effects:* As if by:
5125
 
5126
  ``` cpp
5127
  if (sz > size())
@@ -5136,49 +5914,48 @@ else
5136
  ```
5137
 
5138
  #### Modifiers <a id="list.modifiers">[[list.modifiers]]</a>
5139
 
5140
  ``` cpp
5141
- iterator insert(const_iterator position, const T& x);
5142
- iterator insert(const_iterator position, T&& x);
5143
- iterator insert(const_iterator position, size_type n, const T& x);
5144
  template<class InputIterator>
5145
- iterator insert(const_iterator position, InputIterator first,
5146
- InputIterator last);
5147
  template<container-compatible-range<T> R>
5148
- iterator insert_range(const_iterator position, R&& rg);
5149
- iterator insert(const_iterator position, initializer_list<T>);
5150
 
5151
- template<class... Args> reference emplace_front(Args&&... args);
5152
- template<class... Args> reference emplace_back(Args&&... args);
5153
- template<class... Args> iterator emplace(const_iterator position, Args&&... args);
5154
- void push_front(const T& x);
5155
- void push_front(T&& x);
5156
  template<container-compatible-range<T> R>
5157
- void prepend_range(R&& rg);
5158
- void push_back(const T& x);
5159
- void push_back(T&& x);
5160
  template<container-compatible-range<T> R>
5161
- void append_range(R&& rg);
5162
  ```
5163
 
5164
  *Complexity:* Insertion of a single element into a list takes constant
5165
  time and exactly one call to a constructor of `T`. Insertion of multiple
5166
  elements into a list is linear in the number of elements inserted, and
5167
  the number of calls to the copy constructor or move constructor of `T`
5168
  is exactly equal to the number of elements inserted.
5169
 
5170
  *Remarks:* Does not affect the validity of iterators and references. If
5171
- an exception is thrown there are no effects.
5172
 
5173
  ``` cpp
5174
- iterator erase(const_iterator position);
5175
- iterator erase(const_iterator first, const_iterator last);
5176
-
5177
- void pop_front();
5178
- void pop_back();
5179
- void clear() noexcept;
5180
  ```
5181
 
5182
  *Effects:* Invalidates only the iterators and references to the erased
5183
  elements.
5184
 
@@ -5205,12 +5982,12 @@ those of `next(i, n)` and `prev(i, n)`, respectively. For `merge` and
5205
  from one list to another. The behavior of splice operations is undefined
5206
  if `get_allocator() !=
5207
  x.get_allocator()`.
5208
 
5209
  ``` cpp
5210
- void splice(const_iterator position, list& x);
5211
- void splice(const_iterator position, list&& x);
5212
  ```
5213
 
5214
  *Preconditions:* `addressof(x) != this` is `true`.
5215
 
5216
  *Effects:* Inserts the contents of `x` before `position` and `x` becomes
@@ -5222,12 +5999,12 @@ now behave as iterators into `*this`, not into `x`.
5222
  *Throws:* Nothing.
5223
 
5224
  *Complexity:* Constant time.
5225
 
5226
  ``` cpp
5227
- void splice(const_iterator position, list& x, const_iterator i);
5228
- void splice(const_iterator position, list&& x, const_iterator i);
5229
  ```
5230
 
5231
  *Preconditions:* `i` is a valid dereferenceable iterator of `x`.
5232
 
5233
  *Effects:* Inserts an element pointed to by `i` from list `x` before
@@ -5240,18 +6017,18 @@ element, but now behave as iterators into `*this`, not into `x`.
5240
  *Throws:* Nothing.
5241
 
5242
  *Complexity:* Constant time.
5243
 
5244
  ``` cpp
5245
- void splice(const_iterator position, list& x, const_iterator first,
5246
- const_iterator last);
5247
- void splice(const_iterator position, list&& x, const_iterator first,
5248
- const_iterator last);
5249
  ```
5250
 
5251
- *Preconditions:* `[first, last)` is a valid range in `x`. `position` is
5252
- not an iterator in the range \[`first`, `last`).
5253
 
5254
  *Effects:* Inserts elements in the range \[`first`, `last`) before
5255
  `position` and removes the elements from `x`. Pointers and references to
5256
  the moved elements of `x` now refer to those same elements but as
5257
  members of `*this`. Iterators referring to the moved elements will
@@ -5262,12 +6039,12 @@ into `*this`, not into `x`.
5262
 
5263
  *Complexity:* Constant time if `addressof(x) == this`; otherwise, linear
5264
  time.
5265
 
5266
  ``` cpp
5267
- size_type remove(const T& value);
5268
- template<class Predicate> size_type remove_if(Predicate pred);
5269
  ```
5270
 
5271
  *Effects:* Erases all the elements in the list referred to by a list
5272
  iterator `i` for which the following conditions hold: `*i == value`,
5273
  `pred(*i) != false`. Invalidates only the iterators and references to
@@ -5282,12 +6059,12 @@ the erased elements.
5282
  predicate.
5283
 
5284
  *Remarks:* Stable [[algorithm.stable]].
5285
 
5286
  ``` cpp
5287
- size_type unique();
5288
- template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
5289
  ```
5290
 
5291
  Let `binary_pred` be `equal_to<>{}` for the first overload.
5292
 
5293
  *Preconditions:* `binary_pred` is an equivalence relation.
@@ -5305,14 +6082,14 @@ only the iterators and references to the erased elements.
5305
  *Complexity:* If `empty()` is `false`, exactly `size() - 1` applications
5306
  of the corresponding predicate, otherwise no applications of the
5307
  predicate.
5308
 
5309
  ``` cpp
5310
- void merge(list& x);
5311
- void merge(list&& x);
5312
- template<class Compare> void merge(list& x, Compare comp);
5313
- template<class Compare> void merge(list&& x, Compare comp);
5314
  ```
5315
 
5316
  Let `comp` be `less<>` for the first two overloads.
5317
 
5318
  *Preconditions:* `*this` and `x` are both sorted with respect to the
@@ -5329,14 +6106,14 @@ elements, but they now behave as iterators into `*this`, not into `x`.
5329
  *Complexity:* At most `size() + x.size() - 1` comparisons if
5330
  `addressof(x) != this`; otherwise, no comparisons are performed.
5331
 
5332
  *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
5333
  is empty after the merge. No elements are copied by this operation. If
5334
- an exception is thrown other than by a comparison there are no effects.
5335
 
5336
  ``` cpp
5337
- void reverse() noexcept;
5338
  ```
5339
 
5340
  *Effects:* Reverses the order of the elements in the list. Does not
5341
  affect the validity of iterators and references.
5342
 
@@ -5350,33 +6127,87 @@ template<class Compare> void sort(Compare comp);
5350
  *Effects:* Sorts the list according to the `operator<` or a `Compare`
5351
  function object. If an exception is thrown, the order of the elements in
5352
  `*this` is unspecified. Does not affect the validity of iterators and
5353
  references.
5354
 
5355
- *Complexity:* Approximately N log N comparisons, where `N == size()`.
5356
 
5357
  *Remarks:* Stable [[algorithm.stable]].
5358
 
5359
  #### Erasure <a id="list.erasure">[[list.erasure]]</a>
5360
 
5361
  ``` cpp
5362
- template<class T, class Allocator, class U>
5363
  typename list<T, Allocator>::size_type
5364
- erase(list<T, Allocator>& c, const U& value);
5365
  ```
5366
 
5367
  *Effects:* Equivalent to:
5368
- `return erase_if(c, [&](auto& elem) { return elem == value; });`
 
 
 
5369
 
5370
  ``` cpp
5371
  template<class T, class Allocator, class Predicate>
5372
  typename list<T, Allocator>::size_type
5373
- erase_if(list<T, Allocator>& c, Predicate pred);
5374
  ```
5375
 
5376
  *Effects:* Equivalent to: `return c.remove_if(pred);`
5377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5378
  ### Class template `vector` <a id="vector">[[vector]]</a>
5379
 
5380
  #### Overview <a id="vector.overview">[[vector.overview]]</a>
5381
 
5382
  A `vector` is a sequence container that supports (amortized) constant
@@ -5405,12 +6236,12 @@ namespace std {
5405
  class vector {
5406
  public:
5407
  // types
5408
  using value_type = T;
5409
  using allocator_type = Allocator;
5410
- using pointer = typename allocator_traits<Allocator>::pointer;
5411
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
5412
  using reference = value_type&;
5413
  using const_reference = const value_type&;
5414
  using size_type = implementation-defined // type of vector::size_type; // see [container.requirements]
5415
  using difference_type = implementation-defined // type of vector::difference_type; // see [container.requirements]
5416
  using iterator = implementation-defined // type of vector::iterator; // see [container.requirements]
@@ -5460,11 +6291,11 @@ namespace std {
5460
  constexpr const_iterator cend() const noexcept;
5461
  constexpr const_reverse_iterator crbegin() const noexcept;
5462
  constexpr const_reverse_iterator crend() const noexcept;
5463
 
5464
  // [vector.capacity], capacity
5465
- [[nodiscard]] constexpr bool empty() const noexcept;
5466
  constexpr size_type size() const noexcept;
5467
  constexpr size_type max_size() const noexcept;
5468
  constexpr size_type capacity() const noexcept;
5469
  constexpr void resize(size_type sz);
5470
  constexpr void resize(size_type sz, const T& c);
@@ -5472,12 +6303,12 @@ namespace std {
5472
  constexpr void shrink_to_fit();
5473
 
5474
  // element access
5475
  constexpr reference operator[](size_type n);
5476
  constexpr const_reference operator[](size_type n) const;
5477
- constexpr const_reference at(size_type n) const;
5478
  constexpr reference at(size_type n);
 
5479
  constexpr reference front();
5480
  constexpr const_reference front() const;
5481
  constexpr reference back();
5482
  constexpr const_reference back() const;
5483
 
@@ -5538,11 +6369,11 @@ constexpr explicit vector(const Allocator&) noexcept;
5538
 
5539
  ``` cpp
5540
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
5541
  ```
5542
 
5543
- *Preconditions:* `T` is *Cpp17DefaultInsertable* into `*this`.
5544
 
5545
  *Effects:* Constructs a `vector` with `n` default-inserted elements
5546
  using the specified allocator.
5547
 
5548
  *Complexity:* Linear in `n`.
@@ -5550,11 +6381,11 @@ using the specified allocator.
5550
  ``` cpp
5551
  constexpr vector(size_type n, const T& value,
5552
  const Allocator& = Allocator());
5553
  ```
5554
 
5555
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
5556
 
5557
  *Effects:* Constructs a `vector` with `n` copies of `value`, using the
5558
  specified allocator.
5559
 
5560
  *Complexity:* Linear in `n`.
@@ -5568,13 +6399,13 @@ template<class InputIterator>
5568
  *Effects:* Constructs a `vector` equal to the range \[`first`, `last`),
5569
  using the specified allocator.
5570
 
5571
  *Complexity:* Makes only N calls to the copy constructor of `T` (where N
5572
  is the distance between `first` and `last`) and no reallocations if
5573
- iterators `first` and `last` are of forward, bidirectional, or random
5574
- access categories. It makes order N calls to the copy constructor of `T`
5575
- and order log N reallocations if they are just input iterators.
5576
 
5577
  ``` cpp
5578
  template<container-compatible-range<T> R>
5579
  constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
5580
  ```
@@ -5582,14 +6413,21 @@ template<container-compatible-range<T> R>
5582
  *Effects:* Constructs a `vector` object with the elements of the range
5583
  `rg`, using the specified allocator.
5584
 
5585
  *Complexity:* Initializes exactly N elements from the results of
5586
  dereferencing successive iterators of `rg`, where N is
5587
- `ranges::distance(rg)`. Performs no reallocations if `R` models
5588
- `ranges::forward_range` or `ranges::sized_range`; otherwise, performs
5589
- order log N reallocations and order N calls to the copy or move
5590
- constructor of `T`.
 
 
 
 
 
 
 
5591
 
5592
  #### Capacity <a id="vector.capacity">[[vector.capacity]]</a>
5593
 
5594
  ``` cpp
5595
  constexpr size_type capacity() const noexcept;
@@ -5602,11 +6440,11 @@ requiring reallocation.
5602
 
5603
  ``` cpp
5604
  constexpr void reserve(size_type n);
5605
  ```
5606
 
5607
- *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
5608
 
5609
  *Effects:* A directive that informs a `vector` of a planned change in
5610
  size, so that it can manage the storage allocation accordingly. After
5611
  `reserve()`, `capacity()` is greater or equal to the argument of
5612
  `reserve` if reallocation happens; and equal to the previous value of
@@ -5615,16 +6453,15 @@ if the current capacity is less than the argument of `reserve()`. If an
5615
  exception is thrown other than by the move constructor of a
5616
  non-*Cpp17CopyInsertable* type, there are no effects.
5617
 
5618
  *Throws:* `length_error` if `n > max_size()`.[^4]
5619
 
5620
- *Complexity:* It does not change the size of the sequence and takes at
5621
- most linear time in the size of the sequence.
5622
 
5623
- *Remarks:* Reallocation invalidates all the references, pointers, and
5624
- iterators referring to the elements in the sequence, as well as the
5625
- past-the-end iterator.
5626
 
5627
  [*Note 1*: If no reallocation happens, they remain
5628
  valid. — *end note*]
5629
 
5630
  No reallocation shall take place during insertions that happen after a
@@ -5633,21 +6470,21 @@ greater than the value of `capacity()`.
5633
 
5634
  ``` cpp
5635
  constexpr void shrink_to_fit();
5636
  ```
5637
 
5638
- *Preconditions:* `T` is *Cpp17MoveInsertable* into `*this`.
5639
 
5640
  *Effects:* `shrink_to_fit` is a non-binding request to reduce
5641
  `capacity()` to `size()`.
5642
 
5643
  [*Note 2*: The request is non-binding to allow latitude for
5644
  implementation-specific optimizations. — *end note*]
5645
 
5646
  It does not increase `capacity()`, but may reduce `capacity()` by
5647
  causing reallocation. If an exception is thrown other than by the move
5648
- constructor of a non-*Cpp17CopyInsertable* `T` there are no effects.
5649
 
5650
  *Complexity:* If reallocation happens, linear in the size of the
5651
  sequence.
5652
 
5653
  *Remarks:* Reallocation invalidates all the references, pointers, and
@@ -5671,40 +6508,40 @@ of `x`.
5671
  ``` cpp
5672
  constexpr void resize(size_type sz);
5673
  ```
5674
 
5675
  *Preconditions:* `T` is *Cpp17MoveInsertable* and
5676
- *Cpp17DefaultInsertable* into `*this`.
5677
 
5678
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
5679
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
5680
  to the sequence.
5681
 
5682
  *Remarks:* If an exception is thrown other than by the move constructor
5683
- of a non-*Cpp17CopyInsertable* `T` there are no effects.
5684
 
5685
  ``` cpp
5686
  constexpr void resize(size_type sz, const T& c);
5687
  ```
5688
 
5689
- *Preconditions:* `T` is *Cpp17CopyInsertable* into `*this`.
5690
 
5691
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
5692
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
5693
  sequence.
5694
 
5695
- *Remarks:* If an exception is thrown there are no effects.
5696
 
5697
  #### Data <a id="vector.data">[[vector.data]]</a>
5698
 
5699
  ``` cpp
5700
  constexpr T* data() noexcept;
5701
  constexpr const T* data() const noexcept;
5702
  ```
5703
 
5704
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
5705
- range. For a non-empty vector, `data()` `==` `addressof(front())`.
5706
 
5707
  *Complexity:* Constant time.
5708
 
5709
  #### Modifiers <a id="vector.modifiers">[[vector.modifiers]]</a>
5710
 
@@ -5736,17 +6573,29 @@ iterators referring to the elements in the sequence, as well as the
5736
  past-the-end iterator. If no reallocation happens, then references,
5737
  pointers, and iterators before the insertion point remain valid but
5738
  those at or after the insertion point, including the past-the-end
5739
  iterator, are invalidated. If an exception is thrown other than by the
5740
  copy constructor, move constructor, assignment operator, or move
5741
- assignment operator of `T` or by any `InputIterator` operation there are
5742
- no effects. If an exception is thrown while inserting a single element
5743
- at the end and `T` is *Cpp17CopyInsertable* or
5744
  `is_nothrow_move_constructible_v<T>` is `true`, there are no effects.
5745
  Otherwise, if an exception is thrown by the move constructor of a
5746
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
5747
 
 
 
 
 
 
 
 
 
 
 
 
 
5748
  ``` cpp
5749
  constexpr iterator erase(const_iterator position);
5750
  constexpr iterator erase(const_iterator first, const_iterator last);
5751
  constexpr void pop_back();
5752
  ```
@@ -5763,11 +6612,11 @@ is called the number of times equal to the number of elements in the
5763
  vector after the erased elements.
5764
 
5765
  #### Erasure <a id="vector.erasure">[[vector.erasure]]</a>
5766
 
5767
  ``` cpp
5768
- template<class T, class Allocator, class U>
5769
  constexpr typename vector<T, Allocator>::size_type
5770
  erase(vector<T, Allocator>& c, const U& value);
5771
  ```
5772
 
5773
  *Effects:* Equivalent to:
@@ -5819,13 +6668,10 @@ namespace std {
5819
  using reverse_iterator = std::reverse_iterator<iterator>;
5820
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
5821
 
5822
  // bit reference
5823
  class reference {
5824
- friend class vector;
5825
- constexpr reference() noexcept;
5826
-
5827
  public:
5828
  constexpr reference(const reference&) = default;
5829
  constexpr ~reference();
5830
  constexpr operator bool() const noexcept;
5831
  constexpr reference& operator=(bool x) noexcept;
@@ -5876,23 +6722,23 @@ namespace std {
5876
  constexpr const_iterator cend() const noexcept;
5877
  constexpr const_reverse_iterator crbegin() const noexcept;
5878
  constexpr const_reverse_iterator crend() const noexcept;
5879
 
5880
  // capacity
5881
- [[nodiscard]] constexpr bool empty() const noexcept;
5882
  constexpr size_type size() const noexcept;
5883
  constexpr size_type max_size() const noexcept;
5884
  constexpr size_type capacity() const noexcept;
5885
  constexpr void resize(size_type sz, bool c = false);
5886
  constexpr void reserve(size_type n);
5887
  constexpr void shrink_to_fit();
5888
 
5889
  // element access
5890
  constexpr reference operator[](size_type n);
5891
  constexpr const_reference operator[](size_type n) const;
5892
- constexpr const_reference at(size_type n) const;
5893
  constexpr reference at(size_type n);
 
5894
  constexpr reference front();
5895
  constexpr const_reference front() const;
5896
  constexpr reference back();
5897
  constexpr const_reference back() const;
5898
 
@@ -5923,11 +6769,11 @@ namespace std {
5923
  };
5924
  }
5925
  ```
5926
 
5927
  Unless described below, all operations have the same requirements and
5928
- semantics as the primary `vector` template, except that operations
5929
  dealing with the `bool` value type map to bit values in the container
5930
  storage and `allocator_traits::construct` [[allocator.traits.members]]
5931
  is not used to construct these values.
5932
 
5933
  There is no requirement that the data be stored as a contiguous
@@ -6011,42 +6857,515 @@ template<class FormatContext>
6011
  format(const T& ref, FormatContext& ctx) const;
6012
  ```
6013
 
6014
  Equivalent to: `return `*`underlying_`*`.format(ref, ctx);`
6015
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6016
  ## Associative containers <a id="associative">[[associative]]</a>
6017
 
6018
- ### In general <a id="associative.general">[[associative.general]]</a>
6019
 
6020
  The header `<map>` defines the class templates `map` and `multimap`; the
6021
  header `<set>` defines the class templates `set` and `multiset`.
6022
 
6023
  The following exposition-only alias templates may appear in deduction
6024
  guides for associative containers:
6025
 
6026
  ``` cpp
6027
  template<class InputIterator>
6028
- using iter-value-type =
6029
- typename iterator_traits<InputIterator>::value_type; // exposition only
6030
  template<class InputIterator>
6031
  using iter-key-type = remove_const_t<
6032
  tuple_element_t<0, iter-value-type<InputIterator>>>; // exposition only
6033
  template<class InputIterator>
6034
  using iter-mapped-type =
6035
  tuple_element_t<1, iter-value-type<InputIterator>>; // exposition only
6036
  template<class InputIterator>
6037
  using iter-to-alloc-type = pair<
6038
- add_const_t<tuple_element_t<0, iter-value-type<InputIterator>>>,
6039
  tuple_element_t<1, iter-value-type<InputIterator>>>; // exposition only
6040
  template<ranges::input_range Range>
6041
  using range-key-type =
6042
  remove_const_t<typename ranges::range_value_t<Range>::first_type>; // exposition only
6043
  template<ranges::input_range Range>
6044
- using range-mapped-type = typename ranges::range_value_t<Range>::second_type; // exposition only
6045
  template<ranges::input_range Range>
6046
  using range-to-alloc-type =
6047
- pair<add_const_t<typename ranges::range_value_t<Range>::first_type>,
6048
  typename ranges::range_value_t<Range>::second_type>; // exposition only
6049
  ```
6050
 
6051
  ### Header `<map>` synopsis <a id="associative.map.syn">[[associative.map.syn]]</a>
6052
 
@@ -6059,48 +7378,48 @@ namespace std {
6059
  template<class Key, class T, class Compare = less<Key>,
6060
  class Allocator = allocator<pair<const Key, T>>>
6061
  class map;
6062
 
6063
  template<class Key, class T, class Compare, class Allocator>
6064
- bool operator==(const map<Key, T, Compare, Allocator>& x,
6065
  const map<Key, T, Compare, Allocator>& y);
6066
  template<class Key, class T, class Compare, class Allocator>
6067
- synth-three-way-result<pair<const Key, T>>
6068
  operator<=>(const map<Key, T, Compare, Allocator>& x,
6069
  const map<Key, T, Compare, Allocator>& y);
6070
 
6071
  template<class Key, class T, class Compare, class Allocator>
6072
- void swap(map<Key, T, Compare, Allocator>& x,
6073
  map<Key, T, Compare, Allocator>& y)
6074
  noexcept(noexcept(x.swap(y)));
6075
 
6076
  // [map.erasure], erasure for map
6077
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6078
- typename map<Key, T, Compare, Allocator>::size_type
6079
  erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
6080
 
6081
  // [multimap], class template multimap
6082
  template<class Key, class T, class Compare = less<Key>,
6083
  class Allocator = allocator<pair<const Key, T>>>
6084
  class multimap;
6085
 
6086
  template<class Key, class T, class Compare, class Allocator>
6087
- bool operator==(const multimap<Key, T, Compare, Allocator>& x,
6088
  const multimap<Key, T, Compare, Allocator>& y);
6089
  template<class Key, class T, class Compare, class Allocator>
6090
- synth-three-way-result<pair<const Key, T>>
6091
  operator<=>(const multimap<Key, T, Compare, Allocator>& x,
6092
  const multimap<Key, T, Compare, Allocator>& y);
6093
 
6094
  template<class Key, class T, class Compare, class Allocator>
6095
- void swap(multimap<Key, T, Compare, Allocator>& x,
6096
  multimap<Key, T, Compare, Allocator>& y)
6097
  noexcept(noexcept(x.swap(y)));
6098
 
6099
  // [multimap.erasure], erasure for multimap
6100
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6101
- typename multimap<Key, T, Compare, Allocator>::size_type
6102
  erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
6103
 
6104
  namespace pmr {
6105
  template<class Key, class T, class Compare = less<Key>>
6106
  using map = std::map<Key, T, Compare,
@@ -6111,69 +7430,10 @@ namespace std {
6111
  polymorphic_allocator<pair<const Key, T>>>;
6112
  }
6113
  }
6114
  ```
6115
 
6116
- ### Header `<set>` synopsis <a id="associative.set.syn">[[associative.set.syn]]</a>
6117
-
6118
- ``` cpp
6119
- #include <compare> // see [compare.syn]
6120
- #include <initializer_list> // see [initializer.list.syn]
6121
-
6122
- namespace std {
6123
- // [set], class template set
6124
- template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
6125
- class set;
6126
-
6127
- template<class Key, class Compare, class Allocator>
6128
- bool operator==(const set<Key, Compare, Allocator>& x,
6129
- const set<Key, Compare, Allocator>& y);
6130
- template<class Key, class Compare, class Allocator>
6131
- synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x,
6132
- \itcorr const set<Key, Compare, Allocator>& y);
6133
-
6134
- template<class Key, class Compare, class Allocator>
6135
- void swap(set<Key, Compare, Allocator>& x,
6136
- set<Key, Compare, Allocator>& y)
6137
- noexcept(noexcept(x.swap(y)));
6138
-
6139
- // [set.erasure], erasure for set
6140
- template<class Key, class Compare, class Allocator, class Predicate>
6141
- typename set<Key, Compare, Allocator>::size_type
6142
- erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
6143
-
6144
- // [multiset], class template multiset
6145
- template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
6146
- class multiset;
6147
-
6148
- template<class Key, class Compare, class Allocator>
6149
- bool operator==(const multiset<Key, Compare, Allocator>& x,
6150
- const multiset<Key, Compare, Allocator>& y);
6151
- template<class Key, class Compare, class Allocator>
6152
- synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x,
6153
- \itcorr const multiset<Key, Compare, Allocator>& y);
6154
-
6155
- template<class Key, class Compare, class Allocator>
6156
- void swap(multiset<Key, Compare, Allocator>& x,
6157
- multiset<Key, Compare, Allocator>& y)
6158
- noexcept(noexcept(x.swap(y)));
6159
-
6160
- // [multiset.erasure], erasure for multiset
6161
- template<class Key, class Compare, class Allocator, class Predicate>
6162
- typename multiset<Key, Compare, Allocator>::size_type
6163
- erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
6164
-
6165
- namespace pmr {
6166
- template<class Key, class Compare = less<Key>>
6167
- using set = std::set<Key, Compare, polymorphic_allocator<Key>>;
6168
-
6169
- template<class Key, class Compare = less<Key>>
6170
- using multiset = std::multiset<Key, Compare, polymorphic_allocator<Key>>;
6171
- }
6172
- }
6173
- ```
6174
-
6175
  ### Class template `map` <a id="map">[[map]]</a>
6176
 
6177
  #### Overview <a id="map.overview">[[map.overview]]</a>
6178
 
6179
  A `map` is an associative container that supports unique keys (i.e.,
@@ -6182,19 +7442,22 @@ of values of another type `T` based on the keys. The `map` class
6182
  supports bidirectional iterators.
6183
 
6184
  A `map` meets all of the requirements of a container
6185
  [[container.reqmts]], of a reversible container
6186
  [[container.rev.reqmts]], of an allocator-aware container
6187
- [[container.alloc.reqmts]]. and of an associative container
6188
  [[associative.reqmts]]. A `map` also provides most operations described
6189
  in  [[associative.reqmts]] for unique keys. This means that a `map`
6190
  supports the `a_uniq` operations in  [[associative.reqmts]] but not the
6191
  `a_eq` operations. For a `map<Key,T>` the `key_type` is `Key` and the
6192
  `value_type` is `pair<const Key,T>`. Descriptions are provided here only
6193
  for operations on `map` that are not described in one of those tables or
6194
  for operations where there is additional semantic information.
6195
 
 
 
 
6196
  ``` cpp
6197
  namespace std {
6198
  template<class Key, class T, class Compare = less<Key>,
6199
  class Allocator = allocator<pair<const Key, T>>>
6200
  class map {
@@ -6203,12 +7466,12 @@ namespace std {
6203
  using key_type = Key;
6204
  using mapped_type = T;
6205
  using value_type = pair<const Key, T>;
6206
  using key_compare = Compare;
6207
  using allocator_type = Allocator;
6208
- using pointer = typename allocator_traits<Allocator>::pointer;
6209
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6210
  using reference = value_type&;
6211
  using const_reference = const value_type&;
6212
  using size_type = implementation-defined // type of map::size_type; // see [container.requirements]
6213
  using difference_type = implementation-defined // type of map::difference_type; // see [container.requirements]
6214
  using iterator = implementation-defined // type of map::iterator; // see [container.requirements]
@@ -6217,170 +7480,181 @@ namespace std {
6217
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6218
  using node_type = unspecified;
6219
  using insert_return_type = insert-return-type<iterator, node_type>;
6220
 
6221
  class value_compare {
6222
- friend class map;
6223
  protected:
6224
  Compare comp;
6225
- value_compare(Compare c) : comp(c) {}
6226
 
6227
  public:
6228
- bool operator()(const value_type& x, const value_type& y) const {
6229
  return comp(x.first, y.first);
6230
  }
6231
  };
6232
 
6233
  // [map.cons], construct/copy/destroy
6234
- map() : map(Compare()) { }
6235
- explicit map(const Compare& comp, const Allocator& = Allocator());
6236
  template<class InputIterator>
6237
- map(InputIterator first, InputIterator last,
6238
  const Compare& comp = Compare(), const Allocator& = Allocator());
6239
  template<container-compatible-range<value_type> R>
6240
- map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6241
- map(const map& x);
6242
- map(map&& x);
 
6243
  explicit map(const Allocator&);
6244
- map(const map&, const type_identity_t<Allocator>&);
6245
- map(map&&, const type_identity_t<Allocator>&);
6246
- map(initializer_list<value_type>,
6247
- const Compare& = Compare(),
6248
  const Allocator& = Allocator());
6249
  template<class InputIterator>
6250
- map(InputIterator first, InputIterator last, const Allocator& a)
6251
  : map(first, last, Compare(), a) { }
6252
  template<container-compatible-range<value_type> R>
6253
- map(from_range_t, R&& rg, const Allocator& a))
6254
  : map(from_range, std::forward<R>(rg), Compare(), a) { }
6255
- map(initializer_list<value_type> il, const Allocator& a)
6256
  : map(il, Compare(), a) { }
6257
- ~map();
6258
- map& operator=(const map& x);
6259
- map& operator=(map&& x)
6260
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6261
  is_nothrow_move_assignable_v<Compare>);
6262
- map& operator=(initializer_list<value_type>);
6263
- allocator_type get_allocator() const noexcept;
6264
 
6265
  // iterators
6266
- iterator begin() noexcept;
6267
- const_iterator begin() const noexcept;
6268
- iterator end() noexcept;
6269
- const_iterator end() const noexcept;
6270
 
6271
- reverse_iterator rbegin() noexcept;
6272
- const_reverse_iterator rbegin() const noexcept;
6273
- reverse_iterator rend() noexcept;
6274
- const_reverse_iterator rend() const noexcept;
6275
 
6276
- const_iterator cbegin() const noexcept;
6277
- const_iterator cend() const noexcept;
6278
- const_reverse_iterator crbegin() const noexcept;
6279
- const_reverse_iterator crend() const noexcept;
6280
 
6281
  // capacity
6282
- [[nodiscard]] bool empty() const noexcept;
6283
- size_type size() const noexcept;
6284
- size_type max_size() const noexcept;
6285
 
6286
  // [map.access], element access
6287
- mapped_type& operator[](const key_type& x);
6288
- mapped_type& operator[](key_type&& x);
6289
- mapped_type& at(const key_type& x);
6290
- const mapped_type& at(const key_type& x) const;
 
 
 
6291
 
6292
  // [map.modifiers], modifiers
6293
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
6294
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
6295
- pair<iterator, bool> insert(const value_type& x);
6296
- pair<iterator, bool> insert(value_type&& x);
6297
- template<class P> pair<iterator, bool> insert(P&& x);
6298
- iterator insert(const_iterator position, const value_type& x);
6299
- iterator insert(const_iterator position, value_type&& x);
 
6300
  template<class P>
6301
- iterator insert(const_iterator position, P&&);
6302
  template<class InputIterator>
6303
- void insert(InputIterator first, InputIterator last);
6304
  template<container-compatible-range<value_type> R>
6305
- void insert_range(R&& rg);
6306
- void insert(initializer_list<value_type>);
6307
 
6308
- node_type extract(const_iterator position);
6309
- node_type extract(const key_type& x);
6310
- template<class K> node_type extract(K&& x);
6311
- insert_return_type insert(node_type&& nh);
6312
- iterator insert(const_iterator hint, node_type&& nh);
6313
 
6314
  template<class... Args>
6315
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
6316
  template<class... Args>
6317
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
 
 
6318
  template<class... Args>
6319
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
6320
  template<class... Args>
6321
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
 
 
6322
  template<class M>
6323
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
6324
  template<class M>
6325
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
 
 
6326
  template<class M>
6327
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
6328
  template<class M>
6329
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
 
 
6330
 
6331
- iterator erase(iterator position);
6332
- iterator erase(const_iterator position);
6333
- size_type erase(const key_type& x);
6334
- template<class K> size_type erase(K&& x);
6335
- iterator erase(const_iterator first, const_iterator last);
6336
- void swap(map&)
6337
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6338
  is_nothrow_swappable_v<Compare>);
6339
- void clear() noexcept;
6340
 
6341
  template<class C2>
6342
- void merge(map<Key, T, C2, Allocator>& source);
6343
  template<class C2>
6344
- void merge(map<Key, T, C2, Allocator>&& source);
6345
  template<class C2>
6346
- void merge(multimap<Key, T, C2, Allocator>& source);
6347
  template<class C2>
6348
- void merge(multimap<Key, T, C2, Allocator>&& source);
6349
 
6350
  // observers
6351
- key_compare key_comp() const;
6352
- value_compare value_comp() const;
6353
 
6354
  // map operations
6355
- iterator find(const key_type& x);
6356
- const_iterator find(const key_type& x) const;
6357
- template<class K> iterator find(const K& x);
6358
- template<class K> const_iterator find(const K& x) const;
6359
 
6360
- size_type count(const key_type& x) const;
6361
- template<class K> size_type count(const K& x) const;
6362
 
6363
- bool contains(const key_type& x) const;
6364
- template<class K> bool contains(const K& x) const;
6365
 
6366
- iterator lower_bound(const key_type& x);
6367
- const_iterator lower_bound(const key_type& x) const;
6368
- template<class K> iterator lower_bound(const K& x);
6369
- template<class K> const_iterator lower_bound(const K& x) const;
6370
 
6371
- iterator upper_bound(const key_type& x);
6372
- const_iterator upper_bound(const key_type& x) const;
6373
- template<class K> iterator upper_bound(const K& x);
6374
- template<class K> const_iterator upper_bound(const K& x) const;
6375
 
6376
- pair<iterator, iterator> equal_range(const key_type& x);
6377
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
6378
  template<class K>
6379
- pair<iterator, iterator> equal_range(const K& x);
6380
  template<class K>
6381
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
6382
  };
6383
 
6384
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
6385
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
6386
  map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
@@ -6411,21 +7685,21 @@ namespace std {
6411
  ```
6412
 
6413
  #### Constructors, copy, and assignment <a id="map.cons">[[map.cons]]</a>
6414
 
6415
  ``` cpp
6416
- explicit map(const Compare& comp, const Allocator& = Allocator());
6417
  ```
6418
 
6419
  *Effects:* Constructs an empty `map` using the specified comparison
6420
  object and allocator.
6421
 
6422
  *Complexity:* Constant.
6423
 
6424
  ``` cpp
6425
  template<class InputIterator>
6426
- map(InputIterator first, InputIterator last,
6427
  const Compare& comp = Compare(), const Allocator& = Allocator());
6428
  ```
6429
 
6430
  *Effects:* Constructs an empty `map` using the specified comparison
6431
  object and allocator, and inserts elements from the range \[`first`,
@@ -6435,11 +7709,12 @@ object and allocator, and inserts elements from the range \[`first`,
6435
  sorted with respect to `comp` and otherwise N log N, where N is
6436
  `last - first`.
6437
 
6438
  ``` cpp
6439
  template<container-compatible-range<value_type> R>
6440
- map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
 
6441
  ```
6442
 
6443
  *Effects:* Constructs an empty `map` using the specified comparison
6444
  object and allocator, and inserts elements from the range `rg`.
6445
 
@@ -6447,55 +7722,83 @@ object and allocator, and inserts elements from the range `rg`.
6447
  `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
6448
 
6449
  #### Element access <a id="map.access">[[map.access]]</a>
6450
 
6451
  ``` cpp
6452
- mapped_type& operator[](const key_type& x);
6453
  ```
6454
 
6455
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
6456
 
6457
  ``` cpp
6458
- mapped_type& operator[](key_type&& x);
6459
  ```
6460
 
6461
  *Effects:* Equivalent to:
6462
  `return try_emplace(std::move(x)).first->second;`
6463
 
6464
  ``` cpp
6465
- mapped_type& at(const key_type& x);
6466
- const mapped_type& at(const key_type& x) const;
 
 
 
 
 
 
 
 
 
 
6467
  ```
6468
 
6469
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
6470
  `*this`.
6471
 
6472
  *Throws:* An exception object of type `out_of_range` if no such element
6473
  is present.
6474
 
6475
  *Complexity:* Logarithmic.
6476
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6477
  #### Modifiers <a id="map.modifiers">[[map.modifiers]]</a>
6478
 
6479
  ``` cpp
6480
  template<class P>
6481
- pair<iterator, bool> insert(P&& x);
6482
  template<class P>
6483
- iterator insert(const_iterator position, P&& x);
6484
  ```
6485
 
6486
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
6487
 
6488
  *Effects:* The first form is equivalent to
6489
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
6490
  `return emplace_hint(position, std::forward<P>(x))`.
6491
 
6492
  ``` cpp
6493
  template<class... Args>
6494
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
6495
  template<class... Args>
6496
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
6497
  ```
6498
 
6499
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
6500
  from `piecewise_construct`, `forward_as_tuple(k)`,
6501
  `forward_as_tuple(std::forward<Args>(args)...)`.
@@ -6511,13 +7814,13 @@ iterator points to the map element whose key is equivalent to `k`.
6511
 
6512
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
6513
 
6514
  ``` cpp
6515
  template<class... Args>
6516
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
6517
  template<class... Args>
6518
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
6519
  ```
6520
 
6521
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
6522
  from `piecewise_construct`, `forward_as_tuple(std::move(k))`,
6523
  `forward_as_tuple(std::forward<Args>(args)...)`.
@@ -6532,15 +7835,44 @@ type `value_type` constructed with `piecewise_construct`,
6532
  pair is `true` if and only if the insertion took place. The returned
6533
  iterator points to the map element whose key is equivalent to `k`.
6534
 
6535
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
6536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6537
  ``` cpp
6538
  template<class M>
6539
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
6540
  template<class M>
6541
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
6542
  ```
6543
 
6544
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
6545
 
6546
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
@@ -6557,13 +7889,13 @@ iterator points to the map element whose key is equivalent to `k`.
6557
 
6558
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
6559
 
6560
  ``` cpp
6561
  template<class M>
6562
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
6563
  template<class M>
6564
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
6565
  ```
6566
 
6567
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
6568
 
6569
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
@@ -6578,16 +7910,44 @@ Otherwise inserts an object of type `value_type` constructed with
6578
  pair is `true` if and only if the insertion took place. The returned
6579
  iterator points to the map element whose key is equivalent to `k`.
6580
 
6581
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
6582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6583
  #### Erasure <a id="map.erasure">[[map.erasure]]</a>
6584
 
6585
  ``` cpp
6586
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6587
  typename map<Key, T, Compare, Allocator>::size_type
6588
- erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
6589
  ```
6590
 
6591
  *Effects:* Equivalent to:
6592
 
6593
  ``` cpp
@@ -6622,10 +7982,13 @@ not the `a_uniq` operations. For a `multimap<Key,T>` the `key_type` is
6622
  `Key` and the `value_type` is `pair<const Key,T>`. Descriptions are
6623
  provided here only for operations on `multimap` that are not described
6624
  in one of those tables or for operations where there is additional
6625
  semantic information.
6626
 
 
 
 
6627
  ``` cpp
6628
  namespace std {
6629
  template<class Key, class T, class Compare = less<Key>,
6630
  class Allocator = allocator<pair<const Key, T>>>
6631
  class multimap {
@@ -6634,12 +7997,12 @@ namespace std {
6634
  using key_type = Key;
6635
  using mapped_type = T;
6636
  using value_type = pair<const Key, T>;
6637
  using key_compare = Compare;
6638
  using allocator_type = Allocator;
6639
- using pointer = typename allocator_traits<Allocator>::pointer;
6640
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6641
  using reference = value_type&;
6642
  using const_reference = const value_type&;
6643
  using size_type = implementation-defined // type of multimap::size_type; // see [container.requirements]
6644
  using difference_type = implementation-defined // type of multimap::difference_type; // see [container.requirements]
6645
  using iterator = implementation-defined // type of multimap::iterator; // see [container.requirements]
@@ -6647,148 +8010,146 @@ namespace std {
6647
  using reverse_iterator = std::reverse_iterator<iterator>;
6648
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6649
  using node_type = unspecified;
6650
 
6651
  class value_compare {
6652
- friend class multimap;
6653
  protected:
6654
  Compare comp;
6655
- value_compare(Compare c) : comp(c) { }
6656
 
6657
  public:
6658
- bool operator()(const value_type& x, const value_type& y) const {
6659
  return comp(x.first, y.first);
6660
  }
6661
  };
6662
 
6663
  // [multimap.cons], construct/copy/destroy
6664
- multimap() : multimap(Compare()) { }
6665
- explicit multimap(const Compare& comp, const Allocator& = Allocator());
6666
  template<class InputIterator>
6667
- multimap(InputIterator first, InputIterator last,
6668
- const Compare& comp = Compare(),
6669
- const Allocator& = Allocator());
6670
  template<container-compatible-range<value_type> R>
6671
- multimap(from_range_t, R&& rg,
6672
  const Compare& comp = Compare(), const Allocator& = Allocator());
6673
- multimap(const multimap& x);
6674
- multimap(multimap&& x);
6675
- explicit multimap(const Allocator&);
6676
- multimap(const multimap&, const type_identity_t<Allocator>&);
6677
- multimap(multimap&&, const type_identity_t<Allocator>&);
6678
- multimap(initializer_list<value_type>,
6679
- const Compare& = Compare(),
6680
- const Allocator& = Allocator());
6681
  template<class InputIterator>
6682
- multimap(InputIterator first, InputIterator last, const Allocator& a)
6683
  : multimap(first, last, Compare(), a) { }
6684
  template<container-compatible-range<value_type> R>
6685
- multimap(from_range_t, R&& rg, const Allocator& a))
6686
  : multimap(from_range, std::forward<R>(rg), Compare(), a) { }
6687
- multimap(initializer_list<value_type> il, const Allocator& a)
6688
  : multimap(il, Compare(), a) { }
6689
- ~multimap();
6690
- multimap& operator=(const multimap& x);
6691
- multimap& operator=(multimap&& x)
6692
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6693
  is_nothrow_move_assignable_v<Compare>);
6694
- multimap& operator=(initializer_list<value_type>);
6695
- allocator_type get_allocator() const noexcept;
6696
 
6697
  // iterators
6698
- iterator begin() noexcept;
6699
- const_iterator begin() const noexcept;
6700
- iterator end() noexcept;
6701
- const_iterator end() const noexcept;
6702
 
6703
- reverse_iterator rbegin() noexcept;
6704
- const_reverse_iterator rbegin() const noexcept;
6705
- reverse_iterator rend() noexcept;
6706
- const_reverse_iterator rend() const noexcept;
6707
 
6708
- const_iterator cbegin() const noexcept;
6709
- const_iterator cend() const noexcept;
6710
- const_reverse_iterator crbegin() const noexcept;
6711
- const_reverse_iterator crend() const noexcept;
6712
 
6713
  // capacity
6714
- [[nodiscard]] bool empty() const noexcept;
6715
- size_type size() const noexcept;
6716
- size_type max_size() const noexcept;
6717
 
6718
  // [multimap.modifiers], modifiers
6719
- template<class... Args> iterator emplace(Args&&... args);
6720
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
6721
- iterator insert(const value_type& x);
6722
- iterator insert(value_type&& x);
6723
- template<class P> iterator insert(P&& x);
6724
- iterator insert(const_iterator position, const value_type& x);
6725
- iterator insert(const_iterator position, value_type&& x);
6726
- template<class P> iterator insert(const_iterator position, P&& x);
 
6727
  template<class InputIterator>
6728
- void insert(InputIterator first, InputIterator last);
6729
  template<container-compatible-range<value_type> R>
6730
- void insert_range(R&& rg);
6731
- void insert(initializer_list<value_type>);
6732
 
6733
- node_type extract(const_iterator position);
6734
- node_type extract(const key_type& x);
6735
  template<class K> node_type extract(K&& x);
6736
- iterator insert(node_type&& nh);
6737
- iterator insert(const_iterator hint, node_type&& nh);
6738
 
6739
- iterator erase(iterator position);
6740
- iterator erase(const_iterator position);
6741
- size_type erase(const key_type& x);
6742
- template<class K> size_type erase(K&& x);
6743
- iterator erase(const_iterator first, const_iterator last);
6744
- void swap(multimap&)
6745
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6746
  is_nothrow_swappable_v<Compare>);
6747
- void clear() noexcept;
6748
 
6749
  template<class C2>
6750
- void merge(multimap<Key, T, C2, Allocator>& source);
6751
  template<class C2>
6752
- void merge(multimap<Key, T, C2, Allocator>&& source);
6753
  template<class C2>
6754
- void merge(map<Key, T, C2, Allocator>& source);
6755
  template<class C2>
6756
- void merge(map<Key, T, C2, Allocator>&& source);
6757
 
6758
  // observers
6759
- key_compare key_comp() const;
6760
- value_compare value_comp() const;
6761
 
6762
  // map operations
6763
- iterator find(const key_type& x);
6764
- const_iterator find(const key_type& x) const;
6765
- template<class K> iterator find(const K& x);
6766
- template<class K> const_iterator find(const K& x) const;
6767
 
6768
- size_type count(const key_type& x) const;
6769
- template<class K> size_type count(const K& x) const;
6770
 
6771
- bool contains(const key_type& x) const;
6772
- template<class K> bool contains(const K& x) const;
6773
 
6774
- iterator lower_bound(const key_type& x);
6775
- const_iterator lower_bound(const key_type& x) const;
6776
- template<class K> iterator lower_bound(const K& x);
6777
- template<class K> const_iterator lower_bound(const K& x) const;
6778
 
6779
- iterator upper_bound(const key_type& x);
6780
- const_iterator upper_bound(const key_type& x) const;
6781
- template<class K> iterator upper_bound(const K& x);
6782
- template<class K> const_iterator upper_bound(const K& x) const;
6783
 
6784
- pair<iterator, iterator> equal_range(const key_type& x);
6785
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
6786
  template<class K>
6787
- pair<iterator, iterator> equal_range(const K& x);
6788
  template<class K>
6789
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
6790
  };
6791
 
6792
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
6793
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
6794
  multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
@@ -6821,23 +8182,22 @@ namespace std {
6821
  ```
6822
 
6823
  #### Constructors <a id="multimap.cons">[[multimap.cons]]</a>
6824
 
6825
  ``` cpp
6826
- explicit multimap(const Compare& comp, const Allocator& = Allocator());
6827
  ```
6828
 
6829
  *Effects:* Constructs an empty `multimap` using the specified comparison
6830
  object and allocator.
6831
 
6832
  *Complexity:* Constant.
6833
 
6834
  ``` cpp
6835
  template<class InputIterator>
6836
- multimap(InputIterator first, InputIterator last,
6837
- const Compare& comp = Compare(),
6838
- const Allocator& = Allocator());
6839
  ```
6840
 
6841
  *Effects:* Constructs an empty `multimap` using the specified comparison
6842
  object and allocator, and inserts elements from the range \[`first`,
6843
  `last`).
@@ -6846,11 +8206,12 @@ object and allocator, and inserts elements from the range \[`first`,
6846
  sorted with respect to `comp` and otherwise N log N, where N is
6847
  `last - first`.
6848
 
6849
  ``` cpp
6850
  template<container-compatible-range<value_type> R>
6851
- multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
 
6852
  ```
6853
 
6854
  *Effects:* Constructs an empty `multimap` using the specified comparison
6855
  object and allocator, and inserts elements from the range `rg`.
6856
 
@@ -6858,12 +8219,12 @@ object and allocator, and inserts elements from the range `rg`.
6858
  `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
6859
 
6860
  #### Modifiers <a id="multimap.modifiers">[[multimap.modifiers]]</a>
6861
 
6862
  ``` cpp
6863
- template<class P> iterator insert(P&& x);
6864
- template<class P> iterator insert(const_iterator position, P&& x);
6865
  ```
6866
 
6867
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
6868
 
6869
  *Effects:* The first form is equivalent to
@@ -6873,11 +8234,11 @@ template<class P> iterator insert(const_iterator position, P&& x);
6873
  #### Erasure <a id="multimap.erasure">[[multimap.erasure]]</a>
6874
 
6875
  ``` cpp
6876
  template<class Key, class T, class Compare, class Allocator, class Predicate>
6877
  typename multimap<Key, T, Compare, Allocator>::size_type
6878
- erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
6879
  ```
6880
 
6881
  *Effects:* Equivalent to:
6882
 
6883
  ``` cpp
@@ -6890,10 +8251,71 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
6890
  }
6891
  }
6892
  return original_size - c.size();
6893
  ```
6894
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6895
  ### Class template `set` <a id="set">[[set]]</a>
6896
 
6897
  #### Overview <a id="set.overview">[[set.overview]]</a>
6898
 
6899
  A `set` is an associative container that supports unique keys (i.e.,
@@ -6902,19 +8324,22 @@ of the keys themselves. The `set` class supports bidirectional
6902
  iterators.
6903
 
6904
  A `set` meets all of the requirements of a container
6905
  [[container.reqmts]], of a reversible container
6906
  [[container.rev.reqmts]], of an allocator-aware container
6907
- [[container.alloc.reqmts]]. and of an associative container
6908
  [[associative.reqmts]]. A `set` also provides most operations described
6909
  in  [[associative.reqmts]] for unique keys. This means that a `set`
6910
  supports the `a_uniq` operations in  [[associative.reqmts]] but not the
6911
  `a_eq` operations. For a `set<Key>` both the `key_type` and `value_type`
6912
  are `Key`. Descriptions are provided here only for operations on `set`
6913
  that are not described in one of these tables and for operations where
6914
  there is additional semantic information.
6915
 
 
 
 
6916
  ``` cpp
6917
  namespace std {
6918
  template<class Key, class Compare = less<Key>,
6919
  class Allocator = allocator<Key>>
6920
  class set {
@@ -6923,12 +8348,12 @@ namespace std {
6923
  using key_type = Key;
6924
  using key_compare = Compare;
6925
  using value_type = Key;
6926
  using value_compare = Compare;
6927
  using allocator_type = Allocator;
6928
- using pointer = typename allocator_traits<Allocator>::pointer;
6929
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
6930
  using reference = value_type&;
6931
  using const_reference = const value_type&;
6932
  using size_type = implementation-defined // type of set::size_type; // see [container.requirements]
6933
  using difference_type = implementation-defined // type of set::difference_type; // see [container.requirements]
6934
  using iterator = implementation-defined // type of set::iterator; // see [container.requirements]
@@ -6937,132 +8362,136 @@ namespace std {
6937
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6938
  using node_type = unspecified;
6939
  using insert_return_type = insert-return-type<iterator, node_type>;
6940
 
6941
  // [set.cons], construct/copy/destroy
6942
- set() : set(Compare()) { }
6943
- explicit set(const Compare& comp, const Allocator& = Allocator());
6944
  template<class InputIterator>
6945
- set(InputIterator first, InputIterator last,
6946
  const Compare& comp = Compare(), const Allocator& = Allocator());
6947
  template<container-compatible-range<value_type> R>
6948
- set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
6949
- set(const set& x);
6950
- set(set&& x);
6951
- explicit set(const Allocator&);
6952
- set(const set&, const type_identity_t<Allocator>&);
6953
- set(set&&, const type_identity_t<Allocator>&);
6954
- set(initializer_list<value_type>, const Compare& = Compare(),
6955
- const Allocator& = Allocator());
 
6956
  template<class InputIterator>
6957
- set(InputIterator first, InputIterator last, const Allocator& a)
6958
  : set(first, last, Compare(), a) { }
6959
  template<container-compatible-range<value_type> R>
6960
- set(from_range_t, R&& rg, const Allocator& a))
6961
  : set(from_range, std::forward<R>(rg), Compare(), a) { }
6962
- set(initializer_list<value_type> il, const Allocator& a)
6963
  : set(il, Compare(), a) { }
6964
- ~set();
6965
- set& operator=(const set& x);
6966
- set& operator=(set&& x)
6967
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
6968
  is_nothrow_move_assignable_v<Compare>);
6969
- set& operator=(initializer_list<value_type>);
6970
- allocator_type get_allocator() const noexcept;
6971
 
6972
  // iterators
6973
- iterator begin() noexcept;
6974
- const_iterator begin() const noexcept;
6975
- iterator end() noexcept;
6976
- const_iterator end() const noexcept;
6977
 
6978
- reverse_iterator rbegin() noexcept;
6979
- const_reverse_iterator rbegin() const noexcept;
6980
- reverse_iterator rend() noexcept;
6981
- const_reverse_iterator rend() const noexcept;
6982
 
6983
- const_iterator cbegin() const noexcept;
6984
- const_iterator cend() const noexcept;
6985
- const_reverse_iterator crbegin() const noexcept;
6986
- const_reverse_iterator crend() const noexcept;
6987
 
6988
  // capacity
6989
- [[nodiscard]] bool empty() const noexcept;
6990
- size_type size() const noexcept;
6991
- size_type max_size() const noexcept;
6992
 
6993
- // modifiers
6994
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
6995
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
6996
- pair<iterator,bool> insert(const value_type& x);
6997
- pair<iterator,bool> insert(value_type&& x);
6998
- iterator insert(const_iterator position, const value_type& x);
6999
- iterator insert(const_iterator position, value_type&& x);
 
 
 
7000
  template<class InputIterator>
7001
- void insert(InputIterator first, InputIterator last);
7002
  template<container-compatible-range<value_type> R>
7003
- void insert_range(R&& rg);
7004
- void insert(initializer_list<value_type>);
7005
 
7006
- node_type extract(const_iterator position);
7007
- node_type extract(const key_type& x);
7008
- template<class K> node_type extract(K&& x);
7009
- insert_return_type insert(node_type&& nh);
7010
- iterator insert(const_iterator hint, node_type&& nh);
7011
 
7012
- iterator erase(iterator position)
7013
  requires (!same_as<iterator, const_iterator>);
7014
- iterator erase(const_iterator position);
7015
- size_type erase(const key_type& x);
7016
- template<class K> size_type erase(K&& x);
7017
- iterator erase(const_iterator first, const_iterator last);
7018
- void swap(set&)
7019
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7020
  is_nothrow_swappable_v<Compare>);
7021
- void clear() noexcept;
7022
 
7023
  template<class C2>
7024
- void merge(set<Key, C2, Allocator>& source);
7025
  template<class C2>
7026
- void merge(set<Key, C2, Allocator>&& source);
7027
  template<class C2>
7028
- void merge(multiset<Key, C2, Allocator>& source);
7029
  template<class C2>
7030
- void merge(multiset<Key, C2, Allocator>&& source);
7031
 
7032
  // observers
7033
- key_compare key_comp() const;
7034
- value_compare value_comp() const;
7035
 
7036
  // set operations
7037
- iterator find(const key_type& x);
7038
- const_iterator find(const key_type& x) const;
7039
- template<class K> iterator find(const K& x);
7040
- template<class K> const_iterator find(const K& x) const;
7041
 
7042
- size_type count(const key_type& x) const;
7043
- template<class K> size_type count(const K& x) const;
7044
 
7045
- bool contains(const key_type& x) const;
7046
- template<class K> bool contains(const K& x) const;
7047
 
7048
- iterator lower_bound(const key_type& x);
7049
- const_iterator lower_bound(const key_type& x) const;
7050
- template<class K> iterator lower_bound(const K& x);
7051
- template<class K> const_iterator lower_bound(const K& x) const;
7052
 
7053
- iterator upper_bound(const key_type& x);
7054
- const_iterator upper_bound(const key_type& x) const;
7055
- template<class K> iterator upper_bound(const K& x);
7056
- template<class K> const_iterator upper_bound(const K& x) const;
7057
 
7058
- pair<iterator, iterator> equal_range(const key_type& x);
7059
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
7060
  template<class K>
7061
- pair<iterator, iterator> equal_range(const K& x);
7062
  template<class K>
7063
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
7064
  };
7065
 
7066
  template<class InputIterator,
7067
  class Compare = less<iter-value-type<InputIterator>>,
7068
  class Allocator = allocator<iter-value-type<InputIterator>>>
@@ -7094,21 +8523,21 @@ namespace std {
7094
  ```
7095
 
7096
  #### Constructors, copy, and assignment <a id="set.cons">[[set.cons]]</a>
7097
 
7098
  ``` cpp
7099
- explicit set(const Compare& comp, const Allocator& = Allocator());
7100
  ```
7101
 
7102
  *Effects:* Constructs an empty `set` using the specified comparison
7103
  object and allocator.
7104
 
7105
  *Complexity:* Constant.
7106
 
7107
  ``` cpp
7108
  template<class InputIterator>
7109
- set(InputIterator first, InputIterator last,
7110
  const Compare& comp = Compare(), const Allocator& = Allocator());
7111
  ```
7112
 
7113
  *Effects:* Constructs an empty `set` using the specified comparison
7114
  object and allocator, and inserts elements from the range \[`first`,
@@ -7118,11 +8547,12 @@ object and allocator, and inserts elements from the range \[`first`,
7118
  sorted with respect to `comp` and otherwise N log N, where N is
7119
  `last - first`.
7120
 
7121
  ``` cpp
7122
  template<container-compatible-range<value_type> R>
7123
- set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
 
7124
  ```
7125
 
7126
  *Effects:* Constructs an empty `set` using the specified comparison
7127
  object and allocator, and inserts elements from the range `rg`.
7128
 
@@ -7131,11 +8561,11 @@ object and allocator, and inserts elements from the range `rg`.
7131
 
7132
  #### Erasure <a id="set.erasure">[[set.erasure]]</a>
7133
 
7134
  ``` cpp
7135
  template<class Key, class Compare, class Allocator, class Predicate>
7136
- typename set<Key, Compare, Allocator>::size_type
7137
  erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
7138
  ```
7139
 
7140
  *Effects:* Equivalent to:
7141
 
@@ -7149,10 +8579,37 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
7149
  }
7150
  }
7151
  return original_size - c.size();
7152
  ```
7153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7154
  ### Class template `multiset` <a id="multiset">[[multiset]]</a>
7155
 
7156
  #### Overview <a id="multiset.overview">[[multiset.overview]]</a>
7157
 
7158
  A `multiset` is an associative container that supports equivalent keys
@@ -7161,20 +8618,23 @@ provides for fast retrieval of the keys themselves. The `multiset` class
7161
  supports bidirectional iterators.
7162
 
7163
  A `multiset` meets all of the requirements of a container
7164
  [[container.reqmts]], of a reversible container
7165
  [[container.rev.reqmts]], of an allocator-aware container
7166
- [[container.alloc.reqmts]], of an associative container
7167
  [[associative.reqmts]]. `multiset` also provides most operations
7168
  described in  [[associative.reqmts]] for duplicate keys. This means that
7169
  a `multiset` supports the `a_eq` operations in  [[associative.reqmts]]
7170
  but not the `a_uniq` operations. For a `multiset<Key>` both the
7171
  `key_type` and `value_type` are `Key`. Descriptions are provided here
7172
  only for operations on `multiset` that are not described in one of these
7173
  tables and for operations where there is additional semantic
7174
  information.
7175
 
 
 
 
7176
  ``` cpp
7177
  namespace std {
7178
  template<class Key, class Compare = less<Key>,
7179
  class Allocator = allocator<Key>>
7180
  class multiset {
@@ -7183,12 +8643,12 @@ namespace std {
7183
  using key_type = Key;
7184
  using key_compare = Compare;
7185
  using value_type = Key;
7186
  using value_compare = Compare;
7187
  using allocator_type = Allocator;
7188
- using pointer = typename allocator_traits<Allocator>::pointer;
7189
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
7190
  using reference = value_type&;
7191
  using const_reference = const value_type&;
7192
  using size_type = implementation-defined // type of multiset::size_type; // see [container.requirements]
7193
  using difference_type = implementation-defined // type of multiset::difference_type; // see [container.requirements]
7194
  using iterator = implementation-defined // type of multiset::iterator; // see [container.requirements]
@@ -7196,133 +8656,134 @@ namespace std {
7196
  using reverse_iterator = std::reverse_iterator<iterator>;
7197
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
7198
  using node_type = unspecified;
7199
 
7200
  // [multiset.cons], construct/copy/destroy
7201
- multiset() : multiset(Compare()) { }
7202
- explicit multiset(const Compare& comp, const Allocator& = Allocator());
7203
  template<class InputIterator>
7204
- multiset(InputIterator first, InputIterator last,
7205
  const Compare& comp = Compare(), const Allocator& = Allocator());
7206
  template<container-compatible-range<value_type> R>
7207
- multiset(from_range_t, R&& rg,
7208
  const Compare& comp = Compare(), const Allocator& = Allocator());
7209
- multiset(const multiset& x);
7210
- multiset(multiset&& x);
7211
- explicit multiset(const Allocator&);
7212
- multiset(const multiset&, const type_identity_t<Allocator>&);
7213
- multiset(multiset&&, const type_identity_t<Allocator>&);
7214
- multiset(initializer_list<value_type>, const Compare& = Compare(),
7215
  const Allocator& = Allocator());
7216
  template<class InputIterator>
7217
- multiset(InputIterator first, InputIterator last, const Allocator& a)
7218
  : multiset(first, last, Compare(), a) { }
7219
  template<container-compatible-range<value_type> R>
7220
- multiset(from_range_t, R&& rg, const Allocator& a))
7221
  : multiset(from_range, std::forward<R>(rg), Compare(), a) { }
7222
- multiset(initializer_list<value_type> il, const Allocator& a)
7223
  : multiset(il, Compare(), a) { }
7224
- ~multiset();
7225
- multiset& operator=(const multiset& x);
7226
- multiset& operator=(multiset&& x)
7227
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7228
  is_nothrow_move_assignable_v<Compare>);
7229
- multiset& operator=(initializer_list<value_type>);
7230
- allocator_type get_allocator() const noexcept;
7231
 
7232
  // iterators
7233
- iterator begin() noexcept;
7234
- const_iterator begin() const noexcept;
7235
- iterator end() noexcept;
7236
- const_iterator end() const noexcept;
7237
 
7238
- reverse_iterator rbegin() noexcept;
7239
- const_reverse_iterator rbegin() const noexcept;
7240
- reverse_iterator rend() noexcept;
7241
- const_reverse_iterator rend() const noexcept;
7242
 
7243
- const_iterator cbegin() const noexcept;
7244
- const_iterator cend() const noexcept;
7245
- const_reverse_iterator crbegin() const noexcept;
7246
- const_reverse_iterator crend() const noexcept;
7247
 
7248
  // capacity
7249
- [[nodiscard]] bool empty() const noexcept;
7250
- size_type size() const noexcept;
7251
- size_type max_size() const noexcept;
7252
 
7253
  // modifiers
7254
- template<class... Args> iterator emplace(Args&&... args);
7255
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
7256
- iterator insert(const value_type& x);
7257
- iterator insert(value_type&& x);
7258
- iterator insert(const_iterator position, const value_type& x);
7259
- iterator insert(const_iterator position, value_type&& x);
 
7260
  template<class InputIterator>
7261
- void insert(InputIterator first, InputIterator last);
7262
  template<container-compatible-range<value_type> R>
7263
- void insert_range(R&& rg);
7264
- void insert(initializer_list<value_type>);
7265
 
7266
- node_type extract(const_iterator position);
7267
- node_type extract(const key_type& x);
7268
- template<class K> node_type extract(K&& x);
7269
- iterator insert(node_type&& nh);
7270
- iterator insert(const_iterator hint, node_type&& nh);
7271
 
7272
- iterator erase(iterator position)
7273
  requires (!same_as<iterator, const_iterator>);
7274
- iterator erase(const_iterator position);
7275
- size_type erase(const key_type& x);
7276
- template<class K> size_type erase(K&& x);
7277
- iterator erase(const_iterator first, const_iterator last);
7278
- void swap(multiset&)
7279
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7280
  is_nothrow_swappable_v<Compare>);
7281
- void clear() noexcept;
7282
 
7283
  template<class C2>
7284
- void merge(multiset<Key, C2, Allocator>& source);
7285
  template<class C2>
7286
- void merge(multiset<Key, C2, Allocator>&& source);
7287
  template<class C2>
7288
- void merge(set<Key, C2, Allocator>& source);
7289
  template<class C2>
7290
- void merge(set<Key, C2, Allocator>&& source);
7291
 
7292
  // observers
7293
- key_compare key_comp() const;
7294
- value_compare value_comp() const;
7295
 
7296
  // set operations
7297
- iterator find(const key_type& x);
7298
- const_iterator find(const key_type& x) const;
7299
- template<class K> iterator find(const K& x);
7300
- template<class K> const_iterator find(const K& x) const;
7301
 
7302
- size_type count(const key_type& x) const;
7303
- template<class K> size_type count(const K& x) const;
7304
 
7305
- bool contains(const key_type& x) const;
7306
- template<class K> bool contains(const K& x) const;
7307
 
7308
- iterator lower_bound(const key_type& x);
7309
- const_iterator lower_bound(const key_type& x) const;
7310
- template<class K> iterator lower_bound(const K& x);
7311
- template<class K> const_iterator lower_bound(const K& x) const;
7312
 
7313
- iterator upper_bound(const key_type& x);
7314
- const_iterator upper_bound(const key_type& x) const;
7315
- template<class K> iterator upper_bound(const K& x);
7316
- template<class K> const_iterator upper_bound(const K& x) const;
7317
 
7318
- pair<iterator, iterator> equal_range(const key_type& x);
7319
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
7320
  template<class K>
7321
- pair<iterator, iterator> equal_range(const K& x);
7322
  template<class K>
7323
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
7324
  };
7325
 
7326
  template<class InputIterator,
7327
  class Compare = less<iter-value-type<InputIterator>>,
7328
  class Allocator = allocator<iter-value-type<InputIterator>>>
@@ -7354,21 +8815,21 @@ namespace std {
7354
  ```
7355
 
7356
  #### Constructors <a id="multiset.cons">[[multiset.cons]]</a>
7357
 
7358
  ``` cpp
7359
- explicit multiset(const Compare& comp, const Allocator& = Allocator());
7360
  ```
7361
 
7362
  *Effects:* Constructs an empty `multiset` using the specified comparison
7363
  object and allocator.
7364
 
7365
  *Complexity:* Constant.
7366
 
7367
  ``` cpp
7368
  template<class InputIterator>
7369
- multiset(InputIterator first, InputIterator last,
7370
  const Compare& comp = Compare(), const Allocator& = Allocator());
7371
  ```
7372
 
7373
  *Effects:* Constructs an empty `multiset` using the specified comparison
7374
  object and allocator, and inserts elements from the range \[`first`,
@@ -7378,11 +8839,12 @@ object and allocator, and inserts elements from the range \[`first`,
7378
  sorted with respect to `comp` and otherwise N log N, where N is
7379
  `last - first`.
7380
 
7381
  ``` cpp
7382
  template<container-compatible-range<value_type> R>
7383
- multiset(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator());
 
7384
  ```
7385
 
7386
  *Effects:* Constructs an empty `multiset` using the specified comparison
7387
  object and allocator, and inserts elements from the range `rg`.
7388
 
@@ -7391,11 +8853,11 @@ object and allocator, and inserts elements from the range `rg`.
7391
 
7392
  #### Erasure <a id="multiset.erasure">[[multiset.erasure]]</a>
7393
 
7394
  ``` cpp
7395
  template<class Key, class Compare, class Allocator, class Predicate>
7396
- typename multiset<Key, Compare, Allocator>::size_type
7397
  erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
7398
  ```
7399
 
7400
  *Effects:* Equivalent to:
7401
 
@@ -7411,11 +8873,11 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
7411
  return original_size - c.size();
7412
  ```
7413
 
7414
  ## Unordered associative containers <a id="unord">[[unord]]</a>
7415
 
7416
- ### In general <a id="unord.general">[[unord.general]]</a>
7417
 
7418
  The header `<unordered_map>` defines the class templates `unordered_map`
7419
  and `unordered_multimap`; the header `<unordered_set>` defines the class
7420
  templates `unordered_set` and `unordered_multiset`.
7421
 
@@ -7447,35 +8909,35 @@ namespace std {
7447
  class Pred = equal_to<Key>,
7448
  class Alloc = allocator<pair<const Key, T>>>
7449
  class unordered_multimap;
7450
 
7451
  template<class Key, class T, class Hash, class Pred, class Alloc>
7452
- bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
7453
  const unordered_map<Key, T, Hash, Pred, Alloc>& b);
7454
 
7455
  template<class Key, class T, class Hash, class Pred, class Alloc>
7456
- bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
7457
  const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
7458
 
7459
  template<class Key, class T, class Hash, class Pred, class Alloc>
7460
- void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
7461
  unordered_map<Key, T, Hash, Pred, Alloc>& y)
7462
  noexcept(noexcept(x.swap(y)));
7463
 
7464
  template<class Key, class T, class Hash, class Pred, class Alloc>
7465
- void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
7466
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
7467
  noexcept(noexcept(x.swap(y)));
7468
 
7469
  // [unord.map.erasure], erasure for unordered_map
7470
  template<class K, class T, class H, class P, class A, class Predicate>
7471
- typename unordered_map<K, T, H, P, A>::size_type
7472
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
7473
 
7474
  // [unord.multimap.erasure], erasure for unordered_multimap
7475
  template<class K, class T, class H, class P, class A, class Predicate>
7476
- typename unordered_multimap<K, T, H, P, A>::size_type
7477
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
7478
 
7479
  namespace pmr {
7480
  template<class Key,
7481
  class T,
@@ -7494,75 +8956,10 @@ namespace std {
7494
 
7495
  }
7496
  }
7497
  ```
7498
 
7499
- ### Header `<unordered_set>` synopsis <a id="unord.set.syn">[[unord.set.syn]]</a>
7500
-
7501
- ``` cpp
7502
- #include <compare> // see [compare.syn]
7503
- #include <initializer_list> // see [initializer.list.syn]
7504
-
7505
- namespace std {
7506
- // [unord.set], class template unordered_set
7507
- template<class Key,
7508
- class Hash = hash<Key>,
7509
- class Pred = equal_to<Key>,
7510
- class Alloc = allocator<Key>>
7511
- class unordered_set;
7512
-
7513
- // [unord.multiset], class template unordered_multiset
7514
- template<class Key,
7515
- class Hash = hash<Key>,
7516
- class Pred = equal_to<Key>,
7517
- class Alloc = allocator<Key>>
7518
- class unordered_multiset;
7519
-
7520
- template<class Key, class Hash, class Pred, class Alloc>
7521
- bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
7522
- const unordered_set<Key, Hash, Pred, Alloc>& b);
7523
-
7524
- template<class Key, class Hash, class Pred, class Alloc>
7525
- bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
7526
- const unordered_multiset<Key, Hash, Pred, Alloc>& b);
7527
-
7528
- template<class Key, class Hash, class Pred, class Alloc>
7529
- void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
7530
- unordered_set<Key, Hash, Pred, Alloc>& y)
7531
- noexcept(noexcept(x.swap(y)));
7532
-
7533
- template<class Key, class Hash, class Pred, class Alloc>
7534
- void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
7535
- unordered_multiset<Key, Hash, Pred, Alloc>& y)
7536
- noexcept(noexcept(x.swap(y)));
7537
-
7538
- // [unord.set.erasure], erasure for unordered_set
7539
- template<class K, class H, class P, class A, class Predicate>
7540
- typename unordered_set<K, H, P, A>::size_type
7541
- erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
7542
-
7543
- // [unord.multiset.erasure], erasure for unordered_multiset
7544
- template<class K, class H, class P, class A, class Predicate>
7545
- typename unordered_multiset<K, H, P, A>::size_type
7546
- erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
7547
-
7548
- namespace pmr {
7549
- template<class Key,
7550
- class Hash = hash<Key>,
7551
- class Pred = equal_to<Key>>
7552
- using unordered_set = std::unordered_set<Key, Hash, Pred,
7553
- polymorphic_allocator<Key>>;
7554
-
7555
- template<class Key,
7556
- class Hash = hash<Key>,
7557
- class Pred = equal_to<Key>>
7558
- using unordered_multiset = std::unordered_multiset<Key, Hash, Pred,
7559
- polymorphic_allocator<Key>>;
7560
- }
7561
- }
7562
- ```
7563
-
7564
  ### Class template `unordered_map` <a id="unord.map">[[unord.map]]</a>
7565
 
7566
  #### Overview <a id="unord.map.overview">[[unord.map.overview]]</a>
7567
 
7568
  An `unordered_map` is an unordered associative container that supports
@@ -7581,10 +8978,13 @@ the `a_uniq` operations in that table, not the `a_eq` operations. For an
7581
 
7582
  Subclause  [[unord.map]] only describes operations on `unordered_map`
7583
  that are not described in one of the requirement tables, or for which
7584
  there is additional semantic information.
7585
 
 
 
 
7586
  ``` cpp
7587
  namespace std {
7588
  template<class Key,
7589
  class T,
7590
  class Hash = hash<Key>,
@@ -7597,12 +8997,12 @@ namespace std {
7597
  using mapped_type = T;
7598
  using value_type = pair<const Key, T>;
7599
  using hasher = Hash;
7600
  using key_equal = Pred;
7601
  using allocator_type = Allocator;
7602
- using pointer = typename allocator_traits<Allocator>::pointer;
7603
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
7604
  using reference = value_type&;
7605
  using const_reference = const value_type&;
7606
  using size_type = implementation-defined // type of unordered_map::size_type; // see [container.requirements]
7607
  using difference_type = implementation-defined // type of unordered_map::difference_type; // see [container.requirements]
7608
 
@@ -7612,185 +9012,197 @@ namespace std {
7612
  using const_local_iterator = implementation-defined // type of unordered_map::const_local_iterator; // see [container.requirements]
7613
  using node_type = unspecified;
7614
  using insert_return_type = insert-return-type<iterator, node_type>;
7615
 
7616
  // [unord.map.cnstr], construct/copy/destroy
7617
- unordered_map();
7618
- explicit unordered_map(size_type n,
7619
- const hasher& hf = hasher(),
7620
  const key_equal& eql = key_equal(),
7621
  const allocator_type& a = allocator_type());
7622
  template<class InputIterator>
7623
- unordered_map(InputIterator f, InputIterator l,
7624
- size_type n = see below,
7625
- const hasher& hf = hasher(),
7626
  const key_equal& eql = key_equal(),
7627
  const allocator_type& a = allocator_type());
7628
 
7629
  template<container-compatible-range<value_type> R>
7630
- unordered_map(from_range_t, R&& rg, size_type n = see below,
7631
  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
7632
  const allocator_type& a = allocator_type());
7633
- unordered_map(const unordered_map&);
7634
- unordered_map(unordered_map&&);
7635
- explicit unordered_map(const Allocator&);
7636
- unordered_map(const unordered_map&, const type_identity_t<Allocator>&);
7637
- unordered_map(unordered_map&&, const type_identity_t<Allocator>&);
7638
- unordered_map(initializer_list<value_type> il,
7639
- size_type n = see below,
7640
  const hasher& hf = hasher(),
7641
  const key_equal& eql = key_equal(),
7642
  const allocator_type& a = allocator_type());
7643
- unordered_map(size_type n, const allocator_type& a)
7644
  : unordered_map(n, hasher(), key_equal(), a) { }
7645
- unordered_map(size_type n, const hasher& hf, const allocator_type& a)
7646
  : unordered_map(n, hf, key_equal(), a) { }
7647
  template<class InputIterator>
7648
- unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
 
7649
  : unordered_map(f, l, n, hasher(), key_equal(), a) { }
7650
  template<class InputIterator>
7651
- unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
7652
  const allocator_type& a)
7653
  : unordered_map(f, l, n, hf, key_equal(), a) { }
7654
  template<container-compatible-range<value_type> R>
7655
- unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a)
7656
  : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
7657
  template<container-compatible-range<value_type> R>
7658
- unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
 
7659
  : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
7660
- unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
 
7661
  : unordered_map(il, n, hasher(), key_equal(), a) { }
7662
- unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
7663
  const allocator_type& a)
7664
  : unordered_map(il, n, hf, key_equal(), a) { }
7665
- ~unordered_map();
7666
- unordered_map& operator=(const unordered_map&);
7667
- unordered_map& operator=(unordered_map&&)
7668
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7669
  is_nothrow_move_assignable_v<Hash> &&
7670
  is_nothrow_move_assignable_v<Pred>);
7671
- unordered_map& operator=(initializer_list<value_type>);
7672
- allocator_type get_allocator() const noexcept;
7673
 
7674
  // iterators
7675
- iterator begin() noexcept;
7676
- const_iterator begin() const noexcept;
7677
- iterator end() noexcept;
7678
- const_iterator end() const noexcept;
7679
- const_iterator cbegin() const noexcept;
7680
- const_iterator cend() const noexcept;
7681
 
7682
  // capacity
7683
- [[nodiscard]] bool empty() const noexcept;
7684
- size_type size() const noexcept;
7685
- size_type max_size() const noexcept;
7686
 
7687
  // [unord.map.modifiers], modifiers
7688
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
7689
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
7690
- pair<iterator, bool> insert(const value_type& obj);
7691
- pair<iterator, bool> insert(value_type&& obj);
7692
- template<class P> pair<iterator, bool> insert(P&& obj);
7693
- iterator insert(const_iterator hint, const value_type& obj);
7694
- iterator insert(const_iterator hint, value_type&& obj);
7695
- template<class P> iterator insert(const_iterator hint, P&& obj);
7696
- template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
7697
  template<container-compatible-range<value_type> R>
7698
- void insert_range(R&& rg);
7699
- void insert(initializer_list<value_type>);
7700
 
7701
- node_type extract(const_iterator position);
7702
- node_type extract(const key_type& x);
7703
- template<class K> node_type extract(K&& x);
7704
- insert_return_type insert(node_type&& nh);
7705
- iterator insert(const_iterator hint, node_type&& nh);
7706
 
7707
  template<class... Args>
7708
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
7709
  template<class... Args>
7710
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
 
 
7711
  template<class... Args>
7712
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
7713
  template<class... Args>
7714
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
 
 
7715
  template<class M>
7716
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
7717
  template<class M>
7718
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
 
 
7719
  template<class M>
7720
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
7721
  template<class M>
7722
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
 
 
7723
 
7724
- iterator erase(iterator position);
7725
- iterator erase(const_iterator position);
7726
- size_type erase(const key_type& k);
7727
- template<class K> size_type erase(K&& x);
7728
- iterator erase(const_iterator first, const_iterator last);
7729
- void swap(unordered_map&)
7730
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7731
- is_nothrow_swappable_v<Hash> &&
7732
- is_nothrow_swappable_v<Pred>);
7733
- void clear() noexcept;
7734
 
7735
  template<class H2, class P2>
7736
- void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
7737
  template<class H2, class P2>
7738
- void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
7739
  template<class H2, class P2>
7740
- void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
7741
  template<class H2, class P2>
7742
- void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
7743
 
7744
  // observers
7745
- hasher hash_function() const;
7746
- key_equal key_eq() const;
7747
 
7748
  // map operations
7749
- iterator find(const key_type& k);
7750
- const_iterator find(const key_type& k) const;
7751
  template<class K>
7752
- iterator find(const K& k);
7753
  template<class K>
7754
- const_iterator find(const K& k) const;
7755
- size_type count(const key_type& k) const;
7756
  template<class K>
7757
- size_type count(const K& k) const;
7758
- bool contains(const key_type& k) const;
7759
  template<class K>
7760
- bool contains(const K& k) const;
7761
- pair<iterator, iterator> equal_range(const key_type& k);
7762
- pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
7763
  template<class K>
7764
- pair<iterator, iterator> equal_range(const K& k);
7765
  template<class K>
7766
- pair<const_iterator, const_iterator> equal_range(const K& k) const;
7767
 
7768
  // [unord.map.elem], element access
7769
- mapped_type& operator[](const key_type& k);
7770
- mapped_type& operator[](key_type&& k);
7771
- mapped_type& at(const key_type& k);
7772
- const mapped_type& at(const key_type& k) const;
 
 
 
7773
 
7774
  // bucket interface
7775
- size_type bucket_count() const noexcept;
7776
- size_type max_bucket_count() const noexcept;
7777
- size_type bucket_size(size_type n) const;
7778
- size_type bucket(const key_type& k) const;
7779
- local_iterator begin(size_type n);
7780
- const_local_iterator begin(size_type n) const;
7781
- local_iterator end(size_type n);
7782
- const_local_iterator end(size_type n) const;
7783
- const_local_iterator cbegin(size_type n) const;
7784
- const_local_iterator cend(size_type n) const;
 
7785
 
7786
  // hash policy
7787
- float load_factor() const noexcept;
7788
- float max_load_factor() const noexcept;
7789
- void max_load_factor(float z);
7790
- void rehash(size_type n);
7791
- void reserve(size_type n);
7792
  };
7793
 
7794
  template<class InputIterator,
7795
  class Hash = hash<iter-key-type<InputIterator>>,
7796
  class Pred = equal_to<iter-key-type<InputIterator>>,
@@ -7867,13 +9279,12 @@ refers to the `size_type` member type of the type deduced by the
7867
  deduction guide.
7868
 
7869
  #### Constructors <a id="unord.map.cnstr">[[unord.map.cnstr]]</a>
7870
 
7871
  ``` cpp
7872
- unordered_map() : unordered_map(size_type(see below)) { }
7873
- explicit unordered_map(size_type n,
7874
- const hasher& hf = hasher(),
7875
  const key_equal& eql = key_equal(),
7876
  const allocator_type& a = allocator_type());
7877
  ```
7878
 
7879
  *Effects:* Constructs an empty `unordered_map` using the specified hash
@@ -7883,24 +9294,21 @@ buckets. For the default constructor, the number of buckets is
7883
 
7884
  *Complexity:* Constant.
7885
 
7886
  ``` cpp
7887
  template<class InputIterator>
7888
- unordered_map(InputIterator f, InputIterator l,
7889
- size_type n = see below,
7890
- const hasher& hf = hasher(),
7891
  const key_equal& eql = key_equal(),
7892
  const allocator_type& a = allocator_type());
7893
  template<container-compatible-range<value_type> R>
7894
- unordered_map(from_range_t, R&& rg,
7895
- size_type n = see below,
7896
- const hasher& hf = hasher(),
7897
  const key_equal& eql = key_equal(),
7898
  const allocator_type& a = allocator_type());
7899
- unordered_map(initializer_list<value_type> il,
7900
- size_type n = see below,
7901
- const hasher& hf = hasher(),
7902
  const key_equal& eql = key_equal(),
7903
  const allocator_type& a = allocator_type());
7904
  ```
7905
 
7906
  *Effects:* Constructs an empty `unordered_map` using the specified hash
@@ -7912,59 +9320,85 @@ buckets. If `n` is not provided, the number of buckets is
7912
  *Complexity:* Average case linear, worst case quadratic.
7913
 
7914
  #### Element access <a id="unord.map.elem">[[unord.map.elem]]</a>
7915
 
7916
  ``` cpp
7917
- mapped_type& operator[](const key_type& k);
7918
  ```
7919
 
7920
  *Effects:* Equivalent to: `return try_emplace(k).first->second;`
7921
 
7922
  ``` cpp
7923
- mapped_type& operator[](key_type&& k);
7924
  ```
7925
 
7926
  *Effects:* Equivalent to:
7927
  `return try_emplace(std::move(k)).first->second;`
7928
 
7929
  ``` cpp
7930
- mapped_type& at(const key_type& k);
7931
- const mapped_type& at(const key_type& k) const;
 
 
 
 
 
 
 
 
 
 
7932
  ```
7933
 
7934
  *Returns:* A reference to `x.second`, where `x` is the (unique) element
7935
  whose key is equivalent to `k`.
7936
 
7937
  *Throws:* An exception object of type `out_of_range` if no such element
7938
  is present.
7939
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7940
  #### Modifiers <a id="unord.map.modifiers">[[unord.map.modifiers]]</a>
7941
 
7942
  ``` cpp
7943
  template<class P>
7944
- pair<iterator, bool> insert(P&& obj);
7945
  ```
7946
 
7947
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
7948
 
7949
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
7950
 
7951
  ``` cpp
7952
  template<class P>
7953
- iterator insert(const_iterator hint, P&& obj);
7954
  ```
7955
 
7956
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
7957
 
7958
  *Effects:* Equivalent to:
7959
  `return emplace_hint(hint, std::forward<P>(obj));`
7960
 
7961
  ``` cpp
7962
  template<class... Args>
7963
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
7964
  template<class... Args>
7965
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
7966
  ```
7967
 
7968
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
7969
  `unordered_map` from `piecewise_construct`, `forward_as_tuple(k)`,
7970
  `forward_as_tuple(std::forward<Args>(args)...)`.
@@ -7980,13 +9414,13 @@ iterator points to the map element whose key is equivalent to `k`.
7980
 
7981
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7982
 
7983
  ``` cpp
7984
  template<class... Args>
7985
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
7986
  template<class... Args>
7987
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
7988
  ```
7989
 
7990
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
7991
  `unordered_map` from `piecewise_construct`,
7992
  `forward_as_tuple(std::move(k))`,
@@ -8002,15 +9436,44 @@ type `value_type` constructed with `piecewise_construct`,
8002
  pair is `true` if and only if the insertion took place. The returned
8003
  iterator points to the map element whose key is equivalent to `k`.
8004
 
8005
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
8006
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8007
  ``` cpp
8008
  template<class M>
8009
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
8010
  template<class M>
8011
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
8012
  ```
8013
 
8014
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
8015
 
8016
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
@@ -8027,13 +9490,13 @@ iterator points to the map element whose key is equivalent to `k`.
8027
 
8028
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
8029
 
8030
  ``` cpp
8031
  template<class M>
8032
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
8033
  template<class M>
8034
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
8035
  ```
8036
 
8037
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
8038
 
8039
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
@@ -8048,15 +9511,43 @@ Otherwise inserts an object of type `value_type` constructed with
8048
  pair is `true` if and only if the insertion took place. The returned
8049
  iterator points to the map element whose key is equivalent to `k`.
8050
 
8051
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
8052
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8053
  #### Erasure <a id="unord.map.erasure">[[unord.map.erasure]]</a>
8054
 
8055
  ``` cpp
8056
  template<class K, class T, class H, class P, class A, class Predicate>
8057
- typename unordered_map<K, T, H, P, A>::size_type
8058
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
8059
  ```
8060
 
8061
  *Effects:* Equivalent to:
8062
 
@@ -8093,10 +9584,13 @@ the `mapped_type` is `T`, and the `value_type` is `pair<const Key, T>`.
8093
 
8094
  Subclause  [[unord.multimap]] only describes operations on
8095
  `unordered_multimap` that are not described in one of the requirement
8096
  tables, or for which there is additional semantic information.
8097
 
 
 
 
8098
  ``` cpp
8099
  namespace std {
8100
  template<class Key,
8101
  class T,
8102
  class Hash = hash<Key>,
@@ -8109,12 +9603,12 @@ namespace std {
8109
  using mapped_type = T;
8110
  using value_type = pair<const Key, T>;
8111
  using hasher = Hash;
8112
  using key_equal = Pred;
8113
  using allocator_type = Allocator;
8114
- using pointer = typename allocator_traits<Allocator>::pointer;
8115
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8116
  using reference = value_type&;
8117
  using const_reference = const value_type&;
8118
  using size_type = implementation-defined // type of unordered_multimap::size_type; // see [container.requirements]
8119
  using difference_type = implementation-defined // type of unordered_multimap::difference_type; // see [container.requirements]
8120
 
@@ -8123,165 +9617,163 @@ namespace std {
8123
  using local_iterator = implementation-defined // type of unordered_multimap::local_iterator; // see [container.requirements]
8124
  using const_local_iterator = implementation-defined // type of unordered_multimap::const_local_iterator; // see [container.requirements]
8125
  using node_type = unspecified;
8126
 
8127
  // [unord.multimap.cnstr], construct/copy/destroy
8128
- unordered_multimap();
8129
- explicit unordered_multimap(size_type n,
8130
- const hasher& hf = hasher(),
8131
  const key_equal& eql = key_equal(),
8132
  const allocator_type& a = allocator_type());
8133
  template<class InputIterator>
8134
- unordered_multimap(InputIterator f, InputIterator l,
8135
- size_type n = see below,
8136
- const hasher& hf = hasher(),
8137
  const key_equal& eql = key_equal(),
8138
  const allocator_type& a = allocator_type());
8139
  template<container-compatible-range<value_type> R>
8140
- unordered_multimap(from_range_t, R&& rg,
8141
- size_type n = see below,
8142
- const hasher& hf = hasher(),
8143
  const key_equal& eql = key_equal(),
8144
  const allocator_type& a = allocator_type());
8145
- unordered_multimap(const unordered_multimap&);
8146
- unordered_multimap(unordered_multimap&&);
8147
- explicit unordered_multimap(const Allocator&);
8148
- unordered_multimap(const unordered_multimap&, const type_identity_t<Allocator>&);
8149
- unordered_multimap(unordered_multimap&&, const type_identity_t<Allocator>&);
8150
- unordered_multimap(initializer_list<value_type> il,
8151
- size_type n = see below,
8152
- const hasher& hf = hasher(),
8153
  const key_equal& eql = key_equal(),
8154
  const allocator_type& a = allocator_type());
8155
- unordered_multimap(size_type n, const allocator_type& a)
8156
  : unordered_multimap(n, hasher(), key_equal(), a) { }
8157
- unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
8158
  : unordered_multimap(n, hf, key_equal(), a) { }
8159
  template<class InputIterator>
8160
- unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
 
8161
  : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
8162
  template<class InputIterator>
8163
- unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8164
- const allocator_type& a)
8165
  : unordered_multimap(f, l, n, hf, key_equal(), a) { }
8166
  template<container-compatible-range<value_type> R>
8167
- unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a)
8168
  : unordered_multimap(from_range, std::forward<R>(rg),
8169
  n, hasher(), key_equal(), a) { }
8170
  template<container-compatible-range<value_type> R>
8171
- unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf,
8172
  const allocator_type& a)
8173
  : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8174
- unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
 
8175
  : unordered_multimap(il, n, hasher(), key_equal(), a) { }
8176
- unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
8177
  const allocator_type& a)
8178
  : unordered_multimap(il, n, hf, key_equal(), a) { }
8179
- ~unordered_multimap();
8180
- unordered_multimap& operator=(const unordered_multimap&);
8181
- unordered_multimap& operator=(unordered_multimap&&)
8182
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8183
- is_nothrow_move_assignable_v<Hash> &&
8184
- is_nothrow_move_assignable_v<Pred>);
8185
- unordered_multimap& operator=(initializer_list<value_type>);
8186
- allocator_type get_allocator() const noexcept;
8187
 
8188
  // iterators
8189
- iterator begin() noexcept;
8190
- const_iterator begin() const noexcept;
8191
- iterator end() noexcept;
8192
- const_iterator end() const noexcept;
8193
- const_iterator cbegin() const noexcept;
8194
- const_iterator cend() const noexcept;
8195
 
8196
  // capacity
8197
- [[nodiscard]] bool empty() const noexcept;
8198
- size_type size() const noexcept;
8199
- size_type max_size() const noexcept;
8200
 
8201
  // [unord.multimap.modifiers], modifiers
8202
- template<class... Args> iterator emplace(Args&&... args);
8203
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
8204
- iterator insert(const value_type& obj);
8205
- iterator insert(value_type&& obj);
8206
- template<class P> iterator insert(P&& obj);
8207
- iterator insert(const_iterator hint, const value_type& obj);
8208
- iterator insert(const_iterator hint, value_type&& obj);
8209
- template<class P> iterator insert(const_iterator hint, P&& obj);
8210
- template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
8211
  template<container-compatible-range<value_type> R>
8212
- void insert_range(R&& rg);
8213
- void insert(initializer_list<value_type>);
8214
 
8215
- node_type extract(const_iterator position);
8216
- node_type extract(const key_type& x);
8217
- template<class K> node_type extract(K&& x);
8218
- iterator insert(node_type&& nh);
8219
- iterator insert(const_iterator hint, node_type&& nh);
8220
 
8221
- iterator erase(iterator position);
8222
- iterator erase(const_iterator position);
8223
- size_type erase(const key_type& k);
8224
- template<class K> size_type erase(K&& x);
8225
- iterator erase(const_iterator first, const_iterator last);
8226
- void swap(unordered_multimap&)
8227
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8228
- is_nothrow_swappable_v<Hash> &&
8229
- is_nothrow_swappable_v<Pred>);
8230
- void clear() noexcept;
8231
 
8232
  template<class H2, class P2>
8233
- void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
8234
  template<class H2, class P2>
8235
- void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
8236
  template<class H2, class P2>
8237
- void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
8238
  template<class H2, class P2>
8239
- void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
8240
 
8241
  // observers
8242
- hasher hash_function() const;
8243
- key_equal key_eq() const;
8244
 
8245
  // map operations
8246
- iterator find(const key_type& k);
8247
- const_iterator find(const key_type& k) const;
8248
  template<class K>
8249
- iterator find(const K& k);
8250
  template<class K>
8251
- const_iterator find(const K& k) const;
8252
- size_type count(const key_type& k) const;
8253
  template<class K>
8254
- size_type count(const K& k) const;
8255
- bool contains(const key_type& k) const;
8256
  template<class K>
8257
- bool contains(const K& k) const;
8258
- pair<iterator, iterator> equal_range(const key_type& k);
8259
- pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
8260
  template<class K>
8261
- pair<iterator, iterator> equal_range(const K& k);
8262
  template<class K>
8263
- pair<const_iterator, const_iterator> equal_range(const K& k) const;
8264
 
8265
  // bucket interface
8266
- size_type bucket_count() const noexcept;
8267
- size_type max_bucket_count() const noexcept;
8268
- size_type bucket_size(size_type n) const;
8269
- size_type bucket(const key_type& k) const;
8270
- local_iterator begin(size_type n);
8271
- const_local_iterator begin(size_type n) const;
8272
- local_iterator end(size_type n);
8273
- const_local_iterator end(size_type n) const;
8274
- const_local_iterator cbegin(size_type n) const;
8275
- const_local_iterator cend(size_type n) const;
 
8276
 
8277
  // hash policy
8278
- float load_factor() const noexcept;
8279
- float max_load_factor() const noexcept;
8280
- void max_load_factor(float z);
8281
- void rehash(size_type n);
8282
- void reserve(size_type n);
8283
  };
8284
 
8285
  template<class InputIterator,
8286
  class Hash = hash<iter-key-type<InputIterator>>,
8287
  class Pred = equal_to<iter-key-type<InputIterator>>,
@@ -8361,13 +9853,12 @@ refers to the `size_type` member type of the type deduced by the
8361
  deduction guide.
8362
 
8363
  #### Constructors <a id="unord.multimap.cnstr">[[unord.multimap.cnstr]]</a>
8364
 
8365
  ``` cpp
8366
- unordered_multimap() : unordered_multimap(size_type(see below)) { }
8367
- explicit unordered_multimap(size_type n,
8368
- const hasher& hf = hasher(),
8369
  const key_equal& eql = key_equal(),
8370
  const allocator_type& a = allocator_type());
8371
  ```
8372
 
8373
  *Effects:* Constructs an empty `unordered_multimap` using the specified
@@ -8377,24 +9868,21 @@ hash function, key equality predicate, and allocator, and using at least
8377
 
8378
  *Complexity:* Constant.
8379
 
8380
  ``` cpp
8381
  template<class InputIterator>
8382
- unordered_multimap(InputIterator f, InputIterator l,
8383
- size_type n = see below,
8384
- const hasher& hf = hasher(),
8385
  const key_equal& eql = key_equal(),
8386
  const allocator_type& a = allocator_type());
8387
  template<container-compatible-range<value_type> R>
8388
- unordered_multimap(from_range_t, R&& rg,
8389
- size_type n = see below,
8390
- const hasher& hf = hasher(),
8391
  const key_equal& eql = key_equal(),
8392
  const allocator_type& a = allocator_type());
8393
- unordered_multimap(initializer_list<value_type> il,
8394
- size_type n = see below,
8395
- const hasher& hf = hasher(),
8396
  const key_equal& eql = key_equal(),
8397
  const allocator_type& a = allocator_type());
8398
  ```
8399
 
8400
  *Effects:* Constructs an empty `unordered_multimap` using the specified
@@ -8407,20 +9895,20 @@ hash function, key equality predicate, and allocator, and using at least
8407
 
8408
  #### Modifiers <a id="unord.multimap.modifiers">[[unord.multimap.modifiers]]</a>
8409
 
8410
  ``` cpp
8411
  template<class P>
8412
- iterator insert(P&& obj);
8413
  ```
8414
 
8415
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
8416
 
8417
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
8418
 
8419
  ``` cpp
8420
  template<class P>
8421
- iterator insert(const_iterator hint, P&& obj);
8422
  ```
8423
 
8424
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
8425
 
8426
  *Effects:* Equivalent to:
@@ -8428,11 +9916,11 @@ template<class P>
8428
 
8429
  #### Erasure <a id="unord.multimap.erasure">[[unord.multimap.erasure]]</a>
8430
 
8431
  ``` cpp
8432
  template<class K, class T, class H, class P, class A, class Predicate>
8433
- typename unordered_multimap<K, T, H, P, A>::size_type
8434
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
8435
  ```
8436
 
8437
  *Effects:* Equivalent to:
8438
 
@@ -8446,10 +9934,75 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
8446
  }
8447
  }
8448
  return original_size - c.size();
8449
  ```
8450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8451
  ### Class template `unordered_set` <a id="unord.set">[[unord.set]]</a>
8452
 
8453
  #### Overview <a id="unord.set.overview">[[unord.set.overview]]</a>
8454
 
8455
  An `unordered_set` is an unordered associative container that supports
@@ -8457,11 +10010,11 @@ unique keys (an `unordered_set` contains at most one of each key value)
8457
  and in which the elements’ keys are the elements themselves. The
8458
  `unordered_set` class supports forward iterators.
8459
 
8460
  An `unordered_set` meets all of the requirements of a container
8461
  [[container.reqmts]], of an allocator-aware container
8462
- [[container.alloc.reqmts]], of an unordered associative container
8463
  [[unord.req]]. It provides the operations described in the preceding
8464
  requirements table for unique keys; that is, an `unordered_set` supports
8465
  the `a_uniq` operations in that table, not the `a_eq` operations. For an
8466
  `unordered_set<Key>` the `key_type` and the `value_type` are both `Key`.
8467
  The `iterator` and `const_iterator` types are both constant iterator
@@ -8469,10 +10022,13 @@ types. It is unspecified whether they are the same type.
8469
 
8470
  Subclause  [[unord.set]] only describes operations on `unordered_set`
8471
  that are not described in one of the requirement tables, or for which
8472
  there is additional semantic information.
8473
 
 
 
 
8474
  ``` cpp
8475
  namespace std {
8476
  template<class Key,
8477
  class Hash = hash<Key>,
8478
  class Pred = equal_to<Key>,
@@ -8483,12 +10039,12 @@ namespace std {
8483
  using key_type = Key;
8484
  using value_type = Key;
8485
  using hasher = Hash;
8486
  using key_equal = Pred;
8487
  using allocator_type = Allocator;
8488
- using pointer = typename allocator_traits<Allocator>::pointer;
8489
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8490
  using reference = value_type&;
8491
  using const_reference = const value_type&;
8492
  using size_type = implementation-defined // type of unordered_set::size_type; // see [container.requirements]
8493
  using difference_type = implementation-defined // type of unordered_set::difference_type; // see [container.requirements]
8494
 
@@ -8498,162 +10054,163 @@ namespace std {
8498
  using const_local_iterator = implementation-defined // type of unordered_set::const_local_iterator; // see [container.requirements]
8499
  using node_type = unspecified;
8500
  using insert_return_type = insert-return-type<iterator, node_type>;
8501
 
8502
  // [unord.set.cnstr], construct/copy/destroy
8503
- unordered_set();
8504
- explicit unordered_set(size_type n,
8505
- const hasher& hf = hasher(),
8506
  const key_equal& eql = key_equal(),
8507
  const allocator_type& a = allocator_type());
8508
  template<class InputIterator>
8509
- unordered_set(InputIterator f, InputIterator l,
8510
- size_type n = see below,
8511
- const hasher& hf = hasher(),
8512
  const key_equal& eql = key_equal(),
8513
  const allocator_type& a = allocator_type());
8514
  template<container-compatible-range<value_type> R>
8515
- unordered_set(from_range_t, R&& rg,
8516
- size_type n = see below,
8517
- const hasher& hf = hasher(),
8518
  const key_equal& eql = key_equal(),
8519
  const allocator_type& a = allocator_type());
8520
- unordered_set(const unordered_set&);
8521
- unordered_set(unordered_set&&);
8522
- explicit unordered_set(const Allocator&);
8523
- unordered_set(const unordered_set&, const type_identity_t<Allocator>&);
8524
- unordered_set(unordered_set&&, const type_identity_t<Allocator>&);
8525
- unordered_set(initializer_list<value_type> il,
8526
- size_type n = see below,
8527
- const hasher& hf = hasher(),
8528
  const key_equal& eql = key_equal(),
8529
  const allocator_type& a = allocator_type());
8530
- unordered_set(size_type n, const allocator_type& a)
8531
  : unordered_set(n, hasher(), key_equal(), a) { }
8532
- unordered_set(size_type n, const hasher& hf, const allocator_type& a)
8533
  : unordered_set(n, hf, key_equal(), a) { }
8534
  template<class InputIterator>
8535
- unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
 
8536
  : unordered_set(f, l, n, hasher(), key_equal(), a) { }
8537
  template<class InputIterator>
8538
- unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8539
  const allocator_type& a)
8540
  : unordered_set(f, l, n, hf, key_equal(), a) { }
8541
- unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
 
8542
  : unordered_set(il, n, hasher(), key_equal(), a) { }
8543
  template<container-compatible-range<value_type> R>
8544
- unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a)
8545
  : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
8546
  template<container-compatible-range<value_type> R>
8547
- unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a)
 
8548
  : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8549
- unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
8550
  const allocator_type& a)
8551
  : unordered_set(il, n, hf, key_equal(), a) { }
8552
- ~unordered_set();
8553
- unordered_set& operator=(const unordered_set&);
8554
- unordered_set& operator=(unordered_set&&)
8555
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8556
- is_nothrow_move_assignable_v<Hash> &&
8557
- is_nothrow_move_assignable_v<Pred>);
8558
- unordered_set& operator=(initializer_list<value_type>);
8559
- allocator_type get_allocator() const noexcept;
8560
 
8561
  // iterators
8562
- iterator begin() noexcept;
8563
- const_iterator begin() const noexcept;
8564
- iterator end() noexcept;
8565
- const_iterator end() const noexcept;
8566
- const_iterator cbegin() const noexcept;
8567
- const_iterator cend() const noexcept;
8568
 
8569
  // capacity
8570
- [[nodiscard]] bool empty() const noexcept;
8571
- size_type size() const noexcept;
8572
- size_type max_size() const noexcept;
8573
 
8574
- // modifiers
8575
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
8576
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
8577
- pair<iterator, bool> insert(const value_type& obj);
8578
- pair<iterator, bool> insert(value_type&& obj);
8579
- iterator insert(const_iterator hint, const value_type& obj);
8580
- iterator insert(const_iterator hint, value_type&& obj);
8581
- template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
 
 
8582
  template<container-compatible-range<value_type> R>
8583
- void insert_range(R&& rg);
8584
- void insert(initializer_list<value_type>);
8585
 
8586
- node_type extract(const_iterator position);
8587
- node_type extract(const key_type& x);
8588
- template<class K> node_type extract(K&& x);
8589
- insert_return_type insert(node_type&& nh);
8590
- iterator insert(const_iterator hint, node_type&& nh);
8591
 
8592
- iterator erase(iterator position)
8593
  requires (!same_as<iterator, const_iterator>);
8594
- iterator erase(const_iterator position);
8595
- size_type erase(const key_type& k);
8596
- template<class K> size_type erase(K&& x);
8597
- iterator erase(const_iterator first, const_iterator last);
8598
- void swap(unordered_set&)
8599
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8600
- is_nothrow_swappable_v<Hash> &&
8601
- is_nothrow_swappable_v<Pred>);
8602
- void clear() noexcept;
8603
 
8604
  template<class H2, class P2>
8605
- void merge(unordered_set<Key, H2, P2, Allocator>& source);
8606
  template<class H2, class P2>
8607
- void merge(unordered_set<Key, H2, P2, Allocator>&& source);
8608
  template<class H2, class P2>
8609
- void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
8610
  template<class H2, class P2>
8611
- void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
8612
 
8613
  // observers
8614
- hasher hash_function() const;
8615
- key_equal key_eq() const;
8616
 
8617
  // set operations
8618
- iterator find(const key_type& k);
8619
- const_iterator find(const key_type& k) const;
8620
  template<class K>
8621
- iterator find(const K& k);
8622
  template<class K>
8623
- const_iterator find(const K& k) const;
8624
- size_type count(const key_type& k) const;
8625
  template<class K>
8626
- size_type count(const K& k) const;
8627
- bool contains(const key_type& k) const;
8628
  template<class K>
8629
- bool contains(const K& k) const;
8630
- pair<iterator, iterator> equal_range(const key_type& k);
8631
- pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
8632
  template<class K>
8633
- pair<iterator, iterator> equal_range(const K& k);
8634
  template<class K>
8635
- pair<const_iterator, const_iterator> equal_range(const K& k) const;
8636
 
8637
  // bucket interface
8638
- size_type bucket_count() const noexcept;
8639
- size_type max_bucket_count() const noexcept;
8640
- size_type bucket_size(size_type n) const;
8641
- size_type bucket(const key_type& k) const;
8642
- local_iterator begin(size_type n);
8643
- const_local_iterator begin(size_type n) const;
8644
- local_iterator end(size_type n);
8645
- const_local_iterator end(size_type n) const;
8646
- const_local_iterator cbegin(size_type n) const;
8647
- const_local_iterator cend(size_type n) const;
 
8648
 
8649
  // hash policy
8650
- float load_factor() const noexcept;
8651
- float max_load_factor() const noexcept;
8652
- void max_load_factor(float z);
8653
- void rehash(size_type n);
8654
- void reserve(size_type n);
8655
  };
8656
 
8657
  template<class InputIterator,
8658
  class Hash = hash<iter-value-type<InputIterator>>,
8659
  class Pred = equal_to<iter-value-type<InputIterator>>,
@@ -8721,13 +10278,12 @@ refers to the `size_type` member type of the type deduced by the
8721
  deduction guide.
8722
 
8723
  #### Constructors <a id="unord.set.cnstr">[[unord.set.cnstr]]</a>
8724
 
8725
  ``` cpp
8726
- unordered_set() : unordered_set(size_type(see below)) { }
8727
- explicit unordered_set(size_type n,
8728
- const hasher& hf = hasher(),
8729
  const key_equal& eql = key_equal(),
8730
  const allocator_type& a = allocator_type());
8731
  ```
8732
 
8733
  *Effects:* Constructs an empty `unordered_set` using the specified hash
@@ -8737,24 +10293,21 @@ buckets. For the default constructor, the number of buckets is
8737
 
8738
  *Complexity:* Constant.
8739
 
8740
  ``` cpp
8741
  template<class InputIterator>
8742
- unordered_set(InputIterator f, InputIterator l,
8743
- size_type n = see below,
8744
- const hasher& hf = hasher(),
8745
  const key_equal& eql = key_equal(),
8746
  const allocator_type& a = allocator_type());
8747
  template<container-compatible-range<value_type> R>
8748
- unordered_multiset(from_range_t, R&& rg,
8749
- size_type n = see below,
8750
- const hasher& hf = hasher(),
8751
  const key_equal& eql = key_equal(),
8752
  const allocator_type& a = allocator_type());
8753
- unordered_set(initializer_list<value_type> il,
8754
- size_type n = see below,
8755
- const hasher& hf = hasher(),
8756
  const key_equal& eql = key_equal(),
8757
  const allocator_type& a = allocator_type());
8758
  ```
8759
 
8760
  *Effects:* Constructs an empty `unordered_set` using the specified hash
@@ -8767,11 +10320,11 @@ buckets. If `n` is not provided, the number of buckets is
8767
 
8768
  #### Erasure <a id="unord.set.erasure">[[unord.set.erasure]]</a>
8769
 
8770
  ``` cpp
8771
  template<class K, class H, class P, class A, class Predicate>
8772
- typename unordered_set<K, H, P, A>::size_type
8773
  erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
8774
  ```
8775
 
8776
  *Effects:* Equivalent to:
8777
 
@@ -8785,10 +10338,37 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
8785
  }
8786
  }
8787
  return original_size - c.size();
8788
  ```
8789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8790
  ### Class template `unordered_multiset` <a id="unord.multiset">[[unord.multiset]]</a>
8791
 
8792
  #### Overview <a id="unord.multiset.overview">[[unord.multiset.overview]]</a>
8793
 
8794
  An `unordered_multiset` is an unordered associative container that
@@ -8810,10 +10390,13 @@ same type.
8810
 
8811
  Subclause  [[unord.multiset]] only describes operations on
8812
  `unordered_multiset` that are not described in one of the requirement
8813
  tables, or for which there is additional semantic information.
8814
 
 
 
 
8815
  ``` cpp
8816
  namespace std {
8817
  template<class Key,
8818
  class Hash = hash<Key>,
8819
  class Pred = equal_to<Key>,
@@ -8824,12 +10407,12 @@ namespace std {
8824
  using key_type = Key;
8825
  using value_type = Key;
8826
  using hasher = Hash;
8827
  using key_equal = Pred;
8828
  using allocator_type = Allocator;
8829
- using pointer = typename allocator_traits<Allocator>::pointer;
8830
- using const_pointer = typename allocator_traits<Allocator>::const_pointer;
8831
  using reference = value_type&;
8832
  using const_reference = const value_type&;
8833
  using size_type = implementation-defined // type of unordered_multiset::size_type; // see [container.requirements]
8834
  using difference_type = implementation-defined // type of unordered_multiset::difference_type; // see [container.requirements]
8835
 
@@ -8838,171 +10421,169 @@ namespace std {
8838
  using local_iterator = implementation-defined // type of unordered_multiset::local_iterator; // see [container.requirements]
8839
  using const_local_iterator = implementation-defined // type of unordered_multiset::const_local_iterator; // see [container.requirements]
8840
  using node_type = unspecified;
8841
 
8842
  // [unord.multiset.cnstr], construct/copy/destroy
8843
- unordered_multiset();
8844
- explicit unordered_multiset(size_type n,
8845
- const hasher& hf = hasher(),
8846
  const key_equal& eql = key_equal(),
8847
  const allocator_type& a = allocator_type());
8848
  template<class InputIterator>
8849
- unordered_multiset(InputIterator f, InputIterator l,
8850
- size_type n = see below,
8851
- const hasher& hf = hasher(),
8852
  const key_equal& eql = key_equal(),
8853
  const allocator_type& a = allocator_type());
8854
  template<container-compatible-range<value_type> R>
8855
- unordered_multiset(from_range_t, R&& rg,
8856
- size_type n = see below,
8857
- const hasher& hf = hasher(),
8858
  const key_equal& eql = key_equal(),
8859
  const allocator_type& a = allocator_type());
8860
- unordered_multiset(const unordered_multiset&);
8861
- unordered_multiset(unordered_multiset&&);
8862
- explicit unordered_multiset(const Allocator&);
8863
- unordered_multiset(const unordered_multiset&, const type_identity_t<Allocator>&);
8864
- unordered_multiset(unordered_multiset&&, const type_identity_t<Allocator>&);
8865
- unordered_multiset(initializer_list<value_type> il,
8866
- size_type n = see below,
8867
- const hasher& hf = hasher(),
8868
  const key_equal& eql = key_equal(),
8869
  const allocator_type& a = allocator_type());
8870
- unordered_multiset(size_type n, const allocator_type& a)
8871
  : unordered_multiset(n, hasher(), key_equal(), a) { }
8872
- unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
8873
  : unordered_multiset(n, hf, key_equal(), a) { }
8874
  template<class InputIterator>
8875
- unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
 
8876
  : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
8877
  template<class InputIterator>
8878
- unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
8879
- const allocator_type& a)
8880
  : unordered_multiset(f, l, n, hf, key_equal(), a) { }
8881
  template<container-compatible-range<value_type> R>
8882
- unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a)
8883
  : unordered_multiset(from_range, std::forward<R>(rg),
8884
  n, hasher(), key_equal(), a) { }
8885
  template<container-compatible-range<value_type> R>
8886
- unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf,
8887
  const allocator_type& a)
8888
  : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
8889
- unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
 
8890
  : unordered_multiset(il, n, hasher(), key_equal(), a) { }
8891
- unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
8892
  const allocator_type& a)
8893
  : unordered_multiset(il, n, hf, key_equal(), a) { }
8894
- ~unordered_multiset();
8895
- unordered_multiset& operator=(const unordered_multiset&);
8896
- unordered_multiset& operator=(unordered_multiset&&)
8897
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8898
- is_nothrow_move_assignable_v<Hash> &&
8899
- is_nothrow_move_assignable_v<Pred>);
8900
- unordered_multiset& operator=(initializer_list<value_type>);
8901
- allocator_type get_allocator() const noexcept;
8902
 
8903
  // iterators
8904
- iterator begin() noexcept;
8905
- const_iterator begin() const noexcept;
8906
- iterator end() noexcept;
8907
- const_iterator end() const noexcept;
8908
- const_iterator cbegin() const noexcept;
8909
- const_iterator cend() const noexcept;
8910
 
8911
  // capacity
8912
- [[nodiscard]] bool empty() const noexcept;
8913
- size_type size() const noexcept;
8914
- size_type max_size() const noexcept;
8915
 
8916
  // modifiers
8917
- template<class... Args> iterator emplace(Args&&... args);
8918
- template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
8919
- iterator insert(const value_type& obj);
8920
- iterator insert(value_type&& obj);
8921
- iterator insert(const_iterator hint, const value_type& obj);
8922
- iterator insert(const_iterator hint, value_type&& obj);
8923
- template<class InputIterator> void insert(InputIterator first, InputIterator last);
 
8924
  template<container-compatible-range<value_type> R>
8925
- void insert_range(R&& rg);
8926
- void insert(initializer_list<value_type>);
8927
 
8928
- node_type extract(const_iterator position);
8929
- node_type extract(const key_type& x);
8930
- template<class K> node_type extract(K&& x);
8931
- iterator insert(node_type&& nh);
8932
- iterator insert(const_iterator hint, node_type&& nh);
8933
 
8934
- iterator erase(iterator position)
8935
  requires (!same_as<iterator, const_iterator>);
8936
- iterator erase(const_iterator position);
8937
- size_type erase(const key_type& k);
8938
- template<class K> size_type erase(K&& x);
8939
- iterator erase(const_iterator first, const_iterator last);
8940
- void swap(unordered_multiset&)
8941
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8942
- is_nothrow_swappable_v<Hash> &&
8943
- is_nothrow_swappable_v<Pred>);
8944
- void clear() noexcept;
8945
 
8946
  template<class H2, class P2>
8947
- void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
8948
  template<class H2, class P2>
8949
- void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
8950
  template<class H2, class P2>
8951
- void merge(unordered_set<Key, H2, P2, Allocator>& source);
8952
  template<class H2, class P2>
8953
- void merge(unordered_set<Key, H2, P2, Allocator>&& source);
8954
 
8955
  // observers
8956
- hasher hash_function() const;
8957
- key_equal key_eq() const;
8958
 
8959
  // set operations
8960
- iterator find(const key_type& k);
8961
- const_iterator find(const key_type& k) const;
8962
  template<class K>
8963
- iterator find(const K& k);
8964
  template<class K>
8965
- const_iterator find(const K& k) const;
8966
- size_type count(const key_type& k) const;
8967
  template<class K>
8968
- size_type count(const K& k) const;
8969
- bool contains(const key_type& k) const;
8970
  template<class K>
8971
- bool contains(const K& k) const;
8972
- pair<iterator, iterator> equal_range(const key_type& k);
8973
- pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
8974
  template<class K>
8975
- pair<iterator, iterator> equal_range(const K& k);
8976
  template<class K>
8977
- pair<const_iterator, const_iterator> equal_range(const K& k) const;
8978
 
8979
  // bucket interface
8980
- size_type bucket_count() const noexcept;
8981
- size_type max_bucket_count() const noexcept;
8982
- size_type bucket_size(size_type n) const;
8983
- size_type bucket(const key_type& k) const;
8984
- local_iterator begin(size_type n);
8985
- const_local_iterator begin(size_type n) const;
8986
- local_iterator end(size_type n);
8987
- const_local_iterator end(size_type n) const;
8988
- const_local_iterator cbegin(size_type n) const;
8989
- const_local_iterator cend(size_type n) const;
 
8990
 
8991
  // hash policy
8992
- float load_factor() const noexcept;
8993
- float max_load_factor() const noexcept;
8994
- void max_load_factor(float z);
8995
- void rehash(size_type n);
8996
- void reserve(size_type n);
8997
  };
8998
 
8999
  template<class InputIterator,
9000
  class Hash = hash<iter-value-type<InputIterator>>,
9001
  class Pred = equal_to<iter-value-type<InputIterator>>,
9002
  class Allocator = allocator<iter-value-type<InputIterator>>>
9003
- unordered_multiset(InputIterator, InputIterator, see below::size_type = see below,
9004
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
9005
  -> unordered_multiset<iter-value-type<InputIterator>,
9006
  Hash, Pred, Allocator>;
9007
 
9008
  template<ranges::input_range R,
@@ -9063,13 +10644,12 @@ refers to the `size_type` member type of the type deduced by the
9063
  deduction guide.
9064
 
9065
  #### Constructors <a id="unord.multiset.cnstr">[[unord.multiset.cnstr]]</a>
9066
 
9067
  ``` cpp
9068
- unordered_multiset() : unordered_multiset(size_type(see below)) { }
9069
- explicit unordered_multiset(size_type n,
9070
- const hasher& hf = hasher(),
9071
  const key_equal& eql = key_equal(),
9072
  const allocator_type& a = allocator_type());
9073
  ```
9074
 
9075
  *Effects:* Constructs an empty `unordered_multiset` using the specified
@@ -9079,24 +10659,21 @@ hash function, key equality predicate, and allocator, and using at least
9079
 
9080
  *Complexity:* Constant.
9081
 
9082
  ``` cpp
9083
  template<class InputIterator>
9084
- unordered_multiset(InputIterator f, InputIterator l,
9085
- size_type n = see below,
9086
- const hasher& hf = hasher(),
9087
  const key_equal& eql = key_equal(),
9088
  const allocator_type& a = allocator_type());
9089
  template<container-compatible-range<value_type> R>
9090
- unordered_multiset(from_range_t, R&& rg,
9091
- size_type n = see below,
9092
- const hasher& hf = hasher(),
9093
  const key_equal& eql = key_equal(),
9094
  const allocator_type& a = allocator_type());
9095
- unordered_multiset(initializer_list<value_type> il,
9096
- size_type n = see below,
9097
- const hasher& hf = hasher(),
9098
  const key_equal& eql = key_equal(),
9099
  const allocator_type& a = allocator_type());
9100
  ```
9101
 
9102
  *Effects:* Constructs an empty `unordered_multiset` using the specified
@@ -9109,11 +10686,11 @@ hash function, key equality predicate, and allocator, and using at least
9109
 
9110
  #### Erasure <a id="unord.multiset.erasure">[[unord.multiset.erasure]]</a>
9111
 
9112
  ``` cpp
9113
  template<class K, class H, class P, class A, class Predicate>
9114
- typename unordered_multiset<K, H, P, A>::size_type
9115
  erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
9116
  ```
9117
 
9118
  *Effects:* Equivalent to:
9119
 
@@ -9129,11 +10706,11 @@ for (auto i = c.begin(), last = c.end(); i != last; ) {
9129
  return original_size - c.size();
9130
  ```
9131
 
9132
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
9133
 
9134
- ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
9135
 
9136
  The headers `<queue>`, `<stack>`, `<flat_map>`, and `<flat_set>` define
9137
  the container adaptors `queue` and `priority_queue`, `stack`, `flat_map`
9138
  and `flat_multimap`, and `flat_set` and `flat_multiset`, respectively.
9139
 
@@ -9204,12 +10781,11 @@ deduction guides for container adaptors.
9204
  The following exposition-only alias template may appear in deduction
9205
  guides for container adaptors:
9206
 
9207
  ``` cpp
9208
  template<class Allocator, class T>
9209
- using alloc-rebind = // exposition only
9210
- typename allocator_traits<Allocator>::template rebind_alloc<T>;
9211
  ```
9212
 
9213
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
9214
 
9215
  ``` cpp
@@ -9219,159 +10795,49 @@ template<class Allocator, class T>
9219
  namespace std {
9220
  // [queue], class template queue
9221
  template<class T, class Container = deque<T>> class queue;
9222
 
9223
  template<class T, class Container>
9224
- bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
9225
  template<class T, class Container>
9226
- bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
9227
  template<class T, class Container>
9228
- bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
9229
  template<class T, class Container>
9230
- bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
9231
  template<class T, class Container>
9232
- bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
9233
  template<class T, class Container>
9234
- bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
9235
  template<class T, three_way_comparable Container>
9236
- compare_three_way_result_t<Container>
9237
  operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
9238
 
9239
  template<class T, class Container>
9240
- void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
9241
  template<class T, class Container, class Alloc>
9242
  struct uses_allocator<queue<T, Container>, Alloc>;
9243
 
 
 
 
 
9244
  // [priority.queue], class template priority_queue
9245
  template<class T, class Container = vector<T>,
9246
  class Compare = less<typename Container::value_type>>
9247
  class priority_queue;
9248
 
9249
  template<class T, class Container, class Compare>
9250
- void swap(priority_queue<T, Container, Compare>& x,
9251
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
9252
  template<class T, class Container, class Compare, class Alloc>
9253
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>;
9254
- }
9255
- ```
9256
 
9257
- ### Header `<stack>` synopsis <a id="stack.syn">[[stack.syn]]</a>
9258
-
9259
- ``` cpp
9260
- #include <compare> // see [compare.syn]
9261
- #include <initializer_list> // see [initializer.list.syn]
9262
-
9263
- namespace std {
9264
- // [stack], class template stack
9265
- template<class T, class Container = deque<T>> class stack;
9266
-
9267
- template<class T, class Container>
9268
- bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
9269
- template<class T, class Container>
9270
- bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
9271
- template<class T, class Container>
9272
- bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
9273
- template<class T, class Container>
9274
- bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
9275
- template<class T, class Container>
9276
- bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
9277
- template<class T, class Container>
9278
- bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
9279
- template<class T, three_way_comparable Container>
9280
- compare_three_way_result_t<Container>
9281
- operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
9282
-
9283
- template<class T, class Container>
9284
- void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
9285
- template<class T, class Container, class Alloc>
9286
- struct uses_allocator<stack<T, Container>, Alloc>;
9287
- }
9288
- ```
9289
-
9290
- ### Header `<flat_map>` synopsis <a id="flat.map.syn">[[flat.map.syn]]</a>
9291
-
9292
- ``` cpp
9293
- #include <compare> // see [compare.syn]
9294
- #include <initializer_list> // see [initializer.list.syn]
9295
-
9296
- namespace std {
9297
- // [flat.map], class template flat_map
9298
- template<class Key, class T, class Compare = less<Key>,
9299
- class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
9300
- class flat_map;
9301
-
9302
- struct sorted_unique_t { explicit sorted_unique_t() = default; };
9303
- inline constexpr sorted_unique_t sorted_unique{};
9304
-
9305
- template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9306
- class Allocator>
9307
- struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
9308
- Allocator>;
9309
-
9310
- // [flat.map.erasure], erasure for flat_map
9311
- template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9312
- class Predicate>
9313
- typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
9314
- erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
9315
-
9316
- // [flat.multimap], class template flat_multimap
9317
- template<class Key, class T, class Compare = less<Key>,
9318
- class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
9319
- class flat_multimap;
9320
-
9321
- struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
9322
- inline constexpr sorted_equivalent_t sorted_equivalent{};
9323
-
9324
- template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9325
- class Allocator>
9326
- struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
9327
- Allocator>;
9328
-
9329
- // [flat.multimap.erasure], erasure for flat_multimap
9330
- template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
9331
- class Predicate>
9332
- typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
9333
- erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
9334
- }
9335
- ```
9336
-
9337
- ### Header `<flat_set>` synopsis <a id="flat.set.syn">[[flat.set.syn]]</a>
9338
-
9339
- ``` cpp
9340
- #include <compare> // see [compare.syn]
9341
- #include <initializer_list> // see [initializer.list.syn]
9342
-
9343
- namespace std {
9344
- // [flat.set], class template flat_set
9345
- template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
9346
- class flat_set;
9347
-
9348
- struct sorted_unique_t { explicit sorted_unique_t() = default; };
9349
- inline constexpr sorted_unique_t sorted_unique{};
9350
-
9351
- template<class Key, class Compare, class KeyContainer, class Allocator>
9352
- struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
9353
-
9354
- // [flat.set.erasure], erasure for flat_set
9355
- template<class Key, class Compare, class KeyContainer, class Predicate>
9356
- typename flat_set<Key, Compare, KeyContainer>::size_type
9357
- erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
9358
-
9359
- // [flat.multiset], class template flat_multiset
9360
- template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
9361
- class flat_multiset;
9362
-
9363
- struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
9364
- inline constexpr sorted_equivalent_t sorted_equivalent{};
9365
-
9366
- template<class Key, class Compare, class KeyContainer, class Allocator>
9367
- struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>;
9368
-
9369
- // [flat.multiset.erasure], erasure for flat_multiset
9370
- template<class Key, class Compare, class KeyContainer, class Predicate>
9371
- typename flat_multiset<Key, Compare, KeyContainer>::size_type
9372
- erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
9373
  }
9374
  ```
9375
 
9376
  ### Class template `queue` <a id="queue">[[queue]]</a>
9377
 
@@ -9384,49 +10850,49 @@ particular, `list` [[list]] and `deque` [[deque]] can be used.
9384
  ``` cpp
9385
  namespace std {
9386
  template<class T, class Container = deque<T>>
9387
  class queue {
9388
  public:
9389
- using value_type = typename Container::value_type;
9390
- using reference = typename Container::reference;
9391
- using const_reference = typename Container::const_reference;
9392
- using size_type = typename Container::size_type;
9393
  using container_type = Container;
9394
 
9395
  protected:
9396
  Container c;
9397
 
9398
  public:
9399
- queue() : queue(Container()) {}
9400
- explicit queue(const Container&);
9401
- explicit queue(Container&&);
9402
- template<class InputIterator> queue(InputIterator first, InputIterator last);
9403
- template<container-compatible-range<T> R> queue(from_range_t, R&& rg);
9404
- template<class Alloc> explicit queue(const Alloc&);
9405
- template<class Alloc> queue(const Container&, const Alloc&);
9406
- template<class Alloc> queue(Container&&, const Alloc&);
9407
- template<class Alloc> queue(const queue&, const Alloc&);
9408
- template<class Alloc> queue(queue&&, const Alloc&);
9409
  template<class InputIterator, class Alloc>
9410
- queue(InputIterator first, InputIterator last, const Alloc&);
9411
  template<container-compatible-range<T> R, class Alloc>
9412
- queue(from_range_t, R&& rg, const Alloc&);
9413
 
9414
- [[nodiscard]] bool empty() const { return c.empty(); }
9415
- size_type size() const { return c.size(); }
9416
- reference front() { return c.front(); }
9417
- const_reference front() const { return c.front(); }
9418
- reference back() { return c.back(); }
9419
- const_reference back() const { return c.back(); }
9420
- void push(const value_type& x) { c.push_back(x); }
9421
- void push(value_type&& x) { c.push_back(std::move(x)); }
9422
- template<container-compatible-range<T> R> void push_range(R&& rg);
9423
  template<class... Args>
9424
- decltype(auto) emplace(Args&&... args)
9425
  { return c.emplace_back(std::forward<Args>(args)...); }
9426
- void pop() { c.pop_front(); }
9427
- void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
9428
  { using std::swap; swap(c, q.c); }
9429
  };
9430
 
9431
  template<class Container>
9432
  queue(Container) -> queue<typename Container::value_type, Container>;
@@ -9456,32 +10922,32 @@ namespace std {
9456
  ```
9457
 
9458
  #### Constructors <a id="queue.cons">[[queue.cons]]</a>
9459
 
9460
  ``` cpp
9461
- explicit queue(const Container& cont);
9462
  ```
9463
 
9464
  *Effects:* Initializes `c` with `cont`.
9465
 
9466
  ``` cpp
9467
- explicit queue(Container&& cont);
9468
  ```
9469
 
9470
  *Effects:* Initializes `c` with `std::move(cont)`.
9471
 
9472
  ``` cpp
9473
  template<class InputIterator>
9474
- queue(InputIterator first, InputIterator last);
9475
  ```
9476
 
9477
  *Effects:* Initializes `c` with `first` as the first argument and `last`
9478
  as the second argument.
9479
 
9480
  ``` cpp
9481
  template<container-compatible-range<T> R>
9482
- queue(from_range_t, R&& rg);
9483
  ```
9484
 
9485
  *Effects:* Initializes `c` with
9486
  `ranges::to<Container>(std::forward<R>(rg))`.
9487
 
@@ -9489,127 +10955,127 @@ template<container-compatible-range<T> R>
9489
 
9490
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
9491
  in this subclause shall not participate in overload resolution.
9492
 
9493
  ``` cpp
9494
- template<class Alloc> explicit queue(const Alloc& a);
9495
  ```
9496
 
9497
  *Effects:* Initializes `c` with `a`.
9498
 
9499
  ``` cpp
9500
- template<class Alloc> queue(const container_type& cont, const Alloc& a);
9501
  ```
9502
 
9503
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
9504
  the second argument.
9505
 
9506
  ``` cpp
9507
- template<class Alloc> queue(container_type&& cont, const Alloc& a);
9508
  ```
9509
 
9510
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
9511
  and `a` as the second argument.
9512
 
9513
  ``` cpp
9514
- template<class Alloc> queue(const queue& q, const Alloc& a);
9515
  ```
9516
 
9517
  *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
9518
  the second argument.
9519
 
9520
  ``` cpp
9521
- template<class Alloc> queue(queue&& q, const Alloc& a);
9522
  ```
9523
 
9524
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
9525
  and `a` as the second argument.
9526
 
9527
  ``` cpp
9528
  template<class InputIterator, class Alloc>
9529
- queue(InputIterator first, InputIterator last, const Alloc& alloc);
9530
  ```
9531
 
9532
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
9533
  the second argument, and `alloc` as the third argument.
9534
 
9535
  ``` cpp
9536
  template<container-compatible-range<T> R, class Alloc>
9537
- queue(from_range_t, R&& rg, const Alloc& a);
9538
  ```
9539
 
9540
  *Effects:* Initializes `c` with
9541
  `ranges::to<Container>(std::forward<R>(rg), a)`.
9542
 
9543
  #### Modifiers <a id="queue.mod">[[queue.mod]]</a>
9544
 
9545
  ``` cpp
9546
  template<container-compatible-range<T> R>
9547
- void push_range(R&& rg);
9548
  ```
9549
 
9550
  *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
9551
  is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
9552
 
9553
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
9554
 
9555
  ``` cpp
9556
  template<class T, class Container>
9557
- bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
9558
  ```
9559
 
9560
  *Returns:* `x.c == y.c`.
9561
 
9562
  ``` cpp
9563
  template<class T, class Container>
9564
- bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
9565
  ```
9566
 
9567
  *Returns:* `x.c != y.c`.
9568
 
9569
  ``` cpp
9570
  template<class T, class Container>
9571
- bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
9572
  ```
9573
 
9574
  *Returns:* `x.c < y.c`.
9575
 
9576
  ``` cpp
9577
  template<class T, class Container>
9578
- bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
9579
  ```
9580
 
9581
  *Returns:* `x.c > y.c`.
9582
 
9583
  ``` cpp
9584
  template<class T, class Container>
9585
- bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
9586
  ```
9587
 
9588
  *Returns:* `x.c <= y.c`.
9589
 
9590
  ``` cpp
9591
  template<class T, class Container>
9592
- bool operator>=(const queue<T, Container>& x,
9593
- const queue<T, Container>& y);
9594
  ```
9595
 
9596
  *Returns:* `x.c >= y.c`.
9597
 
9598
  ``` cpp
9599
  template<class T, three_way_comparable Container>
9600
- compare_three_way_result_t<Container>
9601
  operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
9602
  ```
9603
 
9604
  *Returns:* `x.c <=> y.c`.
9605
 
9606
  #### Specialized algorithms <a id="queue.special">[[queue.special]]</a>
9607
 
9608
  ``` cpp
9609
  template<class T, class Container>
9610
- void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
9611
  ```
9612
 
9613
  *Constraints:* `is_swappable_v<Container>` is `true`.
9614
 
9615
  *Effects:* As if by `x.swap(y)`.
@@ -9630,67 +11096,70 @@ defines a strict weak ordering [[alg.sorting]].
9630
  namespace std {
9631
  template<class T, class Container = vector<T>,
9632
  class Compare = less<typename Container::value_type>>
9633
  class priority_queue {
9634
  public:
9635
- using value_type = typename Container::value_type;
9636
- using reference = typename Container::reference;
9637
- using const_reference = typename Container::const_reference;
9638
- using size_type = typename Container::size_type;
9639
  using container_type = Container;
9640
  using value_compare = Compare;
9641
 
9642
  protected:
9643
  Container c;
9644
  Compare comp;
9645
 
9646
  public:
9647
- priority_queue() : priority_queue(Compare()) {}
9648
- explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
9649
- priority_queue(const Compare& x, const Container&);
9650
- priority_queue(const Compare& x, Container&&);
9651
  template<class InputIterator>
9652
- priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
 
9653
  template<class InputIterator>
9654
- priority_queue(InputIterator first, InputIterator last, const Compare& x,
9655
  const Container&);
9656
  template<class InputIterator>
9657
- priority_queue(InputIterator first, InputIterator last, const Compare& x,
9658
  Container&&);
9659
  template<container-compatible-range<T> R>
9660
- priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
9661
- template<class Alloc> explicit priority_queue(const Alloc&);
9662
- template<class Alloc> priority_queue(const Compare&, const Alloc&);
9663
- template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
9664
- template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
9665
- template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
9666
- template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
 
9667
  template<class InputIterator, class Alloc>
9668
- priority_queue(InputIterator, InputIterator, const Alloc&);
9669
  template<class InputIterator, class Alloc>
9670
- priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&);
9671
  template<class InputIterator, class Alloc>
9672
- priority_queue(InputIterator, InputIterator, const Compare&, const Container&,
9673
  const Alloc&);
9674
  template<class InputIterator, class Alloc>
9675
- priority_queue(InputIterator, InputIterator, const Compare&, Container&&, const Alloc&);
 
9676
  template<container-compatible-range<T> R, class Alloc>
9677
- priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&);
9678
  template<container-compatible-range<T> R, class Alloc>
9679
- priority_queue(from_range_t, R&& rg, const Alloc&);
9680
 
9681
- [[nodiscard]] bool empty() const { return c.empty(); }
9682
- size_type size() const { return c.size(); }
9683
- const_reference top() const { return c.front(); }
9684
- void push(const value_type& x);
9685
- void push(value_type&& x);
9686
  template<container-compatible-range<T> R>
9687
- void push_range(R&& rg);
9688
- template<class... Args> void emplace(Args&&... args);
9689
- void pop();
9690
- void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
9691
- is_nothrow_swappable_v<Compare>)
9692
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
9693
  };
9694
 
9695
  template<class Compare, class Container>
9696
  priority_queue(Compare, Container)
@@ -9743,36 +11212,38 @@ namespace std {
9743
  ```
9744
 
9745
  #### Constructors <a id="priqueue.cons">[[priqueue.cons]]</a>
9746
 
9747
  ``` cpp
9748
- priority_queue(const Compare& x, const Container& y);
9749
- priority_queue(const Compare& x, Container&& y);
9750
  ```
9751
 
9752
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9753
 
9754
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
9755
  constructing or move constructing as appropriate); calls
9756
  `make_heap(c.begin(), c.end(), comp)`.
9757
 
9758
  ``` cpp
9759
  template<class InputIterator>
9760
- priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
9761
  ```
9762
 
9763
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9764
 
9765
  *Effects:* Initializes `c` with `first` as the first argument and `last`
9766
  as the second argument, and initializes `comp` with `x`; then calls
9767
  `make_heap(c.begin(), c.end(), comp)`.
9768
 
9769
  ``` cpp
9770
  template<class InputIterator>
9771
- priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y);
 
9772
  template<class InputIterator>
9773
- priority_queue(InputIterator first, InputIterator last, const Compare& x, Container&& y);
 
9774
  ```
9775
 
9776
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9777
 
9778
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
@@ -9780,11 +11251,11 @@ constructing or move constructing as appropriate); calls
9780
  `c.insert(c.end(), first, last)`; and finally calls
9781
  `make_heap(c.begin(), c.end(), comp)`.
9782
 
9783
  ``` cpp
9784
  template<container-compatible-range<T> R>
9785
- priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
9786
  ```
9787
 
9788
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
9789
 
9790
  *Effects:* Initializes `comp` with `x` and `c` with
@@ -9795,128 +11266,129 @@ template<container-compatible-range<T> R>
9795
 
9796
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
9797
  in this subclause shall not participate in overload resolution.
9798
 
9799
  ``` cpp
9800
- template<class Alloc> explicit priority_queue(const Alloc& a);
9801
  ```
9802
 
9803
  *Effects:* Initializes `c` with `a` and value-initializes `comp`.
9804
 
9805
  ``` cpp
9806
- template<class Alloc> priority_queue(const Compare& compare, const Alloc& a);
9807
  ```
9808
 
9809
  *Effects:* Initializes `c` with `a` and initializes `comp` with
9810
  `compare`.
9811
 
9812
  ``` cpp
9813
  template<class Alloc>
9814
- priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
9815
  ```
9816
 
9817
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
9818
  the second argument, and initializes `comp` with `compare`; calls
9819
  `make_heap(c.begin(), c.end(), comp)`.
9820
 
9821
  ``` cpp
9822
  template<class Alloc>
9823
- priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
9824
  ```
9825
 
9826
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
9827
  and `a` as the second argument, and initializes `comp` with `compare`;
9828
  calls `make_heap(c.begin(), c.end(), comp)`.
9829
 
9830
  ``` cpp
9831
- template<class Alloc> priority_queue(const priority_queue& q, const Alloc& a);
9832
  ```
9833
 
9834
  *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
9835
  the second argument, and initializes `comp` with `q.comp`.
9836
 
9837
  ``` cpp
9838
- template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
9839
  ```
9840
 
9841
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
9842
  and `a` as the second argument, and initializes `comp` with
9843
  `std::move(q.comp)`.
9844
 
9845
  ``` cpp
9846
  template<class InputIterator, class Alloc>
9847
- priority_queue(InputIterator first, InputIterator last, const Alloc& a);
9848
  ```
9849
 
9850
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
9851
  the second argument, and `a` as the third argument, and
9852
  value-initializes `comp`; calls `make_heap(c.begin(), c.end(), comp)`.
9853
 
9854
  ``` cpp
9855
  template<class InputIterator, class Alloc>
9856
- priority_queue(InputIterator first, InputIterator last, const Compare& compare, const Alloc& a);
 
9857
  ```
9858
 
9859
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
9860
  the second argument, and `a` as the third argument, and initializes
9861
  `comp` with `compare`; calls `make_heap(c.begin(), c.end(), comp)`.
9862
 
9863
  ``` cpp
9864
  template<class InputIterator, class Alloc>
9865
- priority_queue(InputIterator first, InputIterator last, const Compare& compare,
9866
  const Container& cont, const Alloc& a);
9867
  ```
9868
 
9869
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
9870
  the second argument, and initializes `comp` with `compare`; calls
9871
  `c.insert(c.end(), first, last)`; and finally calls
9872
  `make_heap(c.begin(), c.end(), comp)`.
9873
 
9874
  ``` cpp
9875
  template<class InputIterator, class Alloc>
9876
- priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& cont,
9877
- const Alloc& a);
9878
  ```
9879
 
9880
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
9881
  and `a` as the second argument, and initializes `comp` with `compare`;
9882
  calls `c.insert(c.end(), first, last)`; and finally calls
9883
  `make_heap(c.begin(), c.end(), comp)`.
9884
 
9885
  ``` cpp
9886
  template<container-compatible-range<T> R, class Alloc>
9887
- priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a);
9888
  ```
9889
 
9890
  *Effects:* Initializes `comp` with `compare` and `c` with
9891
  `ranges::to<Container>(std::forward<R>(rg), a)`; calls
9892
  `make_heap(c.begin(), c.end(), comp)`.
9893
 
9894
  ``` cpp
9895
  template<container-compatible-range<T> R, class Alloc>
9896
- priority_queue(from_range_t, R&& rg, const Alloc& a);
9897
  ```
9898
 
9899
  *Effects:* Initializes `c` with
9900
- `ranges::to<Container>(std::forward<R>(rg), a)`; calls
9901
- `make_heap(c.begin(), c.end(), comp)`.
9902
 
9903
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
9904
 
9905
  ``` cpp
9906
- void push(const value_type& x);
9907
  ```
9908
 
9909
  *Effects:* As if by:
9910
 
9911
  ``` cpp
9912
  c.push_back(x);
9913
  push_heap(c.begin(), c.end(), comp);
9914
  ```
9915
 
9916
  ``` cpp
9917
- void push(value_type&& x);
9918
  ```
9919
 
9920
  *Effects:* As if by:
9921
 
9922
  ``` cpp
@@ -9924,33 +11396,33 @@ c.push_back(std::move(x));
9924
  push_heap(c.begin(), c.end(), comp);
9925
  ```
9926
 
9927
  ``` cpp
9928
  template<container-compatible-range<T> R>
9929
- void push_range(R&& rg);
9930
  ```
9931
 
9932
  *Effects:* Inserts all elements of `rg` in `c` via
9933
  `c.append_range(std::forward<R>(rg))` if that is a valid expression, or
9934
  `ranges::copy(rg, back_inserter(c))` otherwise. Then restores the heap
9935
  property as if by `make_heap(c.begin(), c.end(), comp)`.
9936
 
9937
  *Ensures:* `is_heap(c.begin(), c.end(), comp)` is `true`.
9938
 
9939
  ``` cpp
9940
- template<class... Args> void emplace(Args&&... args);
9941
  ```
9942
 
9943
  *Effects:* As if by:
9944
 
9945
  ``` cpp
9946
  c.emplace_back(std::forward<Args>(args)...);
9947
  push_heap(c.begin(), c.end(), comp);
9948
  ```
9949
 
9950
  ``` cpp
9951
- void pop();
9952
  ```
9953
 
9954
  *Effects:* As if by:
9955
 
9956
  ``` cpp
@@ -9960,19 +11432,57 @@ c.pop_back();
9960
 
9961
  #### Specialized algorithms <a id="priqueue.special">[[priqueue.special]]</a>
9962
 
9963
  ``` cpp
9964
  template<class T, class Container, class Compare>
9965
- void swap(priority_queue<T, Container, Compare>& x,
9966
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
9967
  ```
9968
 
9969
  *Constraints:* `is_swappable_v<Container>` is `true` and
9970
  `is_swappable_v<Compare>` is `true`.
9971
 
9972
  *Effects:* As if by `x.swap(y)`.
9973
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9974
  ### Class template `stack` <a id="stack">[[stack]]</a>
9975
 
9976
  #### General <a id="stack.general">[[stack.general]]</a>
9977
 
9978
  Any sequence container supporting operations `back()`, `push_back()` and
@@ -9984,48 +11494,49 @@ Any sequence container supporting operations `back()`, `push_back()` and
9984
  ``` cpp
9985
  namespace std {
9986
  template<class T, class Container = deque<T>>
9987
  class stack {
9988
  public:
9989
- using value_type = typename Container::value_type;
9990
- using reference = typename Container::reference;
9991
- using const_reference = typename Container::const_reference;
9992
- using size_type = typename Container::size_type;
9993
  using container_type = Container;
9994
 
9995
  protected:
9996
  Container c;
9997
 
9998
  public:
9999
- stack() : stack(Container()) {}
10000
- explicit stack(const Container&);
10001
- explicit stack(Container&&);
10002
- template<class InputIterator> stack(InputIterator first, InputIterator last);
10003
- template<container-compatible-range<T> R> stack(from_range_t, R&& rg);
10004
- template<class Alloc> explicit stack(const Alloc&);
10005
- template<class Alloc> stack(const Container&, const Alloc&);
10006
- template<class Alloc> stack(Container&&, const Alloc&);
10007
- template<class Alloc> stack(const stack&, const Alloc&);
10008
- template<class Alloc> stack(stack&&, const Alloc&);
 
10009
  template<class InputIterator, class Alloc>
10010
- stack(InputIterator first, InputIterator last, const Alloc&);
10011
  template<container-compatible-range<T> R, class Alloc>
10012
- stack(from_range_t, R&& rg, const Alloc&);
10013
 
10014
- [[nodiscard]] bool empty() const { return c.empty(); }
10015
- size_type size() const { return c.size(); }
10016
- reference top() { return c.back(); }
10017
- const_reference top() const { return c.back(); }
10018
- void push(const value_type& x) { c.push_back(x); }
10019
- void push(value_type&& x) { c.push_back(std::move(x)); }
10020
  template<container-compatible-range<T> R>
10021
- void push_range(R&& rg);
10022
  template<class... Args>
10023
- decltype(auto) emplace(Args&&... args)
10024
  { return c.emplace_back(std::forward<Args>(args)...); }
10025
- void pop() { c.pop_back(); }
10026
- void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
10027
  { using std::swap; swap(c, s.c); }
10028
  };
10029
 
10030
  template<class Container>
10031
  stack(Container) -> stack<typename Container::value_type, Container>;
@@ -10055,32 +11566,32 @@ namespace std {
10055
  ```
10056
 
10057
  #### Constructors <a id="stack.cons">[[stack.cons]]</a>
10058
 
10059
  ``` cpp
10060
- explicit stack(const Container& cont);
10061
  ```
10062
 
10063
  *Effects:* Initializes `c` with `cont`.
10064
 
10065
  ``` cpp
10066
- explicit stack(Container&& cont);
10067
  ```
10068
 
10069
  *Effects:* Initializes `c` with `std::move(cont)`.
10070
 
10071
  ``` cpp
10072
  template<class InputIterator>
10073
- stack(InputIterator first, InputIterator last);
10074
  ```
10075
 
10076
  *Effects:* Initializes `c` with `first` as the first argument and `last`
10077
  as the second argument.
10078
 
10079
  ``` cpp
10080
  template<container-compatible-range<T> R>
10081
- stack(from_range_t, R&& rg);
10082
  ```
10083
 
10084
  *Effects:* Initializes `c` with
10085
  `ranges::to<Container>(std::forward<R>(rg))`.
10086
 
@@ -10088,132 +11599,180 @@ template<container-compatible-range<T> R>
10088
 
10089
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
10090
  in this subclause shall not participate in overload resolution.
10091
 
10092
  ``` cpp
10093
- template<class Alloc> explicit stack(const Alloc& a);
10094
  ```
10095
 
10096
  *Effects:* Initializes `c` with `a`.
10097
 
10098
  ``` cpp
10099
- template<class Alloc> stack(const container_type& cont, const Alloc& a);
10100
  ```
10101
 
10102
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
10103
  the second argument.
10104
 
10105
  ``` cpp
10106
- template<class Alloc> stack(container_type&& cont, const Alloc& a);
10107
  ```
10108
 
10109
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
10110
  and `a` as the second argument.
10111
 
10112
  ``` cpp
10113
- template<class Alloc> stack(const stack& s, const Alloc& a);
10114
  ```
10115
 
10116
  *Effects:* Initializes `c` with `s.c` as the first argument and `a` as
10117
  the second argument.
10118
 
10119
  ``` cpp
10120
- template<class Alloc> stack(stack&& s, const Alloc& a);
10121
  ```
10122
 
10123
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
10124
  and `a` as the second argument.
10125
 
10126
  ``` cpp
10127
  template<class InputIterator, class Alloc>
10128
- stack(InputIterator first, InputIterator last, const Alloc& alloc);
10129
  ```
10130
 
10131
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
10132
  the second argument, and `alloc` as the third argument.
10133
 
10134
  ``` cpp
10135
  template<container-compatible-range<T> R, class Alloc>
10136
- stack(from_range_t, R&& rg, const Alloc& a);
10137
  ```
10138
 
10139
  *Effects:* Initializes `c` with
10140
  `ranges::to<Container>(std::forward<R>(rg), a)`.
10141
 
10142
  #### Modifiers <a id="stack.mod">[[stack.mod]]</a>
10143
 
10144
  ``` cpp
10145
  template<container-compatible-range<T> R>
10146
- void push_range(R&& rg);
10147
  ```
10148
 
10149
  *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
10150
  is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
10151
 
10152
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
10153
 
10154
  ``` cpp
10155
  template<class T, class Container>
10156
- bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
10157
  ```
10158
 
10159
  *Returns:* `x.c == y.c`.
10160
 
10161
  ``` cpp
10162
  template<class T, class Container>
10163
- bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
10164
  ```
10165
 
10166
  *Returns:* `x.c != y.c`.
10167
 
10168
  ``` cpp
10169
  template<class T, class Container>
10170
- bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
10171
  ```
10172
 
10173
  *Returns:* `x.c < y.c`.
10174
 
10175
  ``` cpp
10176
  template<class T, class Container>
10177
- bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
10178
  ```
10179
 
10180
  *Returns:* `x.c > y.c`.
10181
 
10182
  ``` cpp
10183
  template<class T, class Container>
10184
- bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
10185
  ```
10186
 
10187
  *Returns:* `x.c <= y.c`.
10188
 
10189
  ``` cpp
10190
  template<class T, class Container>
10191
- bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
10192
  ```
10193
 
10194
  *Returns:* `x.c >= y.c`.
10195
 
10196
  ``` cpp
10197
  template<class T, three_way_comparable Container>
10198
- compare_three_way_result_t<Container>
10199
  operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
10200
  ```
10201
 
10202
  *Returns:* `x.c <=> y.c`.
10203
 
10204
  #### Specialized algorithms <a id="stack.special">[[stack.special]]</a>
10205
 
10206
  ``` cpp
10207
  template<class T, class Container>
10208
- void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
10209
  ```
10210
 
10211
  *Constraints:* `is_swappable_v<Container>` is `true`.
10212
 
10213
  *Effects:* As if by `x.swap(y)`.
10214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10215
  ### Class template `flat_map` <a id="flat.map">[[flat.map]]</a>
10216
 
10217
  #### Overview <a id="flat.map.overview">[[flat.map.overview]]</a>
10218
 
10219
  A `flat_map` is a container adaptor that provides an associative
@@ -10278,14 +11837,16 @@ The program is ill-formed if `Key` is not the same type as
10278
 
10279
  The effect of calling a constructor that takes both `key_container_type`
10280
  and `mapped_container_type` arguments with containers of different sizes
10281
  is undefined.
10282
 
10283
- The effect of calling a constructor or member function that takes a
10284
- `sorted_unique_t` argument with a container, containers, or range that
10285
- is not sorted with respect to `key_comp()`, or that contains equal
10286
- elements, is undefined.
 
 
10287
 
10288
  #### Definition <a id="flat.map.defn">[[flat.map.defn]]</a>
10289
 
10290
  ``` cpp
10291
  namespace std {
@@ -10310,245 +11871,259 @@ namespace std {
10310
  using mapped_container_type = MappedContainer;
10311
 
10312
  class value_compare {
10313
  private:
10314
  key_compare comp; // exposition only
10315
- value_compare(key_compare c) : comp(c) { } // exposition only
10316
 
10317
  public:
10318
- bool operator()(const_reference x, const_reference y) const {
10319
  return comp(x.first, y.first);
10320
  }
10321
  };
10322
 
10323
  struct containers {
10324
  key_container_type keys;
10325
  mapped_container_type values;
10326
  };
10327
 
10328
- // [flat.map.cons], construct/copy/destroy
10329
- flat_map() : flat_map(key_compare()) { }
10330
 
10331
- flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
10332
- const key_compare& comp = key_compare());
10333
- template<class Allocator>
10334
- flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10335
- const Allocator& a);
10336
- template<class Allocator>
10337
- flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10338
- const key_compare& comp, const Allocator& a);
10339
-
10340
- flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
10341
- const key_compare& comp = key_compare());
10342
- template<class Allocator>
10343
- flat_map(sorted_unique_t, const key_container_type& key_cont,
10344
- const mapped_container_type& mapped_cont, const Allocator& a);
10345
- template<class Allocator>
10346
- flat_map(sorted_unique_t, const key_container_type& key_cont,
10347
- const mapped_container_type& mapped_cont,
10348
- const key_compare& comp, const Allocator& a);
10349
-
10350
- explicit flat_map(const key_compare& comp)
10351
  : c(), compare(comp) { }
10352
- template<class Allocator>
10353
- flat_map(const key_compare& comp, const Allocator& a);
10354
- template<class Allocator>
10355
- explicit flat_map(const Allocator& a);
 
 
 
10356
 
10357
  template<class InputIterator>
10358
- flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
 
10359
  : c(), compare(comp) { insert(first, last); }
10360
- template<class InputIterator, class Allocator>
10361
- flat_map(InputIterator first, InputIterator last,
10362
- const key_compare& comp, const Allocator& a);
10363
- template<class InputIterator, class Allocator>
10364
- flat_map(InputIterator first, InputIterator last, const Allocator& a);
10365
 
10366
  template<container-compatible-range<value_type> R>
10367
- flat_map(from_range_t fr, R&& rg)
10368
- : flat_map(fr, std::forward<R>(rg), key_compare()) { }
10369
- template<container-compatible-range<value_type> R, class Allocator>
10370
- flat_map(from_range_t, R&& rg, const Allocator& a);
10371
  template<container-compatible-range<value_type> R>
10372
- flat_map(from_range_t, R&& rg, const key_compare& comp)
10373
  : flat_map(comp) { insert_range(std::forward<R>(rg)); }
10374
- template<container-compatible-range<value_type> R, class Allocator>
10375
- flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
10376
 
10377
- template<class InputIterator>
10378
- flat_map(sorted_unique_t s, InputIterator first, InputIterator last,
10379
- const key_compare& comp = key_compare())
10380
- : c(), compare(comp) { insert(s, first, last); }
10381
- template<class InputIterator, class Allocator>
10382
- flat_map(sorted_unique_t, InputIterator first, InputIterator last,
10383
- const key_compare& comp, const Allocator& a);
10384
- template<class InputIterator, class Allocator>
10385
- flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
10386
-
10387
- flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare())
10388
  : flat_map(il.begin(), il.end(), comp) { }
10389
- template<class Allocator>
10390
- flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
10391
- template<class Allocator>
10392
- flat_map(initializer_list<value_type> il, const Allocator& a);
10393
 
10394
- flat_map(sorted_unique_t s, initializer_list<value_type> il,
10395
  const key_compare& comp = key_compare())
10396
- : flat_map(s, il.begin(), il.end(), comp) { }
10397
- template<class Allocator>
10398
- flat_map(sorted_unique_t, initializer_list<value_type> il,
10399
- const key_compare& comp, const Allocator& a);
10400
- template<class Allocator>
10401
- flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
10402
 
10403
- flat_map& operator=(initializer_list<value_type> il);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10404
 
10405
  // iterators
10406
- iterator begin() noexcept;
10407
- const_iterator begin() const noexcept;
10408
- iterator end() noexcept;
10409
- const_iterator end() const noexcept;
10410
 
10411
- reverse_iterator rbegin() noexcept;
10412
- const_reverse_iterator rbegin() const noexcept;
10413
- reverse_iterator rend() noexcept;
10414
- const_reverse_iterator rend() const noexcept;
10415
 
10416
- const_iterator cbegin() const noexcept;
10417
- const_iterator cend() const noexcept;
10418
- const_reverse_iterator crbegin() const noexcept;
10419
- const_reverse_iterator crend() const noexcept;
10420
 
10421
  // [flat.map.capacity], capacity
10422
- [[nodiscard]] bool empty() const noexcept;
10423
- size_type size() const noexcept;
10424
- size_type max_size() const noexcept;
10425
 
10426
  // [flat.map.access], element access
10427
- mapped_type& operator[](const key_type& x);
10428
- mapped_type& operator[](key_type&& x);
10429
- template<class K> mapped_type& operator[](K&& x);
10430
- mapped_type& at(const key_type& x);
10431
- const mapped_type& at(const key_type& x) const;
10432
- template<class K> mapped_type& at(const K& x);
10433
- template<class K> const mapped_type& at(const K& x) const;
10434
 
10435
  // [flat.map.modifiers], modifiers
10436
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
10437
  template<class... Args>
10438
- iterator emplace_hint(const_iterator position, Args&&... args);
10439
 
10440
- pair<iterator, bool> insert(const value_type& x)
10441
  { return emplace(x); }
10442
- pair<iterator, bool> insert(value_type&& x)
10443
  { return emplace(std::move(x)); }
10444
- iterator insert(const_iterator position, const value_type& x)
10445
  { return emplace_hint(position, x); }
10446
- iterator insert(const_iterator position, value_type&& x)
10447
  { return emplace_hint(position, std::move(x)); }
10448
 
10449
- template<class P> pair<iterator, bool> insert(P&& x);
10450
  template<class P>
10451
- iterator insert(const_iterator position, P&&);
10452
  template<class InputIterator>
10453
- void insert(InputIterator first, InputIterator last);
10454
  template<class InputIterator>
10455
- void insert(sorted_unique_t, InputIterator first, InputIterator last);
10456
  template<container-compatible-range<value_type> R>
10457
- void insert_range(R&& rg);
10458
 
10459
- void insert(initializer_list<value_type> il)
10460
  { insert(il.begin(), il.end()); }
10461
- void insert(sorted_unique_t s, initializer_list<value_type> il)
10462
- { insert(s, il.begin(), il.end()); }
10463
 
10464
- containers extract() &&;
10465
- void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
10466
 
10467
  template<class... Args>
10468
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
10469
  template<class... Args>
10470
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
10471
  template<class K, class... Args>
10472
- pair<iterator, bool> try_emplace(K&& k, Args&&... args);
10473
  template<class... Args>
10474
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
10475
  template<class... Args>
10476
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
10477
  template<class K, class... Args>
10478
- iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
10479
  template<class M>
10480
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
10481
  template<class M>
10482
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
10483
  template<class K, class M>
10484
- pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
10485
  template<class M>
10486
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
10487
  template<class M>
10488
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
10489
  template<class K, class M>
10490
- iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
10491
 
10492
- iterator erase(iterator position);
10493
- iterator erase(const_iterator position);
10494
- size_type erase(const key_type& x);
10495
- template<class K> size_type erase(K&& x);
10496
- iterator erase(const_iterator first, const_iterator last);
10497
 
10498
- void swap(flat_map& y) noexcept;
10499
- void clear() noexcept;
10500
 
10501
  // observers
10502
- key_compare key_comp() const;
10503
- value_compare value_comp() const;
10504
 
10505
- const key_container_type& keys() const noexcept { return c.keys; }
10506
- const mapped_container_type& values() const noexcept { return c.values; }
10507
 
10508
  // map operations
10509
- iterator find(const key_type& x);
10510
- const_iterator find(const key_type& x) const;
10511
- template<class K> iterator find(const K& x);
10512
- template<class K> const_iterator find(const K& x) const;
10513
 
10514
- size_type count(const key_type& x) const;
10515
- template<class K> size_type count(const K& x) const;
10516
 
10517
- bool contains(const key_type& x) const;
10518
- template<class K> bool contains(const K& x) const;
10519
 
10520
- iterator lower_bound(const key_type& x);
10521
- const_iterator lower_bound(const key_type& x) const;
10522
- template<class K> iterator lower_bound(const K& x);
10523
- template<class K> const_iterator lower_bound(const K& x) const;
10524
 
10525
- iterator upper_bound(const key_type& x);
10526
- const_iterator upper_bound(const key_type& x) const;
10527
- template<class K> iterator upper_bound(const K& x);
10528
- template<class K> const_iterator upper_bound(const K& x) const;
10529
 
10530
- pair<iterator, iterator> equal_range(const key_type& x);
10531
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
10532
- template<class K> pair<iterator, iterator> equal_range(const K& x);
10533
- template<class K> pair<const_iterator, const_iterator> equal_range(const K& x) const;
 
10534
 
10535
- friend bool operator==(const flat_map& x, const flat_map& y);
10536
 
10537
- friend synth-three-way-result<value_type>
10538
  operator<=>(const flat_map& x, const flat_map& y);
10539
 
10540
- friend void swap(flat_map& x, flat_map& y) noexcept
10541
  { x.swap(y); }
10542
 
10543
  private:
10544
  containers c; // exposition only
10545
  key_compare compare; // exposition only
10546
 
10547
- struct key_equiv { // exposition only
10548
- key_equiv(key_compare c) : comp(c) { }
10549
- bool operator()(const_reference x, const_reference y) const {
10550
  return !comp(x.first, y.first) && !comp(y.first, x.first);
10551
  }
10552
  key_compare comp;
10553
  };
10554
  };
@@ -10625,162 +12200,163 @@ specified above. It has no base classes or members other than those
10625
  specified.
10626
 
10627
  #### Constructors <a id="flat.map.cons">[[flat.map.cons]]</a>
10628
 
10629
  ``` cpp
10630
- flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
10631
  const key_compare& comp = key_compare());
10632
  ```
10633
 
10634
- *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
10635
- with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
10636
- range \[`begin()`, `end()`) with respect to `value_comp()`; and finally
10637
- erases the duplicate elements as if by:
10638
 
10639
  ``` cpp
10640
- auto zv = ranges::zip_view(c.keys, c.values);
10641
- auto it = ranges::unique(zv, key_equiv(compare)).begin();
10642
  auto dist = distance(zv.begin(), it);
10643
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
10644
  c.values.erase(c.values.begin() + dist, c.values.end());
10645
  ```
10646
 
10647
  *Complexity:* Linear in N if the container arguments are already sorted
10648
  with respect to `value_comp()` and otherwise N log N, where N is the
10649
  value of `key_cont.size()` before this call.
10650
 
10651
  ``` cpp
10652
- template<class Allocator>
10653
- flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10654
- const Allocator& a);
10655
- template<class Allocator>
10656
- flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
10657
- const key_compare& comp, const Allocator& a);
10658
  ```
10659
 
10660
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10661
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10662
- `true`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10663
 
10664
  *Effects:* Equivalent to `flat_map(key_cont, mapped_cont)` and
10665
  `flat_map(key_cont, mapped_cont, comp)`, respectively, except that
10666
- `c.keys` and `c.values` are constructed with uses-allocator
10667
  construction [[allocator.uses.construction]].
10668
 
10669
  *Complexity:* Same as `flat_map(key_cont, mapped_cont)` and
10670
  `flat_map(key_cont, mapped_cont, comp)`, respectively.
10671
 
10672
  ``` cpp
10673
- flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
10674
- const key_compare& comp = key_compare());
10675
- ```
10676
-
10677
- *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
10678
- with `std::move(mapped_cont)`, and `compare` with `comp`.
10679
-
10680
- *Complexity:* Constant.
10681
-
10682
- ``` cpp
10683
- template<class Allocator>
10684
- flat_map(sorted_unique_t s, const key_container_type& key_cont,
10685
- const mapped_container_type& mapped_cont, const Allocator& a);
10686
- template<class Allocator>
10687
- flat_map(sorted_unique_t s, const key_container_type& key_cont,
10688
  const mapped_container_type& mapped_cont, const key_compare& comp,
10689
- const Allocator& a);
10690
  ```
10691
 
10692
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10693
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10694
- `true`.
10695
-
10696
- *Effects:* Equivalent to `flat_map(s, key_cont, mapped_cont)` and
10697
- `flat_map(s, key_cont, mapped_cont, comp)`, respectively, except that
10698
- `c.keys` and `c.values` are constructed with uses-allocator
10699
- construction [[allocator.uses.construction]].
10700
 
10701
  *Complexity:* Linear.
10702
 
10703
  ``` cpp
10704
- template<class Allocator>
10705
- flat_map(const key_compare& comp, const Allocator& a);
10706
- template<class Allocator>
10707
- explicit flat_map(const Allocator& a);
10708
- template<class InputIterator, class Allocator>
10709
- flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
10710
- template<class InputIterator, class Allocator>
10711
- flat_map(InputIterator first, InputIterator last, const Allocator& a);
10712
- template<container-compatible-range<value_type> R, class Allocator>
10713
- flat_map(from_range_t, R&& rg, const Allocator& a);
10714
- template<container-compatible-range<value_type> R, class Allocator>
10715
- flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
10716
- template<class InputIterator, class Allocator>
10717
- flat_map(sorted_unique_t, InputIterator first, InputIterator last,
10718
- const key_compare& comp, const Allocator& a);
10719
- template<class InputIterator, class Allocator>
10720
- flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
10721
- template<class Allocator>
10722
- flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
10723
- template<class Allocator>
10724
- flat_map(initializer_list<value_type> il, const Allocator& a);
10725
- template<class Allocator>
10726
- flat_map(sorted_unique_t, initializer_list<value_type> il,
10727
- const key_compare& comp, const Allocator& a);
10728
- template<class Allocator>
10729
- flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
 
 
 
 
 
10730
  ```
10731
 
10732
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
10733
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
10734
- `true`.
10735
-
10736
  *Effects:* Equivalent to the corresponding non-allocator constructors
10737
- except that `c.keys` and `c.values` are constructed with uses-allocator
10738
- construction [[allocator.uses.construction]].
10739
 
10740
  #### Capacity <a id="flat.map.capacity">[[flat.map.capacity]]</a>
10741
 
10742
  ``` cpp
10743
- size_type size() const noexcept;
10744
  ```
10745
 
10746
- *Returns:* `c.keys.size()`.
10747
 
10748
  ``` cpp
10749
- size_type max_size() const noexcept;
10750
  ```
10751
 
10752
- *Returns:* `min<size_type>(c.keys.max_size(), c.values.max_size())`.
 
10753
 
10754
  #### Access <a id="flat.map.access">[[flat.map.access]]</a>
10755
 
10756
  ``` cpp
10757
- mapped_type& operator[](const key_type& x);
10758
  ```
10759
 
10760
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
10761
 
10762
  ``` cpp
10763
- mapped_type& operator[](key_type&& x);
10764
  ```
10765
 
10766
  *Effects:* Equivalent to:
10767
  `return try_emplace(std::move(x)).first->second;`
10768
 
10769
  ``` cpp
10770
- template<class K> mapped_type& operator[](K&& x);
10771
  ```
10772
 
10773
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
10774
  denotes a type.
10775
 
10776
  *Effects:* Equivalent to:
10777
  `return try_emplace(std::forward<K>(x)).first->second;`
10778
 
10779
  ``` cpp
10780
- mapped_type& at(const key_type& x);
10781
- const mapped_type& at(const key_type& x) const;
10782
  ```
10783
 
10784
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
10785
  `*this`.
10786
 
@@ -10788,12 +12364,12 @@ const mapped_type& at(const key_type& x) const;
10788
  is present.
10789
 
10790
  *Complexity:* Logarithmic.
10791
 
10792
  ``` cpp
10793
- template<class K> mapped_type& at(const K& x);
10794
- template<class K> const mapped_type& at(const K& x) const;
10795
  ```
10796
 
10797
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
10798
  denotes a type.
10799
 
@@ -10809,11 +12385,11 @@ is present.
10809
  *Complexity:* Logarithmic.
10810
 
10811
  #### Modifiers <a id="flat.map.modifiers">[[flat.map.modifiers]]</a>
10812
 
10813
  ``` cpp
10814
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
10815
  ```
10816
 
10817
  *Constraints:*
10818
  `is_constructible_v<pair<key_type, mapped_type>, Args...>` is `true`.
10819
 
@@ -10832,12 +12408,12 @@ c.values.insert(value_it, std::move(t.second));
10832
  *Returns:* The `bool` component of the returned pair is `true` if and
10833
  only if the insertion took place, and the iterator component of the pair
10834
  points to the element with key equivalent to `t.first`.
10835
 
10836
  ``` cpp
10837
- template<class P> pair<iterator, bool> insert(P&& x);
10838
- template<class P> iterator insert(const_iterator position, P&& x);
10839
  ```
10840
 
10841
  *Constraints:* `is_constructible_v<pair<key_type, mapped_type>, P>` is
10842
  `true`.
10843
 
@@ -10845,14 +12421,14 @@ template<class P> iterator insert(const_iterator position, P&& x);
10845
  `return emplace(std::forward<P>(x));`. The second form is equivalent to
10846
  `return emplace_hint(position, std::forward<P>(x));`.
10847
 
10848
  ``` cpp
10849
  template<class InputIterator>
10850
- void insert(InputIterator first, InputIterator last);
10851
  ```
10852
 
10853
- *Effects:* Adds elements to `c` as if by:
10854
 
10855
  ``` cpp
10856
  for (; first != last; ++first) {
10857
  value_type value = *first;
10858
  c.keys.insert(c.keys.end(), std::move(value.first));
@@ -10864,12 +12440,12 @@ Then, sorts the range of newly inserted elements with respect to
10864
  `value_comp()`; merges the resulting sorted range and the sorted range
10865
  of pre-existing elements into a single sorted range; and finally erases
10866
  the duplicate elements as if by:
10867
 
10868
  ``` cpp
10869
- auto zv = ranges::zip_view(c.keys, c.values);
10870
- auto it = ranges::unique(zv, key_equiv(compare)).begin();
10871
  auto dist = distance(zv.begin(), it);
10872
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
10873
  c.values.erase(c.values.begin() + dist, c.values.end());
10874
  ```
10875
 
@@ -10879,46 +12455,23 @@ M is `distance(first, last)`.
10879
  *Remarks:* Since this operation performs an in-place merge, it may
10880
  allocate memory.
10881
 
10882
  ``` cpp
10883
  template<class InputIterator>
10884
- void insert(sorted_unique_t, InputIterator first, InputIterator last);
10885
  ```
10886
 
10887
- *Effects:* Adds elements to `c` as if by:
10888
-
10889
- ``` cpp
10890
- for (; first != last; ++first) {
10891
- value_type value = *first;
10892
- c.keys.insert(c.keys.end(), std::move(value.first));
10893
- c.values.insert(c.values.end(), std::move(value.second));
10894
- }
10895
- ```
10896
-
10897
- Then, merges the sorted range of newly added elements and the sorted
10898
- range of pre-existing elements into a single sorted range; and finally
10899
- erases the duplicate elements as if by:
10900
-
10901
- ``` cpp
10902
- auto zv = ranges::zip_view(c.keys, c.values);
10903
- auto it = ranges::unique(zv, key_equiv(compare)).begin();
10904
- auto dist = distance(zv.begin(), it);
10905
- c.keys.erase(c.keys.begin() + dist, c.keys.end());
10906
- c.values.erase(c.values.begin() + dist, c.values.end());
10907
- ```
10908
 
10909
  *Complexity:* Linear in N, where N is `size()` after the operation.
10910
 
10911
- *Remarks:* Since this operation performs an in-place merge, it may
10912
- allocate memory.
10913
-
10914
  ``` cpp
10915
  template<container-compatible-range<value_type> R>
10916
- void insert_range(R&& rg);
10917
  ```
10918
 
10919
- *Effects:* Adds elements to `c` as if by:
10920
 
10921
  ``` cpp
10922
  for (const auto& e : rg) {
10923
  c.keys.insert(c.keys.end(), e.first);
10924
  c.values.insert(c.values.end(), e.second);
@@ -10929,12 +12482,12 @@ Then, sorts the range of newly inserted elements with respect to
10929
  `value_comp()`; merges the resulting sorted range and the sorted range
10930
  of pre-existing elements into a single sorted range; and finally erases
10931
  the duplicate elements as if by:
10932
 
10933
  ``` cpp
10934
- auto zv = ranges::zip_view(c.keys, c.values);
10935
- auto it = ranges::unique(zv, key_equiv(compare)).begin();
10936
  auto dist = distance(zv.begin(), it);
10937
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
10938
  c.values.erase(c.values.begin() + dist, c.values.end());
10939
  ```
10940
 
@@ -10944,17 +12497,17 @@ M is `ranges::distance(rg)`.
10944
  *Remarks:* Since this operation performs an in-place merge, it may
10945
  allocate memory.
10946
 
10947
  ``` cpp
10948
  template<class... Args>
10949
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
10950
  template<class... Args>
10951
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
10952
  template<class... Args>
10953
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
10954
  template<class... Args>
10955
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
10956
  ```
10957
 
10958
  *Constraints:* `is_constructible_v<mapped_type, Args...>` is `true`.
10959
 
10960
  *Effects:* If the map already contains an element whose key is
@@ -10976,13 +12529,13 @@ returned iterator points to the map element whose key is equivalent to
10976
  *Complexity:* The same as `emplace` for the first two overloads, and the
10977
  same as `emplace_hint` for the last two overloads.
10978
 
10979
  ``` cpp
10980
  template<class K, class... Args>
10981
- pair<iterator, bool> try_emplace(K&& k, Args&&... args);
10982
  template<class K, class... Args>
10983
- iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
10984
  ```
10985
 
10986
  *Constraints:*
10987
 
10988
  - The *qualified-id* `Compare::is_transparent` is valid and denotes a
@@ -10998,11 +12551,11 @@ object `u`, for which `find(k) == find(u)` is `true`.
10998
  *Effects:* If the map already contains an element whose key is
10999
  equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
11000
  equivalent to:
11001
 
11002
  ``` cpp
11003
- auto key_it = ranges::upper_bound(c.keys, k, compare);
11004
  auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
11005
  c.keys.emplace(key_it, std::forward<K>(k));
11006
  c.values.emplace(value_it, std::forward<Args>(args)...);
11007
  ```
11008
 
@@ -11012,17 +12565,17 @@ iterator points to the map element whose key is equivalent to `k`.
11012
 
11013
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
11014
 
11015
  ``` cpp
11016
  template<class M>
11017
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
11018
  template<class M>
11019
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
11020
  template<class M>
11021
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
11022
  template<class M>
11023
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
11024
  ```
11025
 
11026
  *Constraints:* `is_assignable_v<mapped_type&, M>` is `true` and
11027
  `is_constructible_v<mapped_type, M>` is `true`.
11028
 
@@ -11050,13 +12603,13 @@ returned iterator points to the map element whose key is equivalent to
11050
  *Complexity:* The same as `emplace` for the first two overloads and the
11051
  same as `emplace_hint` for the last two overloads.
11052
 
11053
  ``` cpp
11054
  template<class K, class M>
11055
- pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
11056
  template<class K, class M>
11057
- iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
11058
  ```
11059
 
11060
  *Constraints:*
11061
 
11062
  - The *qualified-id* `Compare::is_transparent` is valid and denotes a
@@ -11089,11 +12642,11 @@ pair is `true` if and only if the insertion took place. The returned
11089
  iterator points to the map element whose key is equivalent to `k`.
11090
 
11091
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
11092
 
11093
  ``` cpp
11094
- void swap(flat_map& y) noexcept;
11095
  ```
11096
 
11097
  *Effects:* Equivalent to:
11098
 
11099
  ``` cpp
@@ -11101,24 +12654,24 @@ ranges::swap(compare, y.compare);
11101
  ranges::swap(c.keys, y.c.keys);
11102
  ranges::swap(c.values, y.c.values);
11103
  ```
11104
 
11105
  ``` cpp
11106
- containers extract() &&;
11107
  ```
11108
 
11109
  *Ensures:* `*this` is emptied, even if the function exits via an
11110
  exception.
11111
 
11112
- *Returns:* `std::move(c)`.
11113
 
11114
  ``` cpp
11115
- void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
11116
  ```
11117
 
11118
  *Preconditions:* `key_cont.size() == mapped_cont.size()` is `true`, the
11119
- elements of `key_cont` are sorted with respect to `compare`, and
11120
  `key_cont` contains no equal elements.
11121
 
11122
  *Effects:* Equivalent to:
11123
 
11124
  ``` cpp
@@ -11129,11 +12682,11 @@ c.values = std::move(mapped_cont);
11129
  #### Erasure <a id="flat.map.erasure">[[flat.map.erasure]]</a>
11130
 
11131
  ``` cpp
11132
  template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11133
  class Predicate>
11134
- typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11135
  erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11136
  ```
11137
 
11138
  *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
11139
  requirements.
@@ -11223,14 +12776,17 @@ The program is ill-formed if `Key` is not the same type as
11223
 
11224
  The effect of calling a constructor that takes both `key_container_type`
11225
  and `mapped_container_type` arguments with containers of different sizes
11226
  is undefined.
11227
 
11228
- The effect of calling a constructor or member function that takes a
11229
  `sorted_equivalent_t` argument with a container, containers, or range
11230
  that are not sorted with respect to `key_comp()` is undefined.
11231
 
 
 
 
11232
  #### Definition <a id="flat.multimap.defn">[[flat.multimap.defn]]</a>
11233
 
11234
  ``` cpp
11235
  namespace std {
11236
  template<class Key, class T, class Compare = less<Key>,
@@ -11254,209 +12810,219 @@ namespace std {
11254
  using mapped_container_type = MappedContainer;
11255
 
11256
  class value_compare {
11257
  private:
11258
  key_compare comp; // exposition only
11259
- value_compare(key_compare c) : comp(c) { } // exposition only
11260
 
11261
  public:
11262
- bool operator()(const_reference x, const_reference y) const {
11263
  return comp(x.first, y.first);
11264
  }
11265
  };
11266
 
11267
  struct containers {
11268
  key_container_type keys;
11269
  mapped_container_type values;
11270
  };
11271
 
11272
- // [flat.multimap.cons], construct/copy/destroy
11273
- flat_multimap() : flat_multimap(key_compare()) { }
11274
 
11275
- flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
 
 
 
11276
  const key_compare& comp = key_compare());
11277
- template<class Allocator>
11278
- flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11279
- const Allocator& a);
11280
- template<class Allocator>
11281
- flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11282
- const key_compare& comp, const Allocator& a);
11283
 
11284
- flat_multimap(sorted_equivalent_t,
11285
  key_container_type key_cont, mapped_container_type mapped_cont,
11286
  const key_compare& comp = key_compare());
11287
- template<class Allocator>
11288
- flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
11289
- const mapped_container_type& mapped_cont, const Allocator& a);
11290
- template<class Allocator>
11291
- flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
11292
- const mapped_container_type& mapped_cont,
11293
- const key_compare& comp, const Allocator& a);
11294
-
11295
- explicit flat_multimap(const key_compare& comp)
11296
- : c(), compare(comp) { }
11297
- template<class Allocator>
11298
- flat_multimap(const key_compare& comp, const Allocator& a);
11299
- template<class Allocator>
11300
- explicit flat_multimap(const Allocator& a);
11301
 
11302
  template<class InputIterator>
11303
- flat_multimap(InputIterator first, InputIterator last,
11304
  const key_compare& comp = key_compare())
11305
  : c(), compare(comp)
11306
  { insert(first, last); }
11307
- template<class InputIterator, class Allocator>
11308
- flat_multimap(InputIterator first, InputIterator last,
11309
- const key_compare& comp, const Allocator& a);
11310
- template<class InputIterator, class Allocator>
11311
- flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
11312
 
11313
  template<container-compatible-range<value_type> R>
11314
- flat_multimap(from_range_t fr, R&& rg)
11315
- : flat_multimap(fr, std::forward<R>(rg), key_compare()) { }
11316
- template<container-compatible-range<value_type> R, class Allocator>
11317
- flat_multimap(from_range_t, R&& rg, const Allocator& a);
11318
  template<container-compatible-range<value_type> R>
11319
- flat_multimap(from_range_t, R&& rg, const key_compare& comp)
11320
  : flat_multimap(comp) { insert_range(std::forward<R>(rg)); }
11321
- template<container-compatible-range<value_type> R, class Allocator>
11322
- flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11323
 
11324
- template<class InputIterator>
11325
- flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last,
11326
  const key_compare& comp = key_compare())
11327
- : c(), compare(comp) { insert(s, first, last); }
11328
- template<class InputIterator, class Allocator>
11329
- flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11330
- const key_compare& comp, const Allocator& a);
11331
- template<class InputIterator, class Allocator>
11332
- flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11333
- const Allocator& a);
11334
-
11335
- flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare())
11336
  : flat_multimap(il.begin(), il.end(), comp) { }
11337
- template<class Allocator>
11338
- flat_multimap(initializer_list<value_type> il, const key_compare& comp,
11339
- const Allocator& a);
11340
- template<class Allocator>
11341
- flat_multimap(initializer_list<value_type> il, const Allocator& a);
11342
 
11343
- flat_multimap(sorted_equivalent_t s, initializer_list<value_type> il,
11344
  const key_compare& comp = key_compare())
11345
- : flat_multimap(s, il.begin(), il.end(), comp) { }
11346
- template<class Allocator>
11347
- flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
11348
- const key_compare& comp, const Allocator& a);
11349
- template<class Allocator>
11350
- flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
11351
 
11352
- flat_multimap& operator=(initializer_list<value_type> il);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11353
 
11354
  // iterators
11355
- iterator begin() noexcept;
11356
- const_iterator begin() const noexcept;
11357
- iterator end() noexcept;
11358
- const_iterator end() const noexcept;
11359
 
11360
- reverse_iterator rbegin() noexcept;
11361
- const_reverse_iterator rbegin() const noexcept;
11362
- reverse_iterator rend() noexcept;
11363
- const_reverse_iterator rend() const noexcept;
11364
 
11365
- const_iterator cbegin() const noexcept;
11366
- const_iterator cend() const noexcept;
11367
- const_reverse_iterator crbegin() const noexcept;
11368
- const_reverse_iterator crend() const noexcept;
11369
 
11370
  // capacity
11371
- [[nodiscard]] bool empty() const noexcept;
11372
- size_type size() const noexcept;
11373
- size_type max_size() const noexcept;
11374
 
11375
  // modifiers
11376
- template<class... Args> iterator emplace(Args&&... args);
11377
  template<class... Args>
11378
- iterator emplace_hint(const_iterator position, Args&&... args);
11379
 
11380
- iterator insert(const value_type& x)
11381
  { return emplace(x); }
11382
- iterator insert(value_type&& x)
11383
  { return emplace(std::move(x)); }
11384
- iterator insert(const_iterator position, const value_type& x)
11385
  { return emplace_hint(position, x); }
11386
- iterator insert(const_iterator position, value_type&& x)
11387
  { return emplace_hint(position, std::move(x)); }
11388
 
11389
- template<class P> iterator insert(P&& x);
11390
  template<class P>
11391
- iterator insert(const_iterator position, P&&);
11392
  template<class InputIterator>
11393
- void insert(InputIterator first, InputIterator last);
11394
  template<class InputIterator>
11395
- void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
11396
  template<container-compatible-range<value_type> R>
11397
- void insert_range(R&& rg);
11398
 
11399
- void insert(initializer_list<value_type> il)
11400
  { insert(il.begin(), il.end()); }
11401
- void insert(sorted_equivalent_t s, initializer_list<value_type> il)
11402
- { insert(s, il.begin(), il.end()); }
11403
 
11404
- containers extract() &&;
11405
- void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
11406
 
11407
- iterator erase(iterator position);
11408
- iterator erase(const_iterator position);
11409
- size_type erase(const key_type& x);
11410
- template<class K> size_type erase(K&& x);
11411
- iterator erase(const_iterator first, const_iterator last);
11412
 
11413
- void swap(flat_multimap&) noexcept;
11414
- void clear() noexcept;
11415
 
11416
  // observers
11417
- key_compare key_comp() const;
11418
- value_compare value_comp() const;
11419
 
11420
- const key_container_type& keys() const noexcept { return c.keys; }
11421
- const mapped_container_type& values() const noexcept { return c.values; }
11422
 
11423
  // map operations
11424
- iterator find(const key_type& x);
11425
- const_iterator find(const key_type& x) const;
11426
- template<class K> iterator find(const K& x);
11427
- template<class K> const_iterator find(const K& x) const;
11428
 
11429
- size_type count(const key_type& x) const;
11430
- template<class K> size_type count(const K& x) const;
11431
 
11432
- bool contains(const key_type& x) const;
11433
- template<class K> bool contains(const K& x) const;
11434
 
11435
- iterator lower_bound(const key_type& x);
11436
- const_iterator lower_bound(const key_type& x) const;
11437
- template<class K> iterator lower_bound(const K& x);
11438
- template<class K> const_iterator lower_bound(const K& x) const;
11439
 
11440
- iterator upper_bound(const key_type& x);
11441
- const_iterator upper_bound(const key_type& x) const;
11442
- template<class K> iterator upper_bound(const K& x);
11443
- template<class K> const_iterator upper_bound(const K& x) const;
11444
 
11445
- pair<iterator, iterator> equal_range(const key_type& x);
11446
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
11447
  template<class K>
11448
- pair<iterator, iterator> equal_range(const K& x);
11449
  template<class K>
11450
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
11451
 
11452
- friend bool operator==(const flat_multimap& x, const flat_multimap& y);
11453
 
11454
- friend synth-three-way-result<value_type>
11455
  operator<=>(const flat_multimap& x, const flat_multimap& y);
11456
 
11457
- friend void swap(flat_multimap& x, flat_multimap& y) noexcept
11458
  { x.swap(y); }
11459
 
11460
  private:
11461
  containers c; // exposition only
11462
  key_compare compare; // exposition only
@@ -11539,119 +13105,122 @@ specified above. It has no base classes or members other than those
11539
  specified.
11540
 
11541
  #### Constructors <a id="flat.multimap.cons">[[flat.multimap.cons]]</a>
11542
 
11543
  ``` cpp
11544
- flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
11545
  const key_compare& comp = key_compare());
11546
  ```
11547
 
11548
- *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
11549
- with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
11550
- range \[`begin()`, `end()`) with respect to `value_comp()`.
11551
 
11552
  *Complexity:* Linear in N if the container arguments are already sorted
11553
  with respect to `value_comp()` and otherwise N log N, where N is the
11554
  value of `key_cont.size()` before this call.
11555
 
11556
  ``` cpp
11557
- template<class Allocator>
11558
- flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11559
- const Allocator& a);
11560
- template<class Allocator>
11561
- flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
11562
- const key_compare& comp, const Allocator& a);
11563
  ```
11564
 
11565
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11566
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11567
- `true`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11568
 
11569
  *Effects:* Equivalent to `flat_multimap(key_cont, mapped_cont)` and
11570
  `flat_multimap(key_cont, mapped_cont, comp)`, respectively, except that
11571
- `c.keys` and `c.values` are constructed with uses-allocator
11572
  construction [[allocator.uses.construction]].
11573
 
11574
  *Complexity:* Same as `flat_multimap(key_cont, mapped_cont)` and
11575
  `flat_multimap(key_cont, mapped_cont, comp)`, respectively.
11576
 
11577
  ``` cpp
11578
- flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont,
11579
- const key_compare& comp = key_compare());
11580
- ```
11581
-
11582
- *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
11583
- with `std::move(mapped_cont)`, and `compare` with `comp`.
11584
-
11585
- *Complexity:* Constant.
11586
-
11587
- ``` cpp
11588
- template<class Allocator>
11589
- flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
11590
- const mapped_container_type& mapped_cont, const Allocator& a);
11591
- template<class Allocator>
11592
- flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
11593
  const mapped_container_type& mapped_cont, const key_compare& comp,
11594
- const Allocator& a);
11595
  ```
11596
 
11597
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11598
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11599
- `true`.
11600
-
11601
- *Effects:* Equivalent to `flat_multimap(s, key_cont, mapped_cont)` and
11602
- `flat_multimap(s, key_cont, mapped_cont, comp)`, respectively, except
11603
- that `c.keys` and `c.values` are constructed with uses-allocator
11604
  construction [[allocator.uses.construction]].
11605
 
11606
  *Complexity:* Linear.
11607
 
11608
  ``` cpp
11609
- template<class Allocator>
11610
- flat_multimap(const key_compare& comp, const Allocator& a);
11611
- template<class Allocator>
11612
- explicit flat_multimap(const Allocator& a);
11613
- template<class InputIterator, class Allocator>
11614
- flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
11615
- const Allocator& a);
11616
- template<class InputIterator, class Allocator>
11617
- flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
11618
- template<container-compatible-range<value_type> R, class Allocator>
11619
- flat_multimap(from_range_t, R&& rg, const Allocator& a);
11620
- template<container-compatible-range<value_type> R, class Allocator>
11621
- flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11622
- template<class InputIterator, class Allocator>
11623
- flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11624
- const key_compare& comp, const Allocator& a);
11625
- template<class InputIterator, class Allocator>
11626
- flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
11627
- const Allocator& a);
11628
- template<class Allocator>
11629
- flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
11630
- template<class Allocator>
11631
- flat_multimap(initializer_list<value_type> il, const Allocator& a);
11632
- template<class Allocator>
11633
- flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
11634
- const key_compare& comp, const Allocator& a);
11635
- template<class Allocator>
11636
- flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
 
 
 
 
 
11637
  ```
11638
 
11639
- *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
11640
- `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
11641
- `true`.
11642
-
11643
  *Effects:* Equivalent to the corresponding non-allocator constructors
11644
- except that `c.keys` and `c.values` are constructed with uses-allocator
11645
- construction [[allocator.uses.construction]].
11646
 
11647
  #### Erasure <a id="flat.multimap.erasure">[[flat.multimap.erasure]]</a>
11648
 
11649
  ``` cpp
11650
  template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11651
  class Predicate>
11652
- typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11653
  erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11654
  ```
11655
 
11656
  *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
11657
  requirements.
@@ -11668,10 +13237,49 @@ exits via an exception, `c` is in a valid but unspecified
11668
  state [[defns.valid]].
11669
 
11670
  [*Note 1*: `c` still meets its invariants, but can be
11671
  empty. — *end note*]
11672
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11673
  ### Class template `flat_set` <a id="flat.set">[[flat.set]]</a>
11674
 
11675
  #### Overview <a id="flat.set.overview">[[flat.set.overview]]</a>
11676
 
11677
  A `flat_set` is a container adaptor that provides an associative
@@ -11724,13 +13332,16 @@ particular, `vector` [[vector]] and `deque` [[deque]] can be used.
11724
  [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
11725
 
11726
  The program is ill-formed if `Key` is not the same type as
11727
  `KeyContainer::value_type`.
11728
 
11729
- The effect of calling a constructor or member function that takes a
11730
- `sorted_unique_t` argument with a range that is not sorted with respect
11731
- to `key_comp()`, or that contains equal elements, is undefined.
 
 
 
11732
 
11733
  #### Definition <a id="flat.set.defn">[[flat.set.defn]]</a>
11734
 
11735
  ``` cpp
11736
  namespace std {
@@ -11742,192 +13353,203 @@ namespace std {
11742
  using value_type = Key;
11743
  using key_compare = Compare;
11744
  using value_compare = Compare;
11745
  using reference = value_type&;
11746
  using const_reference = const value_type&;
11747
- using size_type = typename KeyContainer::size_type;
11748
- using difference_type = typename KeyContainer::difference_type;
11749
  using iterator = implementation-defined // type of flat_set::iterator; // see [container.requirements]
11750
  using const_iterator = implementation-defined // type of flat_set::const_iterator; // see [container.requirements]
11751
  using reverse_iterator = std::reverse_iterator<iterator>;
11752
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
11753
  using container_type = KeyContainer;
11754
 
11755
  // [flat.set.cons], constructors
11756
- flat_set() : flat_set(key_compare()) { }
11757
 
11758
- explicit flat_set(container_type cont, const key_compare& comp = key_compare());
11759
- template<class Allocator>
11760
- flat_set(const container_type& cont, const Allocator& a);
11761
- template<class Allocator>
11762
- flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
11763
-
11764
- flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare())
11765
- : c(std::move(cont)), compare(comp) { }
11766
- template<class Allocator>
11767
- flat_set(sorted_unique_t, const container_type& cont, const Allocator& a);
11768
- template<class Allocator>
11769
- flat_set(sorted_unique_t, const container_type& cont,
11770
- const key_compare& comp, const Allocator& a);
11771
-
11772
- explicit flat_set(const key_compare& comp)
11773
  : c(), compare(comp) { }
11774
- template<class Allocator>
11775
- flat_set(const key_compare& comp, const Allocator& a);
11776
- template<class Allocator>
11777
- explicit flat_set(const Allocator& a);
 
 
11778
 
11779
  template<class InputIterator>
11780
- flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
 
11781
  : c(), compare(comp)
11782
  { insert(first, last); }
11783
- template<class InputIterator, class Allocator>
11784
- flat_set(InputIterator first, InputIterator last,
11785
- const key_compare& comp, const Allocator& a);
11786
- template<class InputIterator, class Allocator>
11787
- flat_set(InputIterator first, InputIterator last, const Allocator& a);
11788
 
11789
  template<container-compatible-range<value_type> R>
11790
- flat_set(from_range_t fr, R&& rg)
11791
- : flat_set(fr, std::forward<R>(rg), key_compare()) { }
11792
- template<container-compatible-range<value_type> R, class Allocator>
11793
- flat_set(from_range_t, R&& rg, const Allocator& a);
11794
  template<container-compatible-range<value_type> R>
11795
- flat_set(from_range_t, R&& rg, const key_compare& comp)
11796
  : flat_set(comp)
11797
  { insert_range(std::forward<R>(rg)); }
11798
- template<container-compatible-range<value_type> R, class Allocator>
11799
- flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
11800
 
11801
- template<class InputIterator>
11802
- flat_set(sorted_unique_t, InputIterator first, InputIterator last,
11803
- const key_compare& comp = key_compare())
11804
- : c(first, last), compare(comp) { }
11805
- template<class InputIterator, class Allocator>
11806
- flat_set(sorted_unique_t, InputIterator first, InputIterator last,
11807
- const key_compare& comp, const Allocator& a);
11808
- template<class InputIterator, class Allocator>
11809
- flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
11810
-
11811
- flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare())
11812
  : flat_set(il.begin(), il.end(), comp) { }
11813
- template<class Allocator>
11814
- flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
11815
- template<class Allocator>
11816
- flat_set(initializer_list<value_type> il, const Allocator& a);
11817
 
11818
- flat_set(sorted_unique_t s, initializer_list<value_type> il,
11819
  const key_compare& comp = key_compare())
11820
- : flat_set(s, il.begin(), il.end(), comp) { }
11821
- template<class Allocator>
11822
- flat_set(sorted_unique_t, initializer_list<value_type> il,
11823
- const key_compare& comp, const Allocator& a);
11824
- template<class Allocator>
11825
- flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
11826
 
11827
- flat_set& operator=(initializer_list<value_type>);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11828
 
11829
  // iterators
11830
- iterator begin() noexcept;
11831
- const_iterator begin() const noexcept;
11832
- iterator end() noexcept;
11833
- const_iterator end() const noexcept;
11834
 
11835
- reverse_iterator rbegin() noexcept;
11836
- const_reverse_iterator rbegin() const noexcept;
11837
- reverse_iterator rend() noexcept;
11838
- const_reverse_iterator rend() const noexcept;
11839
 
11840
- const_iterator cbegin() const noexcept;
11841
- const_iterator cend() const noexcept;
11842
- const_reverse_iterator crbegin() const noexcept;
11843
- const_reverse_iterator crend() const noexcept;
11844
 
11845
  // capacity
11846
- [[nodiscard]] bool empty() const noexcept;
11847
- size_type size() const noexcept;
11848
- size_type max_size() const noexcept;
11849
 
11850
  // [flat.set.modifiers], modifiers
11851
- template<class... Args> pair<iterator, bool> emplace(Args&&... args);
11852
  template<class... Args>
11853
- iterator emplace_hint(const_iterator position, Args&&... args);
11854
 
11855
- pair<iterator, bool> insert(const value_type& x)
11856
  { return emplace(x); }
11857
- pair<iterator, bool> insert(value_type&& x)
11858
  { return emplace(std::move(x)); }
11859
- template<class K> pair<iterator, bool> insert(K&& x);
11860
- iterator insert(const_iterator position, const value_type& x)
11861
  { return emplace_hint(position, x); }
11862
- iterator insert(const_iterator position, value_type&& x)
11863
  { return emplace_hint(position, std::move(x)); }
11864
- template<class K> iterator insert(const_iterator hint, K&& x);
11865
 
11866
  template<class InputIterator>
11867
- void insert(InputIterator first, InputIterator last);
11868
  template<class InputIterator>
11869
- void insert(sorted_unique_t, InputIterator first, InputIterator last);
11870
  template<container-compatible-range<value_type> R>
11871
- void insert_range(R&& rg);
11872
 
11873
- void insert(initializer_list<value_type> il)
11874
  { insert(il.begin(), il.end()); }
11875
- void insert(sorted_unique_t s, initializer_list<value_type> il)
11876
- { insert(s, il.begin(), il.end()); }
11877
 
11878
- container_type extract() &&;
11879
- void replace(container_type&&);
11880
 
11881
- iterator erase(iterator position);
11882
- iterator erase(const_iterator position);
11883
- size_type erase(const key_type& x);
11884
- template<class K> size_type erase(K&& x);
11885
- iterator erase(const_iterator first, const_iterator last);
11886
 
11887
- void swap(flat_set& y) noexcept;
11888
- void clear() noexcept;
11889
 
11890
  // observers
11891
- key_compare key_comp() const;
11892
- value_compare value_comp() const;
11893
 
11894
  // set operations
11895
- iterator find(const key_type& x);
11896
- const_iterator find(const key_type& x) const;
11897
- template<class K> iterator find(const K& x);
11898
- template<class K> const_iterator find(const K& x) const;
11899
 
11900
- size_type count(const key_type& x) const;
11901
- template<class K> size_type count(const K& x) const;
11902
 
11903
- bool contains(const key_type& x) const;
11904
- template<class K> bool contains(const K& x) const;
11905
 
11906
- iterator lower_bound(const key_type& x);
11907
- const_iterator lower_bound(const key_type& x) const;
11908
- template<class K> iterator lower_bound(const K& x);
11909
- template<class K> const_iterator lower_bound(const K& x) const;
11910
 
11911
- iterator upper_bound(const key_type& x);
11912
- const_iterator upper_bound(const key_type& x) const;
11913
- template<class K> iterator upper_bound(const K& x);
11914
- template<class K> const_iterator upper_bound(const K& x) const;
11915
 
11916
- pair<iterator, iterator> equal_range(const key_type& x);
11917
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
11918
  template<class K>
11919
- pair<iterator, iterator> equal_range(const K& x);
11920
  template<class K>
11921
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
11922
 
11923
- friend bool operator==(const flat_set& x, const flat_set& y);
11924
 
11925
- friend synth-three-way-result<value_type>
11926
  operator<=>(const flat_set& x, const flat_set& y);
11927
 
11928
- friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); }
11929
 
11930
  private:
11931
  container_type c; // exposition only
11932
  key_compare compare; // exposition only
11933
  };
@@ -11990,101 +13612,106 @@ namespace std {
11990
  ```
11991
 
11992
  #### Constructors <a id="flat.set.cons">[[flat.set.cons]]</a>
11993
 
11994
  ``` cpp
11995
- explicit flat_set(container_type cont, const key_compare& comp = key_compare());
11996
  ```
11997
 
11998
  *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
11999
  `comp`, sorts the range \[`begin()`, `end()`) with respect to *compare*,
12000
  and finally erases all but the first element from each group of
12001
  consecutive equivalent elements.
12002
 
12003
- *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
12004
- and otherwise N log N, where N is the value of `cont.size()` before this
12005
- call.
 
 
 
 
 
12006
 
12007
  ``` cpp
12008
- template<class Allocator>
12009
- flat_set(const container_type& cont, const Allocator& a);
12010
- template<class Allocator>
12011
- flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
12012
  ```
12013
 
12014
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12015
-
12016
  *Effects:* Equivalent to `flat_set(cont)` and `flat_set(cont, comp)`,
12017
  respectively, except that *c* is constructed with uses-allocator
12018
  construction [[allocator.uses.construction]].
12019
 
12020
  *Complexity:* Same as `flat_set(cont)` and `flat_set(cont, comp)`,
12021
  respectively.
12022
 
12023
  ``` cpp
12024
- template<class Allocator>
12025
- flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a);
12026
- template<class Allocator>
12027
- flat_set(sorted_unique_t s, const container_type& cont,
12028
- const key_compare& comp, const Allocator& a);
12029
  ```
12030
 
12031
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12032
-
12033
- *Effects:* Equivalent to `flat_set(s, cont)` and
12034
- `flat_set(s, cont, comp)`, respectively, except that *c* is constructed
12035
- with uses-allocator construction [[allocator.uses.construction]].
12036
 
12037
  *Complexity:* Linear.
12038
 
12039
  ``` cpp
12040
- template<class Allocator>
12041
- flat_set(const key_compare& comp, const Allocator& a);
12042
- template<class Allocator>
12043
- explicit flat_set(const Allocator& a);
12044
- template<class InputIterator, class Allocator>
12045
- flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
12046
- template<class InputIterator, class Allocator>
12047
- flat_set(InputIterator first, InputIterator last, const Allocator& a);
12048
- template<container-compatible-range<value_type> R, class Allocator>
12049
- flat_set(from_range_t, R&& rg, const Allocator& a);
12050
- template<container-compatible-range<value_type> R, class Allocator>
12051
- flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12052
- template<class InputIterator, class Allocator>
12053
- flat_set(sorted_unique_t, InputIterator first, InputIterator last,
12054
- const key_compare& comp, const Allocator& a);
12055
- template<class InputIterator, class Allocator>
12056
- flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
12057
- template<class Allocator>
12058
- flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
12059
- template<class Allocator>
12060
- flat_set(initializer_list<value_type> il, const Allocator& a);
12061
- template<class Allocator>
12062
- flat_set(sorted_unique_t, initializer_list<value_type> il,
12063
- const key_compare& comp, const Allocator& a);
12064
- template<class Allocator>
12065
- flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
 
 
 
 
 
12066
  ```
12067
 
12068
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12069
-
12070
  *Effects:* Equivalent to the corresponding non-allocator constructors
12071
  except that *c* is constructed with uses-allocator
12072
  construction [[allocator.uses.construction]].
12073
 
12074
  #### Modifiers <a id="flat.set.modifiers">[[flat.set.modifiers]]</a>
12075
 
12076
  ``` cpp
12077
- template<class K> pair<iterator, bool> insert(K&& x);
12078
- template<class K> iterator insert(const_iterator hint, K&& x);
12079
  ```
12080
 
12081
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
12082
  denotes a type. `is_constructible_v<value_type, K>` is `true`.
12083
 
12084
  *Preconditions:* The conversion from `x` into `value_type` constructs an
12085
- object `u`, for which `find(x) == find(u)` is true.
12086
 
12087
  *Effects:* If the set already contains an element equivalent to `x`,
12088
  `*this` and `x` are unchanged. Otherwise, inserts a new element as if by
12089
  `emplace(std::forward<K>(x))`.
12090
 
@@ -12092,11 +13719,11 @@ object `u`, for which `find(x) == find(u)` is true.
12092
  pair is `true` if and only if the insertion took place. The returned
12093
  iterator points to the element whose key is equivalent to `x`.
12094
 
12095
  ``` cpp
12096
  template<class InputIterator>
12097
- void insert(InputIterator first, InputIterator last);
12098
  ```
12099
 
12100
  *Effects:* Adds elements to *c* as if by:
12101
 
12102
  ``` cpp
@@ -12115,20 +13742,20 @@ M is `distance(first, last)`.
12115
  *Remarks:* Since this operation performs an in-place merge, it may
12116
  allocate memory.
12117
 
12118
  ``` cpp
12119
  template<class InputIterator>
12120
- void insert(sorted_unique_t, InputIterator first, InputIterator last);
12121
  ```
12122
 
12123
  *Effects:* Equivalent to `insert(first, last)`.
12124
 
12125
  *Complexity:* Linear.
12126
 
12127
  ``` cpp
12128
  template<container-compatible-range<value_type> R>
12129
- void insert_range(R&& rg);
12130
  ```
12131
 
12132
  *Effects:* Adds elements to *c* as if by:
12133
 
12134
  ``` cpp
@@ -12148,31 +13775,31 @@ M is `ranges::distance(rg)`.
12148
 
12149
  *Remarks:* Since this operation performs an in-place merge, it may
12150
  allocate memory.
12151
 
12152
  ``` cpp
12153
- void swap(flat_set& y) noexcept;
12154
  ```
12155
 
12156
  *Effects:* Equivalent to:
12157
 
12158
  ``` cpp
12159
  ranges::swap(compare, y.compare);
12160
  ranges::swap(c, y.c);
12161
  ```
12162
 
12163
  ``` cpp
12164
- container_type extract() &&;
12165
  ```
12166
 
12167
  *Ensures:* `*this` is emptied, even if the function exits via an
12168
  exception.
12169
 
12170
  *Returns:* `std::move(`*`c`*`)`.
12171
 
12172
  ``` cpp
12173
- void replace(container_type&& cont);
12174
  ```
12175
 
12176
  *Preconditions:* The elements of `cont` are sorted with respect to
12177
  *compare*, and `cont` contains no equal elements.
12178
 
@@ -12180,11 +13807,11 @@ void replace(container_type&& cont);
12180
 
12181
  #### Erasure <a id="flat.set.erasure">[[flat.set.erasure]]</a>
12182
 
12183
  ``` cpp
12184
  template<class Key, class Compare, class KeyContainer, class Predicate>
12185
- typename flat_set<Key, Compare, KeyContainer>::size_type
12186
  erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
12187
  ```
12188
 
12189
  *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
12190
 
@@ -12257,14 +13884,17 @@ In particular, `vector` [[vector]] and `deque` [[deque]] can be used.
12257
  [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
12258
 
12259
  The program is ill-formed if `Key` is not the same type as
12260
  `KeyContainer::value_type`.
12261
 
12262
- The effect of calling a constructor or member function that takes a
12263
  `sorted_equivalent_t` argument with a range that is not sorted with
12264
  respect to `key_comp()` is undefined.
12265
 
 
 
 
12266
  #### Definition <a id="flat.multiset.defn">[[flat.multiset.defn]]</a>
12267
 
12268
  ``` cpp
12269
  namespace std {
12270
  template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
@@ -12275,194 +13905,205 @@ namespace std {
12275
  using value_type = Key;
12276
  using key_compare = Compare;
12277
  using value_compare = Compare;
12278
  using reference = value_type&;
12279
  using const_reference = const value_type&;
12280
- using size_type = typename KeyContainer::size_type;
12281
- using difference_type = typename KeyContainer::difference_type;
12282
  using iterator = implementation-defined // type of flat_multiset::iterator; // see [container.requirements]
12283
  using const_iterator = implementation-defined // type of flat_multiset::const_iterator; // see [container.requirements]
12284
  using reverse_iterator = std::reverse_iterator<iterator>;
12285
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
12286
  using container_type = KeyContainer;
12287
 
12288
  // [flat.multiset.cons], constructors
12289
- flat_multiset() : flat_multiset(key_compare()) { }
12290
 
12291
- explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
12292
- template<class Allocator>
12293
- flat_multiset(const container_type& cont, const Allocator& a);
12294
- template<class Allocator>
12295
- flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
12296
-
12297
- flat_multiset(sorted_equivalent_t, container_type cont,
12298
- const key_compare& comp = key_compare())
12299
- : c(std::move(cont)), compare(comp) { }
12300
- template<class Allocator>
12301
- flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a);
12302
- template<class Allocator>
12303
- flat_multiset(sorted_equivalent_t, const container_type& cont,
12304
- const key_compare& comp, const Allocator& a);
12305
-
12306
- explicit flat_multiset(const key_compare& comp)
12307
  : c(), compare(comp) { }
12308
- template<class Allocator>
12309
- flat_multiset(const key_compare& comp, const Allocator& a);
12310
- template<class Allocator>
12311
- explicit flat_multiset(const Allocator& a);
 
 
 
12312
 
12313
  template<class InputIterator>
12314
- flat_multiset(InputIterator first, InputIterator last,
12315
  const key_compare& comp = key_compare())
12316
  : c(), compare(comp)
12317
  { insert(first, last); }
12318
- template<class InputIterator, class Allocator>
12319
- flat_multiset(InputIterator first, InputIterator last,
12320
- const key_compare& comp, const Allocator& a);
12321
- template<class InputIterator, class Allocator>
12322
- flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
12323
 
12324
  template<container-compatible-range<value_type> R>
12325
- flat_multiset(from_range_t fr, R&& rg)
12326
- : flat_multiset(fr, std::forward<R>(rg), key_compare()) { }
12327
- template<container-compatible-range<value_type> R, class Allocator>
12328
- flat_multiset(from_range_t, R&& rg, const Allocator& a);
12329
  template<container-compatible-range<value_type> R>
12330
- flat_multiset(from_range_t, R&& rg, const key_compare& comp)
12331
  : flat_multiset(comp)
12332
  { insert_range(std::forward<R>(rg)); }
12333
- template<container-compatible-range<value_type> R, class Allocator>
12334
- flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12335
 
12336
- template<class InputIterator>
12337
- flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12338
  const key_compare& comp = key_compare())
12339
- : c(first, last), compare(comp) { }
12340
- template<class InputIterator, class Allocator>
12341
- flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12342
- const key_compare& comp, const Allocator& a);
12343
- template<class InputIterator, class Allocator>
12344
- flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12345
- const Allocator& a);
12346
-
12347
- flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare())
12348
  : flat_multiset(il.begin(), il.end(), comp) { }
12349
- template<class Allocator>
12350
- flat_multiset(initializer_list<value_type> il, const key_compare& comp,
12351
- const Allocator& a);
12352
- template<class Allocator>
12353
- flat_multiset(initializer_list<value_type> il, const Allocator& a);
12354
 
12355
- flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il,
12356
  const key_compare& comp = key_compare())
12357
- : flat_multiset(s, il.begin(), il.end(), comp) { }
12358
- template<class Allocator>
12359
- flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
12360
- const key_compare& comp, const Allocator& a);
12361
- template<class Allocator>
12362
- flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
12363
 
12364
- flat_multiset& operator=(initializer_list<value_type>);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12365
 
12366
  // iterators
12367
- iterator begin() noexcept;
12368
- const_iterator begin() const noexcept;
12369
- iterator end() noexcept;
12370
- const_iterator end() const noexcept;
12371
 
12372
- reverse_iterator rbegin() noexcept;
12373
- const_reverse_iterator rbegin() const noexcept;
12374
- reverse_iterator rend() noexcept;
12375
- const_reverse_iterator rend() const noexcept;
12376
 
12377
- const_iterator cbegin() const noexcept;
12378
- const_iterator cend() const noexcept;
12379
- const_reverse_iterator crbegin() const noexcept;
12380
- const_reverse_iterator crend() const noexcept;
12381
 
12382
  // capacity
12383
- [[nodiscard]] bool empty() const noexcept;
12384
- size_type size() const noexcept;
12385
- size_type max_size() const noexcept;
12386
 
12387
  // [flat.multiset.modifiers], modifiers
12388
- template<class... Args> iterator emplace(Args&&... args);
12389
  template<class... Args>
12390
- iterator emplace_hint(const_iterator position, Args&&... args);
12391
 
12392
- iterator insert(const value_type& x)
12393
  { return emplace(x); }
12394
- iterator insert(value_type&& x)
12395
  { return emplace(std::move(x)); }
12396
- iterator insert(const_iterator position, const value_type& x)
12397
  { return emplace_hint(position, x); }
12398
- iterator insert(const_iterator position, value_type&& x)
12399
  { return emplace_hint(position, std::move(x)); }
12400
 
12401
  template<class InputIterator>
12402
- void insert(InputIterator first, InputIterator last);
12403
  template<class InputIterator>
12404
- void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
12405
  template<container-compatible-range<value_type> R>
12406
- void insert_range(R&& rg);
12407
 
12408
- void insert(initializer_list<value_type> il)
12409
  { insert(il.begin(), il.end()); }
12410
- void insert(sorted_equivalent_t s, initializer_list<value_type> il)
12411
- { insert(s, il.begin(), il.end()); }
12412
 
12413
- container_type extract() &&;
12414
- void replace(container_type&&);
12415
 
12416
- iterator erase(iterator position);
12417
- iterator erase(const_iterator position);
12418
- size_type erase(const key_type& x);
12419
- template<class K> size_type erase(K&& x);
12420
- iterator erase(const_iterator first, const_iterator last);
12421
 
12422
- void swap(flat_multiset& y) noexcept;
12423
- void clear() noexcept;
12424
 
12425
  // observers
12426
- key_compare key_comp() const;
12427
- value_compare value_comp() const;
12428
 
12429
  // set operations
12430
- iterator find(const key_type& x);
12431
- const_iterator find(const key_type& x) const;
12432
- template<class K> iterator find(const K& x);
12433
- template<class K> const_iterator find(const K& x) const;
12434
 
12435
- size_type count(const key_type& x) const;
12436
- template<class K> size_type count(const K& x) const;
12437
 
12438
- bool contains(const key_type& x) const;
12439
- template<class K> bool contains(const K& x) const;
12440
 
12441
- iterator lower_bound(const key_type& x);
12442
- const_iterator lower_bound(const key_type& x) const;
12443
- template<class K> iterator lower_bound(const K& x);
12444
- template<class K> const_iterator lower_bound(const K& x) const;
12445
 
12446
- iterator upper_bound(const key_type& x);
12447
- const_iterator upper_bound(const key_type& x) const;
12448
- template<class K> iterator upper_bound(const K& x);
12449
- template<class K> const_iterator upper_bound(const K& x) const;
12450
 
12451
- pair<iterator, iterator> equal_range(const key_type& x);
12452
- pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
12453
  template<class K>
12454
- pair<iterator, iterator> equal_range(const K& x);
12455
  template<class K>
12456
- pair<const_iterator, const_iterator> equal_range(const K& x) const;
12457
 
12458
- friend bool operator==(const flat_multiset& x, const flat_multiset& y);
12459
 
12460
- friend synth-three-way-result<value_type>
12461
  operator<=>(const flat_multiset& x, const flat_multiset& y);
12462
 
12463
- friend void swap(flat_multiset& x, flat_multiset& y) noexcept
12464
  { x.swap(y); }
12465
 
12466
  private:
12467
  container_type c; // exposition only
12468
  key_compare compare; // exposition only
@@ -12490,15 +14131,15 @@ namespace std {
12490
  flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
12491
  -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
12492
 
12493
  template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
12494
  flat_multiset(InputIterator, InputIterator, Compare = Compare())
12495
- -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
12496
 
12497
  template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
12498
  flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
12499
- -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
12500
 
12501
  template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
12502
  class Allocator = allocator<ranges::range_value_t<R>>>
12503
  flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
12504
  -> flat_multiset<ranges::range_value_t<R>, Compare,
@@ -12526,95 +14167,100 @@ namespace std {
12526
  ```
12527
 
12528
  #### Constructors <a id="flat.multiset.cons">[[flat.multiset.cons]]</a>
12529
 
12530
  ``` cpp
12531
- explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
12532
  ```
12533
 
12534
  *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
12535
  `comp`, and sorts the range \[`begin()`, `end()`) with respect to
12536
  *compare*.
12537
 
12538
- *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
12539
- and otherwise N log N, where N is the value of `cont.size()` before this
12540
- call.
 
 
 
 
 
12541
 
12542
  ``` cpp
12543
- template<class Allocator>
12544
- flat_multiset(const container_type& cont, const Allocator& a);
12545
- template<class Allocator>
12546
- flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
12547
  ```
12548
 
12549
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12550
-
12551
  *Effects:* Equivalent to `flat_multiset(cont)` and
12552
  `flat_multiset(cont, comp)`, respectively, except that *c* is
12553
  constructed with uses-allocator
12554
  construction [[allocator.uses.construction]].
12555
 
12556
  *Complexity:* Same as `flat_multiset(cont)` and
12557
  `flat_multiset(cont, comp)`, respectively.
12558
 
12559
  ``` cpp
12560
- template<class Allocator>
12561
- flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a);
12562
- template<class Allocator>
12563
- flat_multiset(sorted_equivalent_t s, const container_type& cont,
12564
- const key_compare& comp, const Allocator& a);
12565
  ```
12566
 
12567
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12568
-
12569
- *Effects:* Equivalent to `flat_multiset(s, cont)` and
12570
- `flat_multiset(s, cont, comp)`, respectively, except that *c* is
12571
- constructed with uses-allocator
12572
  construction [[allocator.uses.construction]].
12573
 
12574
  *Complexity:* Linear.
12575
 
12576
  ``` cpp
12577
- template<class Allocator>
12578
- flat_multiset(const key_compare& comp, const Allocator& a);
12579
- template<class Allocator>
12580
- explicit flat_multiset(const Allocator& a);
12581
- template<class InputIterator, class Allocator>
12582
- flat_multiset(InputIterator first, InputIterator last,
12583
- const key_compare& comp, const Allocator& a);
12584
- template<class InputIterator, class Allocator>
12585
- flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
12586
- template<container-compatible-range<value_type> R, class Allocator>
12587
- flat_multiset(from_range_t, R&& rg, const Allocator& a);
12588
- template<container-compatible-range<value_type> R, class Allocator>
12589
- flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
12590
- template<class InputIterator, class Allocator>
12591
- flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
12592
- const key_compare& comp, const Allocator& a);
12593
- template<class InputIterator, class Allocator>
12594
- flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a);
12595
- template<class Allocator>
12596
- flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
12597
- template<class Allocator>
12598
- flat_multiset(initializer_list<value_type> il, const Allocator& a);
12599
- template<class Allocator>
12600
- flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
12601
- const key_compare& comp, const Allocator& a);
12602
- template<class Allocator>
12603
- flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
 
 
 
 
 
 
12604
  ```
12605
 
12606
- *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
12607
-
12608
  *Effects:* Equivalent to the corresponding non-allocator constructors
12609
  except that *c* is constructed with uses-allocator
12610
  construction [[allocator.uses.construction]].
12611
 
12612
  #### Modifiers <a id="flat.multiset.modifiers">[[flat.multiset.modifiers]]</a>
12613
 
12614
  ``` cpp
12615
- template<class... Args> iterator emplace(Args&&... args);
12616
  ```
12617
 
12618
  *Constraints:* `is_constructible_v<value_type, Args...>` is `true`.
12619
 
12620
  *Effects:* First, initializes an object `t` of type `value_type` with
@@ -12627,11 +14273,11 @@ c.insert(it, std::move(t));
12627
 
12628
  *Returns:* An iterator that points to the inserted element.
12629
 
12630
  ``` cpp
12631
  template<class InputIterator>
12632
- void insert(InputIterator first, InputIterator last);
12633
  ```
12634
 
12635
  *Effects:* Adds elements to *c* as if by:
12636
 
12637
  ``` cpp
@@ -12648,51 +14294,51 @@ M is `distance(first, last)`.
12648
  *Remarks:* Since this operation performs an in-place merge, it may
12649
  allocate memory.
12650
 
12651
  ``` cpp
12652
  template<class InputIterator>
12653
- void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
12654
  ```
12655
 
12656
  *Effects:* Equivalent to `insert(first, last)`.
12657
 
12658
  *Complexity:* Linear.
12659
 
12660
  ``` cpp
12661
- void swap(flat_multiset& y) noexcept;
12662
  ```
12663
 
12664
  *Effects:* Equivalent to:
12665
 
12666
  ``` cpp
12667
  ranges::swap(compare, y.compare);
12668
  ranges::swap(c, y.c);
12669
  ```
12670
 
12671
  ``` cpp
12672
- container_type extract() &&;
12673
  ```
12674
 
12675
  *Ensures:* `*this` is emptied, even if the function exits via an
12676
  exception.
12677
 
12678
- *Returns:* `std::move(c)`.
12679
 
12680
  ``` cpp
12681
- void replace(container_type&& cont);
12682
  ```
12683
 
12684
  *Preconditions:* The elements of `cont` are sorted with respect to
12685
  *compare*.
12686
 
12687
- *Effects:* Equivalent to: `c = std::move(cont);`
12688
 
12689
  #### Erasure <a id="flat.multiset.erasure">[[flat.multiset.erasure]]</a>
12690
 
12691
  ``` cpp
12692
  template<class Key, class Compare, class KeyContainer, class Predicate>
12693
- typename flat_multiset<Key, Compare, KeyContainer>::size_type
12694
  erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
12695
  ```
12696
 
12697
  *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
12698
 
@@ -12767,22 +14413,39 @@ with these multidimensional views.
12767
  ### Contiguous access <a id="views.contiguous">[[views.contiguous]]</a>
12768
 
12769
  #### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
12770
 
12771
  ``` cpp
 
 
 
12772
  namespace std {
12773
  // constants
12774
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
12775
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12776
  // [views.span], class template span
12777
  template<class ElementType, size_t Extent = dynamic_extent>
12778
- class span;
12779
 
12780
  template<class ElementType, size_t Extent>
12781
- constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
12782
  template<class ElementType, size_t Extent>
12783
- constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
12784
 
12785
  // [span.objectrep], views of object representation
12786
  template<class ElementType, size_t Extent>
12787
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
12788
  as_bytes(span<ElementType, Extent> s) noexcept;
@@ -12834,16 +14497,15 @@ namespace std {
12834
  constexpr span(array<T, N>& arr) noexcept;
12835
  template<class T, size_t N>
12836
  constexpr span(const array<T, N>& arr) noexcept;
12837
  template<class R>
12838
  constexpr explicit(extent != dynamic_extent) span(R&& r);
 
12839
  constexpr span(const span& other) noexcept = default;
12840
  template<class OtherElementType, size_t OtherExtent>
12841
  constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
12842
 
12843
- ~span() noexcept = default;
12844
-
12845
  constexpr span& operator=(const span& other) noexcept = default;
12846
 
12847
  // [span.sub], subviews
12848
  template<size_t Count>
12849
  constexpr span<element_type, Count> first() const;
@@ -12858,14 +14520,15 @@ namespace std {
12858
  size_type offset, size_type count = dynamic_extent) const;
12859
 
12860
  // [span.obs], observers
12861
  constexpr size_type size() const noexcept;
12862
  constexpr size_type size_bytes() const noexcept;
12863
- [[nodiscard]] constexpr bool empty() const noexcept;
12864
 
12865
  // [span.elem], element access
12866
  constexpr reference operator[](size_type idx) const;
 
12867
  constexpr reference front() const;
12868
  constexpr reference back() const;
12869
  constexpr pointer data() const noexcept;
12870
 
12871
  // [span.iterators], iterator support
@@ -12882,11 +14545,12 @@ namespace std {
12882
  pointer data_; // exposition only
12883
  size_type size_; // exposition only
12884
  };
12885
 
12886
  template<class It, class EndOrSize>
12887
- span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
 
12888
  template<class T, size_t N>
12889
  span(T (&)[N]) -> span<T, N>;
12890
  template<class T, size_t N>
12891
  span(array<T, N>&) -> span<T, N>;
12892
  template<class T, size_t N>
@@ -12900,10 +14564,14 @@ namespace std {
12900
  [[term.trivially.copyable.type]].
12901
 
12902
  `ElementType` is required to be a complete object type that is not an
12903
  abstract class type.
12904
 
 
 
 
 
12905
  ##### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
12906
 
12907
  ``` cpp
12908
  constexpr span() noexcept;
12909
  ```
@@ -12926,14 +14594,15 @@ template<class It>
12926
 
12927
  *Preconditions:*
12928
 
12929
  - \[`first`, `first + count`) is a valid range.
12930
  - `It` models `contiguous_iterator`.
12931
- - If `extent` is not equal to `dynamic_extent`, then `count` is equal to
12932
- `extent`.
12933
 
12934
- *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
 
 
 
12935
  with `count`.
12936
 
12937
  *Throws:* Nothing.
12938
 
12939
  ``` cpp
@@ -12950,28 +14619,29 @@ template<class It, class End>
12950
  - `End` satisfies `sized_sentinel_for<It>`.
12951
  - `is_convertible_v<End, size_t>` is `false`.
12952
 
12953
  *Preconditions:*
12954
 
12955
- - If `extent` is not equal to `dynamic_extent`, then `last - first` is
12956
- equal to `extent`.
12957
  - \[`first`, `last`) is a valid range.
12958
  - `It` models `contiguous_iterator`.
12959
  - `End` models `sized_sentinel_for<It>`.
12960
 
12961
- *Effects:* Initializes *`data_`* with `to_address(first)` and *`size_`*
 
 
 
12962
  with `last - first`.
12963
 
12964
  *Throws:* When and what `last - first` throws.
12965
 
12966
  ``` cpp
12967
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
12968
  template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
12969
  template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
12970
  ```
12971
 
12972
- *Constraints:* Let `U` be `remove_pointer_t<decltype(data(arr))>`.
12973
 
12974
  - `extent == dynamic_extent || N == extent` is `true`, and
12975
  - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
12976
  \[*Note 3*: The intent is to allow only qualification conversions of
12977
  the array element type to `element_type`. — *end note*]
@@ -12979,11 +14649,11 @@ template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
12979
  *Effects:* Constructs a `span` that is a view over the supplied array.
12980
 
12981
  [*Note 1*: `type_identity_t` affects class template argument
12982
  deduction. — *end note*]
12983
 
12984
- *Ensures:* `size() == N && data() == data(arr)` is `true`.
12985
 
12986
  ``` cpp
12987
  template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
12988
  ```
12989
 
@@ -13000,21 +14670,34 @@ template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
13000
  \[*Note 4*: The intent is to allow only qualification conversions of
13001
  the range reference type to `element_type`. — *end note*]
13002
 
13003
  *Preconditions:*
13004
 
13005
- - If `extent` is not equal to `dynamic_extent`, then `ranges::size(r)`
13006
- is equal to `extent`.
13007
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
13008
  - If `is_const_v<element_type>` is `false`, `R` models
13009
  `ranges::borrowed_range`.
13010
 
13011
- *Effects:* Initializes *`data_`* with `ranges::data(r)` and *`size_`*
13012
- with `ranges::size(r)`.
 
 
 
13013
 
13014
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
13015
 
 
 
 
 
 
 
 
 
 
 
 
 
13016
  ``` cpp
13017
  constexpr span(const span& other) noexcept = default;
13018
  ```
13019
 
13020
  *Ensures:* `other.size() == size() && other.data() == data()`.
@@ -13031,12 +14714,12 @@ template<class OtherElementType, size_t OtherExtent>
13031
  - `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is
13032
  `true`. \[*Note 5*: The intent is to allow only qualification
13033
  conversions of the `OtherElementType` to
13034
  `element_type`. — *end note*]
13035
 
13036
- *Preconditions:* If `extent` is not equal to `dynamic_extent`, then
13037
- `s.size()` is equal to `extent`.
13038
 
13039
  *Effects:* Constructs a `span` that is a view over the range
13040
  \[`s.data()`, `s.data() + s.size()`).
13041
 
13042
  *Ensures:* `size() == s.size() && data() == s.data()`.
@@ -13055,11 +14738,12 @@ constexpr span& operator=(const span& other) noexcept = default;
13055
 
13056
  ##### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
13057
 
13058
  ``` cpp
13059
  template<class It, class EndOrSize>
13060
- span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>>;
 
13061
  ```
13062
 
13063
  *Constraints:* `It` satisfies `contiguous_iterator`.
13064
 
13065
  ``` cpp
@@ -13075,22 +14759,22 @@ template<class R>
13075
  template<size_t Count> constexpr span<element_type, Count> first() const;
13076
  ```
13077
 
13078
  *Mandates:* `Count <= Extent` is `true`.
13079
 
13080
- *Preconditions:* `Count <= size()` is `true`.
13081
 
13082
  *Effects:* Equivalent to: `return R{data(), Count};` where `R` is the
13083
  return type.
13084
 
13085
  ``` cpp
13086
  template<size_t Count> constexpr span<element_type, Count> last() const;
13087
  ```
13088
 
13089
  *Mandates:* `Count <= Extent` is `true`.
13090
 
13091
- *Preconditions:* `Count <= size()` is `true`.
13092
 
13093
  *Effects:* Equivalent to: `return R{data() + (size() - Count), Count};`
13094
  where `R` is the return type.
13095
 
13096
  ``` cpp
@@ -13104,12 +14788,10 @@ template<size_t Offset, size_t Count = dynamic_extent>
13104
  Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset)
13105
  ```
13106
 
13107
  is `true`.
13108
 
13109
- *Preconditions:*
13110
-
13111
  ``` cpp
13112
  Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)
13113
  ```
13114
 
13115
  is `true`.
@@ -13131,29 +14813,27 @@ Count != dynamic_extent ? Count
13131
 
13132
  ``` cpp
13133
  constexpr span<element_type, dynamic_extent> first(size_type count) const;
13134
  ```
13135
 
13136
- *Preconditions:* `count <= size()` is `true`.
13137
 
13138
  *Effects:* Equivalent to: `return {data(), count};`
13139
 
13140
  ``` cpp
13141
  constexpr span<element_type, dynamic_extent> last(size_type count) const;
13142
  ```
13143
 
13144
- *Preconditions:* `count <= size()` is `true`.
13145
 
13146
  *Effects:* Equivalent to: `return {data() + (size() - count), count};`
13147
 
13148
  ``` cpp
13149
  constexpr span<element_type, dynamic_extent> subspan(
13150
  size_type offset, size_type count = dynamic_extent) const;
13151
  ```
13152
 
13153
- *Preconditions:*
13154
-
13155
  ``` cpp
13156
  offset <= size() && (count == dynamic_extent || count <= size() - offset)
13157
  ```
13158
 
13159
  is `true`.
@@ -13177,46 +14857,60 @@ constexpr size_type size_bytes() const noexcept;
13177
  ```
13178
 
13179
  *Effects:* Equivalent to: `return size() * sizeof(element_type);`
13180
 
13181
  ``` cpp
13182
- [[nodiscard]] constexpr bool empty() const noexcept;
13183
  ```
13184
 
13185
  *Effects:* Equivalent to: `return size() == 0;`
13186
 
13187
  ##### Element access <a id="span.elem">[[span.elem]]</a>
13188
 
13189
  ``` cpp
13190
  constexpr reference operator[](size_type idx) const;
13191
  ```
13192
 
13193
- *Preconditions:* `idx < size()` is `true`.
13194
 
13195
- *Effects:* Equivalent to: `return *(data() + idx);`
 
 
 
 
 
 
 
 
 
 
13196
 
13197
  ``` cpp
13198
  constexpr reference front() const;
13199
  ```
13200
 
13201
- *Preconditions:* `empty()` is `false`.
13202
 
13203
- *Effects:* Equivalent to: `return *data();`
 
 
13204
 
13205
  ``` cpp
13206
  constexpr reference back() const;
13207
  ```
13208
 
13209
- *Preconditions:* `empty()` is `false`.
13210
 
13211
- *Effects:* Equivalent to: `return *(data() + (size() - 1));`
 
 
13212
 
13213
  ``` cpp
13214
  constexpr pointer data() const noexcept;
13215
  ```
13216
 
13217
- *Effects:* Equivalent to: `return `*`data_`*`;`
13218
 
13219
  ##### Iterator support <a id="span.iterators">[[span.iterators]]</a>
13220
 
13221
  ``` cpp
13222
  using iterator = implementation-defined // type of span::iterator;
@@ -13304,42 +14998,81 @@ the following are true:
13304
  the interval [Lᵢ, Uᵢ) of S.
13305
 
13306
  #### Header `<mdspan>` synopsis <a id="mdspan.syn">[[mdspan.syn]]</a>
13307
 
13308
  ``` cpp
 
13309
  namespace std {
13310
  // [mdspan.extents], class template extents
13311
  template<class IndexType, size_t... Extents>
13312
  class extents;
13313
 
13314
  // [mdspan.extents.dextents], alias template dextents
13315
  template<class IndexType, size_t Rank>
13316
  using dextents = see below;
13317
 
 
 
 
 
13318
  // [mdspan.layout], layout mapping
13319
  struct layout_left;
13320
  struct layout_right;
13321
  struct layout_stride;
 
 
 
 
13322
 
13323
  // [mdspan.accessor.default], class template default_accessor
13324
  template<class ElementType>
13325
  class default_accessor;
13326
 
 
 
 
 
13327
  // [mdspan.mdspan], class template mdspan
13328
  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
13329
  class AccessorPolicy = default_accessor<ElementType>>
13330
- class mdspan;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13331
  }
13332
  ```
13333
 
13334
  #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
13335
 
13336
  ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
13337
 
13338
  The class template `extents` represents a multidimensional index space
13339
- of rank equal to `sizeof...(Extents)`. In subclause [[views]], `extents`
13340
- is used synonymously with multidimensional index space.
13341
 
13342
  ``` cpp
13343
  namespace std {
13344
  template<class IndexType, size_t... Extents>
13345
  class extents {
@@ -13519,12 +15252,12 @@ Let `N` be `sizeof...(OtherIndexTypes)`, and let `exts_arr` be
13519
 
13520
  - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
13521
  r for which Eᵣ is a static extent, and
13522
  - either
13523
  - `sizeof...(exts) == 0` is `true`, or
13524
- - each element of `exts` is nonnegative and is representable as a
13525
- value of type `index_type`.
13526
 
13527
  *Ensures:* `*this == extents(exts_arr)` is `true`.
13528
 
13529
  ``` cpp
13530
  template<class OtherIndexType, size_t N>
@@ -13546,16 +15279,16 @@ template<class OtherIndexType, size_t N>
13546
 
13547
  - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
13548
  for which Eᵣ is a static extent, and
13549
  - either
13550
  - `N` is zero, or
13551
- - `exts[`r`]` is nonnegative and is representable as a value of type
13552
  `index_type` for every rank index r.
13553
 
13554
  *Effects:*
13555
 
13556
- - If `N` equals `dynamic_rank()`, for all d in the range
13557
  [0, `rank_dynamic()`), direct-non-list-initializes
13558
  *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
13559
  - Otherwise, for all d in the range [0, `rank_dynamic()`),
13560
  direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
13561
  `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
@@ -13565,11 +15298,12 @@ template<class... Integrals>
13565
  explicit extents(Integrals...) -> see below;
13566
  ```
13567
 
13568
  *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
13569
 
13570
- *Remarks:* The deduced type is `dextents<size_t, sizeof...(Integrals)>`.
 
13571
 
13572
  ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
13573
 
13574
  ``` cpp
13575
  static constexpr size_t static_extent(rank_type i) noexcept;
@@ -13608,16 +15342,26 @@ template<class IndexType, size_t Rank>
13608
 
13609
  *Result:* A type `E` that is a specialization of `extents` such that
13610
  `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
13611
  `E::index_type` denotes `IndexType`.
13612
 
 
 
 
 
 
 
 
 
 
 
 
13613
  #### Layout mapping <a id="mdspan.layout">[[mdspan.layout]]</a>
13614
 
13615
  ##### General <a id="mdspan.layout.general">[[mdspan.layout.general]]</a>
13616
 
13617
- In subclauses [[mdspan.layout.reqmts]] and
13618
- [[mdspan.layout.policy.reqmts]]:
13619
 
13620
  - `M` denotes a layout mapping class.
13621
  - `m` denotes a (possibly const) value of type `M`.
13622
  - `i` and `j` are packs of (possibly const) integers that are
13623
  multidimensional indices in `m.extents()` [[mdspan.overview]].
@@ -13626,19 +15370,44 @@ In subclauses [[mdspan.layout.reqmts]] and
13626
  - `r` is a (possibly const) rank index of `typename M::extents_type`.
13627
  - `dᵣ` is a pack of (possibly const) integers for which
13628
  `sizeof...(dᵣ) == M::extents_type::rank()` is `true`, the rᵗʰ element
13629
  is equal to 1, and all other elements are equal to 0.
13630
 
13631
- In subclauses [[mdspan.layout.reqmts]] through [[mdspan.layout.stride]],
13632
- let *`is-mapping-of`* be the exposition-only variable template defined
 
13633
  as follows:
13634
-
13635
  ``` cpp
13636
  template<class Layout, class Mapping>
13637
  constexpr bool is-mapping-of = // exposition only
13638
  is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
13639
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13640
 
13641
  ##### Requirements <a id="mdspan.layout.reqmts">[[mdspan.layout.reqmts]]</a>
13642
 
13643
  A type `M` meets the *layout mapping* requirements if
13644
 
@@ -13762,20 +15531,24 @@ m.stride(r)
13762
 
13763
  *Result:* `typename M::index_type`
13764
 
13765
  *Returns:* sᵣ as defined in `m.is_strided()` above.
13766
 
 
 
 
 
13767
  ``` cpp
13768
  M::is_always_unique()
13769
  ```
13770
 
13771
  *Result:* A constant expression [[expr.const]] of type `bool`.
13772
 
13773
  *Returns:* `true` only if `m.is_unique()` is `true` for all possible
13774
  objects `m` of type `M`.
13775
 
13776
- [*Note 5*: A mapping can return `false` even if the above condition is
13777
  met. For certain layout mappings, it is possibly not feasible to
13778
  determine whether every instance is unique. — *end note*]
13779
 
13780
  ``` cpp
13781
  M::is_always_exhaustive()
@@ -13784,11 +15557,11 @@ M::is_always_exhaustive()
13784
  *Result:* A constant expression [[expr.const]] of type `bool`.
13785
 
13786
  *Returns:* `true` only if `m.is_exhaustive()` is `true` for all possible
13787
  objects `m` of type `M`.
13788
 
13789
- [*Note 6*: A mapping can return `false` even if the above condition is
13790
  met. For certain layout mappings, it is possibly not feasible to
13791
  determine whether every instance is exhaustive. — *end note*]
13792
 
13793
  ``` cpp
13794
  M::is_always_strided()
@@ -13797,11 +15570,11 @@ M::is_always_strided()
13797
  *Result:* A constant expression [[expr.const]] of type `bool`.
13798
 
13799
  *Returns:* `true` only if `m.is_strided()` is `true` for all possible
13800
  objects `m` of type `M`.
13801
 
13802
- [*Note 7*: A mapping can return `false` even if the above condition is
13803
  met. For certain layout mappings, it is possibly not feasible to
13804
  determine whether every instance is strided. — *end note*]
13805
 
13806
  ##### Layout mapping policy requirements <a id="mdspan.layout.policy.reqmts">[[mdspan.layout.policy.reqmts]]</a>
13807
 
@@ -13826,15 +15599,27 @@ namespace std {
13826
  };
13827
  struct layout_stride {
13828
  template<class Extents>
13829
  class mapping;
13830
  };
 
 
 
 
 
 
 
 
 
13831
  }
13832
  ```
13833
 
13834
- Each of `layout_left`, `layout_right`, and `layout_stride` meets the
13835
- layout mapping policy requirements and is a trivial type.
 
 
 
13836
 
13837
  ##### Class template `layout_left::mapping` <a id="mdspan.layout.left">[[mdspan.layout.left]]</a>
13838
 
13839
  ###### Overview <a id="mdspan.layout.left.overview">[[mdspan.layout.left.overview]]</a>
13840
 
@@ -13845,13 +15630,13 @@ stride 1, and strides increase left-to-right as the product of extents.
13845
  namespace std {
13846
  template<class Extents>
13847
  class layout_left::mapping {
13848
  public:
13849
  using extents_type = Extents;
13850
- using index_type = typename extents_type::index_type;
13851
- using size_type = typename extents_type::size_type;
13852
- using rank_type = typename extents_type::rank_type;
13853
  using layout_type = layout_left;
13854
 
13855
  // [mdspan.layout.left.cons], constructors
13856
  constexpr mapping() noexcept = default;
13857
  constexpr mapping(const mapping&) noexcept = default;
@@ -13860,10 +15645,14 @@ namespace std {
13860
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13861
  mapping(const mapping<OtherExtents>&) noexcept;
13862
  template<class OtherExtents>
13863
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13864
  mapping(const layout_right::mapping<OtherExtents>&) noexcept;
 
 
 
 
13865
  template<class OtherExtents>
13866
  constexpr explicit(extents_type::rank() > 0)
13867
  mapping(const layout_stride::mapping<OtherExtents>&);
13868
 
13869
  constexpr mapping& operator=(const mapping&) noexcept = default;
@@ -13889,10 +15678,21 @@ namespace std {
13889
  template<class OtherExtents>
13890
  friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
13891
 
13892
  private:
13893
  extents_type extents_{}; // exposition only
 
 
 
 
 
 
 
 
 
 
 
13894
  };
13895
  }
13896
  ```
13897
 
13898
  If `Extents` is not a specialization of `extents`, then the program is
@@ -13930,11 +15730,11 @@ value of type `index_type` [[basic.fundamental]].
13930
 
13931
  *Effects:* Direct-non-list-initializes *extents\_* with
13932
  `other.extents()`.
13933
 
13934
  ``` cpp
13935
- template<class OtherExents>
13936
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
13937
  mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
13938
  ```
13939
 
13940
  *Constraints:*
@@ -13946,10 +15746,44 @@ template<class OtherExents>
13946
  value of type `index_type` [[basic.fundamental]].
13947
 
13948
  *Effects:* Direct-non-list-initializes *extents\_* with
13949
  `other.extents()`.
13950
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13951
  ``` cpp
13952
  template<class OtherExtents>
13953
  constexpr explicit(extents_type::rank() > 0)
13954
  mapping(const layout_stride::mapping<OtherExtents>& other);
13955
  ```
@@ -14001,11 +15835,11 @@ is `true`. Equivalent to:
14001
  ``` cpp
14002
  return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
14003
  ```
14004
 
14005
  ``` cpp
14006
- constexpr index_type stride(rank_type i) const;
14007
  ```
14008
 
14009
  *Constraints:* `extents_type::rank() > 0` is `true`.
14010
 
14011
  *Preconditions:* `i < extents_type::rank()` is `true`.
@@ -14032,13 +15866,13 @@ stride 1, and strides increase right-to-left as the product of extents.
14032
  namespace std {
14033
  template<class Extents>
14034
  class layout_right::mapping {
14035
  public:
14036
  using extents_type = Extents;
14037
- using index_type = typename extents_type::index_type;
14038
- using size_type = typename extents_type::size_type;
14039
- using rank_type = typename extents_type::rank_type;
14040
  using layout_type = layout_right;
14041
 
14042
  // [mdspan.layout.right.cons], constructors
14043
  constexpr mapping() noexcept = default;
14044
  constexpr mapping(const mapping&) noexcept = default;
@@ -14047,10 +15881,14 @@ namespace std {
14047
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14048
  mapping(const mapping<OtherExtents>&) noexcept;
14049
  template<class OtherExtents>
14050
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
14051
  mapping(const layout_left::mapping<OtherExtents>&) noexcept;
 
 
 
 
14052
  template<class OtherExtents>
14053
  constexpr explicit(extents_type::rank() > 0)
14054
  mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
14055
 
14056
  constexpr mapping& operator=(const mapping&) noexcept = default;
@@ -14076,10 +15914,21 @@ namespace std {
14076
  template<class OtherExtents>
14077
  friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
14078
 
14079
  private:
14080
  extents_type extents_{}; // exposition only
 
 
 
 
 
 
 
 
 
 
 
14081
  };
14082
  }
14083
  ```
14084
 
14085
  If `Extents` is not a specialization of `extents`, then the program is
@@ -14133,10 +15982,46 @@ template<class OtherExtents>
14133
  value of type `index_type` [[basic.fundamental]].
14134
 
14135
  *Effects:* Direct-non-list-initializes *extents\_* with
14136
  `other.extents()`.
14137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14138
  ``` cpp
14139
  template<class OtherExtents>
14140
  constexpr explicit(extents_type::rank() > 0)
14141
  mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
14142
  ```
@@ -14156,11 +16041,11 @@ template<class OtherExtents>
14156
  `other.extents()`.
14157
 
14158
  ###### Observers <a id="mdspan.layout.right.obs">[[mdspan.layout.right.obs]]</a>
14159
 
14160
  ``` cpp
14161
- index_type required_span_size() const noexcept;
14162
  ```
14163
 
14164
  *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
14165
 
14166
  ``` cpp
@@ -14219,13 +16104,13 @@ user-defined.
14219
  namespace std {
14220
  template<class Extents>
14221
  class layout_stride::mapping {
14222
  public:
14223
  using extents_type = Extents;
14224
- using index_type = typename extents_type::index_type;
14225
- using size_type = typename extents_type::size_type;
14226
- using rank_type = typename extents_type::rank_type;
14227
  using layout_type = layout_stride;
14228
 
14229
  private:
14230
  static constexpr rank_type rank_ = extents_type::rank(); // exposition only
14231
 
@@ -14266,10 +16151,21 @@ namespace std {
14266
  friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
14267
 
14268
  private:
14269
  extents_type extents_{}; // exposition only
14270
  array<index_type, rank_> strides_{}; // exposition only
 
 
 
 
 
 
 
 
 
 
 
14271
  };
14272
  }
14273
  ```
14274
 
14275
  If `Extents` is not a specialization of `extents`, then the program is
@@ -14288,11 +16184,15 @@ Let `REQUIRED-SPAN-SIZE(e, strides)` be:
14288
 
14289
  - `1`, if `e.rank() == 0` is `true`,
14290
  - otherwise `0`, if the size of the multidimensional index space `e` is
14291
  0,
14292
  - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
14293
- `strides[r]` for all r in the range [0, `e.rank()`).
 
 
 
 
14294
 
14295
  Let `OFFSET(m)` be:
14296
 
14297
  - `m()`, if `e.rank() == 0` is `true`,
14298
  - otherwise `0`, if the size of the multidimensional index space `e` is
@@ -14360,11 +16260,12 @@ template<class OtherIndexType>
14360
  - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
14361
  `true`.
14362
 
14363
  *Preconditions:*
14364
 
14365
- - `s[`i`] > 0` is `true` for all i in the range [0, rank_).
 
14366
  - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
14367
  `index_type` [[basic.fundamental]].
14368
  - If *rank\_* is greater than 0, then there exists a permutation P of
14369
  the integers in the range [0, rank_), such that
14370
  `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
@@ -14392,11 +16293,11 @@ template<class StridedLayoutMapping>
14392
  - `StridedLayoutMapping::is_always_strided()` is `true`.
14393
 
14394
  *Preconditions:*
14395
 
14396
  - `StridedLayoutMapping` meets the layout mapping
14397
- requirements [[mdspan.layout.policy.reqmts]],
14398
  - `other.stride(`r`) > 0` is `true` for every rank index r of
14399
  `extents()`,
14400
  - `other.required_span_size()` is representable as a value of type
14401
  `index_type` [[basic.fundamental]], and
14402
  - *`OFFSET`*`(other) == 0` is `true`.
@@ -14408,13 +16309,15 @@ direct-non-list-initializes *`strides_`*`[`d`]` with
14408
 
14409
  Remarks: The expression inside `explicit` is equivalent to:
14410
 
14411
  ``` cpp
14412
  !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
14413
- (is-mapping-of<layout_left, LayoutStrideMapping> ||
14414
- is-mapping-of<layout_right, LayoutStrideMapping> ||
14415
- is-mapping-of<layout_stride, LayoutStrideMapping>))
 
 
14416
  ```
14417
 
14418
  ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
14419
 
14420
  ``` cpp
@@ -14479,10 +16382,898 @@ requirements [[mdspan.layout.policy.reqmts]].
14479
  *Returns:* `true` if `x.extents() == y.extents()` is `true`,
14480
  *`OFFSET`*`(y) == 0` is `true`, and each of
14481
  `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
14482
  [0, `x.extents().rank()`). Otherwise, `false`.
14483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14484
  #### Accessor policy <a id="mdspan.accessor">[[mdspan.accessor]]</a>
14485
 
14486
  ##### General <a id="mdspan.accessor.general">[[mdspan.accessor.general]]</a>
14487
 
14488
  An *accessor policy* defines types and operations by which a reference
@@ -14491,11 +17282,11 @@ of such objects and an index.
14491
 
14492
  A range of indices [0, N) is an *accessible range* of a given data
14493
  handle and an accessor if, for each i in the range, the accessor
14494
  policy’s `access` function produces a valid reference to an object.
14495
 
14496
- In subclause [[mdspan.accessor.reqmts]],
14497
 
14498
  - `A` denotes an accessor policy.
14499
  - `a` denotes a value of type `A` or `const A`.
14500
  - `p` denotes a value of type `A::data_handle_type` or
14501
  `const A::data_handle_type`. \[*Note 1*: The type
@@ -14635,10 +17426,155 @@ constexpr reference access(data_handle_type p, size_t i) const noexcept;
14635
  constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
14636
  ```
14637
 
14638
  *Effects:* Equivalent to: `return p + i;`
14639
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14640
  #### Class template `mdspan` <a id="mdspan.mdspan">[[mdspan.mdspan]]</a>
14641
 
14642
  ##### Overview <a id="mdspan.mdspan.overview">[[mdspan.mdspan.overview]]</a>
14643
 
14644
  `mdspan` is a view of a multidimensional array of elements.
@@ -14650,18 +17586,18 @@ namespace std {
14650
  class mdspan {
14651
  public:
14652
  using extents_type = Extents;
14653
  using layout_type = LayoutPolicy;
14654
  using accessor_type = AccessorPolicy;
14655
- using mapping_type = typename layout_type::template mapping<extents_type>;
14656
  using element_type = ElementType;
14657
  using value_type = remove_cv_t<element_type>;
14658
- using index_type = typename extents_type::index_type;
14659
- using size_type = typename extents_type::size_type;
14660
- using rank_type = typename extents_type::rank_type;
14661
- using data_handle_type = typename accessor_type::data_handle_type;
14662
- using reference = typename accessor_type::reference;
14663
 
14664
  static constexpr rank_type rank() noexcept { return extents_type::rank(); }
14665
  static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
14666
  static constexpr size_t static_extent(rank_type r) noexcept
14667
  { return extents_type::static_extent(r); }
@@ -14699,12 +17635,22 @@ namespace std {
14699
  template<class OtherIndexType>
14700
  constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
14701
  template<class OtherIndexType>
14702
  constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
14703
 
 
 
 
 
 
 
 
 
 
 
14704
  constexpr size_type size() const noexcept;
14705
- [[nodiscard]] constexpr bool empty() const noexcept;
14706
 
14707
  friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
14708
 
14709
  constexpr const extents_type& extents() const noexcept { return map_.extents(); }
14710
  constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
@@ -14744,11 +17690,11 @@ namespace std {
14744
  -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
14745
 
14746
  template<class ElementType, class... Integrals>
14747
  requires ((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
14748
  explicit mdspan(ElementType*, Integrals...)
14749
- -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
14750
 
14751
  template<class ElementType, class OtherIndexType, size_t N>
14752
  mdspan(ElementType*, span<OtherIndexType, N>)
14753
  -> mdspan<ElementType, dextents<size_t, N>>;
14754
 
@@ -14851,12 +17797,12 @@ template<class OtherIndexType, size_t N>
14851
  ```
14852
 
14853
  *Constraints:*
14854
 
14855
  - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
14856
- - `(is_nothrow_constructible<index_type, const OtherIndexType&> && ...)`
14857
- is `true`,
14858
  - `N == rank() || N == rank_dynamic()` is `true`,
14859
  - `is_constructible_v<mapping_type, extents_type>` is `true`, and
14860
  - `is_default_constructible_v<accessor_type>` is `true`.
14861
 
14862
  *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
@@ -14935,18 +17881,17 @@ template<class OtherElementType, class OtherExtents,
14935
 
14936
  - `is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&>`
14937
  is `true`, and
14938
  - `is_constructible_v<extents_type, OtherExtents>` is `true`.
14939
 
14940
- *Preconditions:*
 
 
14941
 
14942
- - For each rank index `r` of `extents_type`,
14943
  `static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)`
14944
  is `true`.
14945
- - $[0, \texttt{\textit{map_}.required_span_size()})$ is an accessible
14946
- range of *ptr\_* and *acc\_* for values of *ptr\_*, *map\_*, and
14947
- *acc\_* after the invocation of this constructor.
14948
 
14949
  *Effects:*
14950
 
14951
  - Direct-non-list-initializes *ptr\_* with `other.`*`ptr_`*,
14952
  - direct-non-list-initializes *map\_* with `other.`*`map_`*, and
@@ -14973,11 +17918,11 @@ template<class... OtherIndexTypes>
14973
  `true`, and
14974
  - `sizeof...(OtherIndexTypes) == rank()` is `true`.
14975
 
14976
  Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
14977
 
14978
- *Preconditions:* `I` is a multidimensional index in `extents()`.
14979
 
14980
  [*Note 1*: This implies that
14981
  *`map_`*`(I) < `*`map_`*`.required_span_size()` is
14982
  `true`. — *end note*]
14983
 
@@ -15007,11 +17952,55 @@ is_same_v<make_index_sequence<rank()>, index_sequence<P...>>
15007
  ```
15008
 
15009
  is `true`. Equivalent to:
15010
 
15011
  ``` cpp
15012
- return operator[](as_const(indices[P])...);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15013
  ```
15014
 
15015
  ``` cpp
15016
  constexpr size_type size() const noexcept;
15017
  ```
@@ -15021,11 +18010,11 @@ constexpr size_type size() const noexcept;
15021
  [[basic.fundamental]].
15022
 
15023
  *Returns:* `extents().`*`fwd-prod-of-extents`*`(rank())`.
15024
 
15025
  ``` cpp
15026
- [[nodiscard]] constexpr bool empty() const noexcept;
15027
  ```
15028
 
15029
  *Returns:* `true` if the size of the multidimensional index space
15030
  `extents()` is 0, otherwise `false`.
15031
 
@@ -15039,10 +18028,599 @@ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
15039
  swap(x.ptr_, y.ptr_);
15040
  swap(x.map_, y.map_);
15041
  swap(x.acc_, y.acc_);
15042
  ```
15043
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15044
  <!-- Link reference definitions -->
15045
  [alg.equal]: algorithms.md#alg.equal
15046
  [alg.sorting]: algorithms.md#alg.sorting
15047
  [algorithm.stable]: library.md#algorithm.stable
15048
  [algorithms]: algorithms.md#algorithms
@@ -15066,20 +18644,21 @@ swap(x.acc_, y.acc_);
15066
  [associative.reqmts]: #associative.reqmts
15067
  [associative.reqmts.except]: #associative.reqmts.except
15068
  [associative.reqmts.general]: #associative.reqmts.general
15069
  [associative.set.syn]: #associative.set.syn
15070
  [basic.fundamental]: basic.md#basic.fundamental
 
15071
  [basic.string]: strings.md#basic.string
15072
  [class.copy.ctor]: class.md#class.copy.ctor
15073
  [class.default.ctor]: class.md#class.default.ctor
15074
  [class.dtor]: class.md#class.dtor
15075
  [container.adaptors]: #container.adaptors
15076
  [container.adaptors.format]: #container.adaptors.format
15077
  [container.adaptors.general]: #container.adaptors.general
15078
  [container.alloc.reqmts]: #container.alloc.reqmts
15079
- [container.gen.reqmts]: #container.gen.reqmts
15080
  [container.insert.return]: #container.insert.return
 
15081
  [container.node]: #container.node
15082
  [container.node.compat]: #container.node.compat
15083
  [container.node.cons]: #container.node.cons
15084
  [container.node.dtor]: #container.node.dtor
15085
  [container.node.modifiers]: #container.node.modifiers
@@ -15107,28 +18686,32 @@ swap(x.acc_, y.acc_);
15107
  [expr.const]: expr.md#expr.const
15108
  [flat.map]: #flat.map
15109
  [flat.map.access]: #flat.map.access
15110
  [flat.map.capacity]: #flat.map.capacity
15111
  [flat.map.cons]: #flat.map.cons
 
15112
  [flat.map.defn]: #flat.map.defn
15113
  [flat.map.erasure]: #flat.map.erasure
15114
  [flat.map.modifiers]: #flat.map.modifiers
15115
  [flat.map.overview]: #flat.map.overview
15116
  [flat.map.syn]: #flat.map.syn
15117
  [flat.multimap]: #flat.multimap
15118
  [flat.multimap.cons]: #flat.multimap.cons
 
15119
  [flat.multimap.defn]: #flat.multimap.defn
15120
  [flat.multimap.erasure]: #flat.multimap.erasure
15121
  [flat.multimap.overview]: #flat.multimap.overview
15122
  [flat.multiset]: #flat.multiset
15123
  [flat.multiset.cons]: #flat.multiset.cons
 
15124
  [flat.multiset.defn]: #flat.multiset.defn
15125
  [flat.multiset.erasure]: #flat.multiset.erasure
15126
  [flat.multiset.modifiers]: #flat.multiset.modifiers
15127
  [flat.multiset.overview]: #flat.multiset.overview
15128
  [flat.set]: #flat.set
15129
  [flat.set.cons]: #flat.set.cons
 
15130
  [flat.set.defn]: #flat.set.defn
15131
  [flat.set.erasure]: #flat.set.erasure
15132
  [flat.set.modifiers]: #flat.set.modifiers
15133
  [flat.set.overview]: #flat.set.overview
15134
  [flat.set.syn]: #flat.set.syn
@@ -15141,10 +18724,26 @@ swap(x.acc_, y.acc_);
15141
  [forward.list.modifiers]: #forward.list.modifiers
15142
  [forward.list.ops]: #forward.list.ops
15143
  [forward.list.overview]: #forward.list.overview
15144
  [forward.list.syn]: #forward.list.syn
15145
  [hash.requirements]: library.md#hash.requirements
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15146
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
15147
  [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
15148
  [iterator.requirements]: iterators.md#iterator.requirements
15149
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
15150
  [list]: #list
@@ -15160,45 +18759,73 @@ swap(x.acc_, y.acc_);
15160
  [map.cons]: #map.cons
15161
  [map.erasure]: #map.erasure
15162
  [map.modifiers]: #map.modifiers
15163
  [map.overview]: #map.overview
15164
  [mdspan.accessor]: #mdspan.accessor
 
 
 
15165
  [mdspan.accessor.default]: #mdspan.accessor.default
15166
  [mdspan.accessor.default.members]: #mdspan.accessor.default.members
15167
  [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
15168
  [mdspan.accessor.general]: #mdspan.accessor.general
15169
  [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
15170
  [mdspan.extents]: #mdspan.extents
15171
  [mdspan.extents.cmp]: #mdspan.extents.cmp
15172
  [mdspan.extents.cons]: #mdspan.extents.cons
15173
  [mdspan.extents.dextents]: #mdspan.extents.dextents
 
15174
  [mdspan.extents.expo]: #mdspan.extents.expo
15175
  [mdspan.extents.obs]: #mdspan.extents.obs
15176
  [mdspan.extents.overview]: #mdspan.extents.overview
15177
  [mdspan.layout]: #mdspan.layout
15178
  [mdspan.layout.general]: #mdspan.layout.general
15179
  [mdspan.layout.left]: #mdspan.layout.left
15180
  [mdspan.layout.left.cons]: #mdspan.layout.left.cons
15181
  [mdspan.layout.left.obs]: #mdspan.layout.left.obs
15182
  [mdspan.layout.left.overview]: #mdspan.layout.left.overview
 
 
 
 
 
15183
  [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
15184
  [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
15185
  [mdspan.layout.reqmts]: #mdspan.layout.reqmts
15186
  [mdspan.layout.right]: #mdspan.layout.right
15187
  [mdspan.layout.right.cons]: #mdspan.layout.right.cons
15188
  [mdspan.layout.right.obs]: #mdspan.layout.right.obs
15189
  [mdspan.layout.right.overview]: #mdspan.layout.right.overview
 
 
 
 
 
15190
  [mdspan.layout.stride]: #mdspan.layout.stride
15191
  [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
15192
  [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
15193
  [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
15194
  [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
15195
  [mdspan.mdspan]: #mdspan.mdspan
15196
  [mdspan.mdspan.cons]: #mdspan.mdspan.cons
15197
  [mdspan.mdspan.members]: #mdspan.mdspan.members
15198
  [mdspan.mdspan.overview]: #mdspan.mdspan.overview
15199
  [mdspan.overview]: #mdspan.overview
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15200
  [mdspan.syn]: #mdspan.syn
15201
  [multimap]: #multimap
15202
  [multimap.cons]: #multimap.cons
15203
  [multimap.erasure]: #multimap.erasure
15204
  [multimap.modifiers]: #multimap.modifiers
@@ -15220,17 +18847,19 @@ swap(x.acc_, y.acc_);
15220
  [queue.mod]: #queue.mod
15221
  [queue.ops]: #queue.ops
15222
  [queue.special]: #queue.special
15223
  [queue.syn]: #queue.syn
15224
  [random.access.iterators]: iterators.md#random.access.iterators
 
15225
  [res.on.data.races]: library.md#res.on.data.races
15226
  [sequence.reqmts]: #sequence.reqmts
15227
  [sequences]: #sequences
15228
  [sequences.general]: #sequences.general
15229
  [set]: #set
15230
  [set.cons]: #set.cons
15231
  [set.erasure]: #set.erasure
 
15232
  [set.overview]: #set.overview
15233
  [span.cons]: #span.cons
15234
  [span.deduct]: #span.deduct
15235
  [span.elem]: #span.elem
15236
  [span.iterators]: #span.iterators
@@ -15246,15 +18875,16 @@ swap(x.acc_, y.acc_);
15246
  [stack.general]: #stack.general
15247
  [stack.mod]: #stack.mod
15248
  [stack.ops]: #stack.ops
15249
  [stack.special]: #stack.special
15250
  [stack.syn]: #stack.syn
 
15251
  [strings]: strings.md#strings
15252
  [swappable.requirements]: library.md#swappable.requirements
15253
  [temp.deduct]: temp.md#temp.deduct
15254
- [temp.param]: temp.md#temp.param
15255
  [temp.type]: temp.md#temp.type
 
15256
  [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
15257
  [unord]: #unord
15258
  [unord.general]: #unord.general
15259
  [unord.hash]: utilities.md#unord.hash
15260
  [unord.map]: #unord.map
@@ -15277,10 +18907,11 @@ swap(x.acc_, y.acc_);
15277
  [unord.req.except]: #unord.req.except
15278
  [unord.req.general]: #unord.req.general
15279
  [unord.set]: #unord.set
15280
  [unord.set.cnstr]: #unord.set.cnstr
15281
  [unord.set.erasure]: #unord.set.erasure
 
15282
  [unord.set.overview]: #unord.set.overview
15283
  [unord.set.syn]: #unord.set.syn
15284
  [vector]: #vector
15285
  [vector.bool]: #vector.bool
15286
  [vector.bool.fmt]: #vector.bool.fmt
 
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>`, `<hive>`, | | `<inplace_vector>`, `<list>`, `<vector>` |
18
  | [[associative]] | Associative containers | `<map>`, `<set>` |
19
  | [[unord]] | Unordered associative containers | `<unordered_map>`, `<unordered_set>` |
20
  | [[container.adaptors]] | Container adaptors | `<queue>`, `<stack>`, `<flat_map>`, `<flat_set>` |
21
  | [[views]] | Views | `<span>`, `<mdspan>` |
22
 
 
48
 
49
  [*Note 1*: This means, for example, that a node-based container would
50
  need to construct nodes containing aligned buffers and call `construct`
51
  to place the element into the buffer. — *end note*]
52
 
53
+ ### General containers <a id="container.requirements.general">[[container.requirements.general]]</a>
54
 
55
+ #### Introduction <a id="container.intro.reqmts">[[container.intro.reqmts]]</a>
56
 
57
+ In [[container.requirements.general]],
58
 
59
  - `X` denotes a container class containing objects of type `T`,
60
  - `a` denotes a value of type `X`,
61
  - `b` and `c` denote values of type (possibly const) `X`,
62
  - `i` and `j` denote values of type (possibly const) `X::iterator`,
 
73
  template<class R, class T>
74
  concept container-compatible-range = // exposition only
75
  ranges::input_range<R> && convertible_to<ranges::range_reference_t<R>, T>;
76
  ```
77
 
78
+ #### Container requirements <a id="container.reqmts">[[container.reqmts]]</a>
79
 
80
  A type `X` meets the *container* requirements if the following types,
81
  statements, and expressions are well-formed and have the specified
82
  semantics.
83
 
 
157
  ```
158
 
159
  *Ensures:* `u` is equal to the value that `rv` had before this
160
  construction.
161
 
162
+ *Complexity:* Linear for `array` and `inplace_vector` and constant for
163
+ all other standard containers.
164
 
165
  ``` cpp
166
+ t = v
167
  ```
168
 
169
  *Result:* `X&`.
170
 
171
  *Ensures:* `t == v`.
 
278
 
279
  *Result:* `void`.
280
 
281
  *Effects:* Exchanges the contents of `t` and `s`.
282
 
283
+ *Complexity:* Linear for `array` and `inplace_vector`, and constant for
284
+ all other standard containers.
285
 
286
  ``` cpp
287
  swap(t, s)
288
  ```
289
 
 
365
  [*Note 2*: If an invocation of a constructor uses the default value of
366
  an optional allocator argument, then the allocator type must support
367
  value-initialization. — *end note*]
368
 
369
  A copy of this allocator is used for any memory allocation and element
370
+ construction performed, by these constructors and by all other member
371
  functions, during the lifetime of each container object or until the
372
  allocator is replaced. The allocator may be replaced only via assignment
373
  or `swap()`. Allocator replacement is performed by copy assignment, move
374
  assignment, or swapping of the allocator only if
375
 
 
383
  `get_allocator()` returns a copy of the allocator used to construct the
384
  container or, if that allocator has been replaced, a copy of the most
385
  recent replacement.
386
 
387
  The expression `a.swap(b)`, for containers `a` and `b` of a standard
388
+ container type other than `array` and `inplace_vector`, shall exchange
389
+ the values of `a` and `b` without invoking any move, copy, or swap
390
+ operations on the individual container elements. Any `Compare`, `Pred`,
391
+ or `Hash` types belonging to `a` and `b` shall meet the *Cpp17Swappable*
392
+ requirements and shall be exchanged by calling `swap` as described in 
393
  [[swappable.requirements]]. If
394
  `allocator_traits<allocator_type>::propagate_on_container_swap::value`
395
  is `true`, then `allocator_type` shall meet the *Cpp17Swappable*
396
  requirements and the allocators of `a` and `b` shall also be exchanged
397
  by calling `swap` as described in  [[swappable.requirements]].
 
401
  refer to the same element in the other container after the swap. It is
402
  unspecified whether an iterator with value `a.end()` before the swap
403
  will have value `b.end()` after the swap.
404
 
405
  Unless otherwise specified (see  [[associative.reqmts.except]],
406
+ [[unord.req.except]], [[deque.modifiers]], [[inplace.vector.modifiers]],
407
+ and [[vector.modifiers]]) all container types defined in this Clause
408
+ meet the following additional requirements:
409
 
410
  - If an exception is thrown by an `insert()` or `emplace()` function
411
  while inserting a single element, that function has no effects.
412
  - If an exception is thrown by a `push_back()`, `push_front()`,
413
  `emplace_back()`, or `emplace_front()` function, that function has no
 
523
  a <=> b
524
  ```
525
 
526
  *Result:* *`synth-three-way-result`*`<X::value_type>`.
527
 
528
+ *Preconditions:* Either `T` models `three_way_comparable`, or `<` is
529
+ defined for values of type (possibly const) `T` and `<` is a total
530
+ ordering relationship.
531
 
532
  *Returns:*
533
  `lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(), `*`synth-three-way`*`)`
534
 
535
  [*Note 1*: The algorithm `lexicographical_compare_three_way` is defined
 
537
 
538
  *Complexity:* Linear.
539
 
540
  #### Allocator-aware containers <a id="container.alloc.reqmts">[[container.alloc.reqmts]]</a>
541
 
542
+ Except for `array` and `inplace_vector`, all of the containers defined
543
+ in [[containers]], [[stacktrace.basic]], [[basic.string]], and
544
+ [[re.results]] meet the additional requirements of an
545
  *allocator-aware container*, as described below.
546
 
547
  Given an allocator type `A` and given a container type `X` having a
548
  `value_type` identical to `T` and an `allocator_type` identical to
549
  `allocator_traits<A>::rebind_alloc<T>` and given an lvalue `m` of type
550
+ `A`, a pointer `p` of type `T*`, an expression `v` that denotes an
551
+ lvalue of type `T` or `const T` or an rvalue of type `const T`, and an
552
+ rvalue `rv` of type `T`, the following terms are defined. If `X` is not
553
+ allocator-aware or is a specialization of `basic_string`, the terms
554
+ below are defined as if `A` were `allocator<T>` — no allocator object
555
+ needs to be created and user specializations of `allocator<T>` are not
556
+ instantiated:
557
 
558
  - `T` is **Cpp17DefaultInsertable* into `X`* means that the following
559
  expression is well-formed:
560
  ``` cpp
561
  allocator_traits<A>::construct(m, p)
 
576
 
577
  and its evaluation causes the following postcondition to hold: The
578
  value of `*p` is equivalent to the value of `rv` before the
579
  evaluation.
580
  \[*Note 1*: `rv` remains a valid object. Its state is
581
+ unspecified. — *end note*]
582
  - `T` is **Cpp17CopyInsertable* into `X`* means that, in addition to `T`
583
  being *Cpp17MoveInsertable* into `X`, the following expression is
584
  well-formed:
585
  ``` cpp
586
  allocator_traits<A>::construct(m, p, v)
 
660
  X u(t, m);
661
  ```
662
 
663
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
664
 
665
+ *Ensures:* `u == t`, `u.get_allocator() == m`.
666
 
667
  *Complexity:* Linear.
668
 
669
  ``` cpp
670
  X u(rv);
 
750
  `y[1] = true`. — *end note*]
751
 
752
  ### Sequence containers <a id="sequence.reqmts">[[sequence.reqmts]]</a>
753
 
754
  A sequence container organizes a finite set of objects, all of the same
755
+ type, into a strictly linear arrangement. The library provides the
756
+ following basic kinds of sequence containers: `vector`,
757
+ `inplace_vector`, `forward_list`, `list`, and `deque`. In addition,
758
+ `array` and `hive` are provided as sequence containers which provide
759
+ limited sequence operations, in `array`’s case because it has a fixed
760
+ number of elements, and in `hive`’s case because insertion order is
761
+ unspecified. The library also provides container adaptors that make it
762
  easy to construct abstract data types, such as `stack`s, `queue`s,
763
  `flat_map`s, `flat_multimap`s, `flat_set`s, or `flat_multiset`s, out of
764
  the basic sequence container kinds (or out of other program-defined
765
  sequence containers).
766
 
 
 
 
 
 
 
 
 
 
767
  In this subclause,
768
 
769
  - `X` denotes a sequence container class,
770
  - `a` denotes a value of type `X` containing elements of type `T`,
771
  - `u` denotes the name of a variable being declared,
 
773
  `X::allocator_type` is valid and denotes a type [[temp.deduct]] and
774
  `allocator<T>` if it doesn’t,
775
  - `i` and `j` denote iterators that meet the *Cpp17InputIterator*
776
  requirements and refer to elements implicitly convertible to
777
  `value_type`,
778
+ - \[`i`, `j`) denotes a valid range,
779
  - `rg` denotes a value of a type `R` that models
780
  `container-compatible-range<T>`,
781
  - `il` designates an object of type `initializer_list<value_type>`,
782
  - `n` denotes a value of type `X::size_type`,
783
  - `p` denotes a valid constant iterator to `a`,
784
  - `q` denotes a valid dereferenceable constant iterator to `a`,
785
+ - \[`q1`, `q2`) denotes a valid range of constant iterators in `a`,
786
  - `t` denotes an lvalue or a const rvalue of `X::value_type`, and
787
  - `rv` denotes a non-const rvalue of `X::value_type`.
788
  - `Args` denotes a template parameter pack;
789
  - `args` denotes a function parameter pack with the pattern `Args&&`.
790
 
 
811
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
812
  For `vector`, if the iterator does not meet the *Cpp17ForwardIterator*
813
  requirements [[forward.iterators]], `T` is also *Cpp17MoveInsertable*
814
  into `X`.
815
 
816
+ *Effects:* Constructs a sequence container equal to the range \[`i`,
817
+ `j`). Each iterator in the range \[`i`, `j`) is dereferenced exactly
818
+ once.
819
 
820
  *Ensures:* `distance(u.begin(), u.end()) == distance(i, j)` is `true`.
821
 
822
  ``` cpp
823
  X(from_range, rg)
824
  ```
825
 
826
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
827
+ `*ranges::begin(rg)`. For `vector`, if `R` models
828
+ `ranges::approximately_sized_range` but not `ranges::sized_range` or
829
+ models `ranges::input_range` but not `ranges::forward_range`, `T` is
830
+ also *Cpp17MoveInsertable* into `X`.
831
 
832
  *Effects:* Constructs a sequence container equal to the range `rg`. Each
833
  iterator in the range `rg` is dereferenced exactly once.
834
 
835
+ *Recommended practice:* If `R` models
836
+ `ranges::approximately_sized_range` and
837
+ `ranges::distance(rg) <= ranges::reserve_hint(rg)` is `true`, an
838
+ implementation should not perform more than a single reallocation.
839
+
840
  *Ensures:* `distance(begin(), end()) == ranges::distance(rg)` is `true`.
841
 
842
  ``` cpp
843
  X(il)
844
  ```
 
864
  ```
865
 
866
  *Result:* `iterator`.
867
 
868
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
869
+ `args`. For `vector`, `inplace_vector`, and `deque`, `T` is also
870
+ *Cpp17MoveInsertable* into `X` and *Cpp17MoveAssignable*.
871
 
872
  *Effects:* Inserts an object of type `T` constructed with
873
  `std::forward<Args>(args)...` before `p`.
874
 
875
  [*Note 1*: `args` can directly or indirectly refer to a value in
876
  `a`. — *end note*]
877
 
878
+ *Returns:* An iterator that points to the new element.
 
879
 
880
  ``` cpp
881
  a.insert(p, t)
882
  ```
883
 
884
  *Result:* `iterator`.
885
 
886
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`. For `vector`,
887
+ `inplace_vector`, and `deque`, `T` is also *Cpp17CopyAssignable*.
888
 
889
  *Effects:* Inserts a copy of `t` before `p`.
890
 
891
  *Returns:* An iterator that points to the copy of `t` inserted into `a`.
892
 
 
894
  a.insert(p, rv)
895
  ```
896
 
897
  *Result:* `iterator`.
898
 
899
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`. For `vector`,
900
+ `inplace_vector`, and `deque`, `T` is also *Cpp17MoveAssignable*.
901
 
902
  *Effects:* Inserts a copy of `rv` before `p`.
903
 
904
  *Returns:* An iterator that points to the copy of `rv` inserted into
905
  `a`.
 
923
  ```
924
 
925
  *Result:* `iterator`.
926
 
927
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from `*i`.
928
+ For `vector`, `inplace_vector`, and `deque`, `T` is also
929
+ *Cpp17MoveInsertable* into `X`, and `T` meets the
930
+ *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
931
  *Cpp17Swappable*[[swappable.requirements]] requirements. Neither `i` nor
932
  `j` are iterators into `a`.
933
 
934
+ *Effects:* Inserts copies of elements in \[`i`, `j`) before `p`. Each
935
  iterator in the range \[`i`, `j`) shall be dereferenced exactly once.
936
 
937
  *Returns:* An iterator that points to the copy of the first element
938
  inserted into `a`, or `p` if `i == j`.
939
 
 
942
  ```
943
 
944
  *Result:* `iterator`.
945
 
946
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
947
+ `*ranges::begin(rg)`. For `vector`, `inplace_vector`, and `deque`, `T`
948
+ is also *Cpp17MoveInsertable* into `X`, and `T` meets the
949
  *Cpp17MoveConstructible*, *Cpp17MoveAssignable*, and
950
  *Cpp17Swappable*[[swappable.requirements]] requirements. `rg` and `a` do
951
  not overlap.
952
 
953
  *Effects:* Inserts copies of elements in `rg` before `p`. Each iterator
 
966
  a.erase(q)
967
  ```
968
 
969
  *Result:* `iterator`.
970
 
971
+ *Preconditions:* For `vector`, `inplace_vector`, and `deque`, `T` is
972
+ *Cpp17MoveAssignable*.
973
 
974
  *Effects:* Erases the element pointed to by `q`.
975
 
976
  *Returns:* An iterator that points to the element immediately following
977
  `q` prior to the element being erased. If no such element exists,
 
981
  a.erase(q1, q2)
982
  ```
983
 
984
  *Result:* `iterator`.
985
 
986
+ *Preconditions:* For `vector`, `inplace_vector`, and `deque`, `T` is
987
+ *Cpp17MoveAssignable*.
988
 
989
+ *Effects:* Erases the elements in the range \[`q1`, `q2`).
990
 
991
  *Returns:* An iterator that points to the element pointed to by `q2`
992
  prior to any elements being erased. If no such element exists, `a.end()`
993
  is returned.
994
 
 
1016
  and assignable from `*i`. For `vector`, if the iterator does not meet
1017
  the forward iterator requirements [[forward.iterators]], `T` is also
1018
  *Cpp17MoveInsertable* into `X`. Neither `i` nor `j` are iterators into
1019
  `a`.
1020
 
1021
+ *Effects:* Replaces elements in `a` with a copy of \[`i`, `j`).
1022
+ Invalidates all references, pointers and iterators referring to the
1023
+ elements of `a`. For `vector` and `deque`, also invalidates the
1024
+ past-the-end iterator. Each iterator in the range \[`i`, `j`) is
1025
+ dereferenced exactly once.
1026
 
1027
  ``` cpp
1028
  a.assign_range(rg)
1029
  ```
1030
 
 
1032
 
1033
  *Mandates:* `assignable_from<T&, ranges::range_reference_t<R>>` is
1034
  modeled.
1035
 
1036
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `X` from
1037
+ `*ranges::begin(rg)`. For `vector`, if `R` models
1038
+ `ranges::approximately_sized_range` but not `ranges::sized_range` or
1039
+ models `ranges::input_range` but not `ranges::forward_range`, `T` is
1040
+ also *Cpp17MoveInsertable* into `X`. `rg` and `a` do not overlap.
1041
 
1042
  *Effects:* Replaces elements in `a` with a copy of each element in `rg`.
1043
  Invalidates all references, pointers, and iterators referring to the
1044
  elements of `a`. For `vector` and `deque`, also invalidates the
1045
  past-the-end iterator. Each iterator in the range `rg` is dereferenced
1046
  exactly once.
1047
 
1048
+ *Recommended practice:* If `R` models
1049
+ `ranges::approximately_sized_range` and
1050
+ `ranges::distance(rg) <= ranges::reserve_hint(rg)` is `true`, an
1051
+ implementation should not perform any reallocation.
1052
+
1053
  ``` cpp
1054
  a.assign(il)
1055
  ```
1056
 
1057
  *Effects:* Equivalent to `a.assign(il.begin(), il.end())`.
 
1113
  a.front()
1114
  ```
1115
 
1116
  *Result:* `reference; const_reference` for constant `a`.
1117
 
1118
+ `a.empty()` is `false`.
1119
+
1120
  *Returns:* `*a.begin()`
1121
 
1122
  *Remarks:* Required for `basic_string`, `array`, `deque`,
1123
+ `forward_list`, `inplace_vector`, `list`, and `vector`.
1124
 
1125
  ``` cpp
1126
  a.back()
1127
  ```
1128
 
1129
  *Result:* `reference; const_reference` for constant `a`.
1130
 
1131
+ `a.empty()` is `false`.
1132
+
1133
  *Effects:* Equivalent to:
1134
 
1135
  ``` cpp
1136
  auto tmp = a.end();
1137
  --tmp;
1138
  return *tmp;
1139
  ```
1140
 
1141
+ *Remarks:* Required for `basic_string`, `array`, `deque`,
1142
+ `inplace_vector`, `list`, and `vector`.
1143
 
1144
  ``` cpp
1145
  a.emplace_front(args)
1146
  ```
1147
 
 
1169
  *Effects:* Appends an object of type `T` constructed with
1170
  `std::forward<Args>(args)...`.
1171
 
1172
  *Returns:* `a.back()`.
1173
 
1174
+ *Remarks:* Required for `deque`, `inplace_vector`, `list`, and `vector`.
1175
 
1176
  ``` cpp
1177
  a.push_front(t)
1178
  ```
1179
 
 
1225
 
1226
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `X`.
1227
 
1228
  *Effects:* Appends a copy of `t`.
1229
 
1230
+ *Remarks:* Required for `basic_string`, `deque`, `inplace_vector`,
1231
+ `list`, and `vector`.
1232
 
1233
  ``` cpp
1234
  a.push_back(rv)
1235
  ```
1236
 
 
1238
 
1239
  *Preconditions:* `T` is *Cpp17MoveInsertable* into `X`.
1240
 
1241
  *Effects:* Appends a copy of `rv`.
1242
 
1243
+ *Remarks:* Required for `basic_string`, `deque`, `inplace_vector`,
1244
+ `list`, and `vector`.
1245
 
1246
  ``` cpp
1247
  a.append_range(rg)
1248
  ```
1249
 
 
1254
  into `X`.
1255
 
1256
  *Effects:* Inserts copies of elements in `rg` before `end()`. Each
1257
  iterator in the range `rg` is dereferenced exactly once.
1258
 
1259
+ *Remarks:* Required for `deque`, `inplace_vector`, `list`, and `vector`.
1260
 
1261
  ``` cpp
1262
  a.pop_front()
1263
  ```
1264
 
1265
  *Result:* `void`
1266
 
1267
+ `a.empty()` is `false`.
1268
 
1269
  *Effects:* Destroys the first element.
1270
 
1271
  *Remarks:* Required for `deque`, `forward_list`, and `list`.
1272
 
 
1274
  a.pop_back()
1275
  ```
1276
 
1277
  *Result:* `void`
1278
 
1279
+ `a.empty()` is `false`.
1280
 
1281
  *Effects:* Destroys the last element.
1282
 
1283
+ *Remarks:* Required for `basic_string`, `deque`, `inplace_vector`,
1284
+ `list`, and `vector`.
1285
 
1286
  ``` cpp
1287
  a[n]
1288
  ```
1289
 
1290
+ *Result:* `reference; const_reference` for constant `a`.
1291
 
1292
+ `n < a.size()` is `true`.
1293
 
1294
+ *Effects:* Equivalent to: `return *(a.begin() + n);`
1295
+
1296
+ *Remarks:* Required for `basic_string`, `array`, `deque`,
1297
+ `inplace_vector`, and `vector`.
1298
 
1299
  ``` cpp
1300
  a.at(n)
1301
  ```
1302
 
1303
+ *Result:* `reference; const_reference` for constant `a`.
1304
 
1305
  *Returns:* `*(a.begin() + n)`
1306
 
1307
  *Throws:* `out_of_range` if `n >= a.size()`.
1308
 
1309
+ *Remarks:* Required for `basic_string`, `array`, `deque`,
1310
+ `inplace_vector`, and `vector`.
1311
 
1312
  ### Node handles <a id="container.node">[[container.node]]</a>
1313
 
1314
  #### Overview <a id="container.node.overview">[[container.node.overview]]</a>
1315
 
 
1355
  using key_type = see below; // not present for set containers
1356
  using mapped_type = see below; // not present for set containers
1357
  using allocator_type = see below;
1358
 
1359
  private:
1360
+ using container-node-type = unspecified; // exposition only
1361
+ using ator-traits = allocator_traits<allocator_type>; // exposition only
1362
 
1363
+ typename ator-traits::template
1364
+ rebind_traits<container-node-type>::pointer ptr_; // exposition only
1365
  optional<allocator_type> alloc_; // exposition only
1366
 
1367
  public:
1368
  // [container.node.cons], constructors, copy, and assignment
1369
  constexpr node-handle() noexcept : ptr_(), alloc_() {}
1370
+ constexpr node-handle(node-handle&&) noexcept;
1371
+ constexpr node-handle& operator=(node-handle&&);
1372
 
1373
  // [container.node.dtor], destructor
1374
+ constexpr ~node-handle();
1375
 
1376
  // [container.node.observers], observers
1377
+ constexpr value_type& value() const; // not present for map containers
1378
  key_type& key() const; // not present for set containers
1379
+ constexpr mapped_type& mapped() const; // not present for set containers
1380
 
1381
+ constexpr allocator_type get_allocator() const;
1382
+ constexpr explicit operator bool() const noexcept;
1383
+ constexpr bool empty() const noexcept;
1384
 
1385
  // [container.node.modifiers], modifiers
1386
+ constexpr void swap(node-handle&)
1387
+ noexcept(ator-traits::propagate_on_container_swap::value ||
1388
+ ator-traits::is_always_equal::value);
1389
 
1390
+ friend constexpr void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
1391
  x.swap(y);
1392
  }
1393
  };
1394
  ```
1395
 
1396
  #### Constructors, copy, and assignment <a id="container.node.cons">[[container.node.cons]]</a>
1397
 
1398
  ``` cpp
1399
+ constexpr node-handle(node-handle&& nh) noexcept;
1400
  ```
1401
 
1402
+ *Effects:* Constructs a *node-handle* object initializing *ptr\_* with
1403
+ `nh.`*`ptr_`*. Move constructs *alloc\_* with `nh.`*`alloc_`*. Assigns
1404
+ `nullptr` to `nh.`*`ptr_`* and assigns `nullopt` to `nh.`*`alloc_`*.
1405
 
1406
  ``` cpp
1407
+ constexpr node-handle& operator=(node-handle&& nh);
1408
  ```
1409
 
1410
+ *Preconditions:* Either `!`*`alloc_`* is `true`, or
1411
+ *`ator-traits`*`::propagate_on_container_move_assignment::value` is
1412
+ `true`, or *`alloc_`*` == nh.`*`alloc_`* is `true`.
1413
 
1414
  *Effects:*
1415
 
1416
+ - If *`ptr_`*` != nullptr` is `true`, destroys the `value_type`
1417
+ subobject in the *container-node-type* object pointed to by *ptr\_* by
1418
+ calling *`ator-traits`*`::destroy`, then deallocates *ptr\_* by
1419
+ calling
1420
+ *`ator-traits`*`::template rebind_traits<`*`container-node-type`*`>::deallocate`.
1421
+ - Assigns `nh.`*`ptr_`* to *ptr\_*.
1422
+ - If `!`*`alloc_`* is `true` or
1423
+ *`ator-traits`*`::propagate_on_container_move_assignment::value` is
1424
+ `true`, move assigns `nh.`*`alloc_`* to *alloc\_*.
1425
+ - Assigns `nullptr` to `nh.`*`ptr_`* and assigns `nullopt` to
1426
+ `nh.`*`alloc_`*.
1427
 
1428
  *Returns:* `*this`.
1429
 
1430
  *Throws:* Nothing.
1431
 
1432
  #### Destructor <a id="container.node.dtor">[[container.node.dtor]]</a>
1433
 
1434
  ``` cpp
1435
+ constexpr ~node-handle();
1436
  ```
1437
 
1438
+ *Effects:* If *`ptr_`*` != nullptr` is `true`, destroys the `value_type`
1439
+ subobject in the *container-node-type* object pointed to by *ptr\_* by
1440
+ calling *`ator-traits`*`::destroy`, then deallocates *ptr\_* by calling
1441
+ *`ator-traits`*`::template rebind_traits<`*`container-node-type`*`>::deallocate`.
1442
 
1443
  #### Observers <a id="container.node.observers">[[container.node.observers]]</a>
1444
 
1445
  ``` cpp
1446
+ constexpr value_type& value() const;
1447
  ```
1448
 
1449
  *Preconditions:* `empty() == false`.
1450
 
1451
  *Returns:* A reference to the `value_type` subobject in the
1452
+ *container-node-type* object pointed to by *ptr\_*.
1453
 
1454
  *Throws:* Nothing.
1455
 
1456
  ``` cpp
1457
  key_type& key() const;
1458
  ```
1459
 
1460
  *Preconditions:* `empty() == false`.
1461
 
1462
  *Returns:* A non-const reference to the `key_type` member of the
1463
+ `value_type` subobject in the *container-node-type* object pointed to by
1464
+ *ptr\_*.
1465
 
1466
  *Throws:* Nothing.
1467
 
1468
  *Remarks:* Modifying the key through the returned reference is
1469
  permitted.
1470
 
1471
  ``` cpp
1472
+ constexpr mapped_type& mapped() const;
1473
  ```
1474
 
1475
  *Preconditions:* `empty() == false`.
1476
 
1477
  *Returns:* A reference to the `mapped_type` member of the `value_type`
1478
+ subobject in the *container-node-type* object pointed to by *ptr\_*.
1479
 
1480
  *Throws:* Nothing.
1481
 
1482
  ``` cpp
1483
+ constexpr allocator_type get_allocator() const;
1484
  ```
1485
 
1486
  *Preconditions:* `empty() == false`.
1487
 
1488
+ *Returns:* `*`*`alloc_`*.
1489
 
1490
  *Throws:* Nothing.
1491
 
1492
  ``` cpp
1493
+ constexpr explicit operator bool() const noexcept;
1494
  ```
1495
 
1496
+ *Returns:* *`ptr_`*` != nullptr`.
1497
 
1498
  ``` cpp
1499
+ constexpr bool empty() const noexcept;
1500
  ```
1501
 
1502
+ *Returns:* *`ptr_`*` == nullptr`.
1503
 
1504
  #### Modifiers <a id="container.node.modifiers">[[container.node.modifiers]]</a>
1505
 
1506
  ``` cpp
1507
+ constexpr void swap(node-handle& nh)
1508
+ noexcept(ator-traits::propagate_on_container_swap::value ||
1509
+ ator-traits::is_always_equal::value);
1510
  ```
1511
 
1512
+ *Preconditions:* `!`*`alloc_`* is `true`, or `!nh.`*`alloc_`*, or
1513
+ *`ator-traits`*`::propagate_on_container_swap::value` is `true`, or
1514
+ *`alloc_`*` == nh.`*`alloc_`* is `true`.
1515
 
1516
+ *Effects:* Calls `swap(`*`ptr_`*`, nh.`*`ptr_`*`)`. If `!`*`alloc_`* is
1517
+ `true`, or `!nh.`*`alloc_`* is `true`, or
1518
+ *`ator-traits`*`::propagate_on_container_swap::value` is `true` calls
1519
+ `swap(`*`alloc_`*`, nh.`*`alloc_`*`)`.
1520
 
1521
  ### Insert return type <a id="container.insert.return">[[container.insert.return]]</a>
1522
 
1523
  The associative containers with unique keys and the unordered containers
1524
  with unique keys have a member function `insert` that returns a nested
 
1533
  bool inserted;
1534
  NodeType node;
1535
  };
1536
  ```
1537
 
1538
+ The name *`insert-return-type`* is for exposition only.
1539
  *`insert-return-type`* has the template parameters, data members, and
1540
  special members specified above. It has no base classes or members other
1541
  than those specified.
1542
 
1543
  ### Associative containers <a id="associative.reqmts">[[associative.reqmts]]</a>
 
1596
 
1597
  - `X` denotes an associative container class,
1598
  - `a` denotes a value of type `X`,
1599
  - `a2` denotes a value of a type with nodes compatible with type `X` (
1600
  [[container.node.compat]]),
1601
+ - `b` denotes a value of type `X` or `const X`,
1602
  - `u` denotes the name of a variable being declared,
1603
  - `a_uniq` denotes a value of type `X` when `X` supports unique keys,
1604
+ - `a_eq` denotes a value of type `X` when `X` supports equivalent keys,
1605
  - `a_tran` denotes a value of type `X` or `const X` when the
1606
  *qualified-id* `X::key_compare::is_transparent` is valid and denotes a
1607
  type [[temp.deduct]],
1608
  - `i` and `j` meet the *Cpp17InputIterator* requirements and refer to
1609
  elements implicitly convertible to `value_type`,
 
1611
  - `rg` denotes a value of a type `R` that models
1612
  `container-compatible-range<value_type>`,
1613
  - `p` denotes a valid constant iterator to `a`,
1614
  - `q` denotes a valid dereferenceable constant iterator to `a`,
1615
  - `r` denotes a valid dereferenceable iterator to `a`,
1616
+ - \[`q1`, `q2`) denotes a valid range of constant iterators in `a`,
1617
  - `il` designates an object of type `initializer_list<value_type>`,
1618
  - `t` denotes a value of type `X::value_type`,
1619
  - `k` denotes a value of type `X::key_type`, and
1620
  - `c` denotes a value of type `X::key_compare` or
1621
  `const X::key_compare`;
 
1637
  - `m` denotes an allocator of a type convertible to `A`, and `nh`
1638
  denotes a non-const rvalue of type `X::node_type`.
1639
 
1640
  A type `X` meets the *associative container* requirements if `X` meets
1641
  all the requirements of an allocator-aware container
1642
+ [[container.alloc.reqmts]] and the following types, statements, and
1643
+ expressions are well-formed and have the specified semantics, except
1644
  that for `map` and `multimap`, the requirements placed on `value_type`
1645
+ in [[container.reqmts]] apply instead to `key_type` and `mapped_type`.
 
1646
 
1647
+ [*Note 3*: For example, in some cases `key_type` and `mapped_type` need
1648
+ to be *Cpp17CopyAssignable* even though the associated `value_type`,
1649
+ `pair<const key_type, mapped_type>`, is not
1650
  *Cpp17CopyAssignable*. — *end note*]
1651
 
1652
  ``` cpp
1653
  typename X::key_type
1654
  ```
 
1867
 
1868
  *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`,
1869
  except that the element is inserted as close as possible to the position
1870
  just prior to `p`.
1871
 
1872
+ *Returns:* The iterator returned by `emplace`.
 
1873
 
1874
  *Complexity:* Logarithmic in general, but amortized constant if the
1875
  element is inserted right before `p`.
1876
 
1877
  ``` cpp
 
2080
  a.merge(a2)
2081
  ```
2082
 
2083
  *Result:* `void`
2084
 
2085
+ *Preconditions:* `a.get_allocator() == a2.get_allocator()` is `true`.
2086
 
2087
  *Effects:* Attempts to extract each element in `a2` and insert it into
2088
  `a` using the comparison object of `a`. In containers with unique keys,
2089
  if there is an element in `a` with key equivalent to the key of an
2090
  element from `a2`, then that element is not extracted from `a2`.
2091
 
2092
  *Ensures:* Pointers and references to the transferred elements of `a2`
2093
+ refer to those same elements but as members of `a`. If `a.begin()` and
2094
+ `a2.begin()` have the same type, iterators referring to the transferred
2095
+ elements will continue to refer to their elements, but they now behave
2096
+ as iterators into `a`, not into `a2`.
2097
 
2098
  *Throws:* Nothing unless the comparison object throws.
2099
 
2100
  *Complexity:* N log(`a.size()+` N), where N has the value `a2.size()`.
2101
 
 
2267
  *Result:* `iterator`; `const_iterator` for constant `b`.
2268
 
2269
  *Returns:* An iterator pointing to the first element with key greater
2270
  than `k`, or `b.end()` if such an element is not found.
2271
 
2272
+ *Complexity:* Logarithmic.
2273
 
2274
  ``` cpp
2275
  a_tran.upper_bound(ku)
2276
  ```
2277
 
 
2469
  - `a_tran` denotes a value of type `X` or `const X` when the
2470
  *qualified-id*s `X::key_equal::is_transparent` and
2471
  `X::hasher::is_transparent` are both valid and denote types
2472
  [[temp.deduct]],
2473
  - `i` and `j` denote input iterators that refer to `value_type`,
2474
+ - \[`i`, `j`) denotes a valid range,
2475
  - `rg` denotes a value of a type `R` that models
2476
  `container-compatible-range<value_type>`,
2477
  - `p` and `q2` denote valid constant iterators to `a`,
2478
  - `q` and `q1` denote valid dereferenceable constant iterators to `a`,
2479
  - `r` denotes a valid dereferenceable iterator to `a`,
2480
+ - \[`q1`, `q2`) denotes a valid range in `a`,
2481
  - `il` denotes a value of type `initializer_list<value_type>`,
2482
  - `t` denotes a value of type `X::value_type`,
2483
  - `k` denotes a value of type `key_type`,
2484
  - `hf` denotes a value of type `hasher` or `const hasher`,
2485
  - `eq` denotes a value of type `key_equal` or `const key_equal`,
 
2502
  - `z` denotes a value of type `float`, and
2503
  - `nh` denotes an rvalue of type `X::node_type`.
2504
 
2505
  A type `X` meets the *unordered associative container* requirements if
2506
  `X` meets all the requirements of an allocator-aware container
2507
+ [[container.alloc.reqmts]] and the following types, statements, and
2508
+ expressions are well-formed and have the specified semantics, except
2509
  that for `unordered_map` and `unordered_multimap`, the requirements
2510
+ placed on `value_type` in [[container.reqmts]] apply instead to
2511
  `key_type` and `mapped_type`.
2512
 
2513
+ [*Note 3*: For example, `key_type` and `mapped_type` sometimes need to
2514
+ be *Cpp17CopyAssignable* even though the associated `value_type`,
2515
+ `pair<const key_type, mapped_type>`, is not
2516
  *Cpp17CopyAssignable*. — *end note*]
2517
 
2518
  ``` cpp
2519
  typename X::key_type
2520
  ```
 
2781
  ``` cpp
2782
  X(b)
2783
  ```
2784
 
2785
  *Effects:* In addition to the container
2786
+ requirements [[container.reqmts]], copies the hash function, predicate,
2787
+ and maximum load factor.
2788
 
2789
  *Complexity:* Average case linear in `b.size()`, worst case quadratic.
2790
 
2791
  ``` cpp
2792
  a = b
 
2872
  a.emplace_hint(p, args)
2873
  ```
2874
 
2875
  *Result:* `iterator`
2876
 
2877
+ *Effects:* Equivalent to `a.emplace(std::forward<Args>(args)...)`,
2878
+ except that the `const_iterator` `p` is a hint pointing to where the
2879
+ search should start. Implementations are permitted to ignore the hint.
2880
 
2881
+ *Returns:* The iterator returned by `emplace`.
 
 
 
 
 
 
 
2882
 
2883
  ``` cpp
2884
  a_uniq.insert(t)
2885
  ```
2886
 
 
2941
  *Result:* `void`
2942
 
2943
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `X`
2944
  from `*i`. Neither `i` nor `j` are iterators into `a`.
2945
 
2946
+ *Effects:* Equivalent to `a.insert(t)` for each element in \[`i`, `j`).
2947
 
2948
  *Complexity:* Average case 𝑂(N), where N is `distance(i, j)`, worst case
2949
  𝑂(N(`a.size()` + 1)).
2950
 
2951
  ``` cpp
 
3147
  a.erase(q1, q2)
3148
  ```
3149
 
3150
  *Result:* `iterator`
3151
 
3152
+ *Effects:* Erases all elements in the range \[`q1`, `q2`).
3153
 
3154
  *Returns:* The iterator immediately following the erased elements prior
3155
  to the erasure.
3156
 
3157
  *Complexity:* Average case linear in `distance(q1, q2)`, worst case
 
3279
 
3280
  *Preconditions:* `b.bucket_count() > 0`.
3281
 
3282
  *Returns:* The index of the bucket in which elements with keys
3283
  equivalent to `k` would be found, if any such element existed. The
3284
+ return value is in the range \[`0`, `b.bucket_count()`).
3285
+
3286
+ *Complexity:* Constant.
3287
+
3288
+ ``` cpp
3289
+ a_tran.bucket(ke)
3290
+ ```
3291
+
3292
+ *Result:* `size_type`
3293
+
3294
+ *Preconditions:* `a_tran.bucket_count() > 0`.
3295
+
3296
+ *Ensures:* The return value is in the range \[`0`,
3297
+ `a_tran.bucket_count()`).
3298
+
3299
+ *Returns:* The index of the bucket in which elements with keys
3300
+ equivalent to `ke` would be found, if any such element existed.
3301
 
3302
  *Complexity:* Constant.
3303
 
3304
  ``` cpp
3305
  b.bucket_size(n)
3306
  ```
3307
 
3308
  *Result:* `size_type`
3309
 
3310
+ *Preconditions:* `n` shall be in the range \[`0`, `b.bucket_count()`).
3311
 
3312
  *Returns:* The number of elements in the `n`ᵗʰ bucket.
3313
 
3314
  *Complexity:* 𝑂(`b.bucket_size(n)`)
3315
 
 
3317
  b.begin(n)
3318
  ```
3319
 
3320
  *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3321
 
3322
+ *Preconditions:* `n` is in the range \[`0`, `b.bucket_count()`).
3323
 
3324
  *Returns:* An iterator referring to the first element in the bucket. If
3325
  the bucket is empty, then `b.begin(n) == b.end(n)`.
3326
 
3327
  *Complexity:* Constant.
 
3330
  b.end(n)
3331
  ```
3332
 
3333
  *Result:* `local_iterator`; `const_local_iterator` for constant `b`.
3334
 
3335
+ *Preconditions:* `n` is in the range \[`0`, `b.bucket_count()`).
3336
 
3337
  *Returns:* An iterator which is the past-the-end value for the bucket.
3338
 
3339
  *Complexity:* Constant.
3340
 
 
3342
  b.cbegin(n)
3343
  ```
3344
 
3345
  *Result:* `const_local_iterator`
3346
 
3347
+ *Preconditions:* `n` shall be in the range \[`0`, `b.bucket_count()`).
3348
 
3349
  *Returns:* An iterator referring to the first element in the bucket. If
3350
  the bucket is empty, then `b.cbegin(n) == b.cend(n)`.
3351
 
3352
  *Complexity:* Constant.
 
3355
  b.cend(n)
3356
  ```
3357
 
3358
  *Result:* `const_local_iterator`
3359
 
3360
+ *Preconditions:* `n` is in the range \[`0`, `b.bucket_count()`).
3361
 
3362
  *Returns:* An iterator which is the past-the-end value for the bucket.
3363
 
3364
  *Complexity:* Constant.
3365
 
 
3464
  element is owned by a `node_type` is undefined behavior. References and
3465
  pointers to an element obtained while it is owned by a `node_type` are
3466
  invalidated if the element is successfully inserted.
3467
 
3468
  The member function templates `find`, `count`, `equal_range`,
3469
+ `contains`, `extract`, `erase`, and `bucket` shall not participate in
3470
+ overload resolution unless the *qualified-id*s `Pred::is_transparent`
3471
+ and `Hash::is_transparent` are both valid and denote types
3472
+ [[temp.deduct]]. Additionally, the member function templates `extract`
3473
+ and `erase` shall not participate in overload resolution if
3474
  `is_convertible_v<K&&, iterator> || is_convertible_v<K&&, const_iterator>`
3475
  is `true`, where `K` is the type substituted as the first template
3476
  argument.
3477
 
3478
  A deduction guide for an unordered associative container shall not
 
3506
  within a `rehash()` function other than by the container’s hash function
3507
  or comparison function, the `rehash()` function has no effect.
3508
 
3509
  ## Sequence containers <a id="sequences">[[sequences]]</a>
3510
 
3511
+ ### General <a id="sequences.general">[[sequences.general]]</a>
3512
 
3513
+ The headers `<array>`, `<deque>`, `<forward_list>`, `<hive>`,
3514
+ `<inplace_vector>`, `<list>`, and `<vector>` define class templates that
3515
+ meet the requirements for sequence containers.
3516
 
3517
  The following exposition-only alias template may appear in deduction
3518
  guides for sequence containers:
3519
 
3520
  ``` cpp
3521
  template<class InputIterator>
3522
+ using iter-value-type = iterator_traits<InputIterator>::value_type; // exposition only
3523
  ```
3524
 
3525
  ### Header `<array>` synopsis <a id="array.syn">[[array.syn]]</a>
3526
 
3527
  ``` cpp
3528
+ // mostly freestanding
3529
  #include <compare> // see [compare.syn]
3530
  #include <initializer_list> // see [initializer.list.syn]
3531
 
3532
  namespace std {
3533
  // [array], class template array
3534
+ template<class T, size_t N> struct array; // partially freestanding
3535
 
3536
  template<class T, size_t N>
3537
  constexpr bool operator==(const array<T, N>& x, const array<T, N>& y);
3538
  template<class T, size_t N>
3539
  constexpr synth-three-way-result<T>
 
3565
  template<size_t I, class T, size_t N>
3566
  constexpr const T&& get(const array<T, N>&&) noexcept;
3567
  }
3568
  ```
3569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3570
  ### Class template `array` <a id="array">[[array]]</a>
3571
 
3572
  #### Overview <a id="array.overview">[[array.overview]]</a>
3573
 
3574
  The header `<array>` defines a class template for storing fixed-size
 
3587
  requirements of a sequence container [[sequence.reqmts]]. Descriptions
3588
  are provided here only for operations on `array` that are not described
3589
  in one of these tables and for operations where there is additional
3590
  semantic information.
3591
 
3592
+ `array<T, N>` is a structural type [[term.structural.type]] if `T` is a
3593
+ structural type. Two values `a1` and `a2` of type `array<T, N>` are
3594
  template-argument-equivalent [[temp.type]] if and only if each pair of
3595
  corresponding elements in `a1` and `a2` are
3596
  template-argument-equivalent.
3597
 
3598
  The types `iterator` and `const_iterator` meet the constexpr iterator
 
3635
  constexpr const_iterator cend() const noexcept;
3636
  constexpr const_reverse_iterator crbegin() const noexcept;
3637
  constexpr const_reverse_iterator crend() const noexcept;
3638
 
3639
  // capacity
3640
+ constexpr bool empty() const noexcept;
3641
  constexpr size_type size() const noexcept;
3642
  constexpr size_type max_size() const noexcept;
3643
 
3644
  // element access
3645
  constexpr reference operator[](size_type n);
3646
  constexpr const_reference operator[](size_type n) const;
3647
+ constexpr reference at(size_type n); // freestanding-deleted
3648
+ constexpr const_reference at(size_type n) const; // freestanding-deleted
3649
  constexpr reference front();
3650
  constexpr const_reference front() const;
3651
  constexpr reference back();
3652
  constexpr const_reference back() const;
3653
 
 
3660
  }
3661
  ```
3662
 
3663
  #### Constructors, copy, and assignment <a id="array.cons">[[array.cons]]</a>
3664
 
3665
+ An `array` relies on the implicitly-declared special member functions
 
3666
  [[class.default.ctor]], [[class.dtor]], [[class.copy.ctor]] to conform
3667
  to the container requirements table in  [[container.requirements]]. In
3668
  addition to the requirements specified in the container requirements
3669
+ table, the implicitly-declared move constructor and move assignment
3670
+ operator for `array` require that `T` be *Cpp17MoveConstructible* or
3671
  *Cpp17MoveAssignable*, respectively.
3672
 
3673
  ``` cpp
3674
  template<class T, class... U>
3675
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
 
3689
  constexpr T* data() noexcept;
3690
  constexpr const T* data() const noexcept;
3691
  ```
3692
 
3693
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
3694
+ range. For a non-empty array, `data() == addressof(front())` is `true`.
3695
 
3696
  ``` cpp
3697
  constexpr void fill(const T& u);
3698
  ```
3699
 
 
3741
  ``` cpp
3742
  template<class T, size_t N>
3743
  constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
3744
  ```
3745
 
3746
+ *Mandates:* `is_array_v<T>` is `false` and
3747
+ `is_constructible_v<remove_cv_t<T>, T&>` is `true`.
3748
 
3749
  *Preconditions:* `T` meets the *Cpp17CopyConstructible* requirements.
3750
 
3751
  *Returns:* `{{ a[0], `…`, a[N - 1] }}`.
3752
 
3753
  ``` cpp
3754
  template<class T, size_t N>
3755
  constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
3756
  ```
3757
 
3758
+ *Mandates:* `is_array_v<T>` is `false` and
3759
+ `is_constructible_v<remove_cv_t<T>, T>` is `true`.
3760
 
3761
  *Preconditions:* `T` meets the *Cpp17MoveConstructible* requirements.
3762
 
3763
  *Returns:* `{{ std::move(a[0]), `…`, std::move(a[N - 1]) }}`.
3764
 
 
3792
  *Mandates:* `I < N` is `true`.
3793
 
3794
  *Returns:* A reference to the `I`ᵗʰ element of `a`, where indexing is
3795
  zero-based.
3796
 
3797
+ ### Header `<deque>` synopsis <a id="deque.syn">[[deque.syn]]</a>
3798
+
3799
+ ``` cpp
3800
+ #include <compare> // see [compare.syn]
3801
+ #include <initializer_list> // see [initializer.list.syn]
3802
+
3803
+ namespace std {
3804
+ // [deque], class template deque
3805
+ template<class T, class Allocator = allocator<T>> class deque;
3806
+
3807
+ template<class T, class Allocator>
3808
+ constexpr bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
3809
+ template<class T, class Allocator>
3810
+ constexpr synth-three-way-result<T>
3811
+ operator<=>(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
3812
+
3813
+ template<class T, class Allocator>
3814
+ constexpr void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
3815
+ noexcept(noexcept(x.swap(y)));
3816
+
3817
+ // [deque.erasure], erasure
3818
+ template<class T, class Allocator, class U = T>
3819
+ constexpr typename deque<T, Allocator>::size_type
3820
+ erase(deque<T, Allocator>& c, const U& value);
3821
+ template<class T, class Allocator, class Predicate>
3822
+ constexpr typename deque<T, Allocator>::size_type
3823
+ erase_if(deque<T, Allocator>& c, Predicate pred);
3824
+
3825
+ namespace pmr {
3826
+ template<class T>
3827
+ using deque = std::deque<T, polymorphic_allocator<T>>;
3828
+ }
3829
+ }
3830
+ ```
3831
+
3832
  ### Class template `deque` <a id="deque">[[deque]]</a>
3833
 
3834
  #### Overview <a id="deque.overview">[[deque.overview]]</a>
3835
 
3836
  A `deque` is a sequence container that supports random access iterators
 
3847
  optional sequence container requirements [[sequence.reqmts]].
3848
  Descriptions are provided here only for operations on `deque` that are
3849
  not described in one of these tables or for operations where there is
3850
  additional semantic information.
3851
 
3852
+ The types `iterator` and `const_iterator` meet the constexpr iterator
3853
+ requirements [[iterator.requirements.general]].
3854
+
3855
  ``` cpp
3856
  namespace std {
3857
  template<class T, class Allocator = allocator<T>>
3858
  class deque {
3859
  public:
3860
  // types
3861
  using value_type = T;
3862
  using allocator_type = Allocator;
3863
+ using pointer = allocator_traits<Allocator>::pointer;
3864
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
3865
  using reference = value_type&;
3866
  using const_reference = const value_type&;
3867
  using size_type = implementation-defined // type of deque::size_type; // see [container.requirements]
3868
  using difference_type = implementation-defined // type of deque::difference_type; // see [container.requirements]
3869
  using iterator = implementation-defined // type of deque::iterator; // see [container.requirements]
3870
  using const_iterator = implementation-defined // type of deque::const_iterator; // see [container.requirements]
3871
  using reverse_iterator = std::reverse_iterator<iterator>;
3872
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3873
 
3874
  // [deque.cons], construct/copy/destroy
3875
+ constexpr deque() : deque(Allocator()) { }
3876
+ constexpr explicit deque(const Allocator&);
3877
+ constexpr explicit deque(size_type n, const Allocator& = Allocator());
3878
+ constexpr deque(size_type n, const T& value, const Allocator& = Allocator());
3879
  template<class InputIterator>
3880
+ constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
3881
  template<container-compatible-range<T> R>
3882
+ constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator());
3883
+ constexpr deque(const deque& x);
3884
+ constexpr deque(deque&&);
3885
+ constexpr deque(const deque&, const type_identity_t<Allocator>&);
3886
+ constexpr deque(deque&&, const type_identity_t<Allocator>&);
3887
+ constexpr deque(initializer_list<T>, const Allocator& = Allocator());
3888
 
3889
+ constexpr ~deque();
3890
+ constexpr deque& operator=(const deque& x);
3891
+ constexpr deque& operator=(deque&& x)
3892
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
3893
+ constexpr deque& operator=(initializer_list<T>);
3894
  template<class InputIterator>
3895
+ constexpr void assign(InputIterator first, InputIterator last);
3896
  template<container-compatible-range<T> R>
3897
+ constexpr void assign_range(R&& rg);
3898
+ constexpr void assign(size_type n, const T& t);
3899
+ constexpr void assign(initializer_list<T>);
3900
+ constexpr allocator_type get_allocator() const noexcept;
3901
 
3902
  // iterators
3903
+ constexpr iterator begin() noexcept;
3904
+ constexpr const_iterator begin() const noexcept;
3905
+ constexpr iterator end() noexcept;
3906
+ constexpr const_iterator end() const noexcept;
3907
+ constexpr reverse_iterator rbegin() noexcept;
3908
+ constexpr const_reverse_iterator rbegin() const noexcept;
3909
+ constexpr reverse_iterator rend() noexcept;
3910
+ constexpr const_reverse_iterator rend() const noexcept;
3911
 
3912
+ constexpr const_iterator cbegin() const noexcept;
3913
+ constexpr const_iterator cend() const noexcept;
3914
+ constexpr const_reverse_iterator crbegin() const noexcept;
3915
+ constexpr const_reverse_iterator crend() const noexcept;
3916
 
3917
  // [deque.capacity], capacity
3918
+ constexpr bool empty() const noexcept;
3919
+ constexpr size_type size() const noexcept;
3920
+ constexpr size_type max_size() const noexcept;
3921
+ constexpr void resize(size_type sz);
3922
+ constexpr void resize(size_type sz, const T& c);
3923
+ constexpr void shrink_to_fit();
3924
 
3925
  // element access
3926
+ constexpr reference operator[](size_type n);
3927
+ constexpr const_reference operator[](size_type n) const;
3928
+ constexpr reference at(size_type n);
3929
+ constexpr const_reference at(size_type n) const;
3930
+ constexpr reference front();
3931
+ constexpr const_reference front() const;
3932
+ constexpr reference back();
3933
+ constexpr const_reference back() const;
3934
 
3935
  // [deque.modifiers], modifiers
3936
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
3937
+ template<class... Args> constexpr reference emplace_back(Args&&... args);
3938
+ template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
3939
 
3940
+ constexpr void push_front(const T& x);
3941
+ constexpr void push_front(T&& x);
3942
  template<container-compatible-range<T> R>
3943
+ constexpr void prepend_range(R&& rg);
3944
+ constexpr void push_back(const T& x);
3945
+ constexpr void push_back(T&& x);
3946
  template<container-compatible-range<T> R>
3947
+ constexpr void append_range(R&& rg);
3948
 
3949
+ constexpr iterator insert(const_iterator position, const T& x);
3950
+ constexpr iterator insert(const_iterator position, T&& x);
3951
+ constexpr iterator insert(const_iterator position, size_type n, const T& x);
3952
  template<class InputIterator>
3953
+ constexpr iterator insert(const_iterator position,
3954
+ InputIterator first, InputIterator last);
3955
  template<container-compatible-range<T> R>
3956
+ constexpr iterator insert_range(const_iterator position, R&& rg);
3957
+ constexpr iterator insert(const_iterator position, initializer_list<T>);
3958
 
3959
+ constexpr void pop_front();
3960
+ constexpr void pop_back();
3961
 
3962
+ constexpr iterator erase(const_iterator position);
3963
+ constexpr iterator erase(const_iterator first, const_iterator last);
3964
+ constexpr void swap(deque&)
3965
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
3966
+ constexpr void clear() noexcept;
3967
  };
3968
 
3969
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
3970
  deque(InputIterator, InputIterator, Allocator = Allocator())
3971
  -> deque<iter-value-type<InputIterator>, Allocator>;
 
3977
  ```
3978
 
3979
  #### Constructors, copy, and assignment <a id="deque.cons">[[deque.cons]]</a>
3980
 
3981
  ``` cpp
3982
+ constexpr explicit deque(const Allocator&);
3983
  ```
3984
 
3985
  *Effects:* Constructs an empty `deque`, using the specified allocator.
3986
 
3987
  *Complexity:* Constant.
3988
 
3989
  ``` cpp
3990
+ constexpr explicit deque(size_type n, const Allocator& = Allocator());
3991
  ```
3992
 
3993
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `deque`.
3994
 
3995
  *Effects:* Constructs a `deque` with `n` default-inserted elements using
3996
  the specified allocator.
3997
 
3998
  *Complexity:* Linear in `n`.
3999
 
4000
  ``` cpp
4001
+ constexpr deque(size_type n, const T& value, const Allocator& = Allocator());
4002
  ```
4003
 
4004
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `deque`.
4005
 
4006
  *Effects:* Constructs a `deque` with `n` copies of `value`, using the
4007
  specified allocator.
4008
 
4009
  *Complexity:* Linear in `n`.
4010
 
4011
  ``` cpp
4012
  template<class InputIterator>
4013
+ constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
4014
  ```
4015
 
4016
  *Effects:* Constructs a `deque` equal to the range \[`first`, `last`),
4017
  using the specified allocator.
4018
 
4019
  *Complexity:* Linear in `distance(first, last)`.
4020
 
4021
  ``` cpp
4022
  template<container-compatible-range<T> R>
4023
+ constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator());
4024
  ```
4025
 
4026
  *Effects:* Constructs a `deque` with the elements of the range `rg`,
4027
  using the specified allocator.
4028
 
4029
  *Complexity:* Linear in `ranges::distance(rg)`.
4030
 
4031
  #### Capacity <a id="deque.capacity">[[deque.capacity]]</a>
4032
 
4033
  ``` cpp
4034
+ constexpr void resize(size_type sz);
4035
  ```
4036
 
4037
  *Preconditions:* `T` is *Cpp17MoveInsertable* and
4038
+ *Cpp17DefaultInsertable* into `deque`.
4039
 
4040
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
4041
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
4042
  to the sequence.
4043
 
4044
  ``` cpp
4045
+ constexpr void resize(size_type sz, const T& c);
4046
  ```
4047
 
4048
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `deque`.
4049
 
4050
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
4051
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
4052
  sequence.
4053
 
4054
  ``` cpp
4055
+ constexpr void shrink_to_fit();
4056
  ```
4057
 
4058
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `deque`.
4059
 
4060
  *Effects:* `shrink_to_fit` is a non-binding request to reduce memory use
4061
  but does not change the size of the sequence.
4062
 
4063
  [*Note 1*: The request is non-binding to allow latitude for
 
4075
  elements in the sequence, as well as the past-the-end iterator.
4076
 
4077
  #### Modifiers <a id="deque.modifiers">[[deque.modifiers]]</a>
4078
 
4079
  ``` cpp
4080
+ constexpr iterator insert(const_iterator position, const T& x);
4081
+ constexpr iterator insert(const_iterator position, T&& x);
4082
+ constexpr iterator insert(const_iterator position, size_type n, const T& x);
4083
  template<class InputIterator>
4084
+ constexpr iterator insert(const_iterator position,
4085
  InputIterator first, InputIterator last);
4086
  template<container-compatible-range<T> R>
4087
+ constexpr iterator insert_range(const_iterator position, R&& rg);
4088
+ constexpr iterator insert(const_iterator position, initializer_list<T>);
4089
 
4090
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
4091
+ template<class... Args> constexpr reference emplace_back(Args&&... args);
4092
+ template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
4093
+ constexpr void push_front(const T& x);
4094
+ constexpr void push_front(T&& x);
4095
  template<container-compatible-range<T> R>
4096
+ constexpr void prepend_range(R&& rg);
4097
+ constexpr void push_back(const T& x);
4098
+ constexpr void push_back(T&& x);
4099
  template<container-compatible-range<T> R>
4100
+ constexpr void append_range(R&& rg);
4101
  ```
4102
 
4103
  *Effects:* An insertion in the middle of the deque invalidates all the
4104
  iterators and references to elements of the deque. An insertion at
4105
  either end of the deque invalidates all the iterators to the deque, but
 
4111
  a deque always takes constant time and causes a single call to a
4112
  constructor of `T`.
4113
 
4114
  *Remarks:* If an exception is thrown other than by the copy constructor,
4115
  move constructor, assignment operator, or move assignment operator of
4116
+ `T`, there are no effects. If an exception is thrown while inserting a
4117
  single element at either end, there are no effects. Otherwise, if an
4118
  exception is thrown by the move constructor of a
4119
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
4120
 
4121
  ``` cpp
4122
+ constexpr iterator erase(const_iterator position);
4123
+ constexpr iterator erase(const_iterator first, const_iterator last);
4124
+ constexpr void pop_front();
4125
+ constexpr void pop_back();
4126
  ```
4127
 
4128
  *Effects:* An erase operation that erases the last element of a deque
4129
  invalidates only the past-the-end iterator and all iterators and
4130
  references to the erased elements. An erase operation that erases the
 
4147
  erased elements.
4148
 
4149
  #### Erasure <a id="deque.erasure">[[deque.erasure]]</a>
4150
 
4151
  ``` cpp
4152
+ template<class T, class Allocator, class U = T>
4153
+ constexpr typename deque<T, Allocator>::size_type
4154
  erase(deque<T, Allocator>& c, const U& value);
4155
  ```
4156
 
4157
  *Effects:* Equivalent to:
4158
 
 
4163
  return r;
4164
  ```
4165
 
4166
  ``` cpp
4167
  template<class T, class Allocator, class Predicate>
4168
+ constexpr typename deque<T, Allocator>::size_type
4169
  erase_if(deque<T, Allocator>& c, Predicate pred);
4170
  ```
4171
 
4172
  *Effects:* Equivalent to:
4173
 
 
4176
  auto r = distance(it, c.end());
4177
  c.erase(it, c.end());
4178
  return r;
4179
  ```
4180
 
4181
+ ### Header `<forward_list>` synopsis <a id="forward.list.syn">[[forward.list.syn]]</a>
4182
+
4183
+ ``` cpp
4184
+ #include <compare> // see [compare.syn]
4185
+ #include <initializer_list> // see [initializer.list.syn]
4186
+
4187
+ namespace std {
4188
+ // [forward.list], class template forward_list
4189
+ template<class T, class Allocator = allocator<T>> class forward_list;
4190
+
4191
+ template<class T, class Allocator>
4192
+ constexpr bool operator==(const forward_list<T, Allocator>& x,
4193
+ const forward_list<T, Allocator>& y);
4194
+ template<class T, class Allocator>
4195
+ constexpr synth-three-way-result<T>
4196
+ operator<=>(const forward_list<T, Allocator>& x,
4197
+ const forward_list<T, Allocator>& y);
4198
+
4199
+ template<class T, class Allocator>
4200
+ constexpr void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
4201
+ noexcept(noexcept(x.swap(y)));
4202
+
4203
+ // [forward.list.erasure], erasure
4204
+ template<class T, class Allocator, class U = T>
4205
+ constexpr typename forward_list<T, Allocator>::size_type
4206
+ erase(forward_list<T, Allocator>& c, const U& value);
4207
+ template<class T, class Allocator, class Predicate>
4208
+ constexpr typename forward_list<T, Allocator>::size_type
4209
+ erase_if(forward_list<T, Allocator>& c, Predicate pred);
4210
+
4211
+ namespace pmr {
4212
+ template<class T>
4213
+ using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
4214
+ }
4215
+ }
4216
+ ```
4217
+
4218
  ### Class template `forward_list` <a id="forward.list">[[forward.list]]</a>
4219
 
4220
  #### Overview <a id="forward.list.overview">[[forward.list.overview]]</a>
4221
 
4222
  A `forward_list` is a container that supports forward iterators and
 
4228
  overhead relative to a hand-written C-style singly linked list. Features
4229
  that would conflict with that goal have been omitted. — *end note*]
4230
 
4231
  A `forward_list` meets all of the requirements of a container
4232
  [[container.reqmts]], except that the `size()` member function is not
4233
+ provided and `operator==` has linear complexity. A `forward_list` also
4234
  meets all of the requirements for an allocator-aware container
4235
  [[container.alloc.reqmts]]. In addition, a `forward_list` provides the
4236
  `assign` member functions and several of the optional sequence container
4237
  requirements [[sequence.reqmts]]. Descriptions are provided here only
4238
  for operations on `forward_list` that are not described in that table or
 
4242
  the first element of interest, but in a `forward_list` there is no
4243
  constant-time way to access a preceding element. For this reason,
4244
  `erase_after` and `splice_after` take fully-open ranges, not semi-open
4245
  ranges. — *end note*]
4246
 
4247
+ The types `iterator` and `const_iterator` meet the constexpr iterator
4248
+ requirements [[iterator.requirements.general]].
4249
+
4250
  ``` cpp
4251
  namespace std {
4252
  template<class T, class Allocator = allocator<T>>
4253
  class forward_list {
4254
  public:
4255
  // types
4256
  using value_type = T;
4257
  using allocator_type = Allocator;
4258
+ using pointer = allocator_traits<Allocator>::pointer;
4259
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
4260
  using reference = value_type&;
4261
  using const_reference = const value_type&;
4262
  using size_type = implementation-defined // type of forward_list::size_type; // see [container.requirements]
4263
  using difference_type = implementation-defined // type of forward_list::difference_type; // see [container.requirements]
4264
  using iterator = implementation-defined // type of forward_list::iterator; // see [container.requirements]
4265
  using const_iterator = implementation-defined // type of forward_list::const_iterator; // see [container.requirements]
4266
 
4267
  // [forward.list.cons], construct/copy/destroy
4268
+ constexpr forward_list() : forward_list(Allocator()) { }
4269
+ constexpr explicit forward_list(const Allocator&);
4270
+ constexpr explicit forward_list(size_type n, const Allocator& = Allocator());
4271
+ constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator());
4272
  template<class InputIterator>
4273
+ constexpr forward_list(InputIterator first, InputIterator last,
4274
+ const Allocator& = Allocator());
4275
  template<container-compatible-range<T> R>
4276
+ constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4277
+ constexpr forward_list(const forward_list& x);
4278
+ constexpr forward_list(forward_list&& x);
4279
+ constexpr forward_list(const forward_list& x, const type_identity_t<Allocator>&);
4280
+ constexpr forward_list(forward_list&& x, const type_identity_t<Allocator>&);
4281
+ constexpr forward_list(initializer_list<T>, const Allocator& = Allocator());
4282
+ constexpr ~forward_list();
4283
+ constexpr forward_list& operator=(const forward_list& x);
4284
+ constexpr forward_list& operator=(forward_list&& x)
4285
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4286
+ constexpr forward_list& operator=(initializer_list<T>);
4287
  template<class InputIterator>
4288
+ constexpr void assign(InputIterator first, InputIterator last);
4289
  template<container-compatible-range<T> R>
4290
+ constexpr void assign_range(R&& rg);
4291
+ constexpr void assign(size_type n, const T& t);
4292
+ constexpr void assign(initializer_list<T>);
4293
+ constexpr allocator_type get_allocator() const noexcept;
4294
 
4295
  // [forward.list.iter], iterators
4296
+ constexpr iterator before_begin() noexcept;
4297
+ constexpr const_iterator before_begin() const noexcept;
4298
+ constexpr iterator begin() noexcept;
4299
+ constexpr const_iterator begin() const noexcept;
4300
+ constexpr iterator end() noexcept;
4301
+ constexpr const_iterator end() const noexcept;
4302
 
4303
+ constexpr const_iterator cbegin() const noexcept;
4304
+ constexpr const_iterator cbefore_begin() const noexcept;
4305
+ constexpr const_iterator cend() const noexcept;
4306
 
4307
  // capacity
4308
+ constexpr bool empty() const noexcept;
4309
+ constexpr size_type max_size() const noexcept;
4310
 
4311
  // [forward.list.access], element access
4312
+ constexpr reference front();
4313
+ constexpr const_reference front() const;
4314
 
4315
  // [forward.list.modifiers], modifiers
4316
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
4317
+ constexpr void push_front(const T& x);
4318
+ constexpr void push_front(T&& x);
4319
  template<container-compatible-range<T> R>
4320
+ constexpr void prepend_range(R&& rg);
4321
+ constexpr void pop_front();
4322
 
4323
+ template<class... Args>
4324
+ constexpr iterator emplace_after(const_iterator position, Args&&... args);
4325
+ constexpr iterator insert_after(const_iterator position, const T& x);
4326
+ constexpr iterator insert_after(const_iterator position, T&& x);
4327
 
4328
+ constexpr iterator insert_after(const_iterator position, size_type n, const T& x);
4329
  template<class InputIterator>
4330
+ constexpr iterator insert_after(const_iterator position,
4331
+ InputIterator first, InputIterator last);
4332
+ constexpr iterator insert_after(const_iterator position, initializer_list<T> il);
4333
  template<container-compatible-range<T> R>
4334
+ constexpr iterator insert_range_after(const_iterator position, R&& rg);
4335
 
4336
+ constexpr iterator erase_after(const_iterator position);
4337
+ constexpr iterator erase_after(const_iterator position, const_iterator last);
4338
+ constexpr void swap(forward_list&)
4339
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
4340
 
4341
+ constexpr void resize(size_type sz);
4342
+ constexpr void resize(size_type sz, const value_type& c);
4343
+ constexpr void clear() noexcept;
4344
 
4345
  // [forward.list.ops], forward_list operations
4346
+ constexpr void splice_after(const_iterator position, forward_list& x);
4347
+ constexpr void splice_after(const_iterator position, forward_list&& x);
4348
+ constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i);
4349
+ constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i);
4350
+ constexpr void splice_after(const_iterator position, forward_list& x,
4351
  const_iterator first, const_iterator last);
4352
+ constexpr void splice_after(const_iterator position, forward_list&& x,
4353
  const_iterator first, const_iterator last);
4354
 
4355
+ constexpr size_type remove(const T& value);
4356
+ template<class Predicate> constexpr size_type remove_if(Predicate pred);
4357
 
4358
  size_type unique();
4359
+ template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred);
4360
 
4361
+ constexpr void merge(forward_list& x);
4362
+ constexpr void merge(forward_list&& x);
4363
+ template<class Compare> constexpr void merge(forward_list& x, Compare comp);
4364
+ template<class Compare> constexpr void merge(forward_list&& x, Compare comp);
4365
 
4366
+ constexpr void sort();
4367
+ template<class Compare> constexpr void sort(Compare comp);
4368
 
4369
+ constexpr void reverse() noexcept;
4370
  };
4371
 
4372
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
4373
  forward_list(InputIterator, InputIterator, Allocator = Allocator())
4374
  -> forward_list<iter-value-type<InputIterator>, Allocator>;
 
4386
  referenced.
4387
 
4388
  #### Constructors, copy, and assignment <a id="forward.list.cons">[[forward.list.cons]]</a>
4389
 
4390
  ``` cpp
4391
+ constexpr explicit forward_list(const Allocator&);
4392
  ```
4393
 
4394
  *Effects:* Constructs an empty `forward_list` object using the specified
4395
  allocator.
4396
 
4397
  *Complexity:* Constant.
4398
 
4399
  ``` cpp
4400
+ constexpr explicit forward_list(size_type n, const Allocator& = Allocator());
4401
  ```
4402
 
4403
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `forward_list`.
4404
 
4405
  *Effects:* Constructs a `forward_list` object with `n` default-inserted
4406
  elements using the specified allocator.
4407
 
4408
  *Complexity:* Linear in `n`.
4409
 
4410
  ``` cpp
4411
+ constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator());
4412
  ```
4413
 
4414
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4415
 
4416
  *Effects:* Constructs a `forward_list` object with `n` copies of `value`
4417
  using the specified allocator.
4418
 
4419
  *Complexity:* Linear in `n`.
4420
 
4421
  ``` cpp
4422
  template<class InputIterator>
4423
+ constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
4424
  ```
4425
 
4426
  *Effects:* Constructs a `forward_list` object equal to the range
4427
  \[`first`, `last`).
4428
 
4429
  *Complexity:* Linear in `distance(first, last)`.
4430
 
4431
  ``` cpp
4432
  template<container-compatible-range<T> R>
4433
+ constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator());
4434
  ```
4435
 
4436
  *Effects:* Constructs a `forward_list` object with the elements of the
4437
  range `rg`.
4438
 
4439
  *Complexity:* Linear in `ranges::distance(rg)`.
4440
 
4441
  #### Iterators <a id="forward.list.iter">[[forward.list.iter]]</a>
4442
 
4443
  ``` cpp
4444
+ constexpr iterator before_begin() noexcept;
4445
+ constexpr const_iterator before_begin() const noexcept;
4446
+ constexpr const_iterator cbefore_begin() const noexcept;
4447
  ```
4448
 
4449
  *Effects:* `cbefore_begin()` is equivalent to
4450
  `const_cast<forward_list const&>(*this).before_begin()`.
4451
 
 
4455
  *Remarks:* `before_begin() == end()` shall equal `false`.
4456
 
4457
  #### Element access <a id="forward.list.access">[[forward.list.access]]</a>
4458
 
4459
  ``` cpp
4460
+ constexpr reference front();
4461
+ constexpr const_reference front() const;
4462
  ```
4463
 
4464
  *Returns:* `*begin()`
4465
 
4466
  #### Modifiers <a id="forward.list.modifiers">[[forward.list.modifiers]]</a>
4467
 
4468
+ The member functions in this subclause do not affect the validity of
4469
+ iterators and references when inserting elements, and when erasing
4470
+ elements invalidate iterators and references to the erased elements
4471
+ only. If an exception is thrown by any of these member functions there
4472
+ is no effect on the container. Inserting `n` elements into a
4473
+ `forward_list` is linear in `n`, and the number of calls to the copy or
4474
+ move constructor of `T` is exactly equal to `n`. Erasing `n` elements
4475
+ from a `forward_list` is linear in `n` and the number of calls to the
4476
+ destructor of type `T` is exactly equal to `n`.
4477
 
4478
  ``` cpp
4479
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
4480
  ```
4481
 
4482
  *Effects:* Inserts an object of type `value_type` constructed with
4483
  `value_type(std::forward<Args>(args)...)` at the beginning of the list.
4484
 
4485
  ``` cpp
4486
+ constexpr void push_front(const T& x);
4487
+ constexpr void push_front(T&& x);
4488
  ```
4489
 
4490
  *Effects:* Inserts a copy of `x` at the beginning of the list.
4491
 
4492
  ``` cpp
4493
  template<container-compatible-range<T> R>
4494
+ constexpr void prepend_range(R&& rg);
4495
  ```
4496
 
4497
  *Effects:* Inserts a copy of each element of `rg` at the beginning of
4498
  the list.
4499
 
4500
  [*Note 1*: The order of elements is not reversed. — *end note*]
4501
 
4502
  ``` cpp
4503
+ constexpr void pop_front();
4504
  ```
4505
 
4506
  *Effects:* As if by `erase_after(before_begin())`.
4507
 
4508
  ``` cpp
4509
+ constexpr iterator insert_after(const_iterator position, const T& x);
4510
  ```
4511
 
4512
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4513
  `position` is `before_begin()` or is a dereferenceable iterator in the
4514
  range \[`begin()`, `end()`).
 
4516
  *Effects:* Inserts a copy of `x` after `position`.
4517
 
4518
  *Returns:* An iterator pointing to the copy of `x`.
4519
 
4520
  ``` cpp
4521
+ constexpr iterator insert_after(const_iterator position, T&& x);
4522
  ```
4523
 
4524
  *Preconditions:* `T` is *Cpp17MoveInsertable* into `forward_list`.
4525
  `position` is `before_begin()` or is a dereferenceable iterator in the
4526
  range \[`begin()`, `end()`).
 
4528
  *Effects:* Inserts a copy of `x` after `position`.
4529
 
4530
  *Returns:* An iterator pointing to the copy of `x`.
4531
 
4532
  ``` cpp
4533
+ constexpr iterator insert_after(const_iterator position, size_type n, const T& x);
4534
  ```
4535
 
4536
  *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4537
  `position` is `before_begin()` or is a dereferenceable iterator in the
4538
  range \[`begin()`, `end()`).
 
4542
  *Returns:* An iterator pointing to the last inserted copy of `x`, or
4543
  `position` if `n == 0` is `true`.
4544
 
4545
  ``` cpp
4546
  template<class InputIterator>
4547
+ constexpr iterator insert_after(const_iterator position,
4548
+ InputIterator first, InputIterator last);
4549
  ```
4550
 
4551
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4552
  from `*first`. `position` is `before_begin()` or is a dereferenceable
4553
  iterator in the range \[`begin()`, `end()`). Neither `first` nor `last`
 
4559
  *Returns:* An iterator pointing to the last inserted element, or
4560
  `position` if `first == last` is `true`.
4561
 
4562
  ``` cpp
4563
  template<container-compatible-range<T> R>
4564
+ constexpr iterator insert_range_after(const_iterator position, R&& rg);
4565
  ```
4566
 
4567
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4568
  from `*ranges::begin(rg)`. `position` is `before_begin()` or is a
4569
  dereferenceable iterator in the range \[`begin()`, `end()`). `rg` and
 
4574
 
4575
  *Returns:* An iterator pointing to the last inserted element, or
4576
  `position` if `rg` is empty.
4577
 
4578
  ``` cpp
4579
+ constexpr iterator insert_after(const_iterator position, initializer_list<T> il);
4580
  ```
4581
 
4582
  *Effects:* Equivalent to:
4583
  `return insert_after(position, il.begin(), il.end());`
4584
 
4585
  ``` cpp
4586
  template<class... Args>
4587
+ constexpr iterator emplace_after(const_iterator position, Args&&... args);
4588
  ```
4589
 
4590
  *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `forward_list`
4591
  from `std::forward<Args>(args)...`. `position` is `before_begin()` or is
4592
  a dereferenceable iterator in the range \[`begin()`, `end()`).
 
4596
  `position`.
4597
 
4598
  *Returns:* An iterator pointing to the new object.
4599
 
4600
  ``` cpp
4601
+ constexpr iterator erase_after(const_iterator position);
4602
  ```
4603
 
4604
  *Preconditions:* The iterator following `position` is dereferenceable.
4605
 
4606
  *Effects:* Erases the element pointed to by the iterator following
 
4610
  was erased, or `end()` if no such element exists.
4611
 
4612
  *Throws:* Nothing.
4613
 
4614
  ``` cpp
4615
+ constexpr iterator erase_after(const_iterator position, const_iterator last);
4616
  ```
4617
 
4618
  *Preconditions:* All iterators in the range (`position`, `last`) are
4619
  dereferenceable.
4620
 
 
4623
  *Returns:* `last`.
4624
 
4625
  *Throws:* Nothing.
4626
 
4627
  ``` cpp
4628
+ constexpr void resize(size_type sz);
4629
  ```
4630
 
4631
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `forward_list`.
4632
 
4633
  *Effects:* If `sz < distance(begin(), end())`, erases the last
4634
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
4635
  inserts `sz - distance(begin(), end())` default-inserted elements at the
4636
  end of the list.
4637
 
4638
  ``` cpp
4639
+ constexpr void resize(size_type sz, const value_type& c);
4640
  ```
4641
 
4642
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `forward_list`.
4643
 
4644
  *Effects:* If `sz < distance(begin(), end())`, erases the last
4645
  `distance(begin(), end()) - sz` elements from the list. Otherwise,
4646
  inserts `sz - distance(begin(), end())` copies of `c` at the end of the
4647
  list.
4648
 
4649
  ``` cpp
4650
+ constexpr void clear() noexcept;
4651
  ```
4652
 
4653
  *Effects:* Erases all elements in the range \[`begin()`, `end()`).
4654
 
4655
  *Remarks:* Does not invalidate past-the-end iterators.
 
4664
  list and `n` is an integer, means an iterator `j` such that `j + n == i`
4665
  is `true`. For `merge` and `sort`, the definitions and requirements in
4666
  [[alg.sorting]] apply.
4667
 
4668
  ``` cpp
4669
+ constexpr void splice_after(const_iterator position, forward_list& x);
4670
+ constexpr void splice_after(const_iterator position, forward_list&& x);
4671
  ```
4672
 
4673
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4674
  iterator in the range \[`begin()`, `end()`).
4675
  `get_allocator() == x.get_allocator()` is `true`. `addressof(x) != this`
 
4684
  *Throws:* Nothing.
4685
 
4686
  *Complexity:* 𝑂(`distance(x.begin(), x.end())`)
4687
 
4688
  ``` cpp
4689
+ constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i);
4690
+ constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i);
4691
  ```
4692
 
4693
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4694
  iterator in the range \[`begin()`, `end()`). The iterator following `i`
4695
  is a dereferenceable iterator in `x`.
 
4705
  *Throws:* Nothing.
4706
 
4707
  *Complexity:* 𝑂(1)
4708
 
4709
  ``` cpp
4710
+ constexpr void splice_after(const_iterator position, forward_list& x,
4711
  const_iterator first, const_iterator last);
4712
+ constexpr void splice_after(const_iterator position, forward_list&& x,
4713
  const_iterator first, const_iterator last);
4714
  ```
4715
 
4716
  *Preconditions:* `position` is `before_begin()` or is a dereferenceable
4717
  iterator in the range \[`begin()`, `end()`). (`first`, `last`) is a
 
4727
  into `*this`, not into `x`.
4728
 
4729
  *Complexity:* 𝑂(`distance(first, last)`)
4730
 
4731
  ``` cpp
4732
+ constexpr size_type remove(const T& value);
4733
+ template<class Predicate> constexpr size_type remove_if(Predicate pred);
4734
  ```
4735
 
4736
  *Effects:* Erases all the elements in the list referred to by a list
4737
  iterator `i` for which the following conditions hold: `*i == value` (for
4738
  `remove()`), `pred(*i)` is `true` (for `remove_if()`). Invalidates only
 
4747
  corresponding predicate.
4748
 
4749
  *Remarks:* Stable [[algorithm.stable]].
4750
 
4751
  ``` cpp
4752
+ constexpr size_type unique();
4753
+ template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred);
4754
  ```
4755
 
4756
  Let `binary_pred` be `equal_to<>{}` for the first overload.
4757
 
4758
  *Preconditions:* `binary_pred` is an equivalence relation.
 
4770
  *Complexity:* If `empty()` is `false`, exactly
4771
  `distance(begin(), end()) - 1` applications of the corresponding
4772
  predicate, otherwise no applications of the predicate.
4773
 
4774
  ``` cpp
4775
+ constexpr void merge(forward_list& x);
4776
+ constexpr void merge(forward_list&& x);
4777
+ template<class Compare> constexpr void merge(forward_list& x, Compare comp);
4778
+ template<class Compare> constexpr void merge(forward_list&& x, Compare comp);
4779
  ```
4780
 
4781
  Let `comp` be `less<>` for the first two overloads.
4782
 
4783
  *Preconditions:* `*this` and `x` are both sorted with respect to the
 
4799
  *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
4800
  is empty after the merge. No elements are copied by this operation. If
4801
  an exception is thrown other than by a comparison, there are no effects.
4802
 
4803
  ``` cpp
4804
+ constexpr void sort();
4805
+ template<class Compare> constexpr void sort(Compare comp);
4806
  ```
4807
 
4808
  *Effects:* Sorts the list according to the `operator<` or the `comp`
4809
  function object. If an exception is thrown, the order of the elements in
4810
  `*this` is unspecified. Does not affect the validity of iterators and
 
4814
  `distance(begin(), end())`.
4815
 
4816
  *Remarks:* Stable [[algorithm.stable]].
4817
 
4818
  ``` cpp
4819
+ constexpr void reverse() noexcept;
4820
  ```
4821
 
4822
  *Effects:* Reverses the order of the elements in the list. Does not
4823
  affect the validity of iterators and references.
4824
 
4825
  *Complexity:* Linear time.
4826
 
4827
  #### Erasure <a id="forward.list.erasure">[[forward.list.erasure]]</a>
4828
 
4829
  ``` cpp
4830
+ template<class T, class Allocator, class U = T>
4831
+ constexpr typename forward_list<T, Allocator>::size_type
4832
  erase(forward_list<T, Allocator>& c, const U& value);
4833
  ```
4834
 
4835
  *Effects:* Equivalent to:
4836
+
4837
+ ``` cpp
4838
+ return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
4839
+ ```
4840
 
4841
  ``` cpp
4842
  template<class T, class Allocator, class Predicate>
4843
+ constexpr typename forward_list<T, Allocator>::size_type
4844
  erase_if(forward_list<T, Allocator>& c, Predicate pred);
4845
  ```
4846
 
4847
  *Effects:* Equivalent to: `return c.remove_if(pred);`
4848
 
4849
+ ### Header `<hive>` synopsis <a id="hive.syn">[[hive.syn]]</a>
4850
+
4851
+ ``` cpp
4852
+ #include <initializer_list> // see [initializer.list.syn]
4853
+ #include <compare> // see [compare.syn]
4854
+
4855
+ namespace std {
4856
+ struct hive_limits {
4857
+ size_t min;
4858
+ size_t max;
4859
+ constexpr hive_limits(size_t minimum, size_t maximum) noexcept
4860
+ : min(minimum), max(maximum) {}
4861
+ };
4862
+
4863
+ // \ref {hive}, class template hive
4864
+ template<class T, class Allocator = allocator<T>> class hive;
4865
+
4866
+ template<class T, class Allocator>
4867
+ void swap(hive<T, Allocator>& x, hive<T, Allocator>& y)
4868
+ noexcept(noexcept(x.swap(y)));
4869
+
4870
+ template<class T, class Allocator, class U = T>
4871
+ typename hive<T, Allocator>::size_type
4872
+ erase(hive<T, Allocator>& c, const U& value);
4873
+
4874
+ template<class T, class Allocator, class Predicate>
4875
+ typename hive<T, Allocator>::size_type
4876
+ erase_if(hive<T, Allocator>& c, Predicate pred);
4877
+
4878
+ namespace pmr {
4879
+ template<class T>
4880
+ using hive = std::hive<T, polymorphic_allocator<T>>;
4881
+ }
4882
+ }
4883
+ ```
4884
+
4885
+ ### Class template `hive` <a id="hive">[[hive]]</a>
4886
+
4887
+ #### Overview <a id="hive.overview">[[hive.overview]]</a>
4888
+
4889
+ A `hive` is a type of sequence container that provides constant-time
4890
+ insertion and erasure operations. Storage is automatically managed in
4891
+ multiple memory blocks, referred to as *element blocks*. Insertion
4892
+ position is determined by the container, and insertion may re-use the
4893
+ memory locations of erased elements.
4894
+
4895
+ Element blocks which contain elements are referred to as *active
4896
+ blocks*, those which do not are referred to as *reserved blocks*. Active
4897
+ blocks which become empty of elements are either deallocated or become
4898
+ reserved blocks. Reserved blocks become active blocks when they are used
4899
+ to store elements. A user can create additional reserved blocks by
4900
+ calling `reserve`.
4901
+
4902
+ Erasures use unspecified techniques of constant time complexity to
4903
+ identify the memory locations of erased elements, which are subsequently
4904
+ skipped during iteration, as opposed to relocating subsequent elements
4905
+ during erasure.
4906
+
4907
+ Active block capacities have an *implementation-defined* growth factor
4908
+ (which need not be integral), for example a new active block’s capacity
4909
+ could be equal to the summed capacities of the pre-existing active
4910
+ blocks.
4911
+
4912
+ Limits can be placed on both the minimum and maximum element capacities
4913
+ of element blocks, both by users and implementations.
4914
+
4915
+ - The minimum limit shall be no larger than the maximum limit.
4916
+ - When limits are not specified by a user during construction, the
4917
+ implementation’s default limits are used.
4918
+ - The default limits of an implementation are not guaranteed to be the
4919
+ same as the minimum and maximum possible capacities for an
4920
+ implementation’s element blocks. \[*Note 1*: To allow latitude for
4921
+ both implementation-specific and user-directed
4922
+ optimization. — *end note*] The latter are defined as hard limits.
4923
+ The maximum hard limit shall be no larger than
4924
+ `std::allocator_traits<Allocator>::max_size()`.
4925
+ - If user-specified limits are not within hard limits, or if the
4926
+ specified minimum limit is greater than the specified maximum limit,
4927
+ the behavior is undefined.
4928
+ - An element block is said to be *within the bounds* of a pair of
4929
+ minimum/maximum limits when its capacity is greater-or-equal-to the
4930
+ minimum limit and less-than-or-equal-to the maximum limit.
4931
+
4932
+ A `hive` conforms to the requirements for containers
4933
+ [[container.reqmts]], with the exception of operators `==` and `!=`. A
4934
+ `hive` also meets the requirements of a reversible container
4935
+ [[container.rev.reqmts]], of an allocator-aware container
4936
+ [[container.alloc.reqmts]], and some of the requirements of a sequence
4937
+ container [[sequence.reqmts]]. Descriptions are provided here only for
4938
+ operations on `hive` that are not described in that table or for
4939
+ operations where there is additional semantic information.
4940
+
4941
+ The iterators of `hive` meet the *Cpp17BidirectionalIterator*
4942
+ requirements but also model `three_way_comparable<strong_ordering>`.
4943
+
4944
+ ``` cpp
4945
+ namespace std {
4946
+ template<class T, class Allocator = allocator<T>>
4947
+ class hive {
4948
+ public:
4949
+ // types
4950
+ using value_type = T;
4951
+ using allocator_type = Allocator;
4952
+ using pointer = allocator_traits<Allocator>::pointer;
4953
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
4954
+ using reference = value_type&;
4955
+ using const_reference = const value_type&;
4956
+ using size_type = implementation-defined; // see [container.requirements]
4957
+ using difference_type = implementation-defined; // see [container.requirements]
4958
+ using iterator = implementation-defined; // see [container.requirements]
4959
+ using const_iterator = implementation-defined; // see [container.requirements]
4960
+ using reverse_iterator = std::reverse_iterator<iterator>; // see [container.requirements]
4961
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>; // see [container.requirements]
4962
+
4963
+ // [hive.cons], construct/copy/destroy
4964
+ constexpr hive() noexcept(noexcept(Allocator())) : hive(Allocator()) {}
4965
+ constexpr explicit hive(const Allocator&) noexcept;
4966
+ constexpr explicit hive(hive_limits block_limits) : hive(block_limits, Allocator()) {}
4967
+ constexpr hive(hive_limits block_limits, const Allocator&);
4968
+ explicit hive(size_type n, const Allocator& = Allocator());
4969
+ hive(size_type n, hive_limits block_limits, const Allocator& = Allocator());
4970
+ hive(size_type n, const T& value, const Allocator& = Allocator());
4971
+ hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator());
4972
+ template<class InputIterator>
4973
+ hive(InputIterator first, InputIterator last, const Allocator& = Allocator());
4974
+ template<class InputIterator>
4975
+ hive(InputIterator first, InputIterator last, hive_limits block_limits,
4976
+ const Allocator& = Allocator());
4977
+ template<container-compatible-range<T> R>
4978
+ hive(from_range_t, R&& rg, const Allocator& = Allocator());
4979
+ template<container-compatible-range<T> R>
4980
+ hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator());
4981
+ hive(const hive& x);
4982
+ hive(hive&&) noexcept;
4983
+ hive(const hive& x, const type_identity_t<Allocator>& alloc);
4984
+ hive(hive&&, const type_identity_t<Allocator>& alloc);
4985
+ hive(initializer_list<T> il, const Allocator& = Allocator());
4986
+ hive(initializer_list<T> il, hive_limits block_limits, const Allocator& = Allocator());
4987
+ ~hive();
4988
+
4989
+ hive& operator=(const hive& x);
4990
+ hive& operator=(hive&& x) noexcept(see below);
4991
+ hive& operator=(initializer_list<T>);
4992
+ template<class InputIterator>
4993
+ void assign(InputIterator first, InputIterator last);
4994
+ template<container-compatible-range<T> R>
4995
+ void assign_range(R&& rg);
4996
+ void assign(size_type n, const T& t);
4997
+ void assign(initializer_list<T>);
4998
+ allocator_type get_allocator() const noexcept;
4999
+
5000
+ // iterators
5001
+ iterator begin() noexcept;
5002
+ const_iterator begin() const noexcept;
5003
+ iterator end() noexcept;
5004
+ const_iterator end() const noexcept;
5005
+ reverse_iterator rbegin() noexcept;
5006
+ const_reverse_iterator rbegin() const noexcept;
5007
+ reverse_iterator rend() noexcept;
5008
+ const_reverse_iterator rend() const noexcept;
5009
+ const_iterator cbegin() const noexcept;
5010
+ const_iterator cend() const noexcept;
5011
+ const_reverse_iterator crbegin() const noexcept;
5012
+ const_reverse_iterator crend() const noexcept;
5013
+
5014
+ // [hive.capacity], capacity
5015
+ bool empty() const noexcept;
5016
+ size_type size() const noexcept;
5017
+ size_type max_size() const noexcept;
5018
+ size_type capacity() const noexcept;
5019
+ void reserve(size_type n);
5020
+ void shrink_to_fit();
5021
+ void trim_capacity() noexcept;
5022
+ void trim_capacity(size_type n) noexcept;
5023
+ constexpr hive_limits block_capacity_limits() const noexcept;
5024
+ static constexpr hive_limits block_capacity_default_limits() noexcept;
5025
+ static constexpr hive_limits block_capacity_hard_limits() noexcept;
5026
+ void reshape(hive_limits block_limits);
5027
+
5028
+ // [hive.modifiers], modifiers
5029
+ template<class... Args> iterator emplace(Args&&... args);
5030
+ template<class... Args> iterator emplace_hint(const_iterator hint, Args&&... args);
5031
+ iterator insert(const T& x);
5032
+ iterator insert(T&& x);
5033
+ iterator insert(const_iterator hint, const T& x);
5034
+ iterator insert(const_iterator hint, T&& x);
5035
+ void insert(initializer_list<T> il);
5036
+ template<container-compatible-range<T> R>
5037
+ void insert_range(R&& rg);
5038
+ template<class InputIterator>
5039
+ void insert(InputIterator first, InputIterator last);
5040
+ void insert(size_type n, const T& x);
5041
+
5042
+ iterator erase(const_iterator position);
5043
+ iterator erase(const_iterator first, const_iterator last);
5044
+ void swap(hive&) noexcept(see below);
5045
+ void clear() noexcept;
5046
+
5047
+ // [hive.operations], hive operations
5048
+ void splice(hive& x);
5049
+ void splice(hive&& x);
5050
+ template<class BinaryPredicate = equal_to<T>>
5051
+ size_type unique(BinaryPredicate binary_pred = BinaryPredicate());
5052
+
5053
+ template<class Compare = less<T>>
5054
+ void sort(Compare comp = Compare());
5055
+
5056
+ iterator get_iterator(const_pointer p) noexcept;
5057
+ const_iterator get_iterator(const_pointer p) const noexcept;
5058
+
5059
+ private:
5060
+ hive_limits current-limits = implementation-defined; // exposition only
5061
+ };
5062
+
5063
+ template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5064
+ hive(InputIterator, InputIterator, Allocator = Allocator())
5065
+ -> hive<iter-value-type<InputIterator>, Allocator>;
5066
+
5067
+ template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5068
+ hive(InputIterator, InputIterator, hive_limits, Allocator = Allocator())
5069
+ -> hive<iter-value-type<InputIterator>, Allocator>;
5070
+
5071
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
5072
+ hive(from_range_t, R&&, Allocator = Allocator())
5073
+ -> hive<ranges::range_value_t<R>, Allocator>;
5074
+
5075
+ template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>>
5076
+ hive(from_range_t, R&&, hive_limits, Allocator = Allocator())
5077
+ -> hive<ranges::range_value_t<R>, Allocator>;
5078
+ }
5079
+ ```
5080
+
5081
+ #### Constructors, copy, and assignment <a id="hive.cons">[[hive.cons]]</a>
5082
+
5083
+ ``` cpp
5084
+ constexpr explicit hive(const Allocator&) noexcept;
5085
+ ```
5086
+
5087
+ *Effects:* Constructs an empty `hive`, using the specified allocator.
5088
+
5089
+ *Complexity:* Constant.
5090
+
5091
+ ``` cpp
5092
+ constexpr hive(hive_limits block_limits, const Allocator&);
5093
+ ```
5094
+
5095
+ *Effects:* Constructs an empty `hive`, using the specified allocator.
5096
+ Initializes *current-limits* with `block_limits`.
5097
+
5098
+ *Complexity:* Constant.
5099
+
5100
+ ``` cpp
5101
+ explicit hive(size_type n, const Allocator& = Allocator());
5102
+ hive(size_type n, hive_limits block_limits, const Allocator& = Allocator());
5103
+ ```
5104
+
5105
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `hive`.
5106
+
5107
+ *Effects:* Constructs a `hive` with `n` default-inserted elements, using
5108
+ the specified allocator. If the second overload is called, also
5109
+ initializes *current-limits* with `block_limits`.
5110
+
5111
+ *Complexity:* Linear in `n`.
5112
+
5113
+ ``` cpp
5114
+ hive(size_type n, const T& value, const Allocator& = Allocator());
5115
+ hive(size_type n, const T& value, hive_limits block_limits, const Allocator& = Allocator());
5116
+ ```
5117
+
5118
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `hive`.
5119
+
5120
+ *Effects:* Constructs a `hive` with `n` copies of `value`, using the
5121
+ specified allocator. If the second overload is called, also initializes
5122
+ *current-limits* with `block_limits`.
5123
+
5124
+ *Complexity:* Linear in `n`.
5125
+
5126
+ ``` cpp
5127
+ template<class InputIterator>
5128
+ hive(InputIterator first, InputIterator last, const Allocator& = Allocator());
5129
+ template<class InputIterator>
5130
+ hive(InputIterator first, InputIterator last, hive_limits block_limits,
5131
+ const Allocator& = Allocator());
5132
+ ```
5133
+
5134
+ *Effects:* Constructs a `hive` equal to the range \[`first`, `last`),
5135
+ using the specified allocator. If the second overload is called, also
5136
+ initializes *current-limits* with `block_limits`.
5137
+
5138
+ *Complexity:* Linear in `distance(first, last)`.
5139
+
5140
+ ``` cpp
5141
+ template<container-compatible-range<T> R>
5142
+ hive(from_range_t, R&& rg, const Allocator& = Allocator());
5143
+ template<container-compatible-range<T> R>
5144
+ hive(from_range_t, R&& rg, hive_limits block_limits, const Allocator& = Allocator());
5145
+ ```
5146
+
5147
+ *Effects:* Constructs a `hive` object with the elements of the range
5148
+ `rg`, using the specified allocator. If the second overload is called,
5149
+ also initializes *current-limits* with `block_limits`.
5150
+
5151
+ *Complexity:* Linear in `ranges::distance(rg)`.
5152
+
5153
+ ``` cpp
5154
+ hive(const hive& x);
5155
+ hive(const hive& x, const type_identity_t<Allocator>& alloc);
5156
+ ```
5157
+
5158
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `hive`.
5159
+
5160
+ *Effects:* Constructs a `hive` object with the elements of `x`. If the
5161
+ second overload is called, uses `alloc`. Initializes *current-limits*
5162
+ with `x.`*`current-limits`*.
5163
+
5164
+ *Complexity:* Linear in `x.size()`.
5165
+
5166
+ ``` cpp
5167
+ hive(hive&& x) noexcept;
5168
+ hive(hive&& x, const type_identity_t<Allocator>& alloc);
5169
+ ```
5170
+
5171
+ *Preconditions:* For the second overload, when
5172
+ `allocator_traits<alloc>::is_always_equal::value` is `false`, `T` meets
5173
+ the *Cpp17MoveInsertable* requirements.
5174
+
5175
+ *Effects:* When the first overload is called, or the second overload is
5176
+ called and `alloc == x.get_allocator()` is `true`, *current-limits* is
5177
+ set to `x.`*`current-limits`* and each element block is moved from `x`
5178
+ into `*this`. Pointers and references to the elements of `x` now refer
5179
+ to those same elements but as members of `*this`. Iterators referring to
5180
+ the elements of `x` will continue to refer to their elements, but they
5181
+ now behave as iterators into `*this`.
5182
+
5183
+ If the second overload is called and `alloc == x.get_allocator()` is
5184
+ `false`, each element in `x` is moved into `*this`. References, pointers
5185
+ and iterators referring to the elements of `x`, as well as the
5186
+ past-the-end iterator of `x`, are invalidated.
5187
+
5188
+ *Ensures:* `x.empty()` is `true`.
5189
+
5190
+ *Complexity:* If the second overload is called and
5191
+ `alloc == x.get_allocator()` is `false`, linear in `x.size()`. Otherwise
5192
+ constant.
5193
+
5194
+ ``` cpp
5195
+ hive(initializer_list<T> il, const Allocator& = Allocator());
5196
+ hive(initializer_list<T> il, hive_limits block_limits, const Allocator& = Allocator());
5197
+ ```
5198
+
5199
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `hive`.
5200
+
5201
+ *Effects:* Constructs a `hive` object with the elements of `il`, using
5202
+ the specified allocator. If the second overload is called, also
5203
+ initializes *current-limits* with `block_limits`.
5204
+
5205
+ *Complexity:* Linear in `il.size()`.
5206
+
5207
+ ``` cpp
5208
+ hive& operator=(const hive& x);
5209
+ ```
5210
+
5211
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `hive` and
5212
+ *Cpp17CopyAssignable*.
5213
+
5214
+ *Effects:* All elements in `*this` are either copy-assigned to, or
5215
+ destroyed. All elements in `x` are copied into `*this`.
5216
+
5217
+ [*Note 1*: *current-limits* is unchanged. — *end note*]
5218
+
5219
+ *Complexity:* Linear in `size() + x.size()`.
5220
+
5221
+ ``` cpp
5222
+ hive& operator=(hive&& x)
5223
+ noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5224
+ allocator_traits<Allocator>::is_always_equal::value);
5225
+ ```
5226
+
5227
+ *Preconditions:* When
5228
+
5229
+ ``` cpp
5230
+ (allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5231
+ allocator_traits<Allocator>::is_always_equal::value)
5232
+ ```
5233
+
5234
+ is `false`, `T` is *Cpp17MoveInsertable* into `hive` and
5235
+ *Cpp17MoveAssignable*.
5236
+
5237
+ *Effects:* Each element in `*this` is either move-assigned to, or
5238
+ destroyed. When
5239
+
5240
+ ``` cpp
5241
+ (allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5242
+ get_allocator() == x.get_allocator())
5243
+ ```
5244
+
5245
+ is `true`, *current-limits* is set to `x.`*`current-limits`* and each
5246
+ element block is moved from `x` into `*this`. Pointers and references to
5247
+ the elements of `x` now refer to those same elements but as members of
5248
+ `*this`. Iterators referring to the elements of `x` will continue to
5249
+ refer to their elements, but they now behave as iterators into `*this`,
5250
+ not into `x`.
5251
+
5252
+ When
5253
+
5254
+ ``` cpp
5255
+ (allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5256
+ get_allocator() == x.get_allocator())
5257
+ ```
5258
+
5259
+ is `false`, each element in `x` is moved into `*this`. References,
5260
+ pointers and iterators referring to the elements of `x`, as well as the
5261
+ past-the-end iterator of `x`, are invalidated.
5262
+
5263
+ *Ensures:* `x.empty()` is `true`.
5264
+
5265
+ *Complexity:* Linear in `size()`. If
5266
+
5267
+ ``` cpp
5268
+ (allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
5269
+ get_allocator() == x.get_allocator())
5270
+ ```
5271
+
5272
+ is `false`, also linear in `x.size()`.
5273
+
5274
+ #### Capacity <a id="hive.capacity">[[hive.capacity]]</a>
5275
+
5276
+ ``` cpp
5277
+ size_type capacity() const noexcept;
5278
+ ```
5279
+
5280
+ *Returns:* The total number of elements that `*this` can hold without
5281
+ requiring allocation of more element blocks.
5282
+
5283
+ *Complexity:* Constant.
5284
+
5285
+ ``` cpp
5286
+ void reserve(size_type n);
5287
+ ```
5288
+
5289
+ *Effects:* If `n <= capacity()` is `true`, there are no effects.
5290
+ Otherwise increases `capacity()` by allocating reserved blocks.
5291
+
5292
+ *Ensures:* `capacity() >= n` is `true`.
5293
+
5294
+ *Throws:* `length_error` if `n > max_size()`, as well as any exceptions
5295
+ thrown by the allocator.
5296
+
5297
+ *Complexity:* Linear in the number of reserved blocks allocated.
5298
+
5299
+ *Remarks:* The size of the sequence is not changed. All references,
5300
+ pointers, and iterators referring to elements in `*this`, as well as the
5301
+ past-the-end iterator, remain valid.
5302
+
5303
+ ``` cpp
5304
+ void shrink_to_fit();
5305
+ ```
5306
+
5307
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `hive`.
5308
+
5309
+ *Effects:* `shrink_to_fit` is a non-binding request to reduce
5310
+ `capacity()` to be closer to `size()`.
5311
+
5312
+ [*Note 1*: The request is non-binding to allow latitude for
5313
+ implementation-specific optimizations. — *end note*]
5314
+
5315
+ It does not increase `capacity()`, but may reduce `capacity()`. It may
5316
+ reallocate elements. If `capacity()` is already equal to `size()`, there
5317
+ are no effects. If an exception is thrown during allocation of a new
5318
+ element block, `capacity()` may be reduced and reallocation may occur.
5319
+ Otherwise if an exception is thrown, the effects are unspecified.
5320
+
5321
+ *Complexity:* If reallocation happens, linear in the size of the
5322
+ sequence.
5323
+
5324
+ *Remarks:* If reallocation happens, the order of the elements in `*this`
5325
+ may change and all references, pointers, and iterators referring to the
5326
+ elements in `*this`, as well as the past-the-end iterator, are
5327
+ invalidated.
5328
+
5329
+ ``` cpp
5330
+ void trim_capacity() noexcept;
5331
+ void trim_capacity(size_type n) noexcept;
5332
+ ```
5333
+
5334
+ *Effects:* For the first overload, all reserved blocks are deallocated,
5335
+ and `capacity()` is reduced accordingly. For the second overload,
5336
+ `capacity()` is reduced to no less than `n`.
5337
+
5338
+ *Complexity:* Linear in the number of reserved blocks deallocated.
5339
+
5340
+ *Remarks:* All references, pointers, and iterators referring to elements
5341
+ in `*this`, as well as the past-the-end iterator, remain valid.
5342
+
5343
+ ``` cpp
5344
+ constexpr hive_limits block_capacity_limits() const noexcept;
5345
+ ```
5346
+
5347
+ *Returns:* *current-limits*.
5348
+
5349
+ *Complexity:* Constant.
5350
+
5351
+ ``` cpp
5352
+ static constexpr hive_limits block_capacity_default_limits() noexcept;
5353
+ ```
5354
+
5355
+ *Returns:* A `hive_limits` struct with the `min` and `max` members set
5356
+ to the implementation’s default limits.
5357
+
5358
+ *Complexity:* Constant.
5359
+
5360
+ ``` cpp
5361
+ static constexpr hive_limits block_capacity_hard_limits() noexcept;
5362
+ ```
5363
+
5364
+ *Returns:* A `hive_limits` struct with the `min` and `max` members set
5365
+ to the implementation’s hard limits.
5366
+
5367
+ *Complexity:* Constant.
5368
+
5369
+ ``` cpp
5370
+ void reshape(hive_limits block_limits);
5371
+ ```
5372
+
5373
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `hive`.
5374
+
5375
+ *Effects:* For any active blocks not within the bounds of
5376
+ `block_limits`, the elements within those active blocks are reallocated
5377
+ to new or existing element blocks which are within the bounds. Any
5378
+ element blocks not within the bounds of `block_limits` are deallocated.
5379
+ If an exception is thrown during allocation of a new element block,
5380
+ `capacity()` may be reduced, reallocation may occur, and
5381
+ *current-limits* may be assigned a value other than `block_limits`.
5382
+ Otherwise `block_limits` is assigned to *current-limits*. If any other
5383
+ exception is thrown the effects are unspecified.
5384
+
5385
+ *Ensures:* `size()` is unchanged.
5386
+
5387
+ *Complexity:* Linear in the number of element blocks in `*this`. If
5388
+ reallocation happens, also linear in the number of elements reallocated.
5389
+
5390
+ *Remarks:* This operation may change `capacity()`. If reallocation
5391
+ happens, the order of the elements in `*this` may change. Reallocation
5392
+ invalidates all references, pointers, and iterators referring to the
5393
+ elements in `*this`, as well as the past-the-end iterator.
5394
+
5395
+ [*Note 2*: If no reallocation happens, they remain
5396
+ valid. — *end note*]
5397
+
5398
+ #### Modifiers <a id="hive.modifiers">[[hive.modifiers]]</a>
5399
+
5400
+ ``` cpp
5401
+ template<class... Args> iterator emplace(Args&&... args);
5402
+ template<class... Args> iterator emplace_hint(const_iterator hint, Args&&... args);
5403
+ ```
5404
+
5405
+ *Preconditions:* `T` is *Cpp17EmplaceConstructible* into `hive` from
5406
+ `args`.
5407
+
5408
+ *Effects:* Inserts an object of type `T` constructed with
5409
+ `std::forward<Args>(args)...`. The `hint` parameter is ignored. If an
5410
+ exception is thrown, there are no effects.
5411
+
5412
+ [*Note 1*: `args` can directly or indirectly refer to a value in
5413
+ `*this`. — *end note*]
5414
+
5415
+ *Returns:* An iterator that points to the new element.
5416
+
5417
+ *Complexity:* Constant. Exactly one object of type `T` is constructed.
5418
+
5419
+ *Remarks:* Invalidates the past-the-end iterator.
5420
+
5421
+ ``` cpp
5422
+ iterator insert(const T& x);
5423
+ iterator insert(const_iterator hint, const T& x);
5424
+ iterator insert(T&& x);
5425
+ iterator insert(const_iterator hint, T&& x);
5426
+ ```
5427
+
5428
+ *Effects:* Equivalent to:
5429
+ `return emplace(std::forward<decltype(x)>(x));`
5430
+
5431
+ [*Note 2*: The `hint` parameter is ignored. — *end note*]
5432
+
5433
+ ``` cpp
5434
+ void insert(initializer_list<T> rg);
5435
+ template<container-compatible-range<T> R>
5436
+ void insert_range(R&& rg);
5437
+ ```
5438
+
5439
+ *Preconditions:* `T` is *Cpp17EmplaceInsertable* into `hive` from
5440
+ `*ranges::begin(rg)`. `rg` and `*this` do not overlap.
5441
+
5442
+ *Effects:* Inserts copies of elements in `rg`. Each iterator in the
5443
+ range `rg` is dereferenced exactly once.
5444
+
5445
+ *Complexity:* Linear in the number of elements inserted. Exactly one
5446
+ object of type `T` is constructed for each element inserted.
5447
+
5448
+ *Remarks:* If an element is inserted, invalidates the past-the-end
5449
+ iterator.
5450
+
5451
+ ``` cpp
5452
+ void insert(size_type n, const T& x);
5453
+ ```
5454
+
5455
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `hive`.
5456
+
5457
+ *Effects:* Inserts `n` copies of `x`.
5458
+
5459
+ *Complexity:* Linear in `n`. Exactly one object of type `T` is
5460
+ constructed for each element inserted.
5461
+
5462
+ *Remarks:* If an element is inserted, invalidates the past-the-end
5463
+ iterator.
5464
+
5465
+ ``` cpp
5466
+ template<class InputIterator>
5467
+ void insert(InputIterator first, InputIterator last);
5468
+ ```
5469
+
5470
+ *Effects:* Equivalent to `insert_range(ranges::subrange(first, last))`.
5471
+
5472
+ ``` cpp
5473
+ iterator erase(const_iterator position);
5474
+ iterator erase(const_iterator first, const_iterator last);
5475
+ ```
5476
+
5477
+ *Complexity:* Linear in the number of elements erased. Additionally, if
5478
+ any active blocks become empty of elements as a result of the function
5479
+ call, at worst linear in the number of element blocks.
5480
+
5481
+ *Remarks:* Invalidates references, pointers and iterators referring to
5482
+ the erased elements. An erase operation that erases the last element in
5483
+ `*this` also invalidates the past-the-end iterator.
5484
+
5485
+ ``` cpp
5486
+ void swap(hive& x)
5487
+ noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
5488
+ allocator_traits<Allocator>::is_always_equal::value);
5489
+ ```
5490
+
5491
+ *Effects:* Exchanges the contents, `capacity()`, and *current-limits* of
5492
+ `*this` with that of `x`.
5493
+
5494
+ *Complexity:* Constant.
5495
+
5496
+ #### Operations <a id="hive.operations">[[hive.operations]]</a>
5497
+
5498
+ In this subclause, arguments for a template parameter named `Predicate`
5499
+ or `BinaryPredicate` shall meet the corresponding requirements in
5500
+ [[algorithms.requirements]]. The semantics of `i + n` and `i - n`, where
5501
+ `i` is an iterator into the `hive` and `n` is an integer, are the same
5502
+ as those of `next(i, n)` and `prev(i, n)`, respectively. For `sort`, the
5503
+ definitions and requirements in [[alg.sorting]] apply.
5504
+
5505
+ ``` cpp
5506
+ void splice(hive& x);
5507
+ void splice(hive&& x);
5508
+ ```
5509
+
5510
+ *Preconditions:* `get_allocator() == x.get_allocator()` is `true`.
5511
+
5512
+ *Effects:* If `addressof(x) == this` is `true`, the behavior is
5513
+ erroneous and there are no effects. Otherwise, inserts the contents of
5514
+ `x` into `*this` and `x` becomes empty. Pointers and references to the
5515
+ moved elements of `x` now refer to those same elements but as members of
5516
+ `*this`. Iterators referring to the moved elements continue to refer to
5517
+ their elements, but they now behave as iterators into `*this`, not into
5518
+ `x`.
5519
+
5520
+ *Throws:* `length_error` if any of `x`’s active blocks are not within
5521
+ the bounds of *current-limits*.
5522
+
5523
+ *Complexity:* Linear in the sum of all element blocks in `x` plus all
5524
+ element blocks in `*this`.
5525
+
5526
+ *Remarks:* Reserved blocks in `x` are not transferred into `*this`. If
5527
+ `addressof(x) == this` is `false`, invalidates the past-the-end iterator
5528
+ for both `x` and `*this`.
5529
+
5530
+ ``` cpp
5531
+ template<class BinaryPredicate = equal_to<T>>
5532
+ size_type unique(BinaryPredicate binary_pred = BinaryPredicate());
5533
+ ```
5534
+
5535
+ *Preconditions:* `binary_pred` is an equivalence relation.
5536
+
5537
+ *Effects:* Erases all but the first element from every consecutive group
5538
+ of equivalent elements. That is, for a nonempty `hive`, erases all
5539
+ elements referred to by the iterator `i` in the range \[`begin() + 1`,
5540
+ `end()`) for which `binary_pred(*i, *(i - 1))` is `true`.
5541
+
5542
+ *Returns:* The number of elements erased.
5543
+
5544
+ *Throws:* Nothing unless an exception is thrown by the predicate.
5545
+
5546
+ *Complexity:* If `empty()` is `false`, exactly `size() - 1` applications
5547
+ of the corresponding predicate, otherwise no applications of the
5548
+ predicate.
5549
+
5550
+ *Remarks:* Invalidates references, pointers, and iterators referring to
5551
+ the erased elements. If the last element in `*this` is erased, also
5552
+ invalidates the past-the-end iterator.
5553
+
5554
+ ``` cpp
5555
+ template<class Compare = less<T>>
5556
+ void sort(Compare comp = Compare());
5557
+ ```
5558
+
5559
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `hive`,
5560
+ *Cpp17MoveAssignable*, and *Cpp17Swappable*.
5561
+
5562
+ *Effects:* Sorts `*this` according to the `comp` function object. If an
5563
+ exception is thrown, the order of the elements in `*this` is
5564
+ unspecified.
5565
+
5566
+ *Complexity:* 𝑂(N log N) comparisons, where N is `size()`.
5567
+
5568
+ *Remarks:* May allocate. References, pointers, and iterators referring
5569
+ to elements in `*this`, as well as the past-the-end iterator, may be
5570
+ invalidated.
5571
+
5572
+ [*Note 1*: Not required to be
5573
+ stable [[algorithm.stable]]. — *end note*]
5574
+
5575
+ ``` cpp
5576
+ iterator get_iterator(const_pointer p) noexcept;
5577
+ const_iterator get_iterator(const_pointer p) const noexcept;
5578
+ ```
5579
+
5580
+ *Preconditions:* `p` points to an element in `*this`.
5581
+
5582
+ *Returns:* An `iterator` or `const_iterator` pointing to the same
5583
+ element as `p`.
5584
+
5585
+ *Complexity:* Linear in the number of active blocks in `*this`.
5586
+
5587
+ #### Erasure <a id="hive.erasure">[[hive.erasure]]</a>
5588
+
5589
+ ``` cpp
5590
+ template<class T, class Allocator, class U = T>
5591
+ typename hive<T, Allocator>::size_type
5592
+ erase(hive<T, Allocator>& c, const U& value);
5593
+ ```
5594
+
5595
+ *Effects:* Equivalent to:
5596
+
5597
+ ``` cpp
5598
+ return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
5599
+ ```
5600
+
5601
+ ``` cpp
5602
+ template<class T, class Allocator, class Predicate>
5603
+ typename hive<T, Allocator>::size_type
5604
+ erase_if(hive<T, Allocator>& c, Predicate pred);
5605
+ ```
5606
+
5607
+ *Effects:* Equivalent to:
5608
+
5609
+ ``` cpp
5610
+ auto original_size = c.size();
5611
+ for (auto i = c.begin(), last = c.end(); i != last; ) {
5612
+ if (pred(*i)) {
5613
+ i = c.erase(i);
5614
+ } else {
5615
+ ++i;
5616
+ }
5617
+ }
5618
+ return original_size - c.size();
5619
+ ```
5620
+
5621
+ ### Header `<list>` synopsis <a id="list.syn">[[list.syn]]</a>
5622
+
5623
+ ``` cpp
5624
+ #include <compare> // see [compare.syn]
5625
+ #include <initializer_list> // see [initializer.list.syn]
5626
+
5627
+ namespace std {
5628
+ // [list], class template list
5629
+ template<class T, class Allocator = allocator<T>> class list;
5630
+
5631
+ template<class T, class Allocator>
5632
+ constexpr bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
5633
+ template<class T, class Allocator>
5634
+ constexpr synth-three-way-result<T>
5635
+ operator<=>(const list<T, Allocator>& x, const list<T, Allocator>& y);
5636
+
5637
+ template<class T, class Allocator>
5638
+ constexpr void swap(list<T, Allocator>& x, list<T, Allocator>& y)
5639
+ noexcept(noexcept(x.swap(y)));
5640
+
5641
+ // [list.erasure], erasure
5642
+ template<class T, class Allocator, class U = T>
5643
+ constexpr typename list<T, Allocator>::size_type
5644
+ erase(list<T, Allocator>& c, const U& value);
5645
+ template<class T, class Allocator, class Predicate>
5646
+ constexpr typename list<T, Allocator>::size_type
5647
+ erase_if(list<T, Allocator>& c, Predicate pred);
5648
+
5649
+ namespace pmr {
5650
+ template<class T>
5651
+ using list = std::list<T, polymorphic_allocator<T>>;
5652
+ }
5653
+ }
5654
+ ```
5655
+
5656
  ### Class template `list` <a id="list">[[list]]</a>
5657
 
5658
  #### Overview <a id="list.overview">[[list.overview]]</a>
5659
 
5660
  A `list` is a sequence container that supports bidirectional iterators
 
5673
 
5674
  Descriptions are provided here only for operations on `list` that are
5675
  not described in one of these tables or for operations where there is
5676
  additional semantic information.
5677
 
5678
+ The types `iterator` and `const_iterator` meet the constexpr iterator
5679
+ requirements [[iterator.requirements.general]].
5680
+
5681
  ``` cpp
5682
  namespace std {
5683
  template<class T, class Allocator = allocator<T>>
5684
  class list {
5685
  public:
5686
  // types
5687
  using value_type = T;
5688
  using allocator_type = Allocator;
5689
+ using pointer = allocator_traits<Allocator>::pointer;
5690
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
5691
  using reference = value_type&;
5692
  using const_reference = const value_type&;
5693
  using size_type = implementation-defined // type of list::size_type; // see [container.requirements]
5694
  using difference_type = implementation-defined // type of list::difference_type; // see [container.requirements]
5695
  using iterator = implementation-defined // type of list::iterator; // see [container.requirements]
5696
  using const_iterator = implementation-defined // type of list::const_iterator; // see [container.requirements]
5697
  using reverse_iterator = std::reverse_iterator<iterator>;
5698
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
5699
 
5700
  // [list.cons], construct/copy/destroy
5701
+ constexpr list() : list(Allocator()) { }
5702
+ constexpr explicit list(const Allocator&);
5703
+ constexpr explicit list(size_type n, const Allocator& = Allocator());
5704
+ constexpr list(size_type n, const T& value, const Allocator& = Allocator());
5705
  template<class InputIterator>
5706
+ constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator());
5707
  template<container-compatible-range<T> R>
5708
+ constexpr list(from_range_t, R&& rg, const Allocator& = Allocator());
5709
+ constexpr list(const list& x);
5710
+ constexpr list(list&& x);
5711
+ constexpr list(const list&, const type_identity_t<Allocator>&);
5712
+ constexpr list(list&&, const type_identity_t<Allocator>&);
5713
+ constexpr list(initializer_list<T>, const Allocator& = Allocator());
5714
+ constexpr ~list();
5715
+ constexpr list& operator=(const list& x);
5716
+ constexpr list& operator=(list&& x)
5717
  noexcept(allocator_traits<Allocator>::is_always_equal::value);
5718
+ constexpr list& operator=(initializer_list<T>);
5719
  template<class InputIterator>
5720
+ constexpr void assign(InputIterator first, InputIterator last);
5721
  template<container-compatible-range<T> R>
5722
+ constexpr void assign_range(R&& rg);
5723
+ constexpr void assign(size_type n, const T& t);
5724
+ constexpr void assign(initializer_list<T>);
5725
+ constexpr allocator_type get_allocator() const noexcept;
5726
 
5727
  // iterators
5728
+ constexpr iterator begin() noexcept;
5729
+ constexpr const_iterator begin() const noexcept;
5730
+ constexpr iterator end() noexcept;
5731
+ constexpr const_iterator end() const noexcept;
5732
+ constexpr reverse_iterator rbegin() noexcept;
5733
+ constexpr const_reverse_iterator rbegin() const noexcept;
5734
+ constexpr reverse_iterator rend() noexcept;
5735
+ constexpr const_reverse_iterator rend() const noexcept;
5736
 
5737
+ constexpr const_iterator cbegin() const noexcept;
5738
+ constexpr const_iterator cend() const noexcept;
5739
+ constexpr const_reverse_iterator crbegin() const noexcept;
5740
+ constexpr const_reverse_iterator crend() const noexcept;
5741
 
5742
  // [list.capacity], capacity
5743
+ constexpr bool empty() const noexcept;
5744
+ constexpr size_type size() const noexcept;
5745
+ constexpr size_type max_size() const noexcept;
5746
+ constexpr void resize(size_type sz);
5747
+ constexpr void resize(size_type sz, const T& c);
5748
 
5749
  // element access
5750
+ constexpr reference front();
5751
+ constexpr const_reference front() const;
5752
+ constexpr reference back();
5753
+ constexpr const_reference back() const;
5754
 
5755
  // [list.modifiers], modifiers
5756
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
5757
+ template<class... Args> constexpr reference emplace_back(Args&&... args);
5758
+ constexpr void push_front(const T& x);
5759
+ constexpr void push_front(T&& x);
5760
  template<container-compatible-range<T> R>
5761
+ constexpr void prepend_range(R&& rg);
5762
+ constexpr void pop_front();
5763
+ constexpr void push_back(const T& x);
5764
+ constexpr void push_back(T&& x);
5765
  template<container-compatible-range<T> R>
5766
+ constexpr void append_range(R&& rg);
5767
+ constexpr void pop_back();
5768
 
5769
+ template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
5770
+ constexpr iterator insert(const_iterator position, const T& x);
5771
+ constexpr iterator insert(const_iterator position, T&& x);
5772
+ constexpr iterator insert(const_iterator position, size_type n, const T& x);
5773
  template<class InputIterator>
5774
+ constexpr iterator insert(const_iterator position,
5775
+ InputIterator first, InputIterator last);
5776
  template<container-compatible-range<T> R>
5777
+ constexpr iterator insert_range(const_iterator position, R&& rg);
5778
+ constexpr iterator insert(const_iterator position, initializer_list<T> il);
5779
 
5780
+ constexpr iterator erase(const_iterator position);
5781
+ constexpr iterator erase(const_iterator position, const_iterator last);
5782
+ constexpr void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value);
5783
+ constexpr void clear() noexcept;
5784
 
5785
  // [list.ops], list operations
5786
+ constexpr void splice(const_iterator position, list& x);
5787
+ constexpr void splice(const_iterator position, list&& x);
5788
+ constexpr void splice(const_iterator position, list& x, const_iterator i);
5789
+ constexpr void splice(const_iterator position, list&& x, const_iterator i);
5790
+ constexpr void splice(const_iterator position, list& x,
5791
+ const_iterator first, const_iterator last);
5792
+ constexpr void splice(const_iterator position, list&& x,
5793
+ const_iterator first, const_iterator last);
5794
 
5795
+ constexpr size_type remove(const T& value);
5796
+ template<class Predicate> constexpr size_type remove_if(Predicate pred);
5797
 
5798
+ constexpr size_type unique();
5799
  template<class BinaryPredicate>
5800
+ constexpr size_type unique(BinaryPredicate binary_pred);
5801
 
5802
+ constexpr void merge(list& x);
5803
+ constexpr void merge(list&& x);
5804
+ template<class Compare> constexpr void merge(list& x, Compare comp);
5805
+ template<class Compare> constexpr void merge(list&& x, Compare comp);
5806
 
5807
+ constexpr void sort();
5808
+ template<class Compare> constexpr void sort(Compare comp);
5809
 
5810
+ constexpr void reverse() noexcept;
5811
  };
5812
 
5813
  template<class InputIterator, class Allocator = allocator<iter-value-type<InputIterator>>>
5814
  list(InputIterator, InputIterator, Allocator = Allocator())
5815
  -> list<iter-value-type<InputIterator>, Allocator>;
 
5826
  any member of the resulting specialization of `list` is referenced.
5827
 
5828
  #### Constructors, copy, and assignment <a id="list.cons">[[list.cons]]</a>
5829
 
5830
  ``` cpp
5831
+ constexpr explicit list(const Allocator&);
5832
  ```
5833
 
5834
  *Effects:* Constructs an empty list, using the specified allocator.
5835
 
5836
  *Complexity:* Constant.
5837
 
5838
  ``` cpp
5839
+ constexpr explicit list(size_type n, const Allocator& = Allocator());
5840
  ```
5841
 
5842
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `list`.
5843
 
5844
  *Effects:* Constructs a `list` with `n` default-inserted elements using
5845
  the specified allocator.
5846
 
5847
  *Complexity:* Linear in `n`.
5848
 
5849
  ``` cpp
5850
+ constexpr list(size_type n, const T& value, const Allocator& = Allocator());
5851
  ```
5852
 
5853
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `list`.
5854
 
5855
  *Effects:* Constructs a `list` with `n` copies of `value`, using the
5856
  specified allocator.
5857
 
5858
  *Complexity:* Linear in `n`.
5859
 
5860
  ``` cpp
5861
  template<class InputIterator>
5862
+ constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator());
5863
  ```
5864
 
5865
  *Effects:* Constructs a `list` equal to the range \[`first`, `last`).
5866
 
5867
  *Complexity:* Linear in `distance(first, last)`.
5868
 
5869
  ``` cpp
5870
  template<container-compatible-range<T> R>
5871
+ constexpr list(from_range_t, R&& rg, const Allocator& = Allocator());
5872
  ```
5873
 
5874
  *Effects:* Constructs a `list` object with the elements of the range
5875
  `rg`.
5876
 
5877
  *Complexity:* Linear in `ranges::distance(rg)`.
5878
 
5879
  #### Capacity <a id="list.capacity">[[list.capacity]]</a>
5880
 
5881
  ``` cpp
5882
+ constexpr void resize(size_type sz);
5883
  ```
5884
 
5885
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `list`.
5886
 
5887
  *Effects:* If `size() < sz`, appends `sz - size()` default-inserted
5888
  elements to the sequence. If `sz <= size()`, equivalent to:
5889
 
5890
  ``` cpp
 
5892
  advance(it, sz);
5893
  erase(it, end());
5894
  ```
5895
 
5896
  ``` cpp
5897
+ constexpr void resize(size_type sz, const T& c);
5898
  ```
5899
 
5900
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `list`.
5901
 
5902
  *Effects:* As if by:
5903
 
5904
  ``` cpp
5905
  if (sz > size())
 
5914
  ```
5915
 
5916
  #### Modifiers <a id="list.modifiers">[[list.modifiers]]</a>
5917
 
5918
  ``` cpp
5919
+ constexpr iterator insert(const_iterator position, const T& x);
5920
+ constexpr iterator insert(const_iterator position, T&& x);
5921
+ constexpr iterator insert(const_iterator position, size_type n, const T& x);
5922
  template<class InputIterator>
5923
+ constexpr iterator insert(const_iterator position,
5924
+ InputIterator first, InputIterator last);
5925
  template<container-compatible-range<T> R>
5926
+ constexpr iterator insert_range(const_iterator position, R&& rg);
5927
+ constexpr iterator insert(const_iterator position, initializer_list<T>);
5928
 
5929
+ template<class... Args> constexpr reference emplace_front(Args&&... args);
5930
+ template<class... Args> constexpr reference emplace_back(Args&&... args);
5931
+ template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args);
5932
+ constexpr void push_front(const T& x);
5933
+ constexpr void push_front(T&& x);
5934
  template<container-compatible-range<T> R>
5935
+ constexpr void prepend_range(R&& rg);
5936
+ constexpr void push_back(const T& x);
5937
+ constexpr void push_back(T&& x);
5938
  template<container-compatible-range<T> R>
5939
+ constexpr void append_range(R&& rg);
5940
  ```
5941
 
5942
  *Complexity:* Insertion of a single element into a list takes constant
5943
  time and exactly one call to a constructor of `T`. Insertion of multiple
5944
  elements into a list is linear in the number of elements inserted, and
5945
  the number of calls to the copy constructor or move constructor of `T`
5946
  is exactly equal to the number of elements inserted.
5947
 
5948
  *Remarks:* Does not affect the validity of iterators and references. If
5949
+ an exception is thrown, there are no effects.
5950
 
5951
  ``` cpp
5952
+ constexpr iterator erase(const_iterator position);
5953
+ constexpr iterator erase(const_iterator first, const_iterator last);
5954
+ constexpr void pop_front();
5955
+ constexpr void pop_back();
5956
+ constexpr void clear() noexcept;
 
5957
  ```
5958
 
5959
  *Effects:* Invalidates only the iterators and references to the erased
5960
  elements.
5961
 
 
5982
  from one list to another. The behavior of splice operations is undefined
5983
  if `get_allocator() !=
5984
  x.get_allocator()`.
5985
 
5986
  ``` cpp
5987
+ constexpr void splice(const_iterator position, list& x);
5988
+ constexpr void splice(const_iterator position, list&& x);
5989
  ```
5990
 
5991
  *Preconditions:* `addressof(x) != this` is `true`.
5992
 
5993
  *Effects:* Inserts the contents of `x` before `position` and `x` becomes
 
5999
  *Throws:* Nothing.
6000
 
6001
  *Complexity:* Constant time.
6002
 
6003
  ``` cpp
6004
+ constexpr void splice(const_iterator position, list& x, const_iterator i);
6005
+ constexpr void splice(const_iterator position, list&& x, const_iterator i);
6006
  ```
6007
 
6008
  *Preconditions:* `i` is a valid dereferenceable iterator of `x`.
6009
 
6010
  *Effects:* Inserts an element pointed to by `i` from list `x` before
 
6017
  *Throws:* Nothing.
6018
 
6019
  *Complexity:* Constant time.
6020
 
6021
  ``` cpp
6022
+ constexpr void splice(const_iterator position, list& x,
6023
+ const_iterator first, const_iterator last);
6024
+ constexpr void splice(const_iterator position, list&& x,
6025
+ const_iterator first, const_iterator last);
6026
  ```
6027
 
6028
+ *Preconditions:* \[`first`, `last`) is a valid range in `x`. `position`
6029
+ is not an iterator in the range \[`first`, `last`).
6030
 
6031
  *Effects:* Inserts elements in the range \[`first`, `last`) before
6032
  `position` and removes the elements from `x`. Pointers and references to
6033
  the moved elements of `x` now refer to those same elements but as
6034
  members of `*this`. Iterators referring to the moved elements will
 
6039
 
6040
  *Complexity:* Constant time if `addressof(x) == this`; otherwise, linear
6041
  time.
6042
 
6043
  ``` cpp
6044
+ constexpr size_type remove(const T& value);
6045
+ template<class Predicate> constexpr size_type remove_if(Predicate pred);
6046
  ```
6047
 
6048
  *Effects:* Erases all the elements in the list referred to by a list
6049
  iterator `i` for which the following conditions hold: `*i == value`,
6050
  `pred(*i) != false`. Invalidates only the iterators and references to
 
6059
  predicate.
6060
 
6061
  *Remarks:* Stable [[algorithm.stable]].
6062
 
6063
  ``` cpp
6064
+ constexpr size_type unique();
6065
+ template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred);
6066
  ```
6067
 
6068
  Let `binary_pred` be `equal_to<>{}` for the first overload.
6069
 
6070
  *Preconditions:* `binary_pred` is an equivalence relation.
 
6082
  *Complexity:* If `empty()` is `false`, exactly `size() - 1` applications
6083
  of the corresponding predicate, otherwise no applications of the
6084
  predicate.
6085
 
6086
  ``` cpp
6087
+ constexpr void merge(list& x);
6088
+ constexpr void merge(list&& x);
6089
+ template<class Compare> constexpr void merge(list& x, Compare comp);
6090
+ template<class Compare> constexpr void merge(list&& x, Compare comp);
6091
  ```
6092
 
6093
  Let `comp` be `less<>` for the first two overloads.
6094
 
6095
  *Preconditions:* `*this` and `x` are both sorted with respect to the
 
6106
  *Complexity:* At most `size() + x.size() - 1` comparisons if
6107
  `addressof(x) != this`; otherwise, no comparisons are performed.
6108
 
6109
  *Remarks:* Stable [[algorithm.stable]]. If `addressof(x) != this`, `x`
6110
  is empty after the merge. No elements are copied by this operation. If
6111
+ an exception is thrown other than by a comparison, there are no effects.
6112
 
6113
  ``` cpp
6114
+ constexpr void reverse() noexcept;
6115
  ```
6116
 
6117
  *Effects:* Reverses the order of the elements in the list. Does not
6118
  affect the validity of iterators and references.
6119
 
 
6127
  *Effects:* Sorts the list according to the `operator<` or a `Compare`
6128
  function object. If an exception is thrown, the order of the elements in
6129
  `*this` is unspecified. Does not affect the validity of iterators and
6130
  references.
6131
 
6132
+ *Complexity:* Approximately N log N comparisons, where N is `size()`.
6133
 
6134
  *Remarks:* Stable [[algorithm.stable]].
6135
 
6136
  #### Erasure <a id="list.erasure">[[list.erasure]]</a>
6137
 
6138
  ``` cpp
6139
+ template<class T, class Allocator, class U = T>
6140
  typename list<T, Allocator>::size_type
6141
+ constexpr erase(list<T, Allocator>& c, const U& value);
6142
  ```
6143
 
6144
  *Effects:* Equivalent to:
6145
+
6146
+ ``` cpp
6147
+ return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
6148
+ ```
6149
 
6150
  ``` cpp
6151
  template<class T, class Allocator, class Predicate>
6152
  typename list<T, Allocator>::size_type
6153
+ constexpr erase_if(list<T, Allocator>& c, Predicate pred);
6154
  ```
6155
 
6156
  *Effects:* Equivalent to: `return c.remove_if(pred);`
6157
 
6158
+ ### Header `<vector>` synopsis <a id="vector.syn">[[vector.syn]]</a>
6159
+
6160
+ ``` cpp
6161
+ #include <compare> // see [compare.syn]
6162
+ #include <initializer_list> // see [initializer.list.syn]
6163
+
6164
+ namespace std {
6165
+ // [vector], class template vector
6166
+ template<class T, class Allocator = allocator<T>> class vector;
6167
+
6168
+ template<class T, class Allocator>
6169
+ constexpr bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
6170
+ template<class T, class Allocator>
6171
+ constexpr synth-three-way-result<T>
6172
+ operator<=>(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
6173
+
6174
+ template<class T, class Allocator>
6175
+ constexpr void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
6176
+ noexcept(noexcept(x.swap(y)));
6177
+
6178
+ // [vector.erasure], erasure
6179
+ template<class T, class Allocator, class U = T>
6180
+ constexpr typename vector<T, Allocator>::size_type
6181
+ erase(vector<T, Allocator>& c, const U& value);
6182
+ template<class T, class Allocator, class Predicate>
6183
+ constexpr typename vector<T, Allocator>::size_type
6184
+ erase_if(vector<T, Allocator>& c, Predicate pred);
6185
+
6186
+ namespace pmr {
6187
+ template<class T>
6188
+ using vector = std::vector<T, polymorphic_allocator<T>>;
6189
+ }
6190
+
6191
+ // [vector.bool], specialization of vector for bool
6192
+ // [vector.bool.pspc], partial class template specialization vector<bool, Allocator>
6193
+ template<class Allocator>
6194
+ class vector<bool, Allocator>;
6195
+
6196
+ template<class T>
6197
+ constexpr bool is-vector-bool-reference = see below; // exposition only
6198
+
6199
+ // hash support
6200
+ template<class T> struct hash;
6201
+ template<class Allocator> struct hash<vector<bool, Allocator>>;
6202
+
6203
+ // [vector.bool.fmt], formatter specialization for vector<bool>
6204
+ template<class T, class charT> requires is-vector-bool-reference<T>
6205
+ struct formatter<T, charT>;
6206
+ }
6207
+ ```
6208
+
6209
  ### Class template `vector` <a id="vector">[[vector]]</a>
6210
 
6211
  #### Overview <a id="vector.overview">[[vector.overview]]</a>
6212
 
6213
  A `vector` is a sequence container that supports (amortized) constant
 
6236
  class vector {
6237
  public:
6238
  // types
6239
  using value_type = T;
6240
  using allocator_type = Allocator;
6241
+ using pointer = allocator_traits<Allocator>::pointer;
6242
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
6243
  using reference = value_type&;
6244
  using const_reference = const value_type&;
6245
  using size_type = implementation-defined // type of vector::size_type; // see [container.requirements]
6246
  using difference_type = implementation-defined // type of vector::difference_type; // see [container.requirements]
6247
  using iterator = implementation-defined // type of vector::iterator; // see [container.requirements]
 
6291
  constexpr const_iterator cend() const noexcept;
6292
  constexpr const_reverse_iterator crbegin() const noexcept;
6293
  constexpr const_reverse_iterator crend() const noexcept;
6294
 
6295
  // [vector.capacity], capacity
6296
+ constexpr bool empty() const noexcept;
6297
  constexpr size_type size() const noexcept;
6298
  constexpr size_type max_size() const noexcept;
6299
  constexpr size_type capacity() const noexcept;
6300
  constexpr void resize(size_type sz);
6301
  constexpr void resize(size_type sz, const T& c);
 
6303
  constexpr void shrink_to_fit();
6304
 
6305
  // element access
6306
  constexpr reference operator[](size_type n);
6307
  constexpr const_reference operator[](size_type n) const;
 
6308
  constexpr reference at(size_type n);
6309
+ constexpr const_reference at(size_type n) const;
6310
  constexpr reference front();
6311
  constexpr const_reference front() const;
6312
  constexpr reference back();
6313
  constexpr const_reference back() const;
6314
 
 
6369
 
6370
  ``` cpp
6371
  constexpr explicit vector(size_type n, const Allocator& = Allocator());
6372
  ```
6373
 
6374
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `vector`.
6375
 
6376
  *Effects:* Constructs a `vector` with `n` default-inserted elements
6377
  using the specified allocator.
6378
 
6379
  *Complexity:* Linear in `n`.
 
6381
  ``` cpp
6382
  constexpr vector(size_type n, const T& value,
6383
  const Allocator& = Allocator());
6384
  ```
6385
 
6386
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `vector`.
6387
 
6388
  *Effects:* Constructs a `vector` with `n` copies of `value`, using the
6389
  specified allocator.
6390
 
6391
  *Complexity:* Linear in `n`.
 
6399
  *Effects:* Constructs a `vector` equal to the range \[`first`, `last`),
6400
  using the specified allocator.
6401
 
6402
  *Complexity:* Makes only N calls to the copy constructor of `T` (where N
6403
  is the distance between `first` and `last`) and no reallocations if
6404
+ `InputIterator` meets the *Cpp17ForwardIterator* requirements. It makes
6405
+ order N calls to the copy constructor of `T` and order log N
6406
+ reallocations if they are just input iterators.
6407
 
6408
  ``` cpp
6409
  template<container-compatible-range<T> R>
6410
  constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
6411
  ```
 
6413
  *Effects:* Constructs a `vector` object with the elements of the range
6414
  `rg`, using the specified allocator.
6415
 
6416
  *Complexity:* Initializes exactly N elements from the results of
6417
  dereferencing successive iterators of `rg`, where N is
6418
+ `ranges::distance(rg)`.
6419
+
6420
+ Performs no reallocations if:
6421
+
6422
+ - `R` models `ranges::approximately_sized_range`, and
6423
+ `ranges::distance(rg) <= ranges::reserve_hint(rg)` is `true`, or
6424
+ - `R` models `ranges::forward_range` and `R` does not model
6425
+ `ranges::approximately_sized_range`.
6426
+
6427
+ Otherwise, performs order log N reallocations and order N calls to the
6428
+ copy or move constructor of `T`.
6429
 
6430
  #### Capacity <a id="vector.capacity">[[vector.capacity]]</a>
6431
 
6432
  ``` cpp
6433
  constexpr size_type capacity() const noexcept;
 
6440
 
6441
  ``` cpp
6442
  constexpr void reserve(size_type n);
6443
  ```
6444
 
6445
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `vector`.
6446
 
6447
  *Effects:* A directive that informs a `vector` of a planned change in
6448
  size, so that it can manage the storage allocation accordingly. After
6449
  `reserve()`, `capacity()` is greater or equal to the argument of
6450
  `reserve` if reallocation happens; and equal to the previous value of
 
6453
  exception is thrown other than by the move constructor of a
6454
  non-*Cpp17CopyInsertable* type, there are no effects.
6455
 
6456
  *Throws:* `length_error` if `n > max_size()`.[^4]
6457
 
6458
+ *Complexity:* Linear in the size of the sequence.
 
6459
 
6460
+ *Remarks:* The size of the sequence is not changed. Reallocation
6461
+ invalidates all the references, pointers, and iterators referring to the
6462
+ elements in the sequence, as well as the past-the-end iterator.
6463
 
6464
  [*Note 1*: If no reallocation happens, they remain
6465
  valid. — *end note*]
6466
 
6467
  No reallocation shall take place during insertions that happen after a
 
6470
 
6471
  ``` cpp
6472
  constexpr void shrink_to_fit();
6473
  ```
6474
 
6475
+ *Preconditions:* `T` is *Cpp17MoveInsertable* into `vector`.
6476
 
6477
  *Effects:* `shrink_to_fit` is a non-binding request to reduce
6478
  `capacity()` to `size()`.
6479
 
6480
  [*Note 2*: The request is non-binding to allow latitude for
6481
  implementation-specific optimizations. — *end note*]
6482
 
6483
  It does not increase `capacity()`, but may reduce `capacity()` by
6484
  causing reallocation. If an exception is thrown other than by the move
6485
+ constructor of a non-*Cpp17CopyInsertable* `T`, there are no effects.
6486
 
6487
  *Complexity:* If reallocation happens, linear in the size of the
6488
  sequence.
6489
 
6490
  *Remarks:* Reallocation invalidates all the references, pointers, and
 
6508
  ``` cpp
6509
  constexpr void resize(size_type sz);
6510
  ```
6511
 
6512
  *Preconditions:* `T` is *Cpp17MoveInsertable* and
6513
+ *Cpp17DefaultInsertable* into `vector`.
6514
 
6515
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
6516
  the sequence. Otherwise, appends `sz - size()` default-inserted elements
6517
  to the sequence.
6518
 
6519
  *Remarks:* If an exception is thrown other than by the move constructor
6520
+ of a non-*Cpp17CopyInsertable* `T`, there are no effects.
6521
 
6522
  ``` cpp
6523
  constexpr void resize(size_type sz, const T& c);
6524
  ```
6525
 
6526
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `vector`.
6527
 
6528
  *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
6529
  the sequence. Otherwise, appends `sz - size()` copies of `c` to the
6530
  sequence.
6531
 
6532
+ *Remarks:* If an exception is thrown, there are no effects.
6533
 
6534
  #### Data <a id="vector.data">[[vector.data]]</a>
6535
 
6536
  ``` cpp
6537
  constexpr T* data() noexcept;
6538
  constexpr const T* data() const noexcept;
6539
  ```
6540
 
6541
  *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
6542
+ range. For a non-empty vector, `data() == addressof(front())` is `true`.
6543
 
6544
  *Complexity:* Constant time.
6545
 
6546
  #### Modifiers <a id="vector.modifiers">[[vector.modifiers]]</a>
6547
 
 
6573
  past-the-end iterator. If no reallocation happens, then references,
6574
  pointers, and iterators before the insertion point remain valid but
6575
  those at or after the insertion point, including the past-the-end
6576
  iterator, are invalidated. If an exception is thrown other than by the
6577
  copy constructor, move constructor, assignment operator, or move
6578
+ assignment operator of `T` or by any `InputIterator` operation, there
6579
+ are no effects. If an exception is thrown while inserting a single
6580
+ element at the end and `T` is *Cpp17CopyInsertable* or
6581
  `is_nothrow_move_constructible_v<T>` is `true`, there are no effects.
6582
  Otherwise, if an exception is thrown by the move constructor of a
6583
  non-*Cpp17CopyInsertable* `T`, the effects are unspecified.
6584
 
6585
+ For the declarations taking a range `R`, performs at most one
6586
+ reallocation if:
6587
+
6588
+ - `R` models `ranges::approximately_sized_range` and
6589
+ `ranges::distance(rg) <= ranges::reserve_hint(rg)` is `true`, or
6590
+ - `R` models `ranges::forward_range` and `R` does not model
6591
+ `ranges::approximately_sized_range`.
6592
+
6593
+ For the declarations taking a pair of `InputIterator`, performs at most
6594
+ one reallocation if `InputIterator` meets the *Cpp17ForwardIterator*
6595
+ requirements.
6596
+
6597
  ``` cpp
6598
  constexpr iterator erase(const_iterator position);
6599
  constexpr iterator erase(const_iterator first, const_iterator last);
6600
  constexpr void pop_back();
6601
  ```
 
6612
  vector after the erased elements.
6613
 
6614
  #### Erasure <a id="vector.erasure">[[vector.erasure]]</a>
6615
 
6616
  ``` cpp
6617
+ template<class T, class Allocator, class U = T>
6618
  constexpr typename vector<T, Allocator>::size_type
6619
  erase(vector<T, Allocator>& c, const U& value);
6620
  ```
6621
 
6622
  *Effects:* Equivalent to:
 
6668
  using reverse_iterator = std::reverse_iterator<iterator>;
6669
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6670
 
6671
  // bit reference
6672
  class reference {
 
 
 
6673
  public:
6674
  constexpr reference(const reference&) = default;
6675
  constexpr ~reference();
6676
  constexpr operator bool() const noexcept;
6677
  constexpr reference& operator=(bool x) noexcept;
 
6722
  constexpr const_iterator cend() const noexcept;
6723
  constexpr const_reverse_iterator crbegin() const noexcept;
6724
  constexpr const_reverse_iterator crend() const noexcept;
6725
 
6726
  // capacity
6727
+ constexpr bool empty() const noexcept;
6728
  constexpr size_type size() const noexcept;
6729
  constexpr size_type max_size() const noexcept;
6730
  constexpr size_type capacity() const noexcept;
6731
  constexpr void resize(size_type sz, bool c = false);
6732
  constexpr void reserve(size_type n);
6733
  constexpr void shrink_to_fit();
6734
 
6735
  // element access
6736
  constexpr reference operator[](size_type n);
6737
  constexpr const_reference operator[](size_type n) const;
 
6738
  constexpr reference at(size_type n);
6739
+ constexpr const_reference at(size_type n) const;
6740
  constexpr reference front();
6741
  constexpr const_reference front() const;
6742
  constexpr reference back();
6743
  constexpr const_reference back() const;
6744
 
 
6769
  };
6770
  }
6771
  ```
6772
 
6773
  Unless described below, all operations have the same requirements and
6774
+ semantics as the `vector` primary template, except that operations
6775
  dealing with the `bool` value type map to bit values in the container
6776
  storage and `allocator_traits::construct` [[allocator.traits.members]]
6777
  is not used to construct these values.
6778
 
6779
  There is no requirement that the data be stored as a contiguous
 
6857
  format(const T& ref, FormatContext& ctx) const;
6858
  ```
6859
 
6860
  Equivalent to: `return `*`underlying_`*`.format(ref, ctx);`
6861
 
6862
+ ### Header `<inplace_vector>` synopsis <a id="inplace.vector.syn">[[inplace.vector.syn]]</a>
6863
+
6864
+ ``` cpp
6865
+ // mostly freestanding
6866
+ #include <compare> // see [compare.syn]
6867
+ #include <initializer_list> // see [initializer.list.syn]
6868
+
6869
+ namespace std {
6870
+ // [inplace.vector], class template inplace_vector
6871
+ template<class T, size_t N> class inplace_vector; // partially freestanding
6872
+
6873
+ // [inplace.vector.erasure], erasure
6874
+ template<class T, size_t N, class U = T>
6875
+ constexpr typename inplace_vector<T, N>::size_type
6876
+ erase(inplace_vector<T, N>& c, const U& value);
6877
+ template<class T, size_t N, class Predicate>
6878
+ constexpr typename inplace_vector<T, N>::size_type
6879
+ erase_if(inplace_vector<T, N>& c, Predicate pred);
6880
+ }
6881
+ ```
6882
+
6883
+ ### Class template `inplace_vector` <a id="inplace.vector">[[inplace.vector]]</a>
6884
+
6885
+ #### Overview <a id="inplace.vector.overview">[[inplace.vector.overview]]</a>
6886
+
6887
+ An `inplace_vector` is a contiguous container. Its capacity is fixed and
6888
+ its elements are stored within the `inplace_vector` object itself.
6889
+
6890
+ An `inplace_vector` meets all of the requirements of a container
6891
+ [[container.reqmts]], of a reversible container
6892
+ [[container.rev.reqmts]], of a contiguous container, and of a sequence
6893
+ container, including most of the optional sequence container
6894
+ requirements [[sequence.reqmts]]. The exceptions are the `push_front`,
6895
+ `prepend_range`, `pop_front`, and `emplace_front` member functions,
6896
+ which are not provided. Descriptions are provided here only for
6897
+ operations on `inplace_vector` that are not described in one of these
6898
+ tables or for operations where there is additional semantic information.
6899
+
6900
+ For any `N`, `inplace_vector<T, N>::iterator` and
6901
+ `inplace_vector<T, N>::const_iterator` meet the constexpr iterator
6902
+ requirements.
6903
+
6904
+ Any member function of `inplace_vector<T, N>` that would cause the size
6905
+ to exceed `N` throws an exception of type `bad_alloc`.
6906
+
6907
+ Let `IV` denote a specialization of `inplace_vector<T, N>`. If `N` is
6908
+ zero, then `IV` is trivially copyable and empty, and
6909
+ `std::is_trivially_default_constructible_v<IV>` is `true`. Otherwise:
6910
+
6911
+ - If `is_trivially_copy_constructible_v<T>` is `true`, then `IV` has a
6912
+ trivial copy constructor.
6913
+ - If `is_trivially_move_constructible_v<T>` is `true`, then `IV` has a
6914
+ trivial move constructor.
6915
+ - If `is_trivially_destructible_v<T>` is `true`, then:
6916
+ - `IV` has a trivial destructor.
6917
+ - If
6918
+ ``` cpp
6919
+ is_trivially_copy_constructible_v<T> && is_trivially_copy_assignable_v<T>
6920
+ ```
6921
+
6922
+ is `true`, then `IV` has a trivial copy assignment operator.
6923
+ - If
6924
+ ``` cpp
6925
+ is_trivially_move_constructible_v<T> && is_trivially_move_assignable_v<T>
6926
+ ```
6927
+
6928
+ is `true`, then `IV` has a trivial move assignment operator.
6929
+
6930
+ ``` cpp
6931
+ namespace std {
6932
+ template<class T, size_t N>
6933
+ class inplace_vector {
6934
+ public:
6935
+ // types:
6936
+ using value_type = T;
6937
+ using pointer = T*;
6938
+ using const_pointer = const T*;
6939
+ using reference = value_type&;
6940
+ using const_reference = const value_type&;
6941
+ using size_type = size_t;
6942
+ using difference_type = ptrdiff_t;
6943
+ using iterator = implementation-defined // type of inplace_vector::iterator; // see [container.requirements]
6944
+ using const_iterator = implementation-defined // type of inplace_vector::const_iterator; // see [container.requirements]
6945
+ using reverse_iterator = std::reverse_iterator<iterator>;
6946
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
6947
+
6948
+ // [inplace.vector.cons], construct/copy/destroy
6949
+ constexpr inplace_vector() noexcept;
6950
+ constexpr explicit inplace_vector(size_type n); // freestanding-deleted
6951
+ constexpr inplace_vector(size_type n, const T& value); // freestanding-deleted
6952
+ template<class InputIterator>
6953
+ constexpr inplace_vector(InputIterator first, InputIterator last); // freestanding-deleted
6954
+ template<container-compatible-range<T> R>
6955
+ constexpr inplace_vector(from_range_t, R&& rg); // freestanding-deleted
6956
+ constexpr inplace_vector(const inplace_vector&);
6957
+ constexpr inplace_vector(inplace_vector&&)
6958
+ noexcept(N == 0 || is_nothrow_move_constructible_v<T>);
6959
+ constexpr inplace_vector(initializer_list<T> il); // freestanding-deleted
6960
+ constexpr ~inplace_vector();
6961
+ constexpr inplace_vector& operator=(const inplace_vector& other);
6962
+ constexpr inplace_vector& operator=(inplace_vector&& other)
6963
+ noexcept(N == 0 || (is_nothrow_move_assignable_v<T> &&
6964
+ is_nothrow_move_constructible_v<T>));
6965
+ constexpr inplace_vector& operator=(initializer_list<T>); // freestanding-deleted
6966
+ template<class InputIterator>
6967
+ constexpr void assign(InputIterator first, InputIterator last); // freestanding-deleted
6968
+ template<container-compatible-range<T> R>
6969
+ constexpr void assign_range(R&& rg); // freestanding-deleted
6970
+ constexpr void assign(size_type n, const T& u); // freestanding-deleted
6971
+ constexpr void assign(initializer_list<T> il); // freestanding-deleted
6972
+
6973
+ // iterators
6974
+ constexpr iterator begin() noexcept;
6975
+ constexpr const_iterator begin() const noexcept;
6976
+ constexpr iterator end() noexcept;
6977
+ constexpr const_iterator end() const noexcept;
6978
+ constexpr reverse_iterator rbegin() noexcept;
6979
+ constexpr const_reverse_iterator rbegin() const noexcept;
6980
+ constexpr reverse_iterator rend() noexcept;
6981
+ constexpr const_reverse_iterator rend() const noexcept;
6982
+
6983
+ constexpr const_iterator cbegin() const noexcept;
6984
+ constexpr const_iterator cend() const noexcept;
6985
+ constexpr const_reverse_iterator crbegin() const noexcept;
6986
+ constexpr const_reverse_iterator crend() const noexcept;
6987
+
6988
+ // [inplace.vector.capacity], capacity
6989
+ constexpr bool empty() const noexcept;
6990
+ constexpr size_type size() const noexcept;
6991
+ static constexpr size_type max_size() noexcept;
6992
+ static constexpr size_type capacity() noexcept;
6993
+ constexpr void resize(size_type sz); // freestanding-deleted
6994
+ constexpr void resize(size_type sz, const T& c); // freestanding-deleted
6995
+ static constexpr void reserve(size_type n); // freestanding-deleted
6996
+ static constexpr void shrink_to_fit() noexcept;
6997
+
6998
+ // element access
6999
+ constexpr reference operator[](size_type n);
7000
+ constexpr const_reference operator[](size_type n) const;
7001
+ constexpr reference at(size_type n); // freestanding-deleted
7002
+ constexpr const_reference at(size_type n) const; // freestanding-deleted
7003
+ constexpr reference front();
7004
+ constexpr const_reference front() const;
7005
+ constexpr reference back();
7006
+ constexpr const_reference back() const;
7007
+
7008
+ // [inplace.vector.data], data access
7009
+ constexpr T* data() noexcept;
7010
+ constexpr const T* data() const noexcept;
7011
+
7012
+ // [inplace.vector.modifiers], modifiers
7013
+ template<class... Args>
7014
+ constexpr reference emplace_back(Args&&... args); // freestanding-deleted
7015
+ constexpr reference push_back(const T& x); // freestanding-deleted
7016
+ constexpr reference push_back(T&& x); // freestanding-deleted
7017
+ template<container-compatible-range<T> R>
7018
+ constexpr void append_range(R&& rg); // freestanding-deleted
7019
+ constexpr void pop_back();
7020
+
7021
+ template<class... Args>
7022
+ constexpr pointer try_emplace_back(Args&&... args);
7023
+ constexpr pointer try_push_back(const T& x);
7024
+ constexpr pointer try_push_back(T&& x);
7025
+ template<container-compatible-range<T> R>
7026
+ constexpr ranges::borrowed_iterator_t<R> try_append_range(R&& rg);
7027
+
7028
+ template<class... Args>
7029
+ constexpr reference unchecked_emplace_back(Args&&... args);
7030
+ constexpr reference unchecked_push_back(const T& x);
7031
+ constexpr reference unchecked_push_back(T&& x);
7032
+
7033
+ template<class... Args>
7034
+ constexpr iterator emplace(const_iterator position, Args&&... args); // freestanding-deleted
7035
+ constexpr iterator insert(const_iterator position, const T& x); // freestanding-deleted
7036
+ constexpr iterator insert(const_iterator position, T&& x); // freestanding-deleted
7037
+ constexpr iterator insert(const_iterator position, size_type n, // freestanding-deleted
7038
+ const T& x);
7039
+ template<class InputIterator>
7040
+ constexpr iterator insert(const_iterator position, // freestanding-deleted
7041
+ InputIterator first, InputIterator last);
7042
+ template<container-compatible-range<T> R>
7043
+ constexpr iterator insert_range(const_iterator position, R&& rg); // freestanding-deleted
7044
+ constexpr iterator insert(const_iterator position, // freestanding-deleted
7045
+ initializer_list<T> il);
7046
+ constexpr iterator erase(const_iterator position);
7047
+ constexpr iterator erase(const_iterator first, const_iterator last);
7048
+ constexpr void swap(inplace_vector& x)
7049
+ noexcept(N == 0 || (is_nothrow_swappable_v<T> &&
7050
+ is_nothrow_move_constructible_v<T>));
7051
+ constexpr void clear() noexcept;
7052
+
7053
+ friend constexpr bool operator==(const inplace_vector& x,
7054
+ const inplace_vector& y);
7055
+ friend constexpr synth-three-way-result<T>
7056
+ operator<=>(const inplace_vector& x, const inplace_vector& y);
7057
+ friend constexpr void swap(inplace_vector& x, inplace_vector& y)
7058
+ noexcept(N == 0 || (is_nothrow_swappable_v<T> &&
7059
+ is_nothrow_move_constructible_v<T>))
7060
+ { x.swap(y); }
7061
+ };
7062
+ }
7063
+ ```
7064
+
7065
+ #### Constructors <a id="inplace.vector.cons">[[inplace.vector.cons]]</a>
7066
+
7067
+ ``` cpp
7068
+ constexpr explicit inplace_vector(size_type n);
7069
+ ```
7070
+
7071
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `inplace_vector`.
7072
+
7073
+ *Effects:* Constructs an `inplace_vector` with `n` default-inserted
7074
+ elements.
7075
+
7076
+ *Complexity:* Linear in `n`.
7077
+
7078
+ ``` cpp
7079
+ constexpr inplace_vector(size_type n, const T& value);
7080
+ ```
7081
+
7082
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `inplace_vector`.
7083
+
7084
+ *Effects:* Constructs an `inplace_vector` with `n` copies of `value`.
7085
+
7086
+ *Complexity:* Linear in `n`.
7087
+
7088
+ ``` cpp
7089
+ template<class InputIterator>
7090
+ constexpr inplace_vector(InputIterator first, InputIterator last);
7091
+ ```
7092
+
7093
+ *Effects:* Constructs an `inplace_vector` equal to the range \[`first`,
7094
+ `last`).
7095
+
7096
+ *Complexity:* Linear in `distance(first, last)`.
7097
+
7098
+ ``` cpp
7099
+ template<container-compatible-range<T> R>
7100
+ constexpr inplace_vector(from_range_t, R&& rg);
7101
+ ```
7102
+
7103
+ *Effects:* Constructs an `inplace_vector` with the elements of the range
7104
+ `rg`.
7105
+
7106
+ *Complexity:* Linear in `ranges::distance(rg)`.
7107
+
7108
+ #### Capacity <a id="inplace.vector.capacity">[[inplace.vector.capacity]]</a>
7109
+
7110
+ ``` cpp
7111
+ static constexpr size_type capacity() noexcept;
7112
+ static constexpr size_type max_size() noexcept;
7113
+ ```
7114
+
7115
+ *Returns:* `N`.
7116
+
7117
+ ``` cpp
7118
+ constexpr void resize(size_type sz);
7119
+ ```
7120
+
7121
+ *Preconditions:* `T` is *Cpp17DefaultInsertable* into `inplace_vector`.
7122
+
7123
+ *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
7124
+ the sequence. Otherwise, appends `sz - size()` default-inserted elements
7125
+ to the sequence.
7126
+
7127
+ *Remarks:* If an exception is thrown, there are no effects on `*this`.
7128
+
7129
+ ``` cpp
7130
+ constexpr void resize(size_type sz, const T& c);
7131
+ ```
7132
+
7133
+ *Preconditions:* `T` is *Cpp17CopyInsertable* into `inplace_vector`.
7134
+
7135
+ *Effects:* If `sz < size()`, erases the last `size() - sz` elements from
7136
+ the sequence. Otherwise, appends `sz - size()` copies of `c` to the
7137
+ sequence.
7138
+
7139
+ *Remarks:* If an exception is thrown, there are no effects on `*this`.
7140
+
7141
+ ``` cpp
7142
+ static constexpr void reserve(size_type n);
7143
+ ```
7144
+
7145
+ *Effects:* None.
7146
+
7147
+ *Throws:* `bad_alloc` if `n > capacity()` is `true`.
7148
+
7149
+ ``` cpp
7150
+ static constexpr void shrink_to_fit() noexcept;
7151
+ ```
7152
+
7153
+ *Effects:* None.
7154
+
7155
+ #### Data <a id="inplace.vector.data">[[inplace.vector.data]]</a>
7156
+
7157
+ ``` cpp
7158
+ constexpr T* data() noexcept;
7159
+ constexpr const T* data() const noexcept;
7160
+ ```
7161
+
7162
+ *Returns:* A pointer such that \[`data()`, `data() + size()`) is a valid
7163
+ range. For a non-empty `inplace_vector`, `data() == addressof(front())`
7164
+ is `true`.
7165
+
7166
+ *Complexity:* Constant time.
7167
+
7168
+ #### Modifiers <a id="inplace.vector.modifiers">[[inplace.vector.modifiers]]</a>
7169
+
7170
+ ``` cpp
7171
+ constexpr iterator insert(const_iterator position, const T& x);
7172
+ constexpr iterator insert(const_iterator position, T&& x);
7173
+ constexpr iterator insert(const_iterator position, size_type n, const T& x);
7174
+ template<class InputIterator>
7175
+ constexpr iterator insert(const_iterator position, InputIterator first, InputIterator last);
7176
+ template<container-compatible-range<T> R>
7177
+ constexpr iterator insert_range(const_iterator position, R&& rg);
7178
+ constexpr iterator insert(const_iterator position, initializer_list<T> il);
7179
+
7180
+ template<class... Args>
7181
+ constexpr iterator emplace(const_iterator position, Args&&... args);
7182
+ template<container-compatible-range<T> R>
7183
+ constexpr void append_range(R&& rg);
7184
+ ```
7185
+
7186
+ Let n be the value of `size()` before this call for the `append_range`
7187
+ overload, and `distance(begin, position)` otherwise.
7188
+
7189
+ *Complexity:* Linear in the number of elements inserted plus the
7190
+ distance to the end of the vector.
7191
+
7192
+ *Remarks:* If an exception is thrown other than by the copy constructor,
7193
+ move constructor, assignment operator, or move assignment operator of
7194
+ `T` or by any `InputIterator` operation, there are no effects.
7195
+ Otherwise, if an exception is thrown, then `size()` ≥ n and elements in
7196
+ the range `begin() + ``[``0, `n`)` are not modified.
7197
+
7198
+ ``` cpp
7199
+ constexpr reference push_back(const T& x);
7200
+ constexpr reference push_back(T&& x);
7201
+ template<class... Args>
7202
+ constexpr reference emplace_back(Args&&... args);
7203
+ ```
7204
+
7205
+ *Returns:* `back()`.
7206
+
7207
+ *Throws:* `bad_alloc` or any exception thrown by the initialization of
7208
+ the inserted element.
7209
+
7210
+ *Complexity:* Constant.
7211
+
7212
+ *Remarks:* If an exception is thrown, there are no effects on `*this`.
7213
+
7214
+ ``` cpp
7215
+ template<class... Args>
7216
+ constexpr pointer try_emplace_back(Args&&... args);
7217
+ constexpr pointer try_push_back(const T& x);
7218
+ constexpr pointer try_push_back(T&& x);
7219
+ ```
7220
+
7221
+ Let `vals` denote a pack:
7222
+
7223
+ - `std::forward<Args>(args)...` for the first overload,
7224
+ - `x` for the second overload,
7225
+ - `std::move(x)` for the third overload.
7226
+
7227
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
7228
+ `inplace_vector` from `vals...`.
7229
+
7230
+ *Effects:* If `size() < capacity()` is `true`, appends an object of type
7231
+ `T` direct-non-list-initialized with `vals...`. Otherwise, there are no
7232
+ effects.
7233
+
7234
+ *Returns:* `nullptr` if `size() == capacity()` is `true`, otherwise
7235
+ `addressof(back())`.
7236
+
7237
+ *Throws:* Nothing unless an exception is thrown by the initialization of
7238
+ the inserted element.
7239
+
7240
+ *Complexity:* Constant.
7241
+
7242
+ *Remarks:* If an exception is thrown, there are no effects on `*this`.
7243
+
7244
+ ``` cpp
7245
+ template<container-compatible-range<T> R>
7246
+ constexpr ranges::borrowed_iterator_t<R> try_append_range(R&& rg);
7247
+ ```
7248
+
7249
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
7250
+ `inplace_vector` from
7251
+ `*ranges::begin(rg)`.
7252
+
7253
+ *Effects:* Appends copies of initial elements in `rg` before `end()`,
7254
+ until all elements are inserted or `size() == capacity()` is `true`.
7255
+ Each iterator in the range `rg` is dereferenced at most once.
7256
+
7257
+ *Returns:* The first iterator in the range `ranges::begin(rg)`+\[0, `n`)
7258
+ that was not inserted into `*this`, where `n` is the number of elements
7259
+ in `rg`.
7260
+
7261
+ *Complexity:* Linear in the number of elements inserted.
7262
+
7263
+ *Remarks:* Let n be the value of `size()` prior to this call. If an
7264
+ exception is thrown after the insertion of k elements, then `size()`
7265
+ equals n + k, elements in the range `begin() + ``[``0, `n`)` are not
7266
+ modified, and elements in the range `begin() + ``[`n`, `n + k`)`
7267
+ correspond to the inserted elements.
7268
+
7269
+ ``` cpp
7270
+ template<class... Args>
7271
+ constexpr reference unchecked_emplace_back(Args&&... args);
7272
+ ```
7273
+
7274
+ *Preconditions:* `size() < capacity()` is `true`.
7275
+
7276
+ *Effects:* Equivalent to:
7277
+ `return *try_emplace_back(std::forward<Args>(args)...);`
7278
+
7279
+ ``` cpp
7280
+ constexpr reference unchecked_push_back(const T& x);
7281
+ constexpr reference unchecked_push_back(T&& x);
7282
+ ```
7283
+
7284
+ *Preconditions:* `size() < capacity()` is `true`.
7285
+
7286
+ *Effects:* Equivalent to:
7287
+ `return *try_push_back(std::forward<decltype(x)>(x));`
7288
+
7289
+ ``` cpp
7290
+ constexpr iterator erase(const_iterator position);
7291
+ constexpr iterator erase(const_iterator first, const_iterator last);
7292
+ constexpr void pop_back();
7293
+ ```
7294
+
7295
+ *Effects:* Invalidates iterators and references at or after the point of
7296
+ the erase.
7297
+
7298
+ *Throws:* Nothing unless an exception is thrown by the assignment
7299
+ operator or move assignment operator of `T`.
7300
+
7301
+ *Complexity:* The destructor of `T` is called the number of times equal
7302
+ to the number of the elements erased, but the assignment operator of `T`
7303
+ is called the number of times equal to the number of elements after the
7304
+ erased elements.
7305
+
7306
+ #### Erasure <a id="inplace.vector.erasure">[[inplace.vector.erasure]]</a>
7307
+
7308
+ ``` cpp
7309
+ template<class T, size_t N, class U = T>
7310
+ constexpr size_t erase(inplace_vector<T, N>& c, const U& value);
7311
+ ```
7312
+
7313
+ *Effects:* Equivalent to:
7314
+
7315
+ ``` cpp
7316
+ auto it = remove(c.begin(), c.end(), value);
7317
+ auto r = distance(it, c.end());
7318
+ c.erase(it, c.end());
7319
+ return r;
7320
+ ```
7321
+
7322
+ ``` cpp
7323
+ template<class T, size_t N, class Predicate>
7324
+ constexpr size_t erase_if(inplace_vector<T, N>& c, Predicate pred);
7325
+ ```
7326
+
7327
+ *Effects:* Equivalent to:
7328
+
7329
+ ``` cpp
7330
+ auto it = remove_if(c.begin(), c.end(), pred);
7331
+ auto r = distance(it, c.end());
7332
+ c.erase(it, c.end());
7333
+ return r;
7334
+ ```
7335
+
7336
  ## Associative containers <a id="associative">[[associative]]</a>
7337
 
7338
+ ### General <a id="associative.general">[[associative.general]]</a>
7339
 
7340
  The header `<map>` defines the class templates `map` and `multimap`; the
7341
  header `<set>` defines the class templates `set` and `multiset`.
7342
 
7343
  The following exposition-only alias templates may appear in deduction
7344
  guides for associative containers:
7345
 
7346
  ``` cpp
7347
  template<class InputIterator>
7348
+ using iter-value-type = iterator_traits<InputIterator>::value_type; // exposition only
 
7349
  template<class InputIterator>
7350
  using iter-key-type = remove_const_t<
7351
  tuple_element_t<0, iter-value-type<InputIterator>>>; // exposition only
7352
  template<class InputIterator>
7353
  using iter-mapped-type =
7354
  tuple_element_t<1, iter-value-type<InputIterator>>; // exposition only
7355
  template<class InputIterator>
7356
  using iter-to-alloc-type = pair<
7357
+ const tuple_element_t<0, iter-value-type<InputIterator>>,
7358
  tuple_element_t<1, iter-value-type<InputIterator>>>; // exposition only
7359
  template<ranges::input_range Range>
7360
  using range-key-type =
7361
  remove_const_t<typename ranges::range_value_t<Range>::first_type>; // exposition only
7362
  template<ranges::input_range Range>
7363
+ using range-mapped-type = ranges::range_value_t<Range>::second_type; // exposition only
7364
  template<ranges::input_range Range>
7365
  using range-to-alloc-type =
7366
+ pair<const typename ranges::range_value_t<Range>::first_type,
7367
  typename ranges::range_value_t<Range>::second_type>; // exposition only
7368
  ```
7369
 
7370
  ### Header `<map>` synopsis <a id="associative.map.syn">[[associative.map.syn]]</a>
7371
 
 
7378
  template<class Key, class T, class Compare = less<Key>,
7379
  class Allocator = allocator<pair<const Key, T>>>
7380
  class map;
7381
 
7382
  template<class Key, class T, class Compare, class Allocator>
7383
+ constexpr bool operator==(const map<Key, T, Compare, Allocator>& x,
7384
  const map<Key, T, Compare, Allocator>& y);
7385
  template<class Key, class T, class Compare, class Allocator>
7386
+ constexpr synth-three-way-result<pair<const Key, T>>
7387
  operator<=>(const map<Key, T, Compare, Allocator>& x,
7388
  const map<Key, T, Compare, Allocator>& y);
7389
 
7390
  template<class Key, class T, class Compare, class Allocator>
7391
+ constexpr void swap(map<Key, T, Compare, Allocator>& x,
7392
  map<Key, T, Compare, Allocator>& y)
7393
  noexcept(noexcept(x.swap(y)));
7394
 
7395
  // [map.erasure], erasure for map
7396
  template<class Key, class T, class Compare, class Allocator, class Predicate>
7397
+ constexpr typename map<Key, T, Compare, Allocator>::size_type
7398
  erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
7399
 
7400
  // [multimap], class template multimap
7401
  template<class Key, class T, class Compare = less<Key>,
7402
  class Allocator = allocator<pair<const Key, T>>>
7403
  class multimap;
7404
 
7405
  template<class Key, class T, class Compare, class Allocator>
7406
+ constexpr bool operator==(const multimap<Key, T, Compare, Allocator>& x,
7407
  const multimap<Key, T, Compare, Allocator>& y);
7408
  template<class Key, class T, class Compare, class Allocator>
7409
+ constexpr synth-three-way-result<pair<const Key, T>>
7410
  operator<=>(const multimap<Key, T, Compare, Allocator>& x,
7411
  const multimap<Key, T, Compare, Allocator>& y);
7412
 
7413
  template<class Key, class T, class Compare, class Allocator>
7414
+ constexpr void swap(multimap<Key, T, Compare, Allocator>& x,
7415
  multimap<Key, T, Compare, Allocator>& y)
7416
  noexcept(noexcept(x.swap(y)));
7417
 
7418
  // [multimap.erasure], erasure for multimap
7419
  template<class Key, class T, class Compare, class Allocator, class Predicate>
7420
+ constexpr typename multimap<Key, T, Compare, Allocator>::size_type
7421
  erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
7422
 
7423
  namespace pmr {
7424
  template<class Key, class T, class Compare = less<Key>>
7425
  using map = std::map<Key, T, Compare,
 
7430
  polymorphic_allocator<pair<const Key, T>>>;
7431
  }
7432
  }
7433
  ```
7434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7435
  ### Class template `map` <a id="map">[[map]]</a>
7436
 
7437
  #### Overview <a id="map.overview">[[map.overview]]</a>
7438
 
7439
  A `map` is an associative container that supports unique keys (i.e.,
 
7442
  supports bidirectional iterators.
7443
 
7444
  A `map` meets all of the requirements of a container
7445
  [[container.reqmts]], of a reversible container
7446
  [[container.rev.reqmts]], of an allocator-aware container
7447
+ [[container.alloc.reqmts]], and of an associative container
7448
  [[associative.reqmts]]. A `map` also provides most operations described
7449
  in  [[associative.reqmts]] for unique keys. This means that a `map`
7450
  supports the `a_uniq` operations in  [[associative.reqmts]] but not the
7451
  `a_eq` operations. For a `map<Key,T>` the `key_type` is `Key` and the
7452
  `value_type` is `pair<const Key,T>`. Descriptions are provided here only
7453
  for operations on `map` that are not described in one of those tables or
7454
  for operations where there is additional semantic information.
7455
 
7456
+ The types `iterator` and `const_iterator` meet the constexpr iterator
7457
+ requirements [[iterator.requirements.general]].
7458
+
7459
  ``` cpp
7460
  namespace std {
7461
  template<class Key, class T, class Compare = less<Key>,
7462
  class Allocator = allocator<pair<const Key, T>>>
7463
  class map {
 
7466
  using key_type = Key;
7467
  using mapped_type = T;
7468
  using value_type = pair<const Key, T>;
7469
  using key_compare = Compare;
7470
  using allocator_type = Allocator;
7471
+ using pointer = allocator_traits<Allocator>::pointer;
7472
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
7473
  using reference = value_type&;
7474
  using const_reference = const value_type&;
7475
  using size_type = implementation-defined // type of map::size_type; // see [container.requirements]
7476
  using difference_type = implementation-defined // type of map::difference_type; // see [container.requirements]
7477
  using iterator = implementation-defined // type of map::iterator; // see [container.requirements]
 
7480
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
7481
  using node_type = unspecified;
7482
  using insert_return_type = insert-return-type<iterator, node_type>;
7483
 
7484
  class value_compare {
 
7485
  protected:
7486
  Compare comp;
7487
+ constexpr value_compare(Compare c) : comp(c) {}
7488
 
7489
  public:
7490
+ constexpr bool operator()(const value_type& x, const value_type& y) const {
7491
  return comp(x.first, y.first);
7492
  }
7493
  };
7494
 
7495
  // [map.cons], construct/copy/destroy
7496
+ constexpr map() : map(Compare()) { }
7497
+ constexpr explicit map(const Compare& comp, const Allocator& = Allocator());
7498
  template<class InputIterator>
7499
+ constexpr map(InputIterator first, InputIterator last,
7500
  const Compare& comp = Compare(), const Allocator& = Allocator());
7501
  template<container-compatible-range<value_type> R>
7502
+ constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(),
7503
+ const Allocator& = Allocator());
7504
+ constexpr map(const map& x);
7505
+ constexpr map(map&& x);
7506
  explicit map(const Allocator&);
7507
+ constexpr map(const map&, const type_identity_t<Allocator>&);
7508
+ constexpr map(map&&, const type_identity_t<Allocator>&);
7509
+ constexpr map(initializer_list<value_type>, const Compare& = Compare(),
 
7510
  const Allocator& = Allocator());
7511
  template<class InputIterator>
7512
+ constexpr map(InputIterator first, InputIterator last, const Allocator& a)
7513
  : map(first, last, Compare(), a) { }
7514
  template<container-compatible-range<value_type> R>
7515
+ constexpr map(from_range_t, R&& rg, const Allocator& a)
7516
  : map(from_range, std::forward<R>(rg), Compare(), a) { }
7517
+ constexpr map(initializer_list<value_type> il, const Allocator& a)
7518
  : map(il, Compare(), a) { }
7519
+ constexpr ~map();
7520
+ constexpr map& operator=(const map& x);
7521
+ constexpr map& operator=(map&& x)
7522
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7523
  is_nothrow_move_assignable_v<Compare>);
7524
+ constexpr map& operator=(initializer_list<value_type>);
7525
+ constexpr allocator_type get_allocator() const noexcept;
7526
 
7527
  // iterators
7528
+ constexpr iterator begin() noexcept;
7529
+ constexpr const_iterator begin() const noexcept;
7530
+ constexpr iterator end() noexcept;
7531
+ constexpr const_iterator end() const noexcept;
7532
 
7533
+ constexpr reverse_iterator rbegin() noexcept;
7534
+ constexpr const_reverse_iterator rbegin() const noexcept;
7535
+ constexpr reverse_iterator rend() noexcept;
7536
+ constexpr const_reverse_iterator rend() const noexcept;
7537
 
7538
+ constexpr const_iterator cbegin() const noexcept;
7539
+ constexpr const_iterator cend() const noexcept;
7540
+ constexpr const_reverse_iterator crbegin() const noexcept;
7541
+ constexpr const_reverse_iterator crend() const noexcept;
7542
 
7543
  // capacity
7544
+ constexpr bool empty() const noexcept;
7545
+ constexpr size_type size() const noexcept;
7546
+ constexpr size_type max_size() const noexcept;
7547
 
7548
  // [map.access], element access
7549
+ constexpr mapped_type& operator[](const key_type& x);
7550
+ constexpr mapped_type& operator[](key_type&& x);
7551
+ template<class K> constexpr mapped_type& operator[](K&& x);
7552
+ constexpr mapped_type& at(const key_type& x);
7553
+ constexpr const mapped_type& at(const key_type& x) const;
7554
+ template<class K> constexpr mapped_type& at(const K& x);
7555
+ template<class K> constexpr const mapped_type& at(const K& x) const;
7556
 
7557
  // [map.modifiers], modifiers
7558
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
7559
+ template<class... Args>
7560
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
7561
+ constexpr pair<iterator, bool> insert(const value_type& x);
7562
+ constexpr pair<iterator, bool> insert(value_type&& x);
7563
+ template<class P> constexpr pair<iterator, bool> insert(P&& x);
7564
+ constexpr iterator insert(const_iterator position, const value_type& x);
7565
+ constexpr iterator insert(const_iterator position, value_type&& x);
7566
  template<class P>
7567
+ constexpr iterator insert(const_iterator position, P&&);
7568
  template<class InputIterator>
7569
+ constexpr void insert(InputIterator first, InputIterator last);
7570
  template<container-compatible-range<value_type> R>
7571
+ constexpr void insert_range(R&& rg);
7572
+ constexpr void insert(initializer_list<value_type>);
7573
 
7574
+ constexpr node_type extract(const_iterator position);
7575
+ constexpr node_type extract(const key_type& x);
7576
+ template<class K> constexpr node_type extract(K&& x);
7577
+ constexpr insert_return_type insert(node_type&& nh);
7578
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
7579
 
7580
  template<class... Args>
7581
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
7582
  template<class... Args>
7583
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
7584
+ template<class K, class... Args>
7585
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
7586
  template<class... Args>
7587
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
7588
  template<class... Args>
7589
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
7590
+ template<class K, class... Args>
7591
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
7592
  template<class M>
7593
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
7594
  template<class M>
7595
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
7596
+ template<class K, class M>
7597
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
7598
  template<class M>
7599
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
7600
  template<class M>
7601
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
7602
+ template<class K, class M>
7603
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
7604
 
7605
+ constexpr iterator erase(iterator position);
7606
+ constexpr iterator erase(const_iterator position);
7607
+ constexpr size_type erase(const key_type& x);
7608
+ template<class K> constexpr size_type erase(K&& x);
7609
+ constexpr iterator erase(const_iterator first, const_iterator last);
7610
+ constexpr void swap(map&)
7611
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
7612
  is_nothrow_swappable_v<Compare>);
7613
+ constexpr void clear() noexcept;
7614
 
7615
  template<class C2>
7616
+ constexpr void merge(map<Key, T, C2, Allocator>& source);
7617
  template<class C2>
7618
+ constexpr void merge(map<Key, T, C2, Allocator>&& source);
7619
  template<class C2>
7620
+ constexpr void merge(multimap<Key, T, C2, Allocator>& source);
7621
  template<class C2>
7622
+ constexpr void merge(multimap<Key, T, C2, Allocator>&& source);
7623
 
7624
  // observers
7625
+ constexpr key_compare key_comp() const;
7626
+ constexpr value_compare value_comp() const;
7627
 
7628
  // map operations
7629
+ constexpr iterator find(const key_type& x);
7630
+ constexpr const_iterator find(const key_type& x) const;
7631
+ template<class K> constexpr iterator find(const K& x);
7632
+ template<class K> constexpr const_iterator find(const K& x) const;
7633
 
7634
+ constexpr size_type count(const key_type& x) const;
7635
+ template<class K> constexpr size_type count(const K& x) const;
7636
 
7637
+ constexpr bool contains(const key_type& x) const;
7638
+ template<class K> constexpr bool contains(const K& x) const;
7639
 
7640
+ constexpr iterator lower_bound(const key_type& x);
7641
+ constexpr const_iterator lower_bound(const key_type& x) const;
7642
+ template<class K> constexpr iterator lower_bound(const K& x);
7643
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
7644
 
7645
+ constexpr iterator upper_bound(const key_type& x);
7646
+ constexpr const_iterator upper_bound(const key_type& x) const;
7647
+ template<class K> constexpr iterator upper_bound(const K& x);
7648
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
7649
 
7650
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
7651
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
7652
  template<class K>
7653
+ constexpr pair<iterator, iterator> equal_range(const K& x);
7654
  template<class K>
7655
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
7656
  };
7657
 
7658
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
7659
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
7660
  map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
 
7685
  ```
7686
 
7687
  #### Constructors, copy, and assignment <a id="map.cons">[[map.cons]]</a>
7688
 
7689
  ``` cpp
7690
+ constexpr explicit map(const Compare& comp, const Allocator& = Allocator());
7691
  ```
7692
 
7693
  *Effects:* Constructs an empty `map` using the specified comparison
7694
  object and allocator.
7695
 
7696
  *Complexity:* Constant.
7697
 
7698
  ``` cpp
7699
  template<class InputIterator>
7700
+ constexpr map(InputIterator first, InputIterator last,
7701
  const Compare& comp = Compare(), const Allocator& = Allocator());
7702
  ```
7703
 
7704
  *Effects:* Constructs an empty `map` using the specified comparison
7705
  object and allocator, and inserts elements from the range \[`first`,
 
7709
  sorted with respect to `comp` and otherwise N log N, where N is
7710
  `last - first`.
7711
 
7712
  ``` cpp
7713
  template<container-compatible-range<value_type> R>
7714
+ constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(),
7715
+ const Allocator& = Allocator());
7716
  ```
7717
 
7718
  *Effects:* Constructs an empty `map` using the specified comparison
7719
  object and allocator, and inserts elements from the range `rg`.
7720
 
 
7722
  `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
7723
 
7724
  #### Element access <a id="map.access">[[map.access]]</a>
7725
 
7726
  ``` cpp
7727
+ constexpr mapped_type& operator[](const key_type& x);
7728
  ```
7729
 
7730
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
7731
 
7732
  ``` cpp
7733
+ constexpr mapped_type& operator[](key_type&& x);
7734
  ```
7735
 
7736
  *Effects:* Equivalent to:
7737
  `return try_emplace(std::move(x)).first->second;`
7738
 
7739
  ``` cpp
7740
+ template<class K> constexpr mapped_type& operator[](K&& x);
7741
+ ```
7742
+
7743
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
7744
+ denotes a type.
7745
+
7746
+ *Effects:* Equivalent to:
7747
+ `return try_emplace(std::forward<K>(x)).first->second;`
7748
+
7749
+ ``` cpp
7750
+ constexpr mapped_type& at(const key_type& x);
7751
+ constexpr const mapped_type& at(const key_type& x) const;
7752
  ```
7753
 
7754
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
7755
  `*this`.
7756
 
7757
  *Throws:* An exception object of type `out_of_range` if no such element
7758
  is present.
7759
 
7760
  *Complexity:* Logarithmic.
7761
 
7762
+ ``` cpp
7763
+ template<class K> constexpr mapped_type& at(const K& x);
7764
+ template<class K> constexpr const mapped_type& at(const K& x) const;
7765
+ ```
7766
+
7767
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
7768
+ denotes a type.
7769
+
7770
+ *Preconditions:* The expression `find(x)` is well-formed and has
7771
+ well-defined behavior.
7772
+
7773
+ *Returns:* A reference to `find(x)->second`.
7774
+
7775
+ *Throws:* An exception object of type `out_of_range` if
7776
+ `find(x) == end()` is `true`.
7777
+
7778
+ *Complexity:* Logarithmic.
7779
+
7780
  #### Modifiers <a id="map.modifiers">[[map.modifiers]]</a>
7781
 
7782
  ``` cpp
7783
  template<class P>
7784
+ constexpr pair<iterator, bool> insert(P&& x);
7785
  template<class P>
7786
+ constexpr iterator insert(const_iterator position, P&& x);
7787
  ```
7788
 
7789
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
7790
 
7791
  *Effects:* The first form is equivalent to
7792
  `return emplace(std::forward<P>(x))`. The second form is equivalent to
7793
  `return emplace_hint(position, std::forward<P>(x))`.
7794
 
7795
  ``` cpp
7796
  template<class... Args>
7797
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
7798
  template<class... Args>
7799
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
7800
  ```
7801
 
7802
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
7803
  from `piecewise_construct`, `forward_as_tuple(k)`,
7804
  `forward_as_tuple(std::forward<Args>(args)...)`.
 
7814
 
7815
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7816
 
7817
  ``` cpp
7818
  template<class... Args>
7819
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
7820
  template<class... Args>
7821
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
7822
  ```
7823
 
7824
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
7825
  from `piecewise_construct`, `forward_as_tuple(std::move(k))`,
7826
  `forward_as_tuple(std::forward<Args>(args)...)`.
 
7835
  pair is `true` if and only if the insertion took place. The returned
7836
  iterator points to the map element whose key is equivalent to `k`.
7837
 
7838
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7839
 
7840
+ ``` cpp
7841
+ template<class K, class... Args>
7842
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
7843
+ template<class K, class... Args>
7844
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
7845
+ ```
7846
+
7847
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
7848
+ denotes a type. For the first overload,
7849
+ `is_convertible_v<K&&, const_iterator>` and
7850
+ `is_convertible_v<K&&, iterator>` are both `false`.
7851
+
7852
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
7853
+ from
7854
+ `piecewise_construct, forward_as_tuple(std::forward<K>(k)), forward_as_tuple(std::forward<Args>(args)...)`.
7855
+
7856
+ *Effects:* If the map already contains an element whose key is
7857
+ equivalent to `k`, there is no effect. Otherwise, let `r` be
7858
+ `equal_range(k)`. Constructs an object `u` of type `value_type` with
7859
+ `piecewise_construct, forward_as_tuple(std::forward<K>(k)), forward_as_tuple(std::forward<Args>(args)...)`.
7860
+ If `equal_range(u.first) == r` is `false`, the behavior is undefined.
7861
+ Inserts `u` into `*this`.
7862
+
7863
+ *Returns:* For the first overload, the `bool` component of the returned
7864
+ pair is `true` if and only if the insertion took place. The returned
7865
+ iterator points to the map element whose key is equivalent to `k`.
7866
+
7867
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7868
+
7869
  ``` cpp
7870
  template<class M>
7871
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
7872
  template<class M>
7873
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
7874
  ```
7875
 
7876
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
7877
 
7878
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
 
7889
 
7890
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7891
 
7892
  ``` cpp
7893
  template<class M>
7894
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
7895
  template<class M>
7896
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
7897
  ```
7898
 
7899
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
7900
 
7901
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
 
7910
  pair is `true` if and only if the insertion took place. The returned
7911
  iterator points to the map element whose key is equivalent to `k`.
7912
 
7913
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7914
 
7915
+ ``` cpp
7916
+ template<class K, class M>
7917
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
7918
+ template<class K, class M>
7919
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
7920
+ ```
7921
+
7922
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
7923
+ denotes a type.
7924
+
7925
+ *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
7926
+
7927
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `map`
7928
+ from `std::forward<K>(k), std:: forward<M>(obj)`.
7929
+
7930
+ *Effects:* If the map already contains an element `e` whose key is
7931
+ equivalent to `k`, assigns `std::forward<M> (obj)` to `e.second`.
7932
+ Otherwise, let `r` be `equal_range(k)`. Constructs an object `u` of type
7933
+ `value_type` with `std::forward<K>(k), std::forward<M>(obj)`. If
7934
+ `equal_range(u.first) == r` is `false`, the behavior is undefined.
7935
+ Inserts `u` into `*this`.
7936
+
7937
+ *Returns:* For the first overload, the `bool` component of the returned
7938
+ pair is `true` if and only if the insertion took place. The returned
7939
+ iterator points to the map element whose key is equivalent to `k`.
7940
+
7941
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
7942
+
7943
  #### Erasure <a id="map.erasure">[[map.erasure]]</a>
7944
 
7945
  ``` cpp
7946
  template<class Key, class T, class Compare, class Allocator, class Predicate>
7947
  typename map<Key, T, Compare, Allocator>::size_type
7948
+ constexpr erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
7949
  ```
7950
 
7951
  *Effects:* Equivalent to:
7952
 
7953
  ``` cpp
 
7982
  `Key` and the `value_type` is `pair<const Key,T>`. Descriptions are
7983
  provided here only for operations on `multimap` that are not described
7984
  in one of those tables or for operations where there is additional
7985
  semantic information.
7986
 
7987
+ The types `iterator` and `const_iterator` meet the constexpr iterator
7988
+ requirements [[iterator.requirements.general]].
7989
+
7990
  ``` cpp
7991
  namespace std {
7992
  template<class Key, class T, class Compare = less<Key>,
7993
  class Allocator = allocator<pair<const Key, T>>>
7994
  class multimap {
 
7997
  using key_type = Key;
7998
  using mapped_type = T;
7999
  using value_type = pair<const Key, T>;
8000
  using key_compare = Compare;
8001
  using allocator_type = Allocator;
8002
+ using pointer = allocator_traits<Allocator>::pointer;
8003
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
8004
  using reference = value_type&;
8005
  using const_reference = const value_type&;
8006
  using size_type = implementation-defined // type of multimap::size_type; // see [container.requirements]
8007
  using difference_type = implementation-defined // type of multimap::difference_type; // see [container.requirements]
8008
  using iterator = implementation-defined // type of multimap::iterator; // see [container.requirements]
 
8010
  using reverse_iterator = std::reverse_iterator<iterator>;
8011
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
8012
  using node_type = unspecified;
8013
 
8014
  class value_compare {
 
8015
  protected:
8016
  Compare comp;
8017
+ constexpr value_compare(Compare c) : comp(c) { }
8018
 
8019
  public:
8020
+ constexpr bool operator()(const value_type& x, const value_type& y) const {
8021
  return comp(x.first, y.first);
8022
  }
8023
  };
8024
 
8025
  // [multimap.cons], construct/copy/destroy
8026
+ constexpr multimap() : multimap(Compare()) { }
8027
+ constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator());
8028
  template<class InputIterator>
8029
+ constexpr multimap(InputIterator first, InputIterator last,
8030
+ const Compare& comp = Compare(), const Allocator& = Allocator());
 
8031
  template<container-compatible-range<value_type> R>
8032
+ constexpr multimap(from_range_t, R&& rg,
8033
  const Compare& comp = Compare(), const Allocator& = Allocator());
8034
+ constexpr multimap(const multimap& x);
8035
+ constexpr multimap(multimap&& x);
8036
+ constexpr explicit multimap(const Allocator&);
8037
+ constexpr multimap(const multimap&, const type_identity_t<Allocator>&);
8038
+ constexpr multimap(multimap&&, const type_identity_t<Allocator>&);
8039
+ constexpr multimap(initializer_list<value_type>,
8040
+ const Compare& = Compare(), const Allocator& = Allocator());
 
8041
  template<class InputIterator>
8042
+ constexpr multimap(InputIterator first, InputIterator last, const Allocator& a)
8043
  : multimap(first, last, Compare(), a) { }
8044
  template<container-compatible-range<value_type> R>
8045
+ constexpr multimap(from_range_t, R&& rg, const Allocator& a)
8046
  : multimap(from_range, std::forward<R>(rg), Compare(), a) { }
8047
+ constexpr multimap(initializer_list<value_type> il, const Allocator& a)
8048
  : multimap(il, Compare(), a) { }
8049
+ constexpr ~multimap();
8050
+ constexpr multimap& operator=(const multimap& x);
8051
+ constexpr multimap& operator=(multimap&& x)
8052
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8053
  is_nothrow_move_assignable_v<Compare>);
8054
+ constexpr multimap& operator=(initializer_list<value_type>);
8055
+ constexpr allocator_type get_allocator() const noexcept;
8056
 
8057
  // iterators
8058
+ constexpr iterator begin() noexcept;
8059
+ constexpr const_iterator begin() const noexcept;
8060
+ constexpr iterator end() noexcept;
8061
+ constexpr const_iterator end() const noexcept;
8062
 
8063
+ constexpr reverse_iterator rbegin() noexcept;
8064
+ constexpr const_reverse_iterator rbegin() const noexcept;
8065
+ constexpr reverse_iterator rend() noexcept;
8066
+ constexpr const_reverse_iterator rend() const noexcept;
8067
 
8068
+ constexpr const_iterator cbegin() const noexcept;
8069
+ constexpr const_iterator cend() const noexcept;
8070
+ constexpr const_reverse_iterator crbegin() const noexcept;
8071
+ constexpr const_reverse_iterator crend() const noexcept;
8072
 
8073
  // capacity
8074
+ constexpr bool empty() const noexcept;
8075
+ constexpr size_type size() const noexcept;
8076
+ constexpr size_type max_size() const noexcept;
8077
 
8078
  // [multimap.modifiers], modifiers
8079
+ template<class... Args> constexpr iterator emplace(Args&&... args);
8080
+ template<class... Args>
8081
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
8082
+ constexpr iterator insert(const value_type& x);
8083
+ constexpr iterator insert(value_type&& x);
8084
+ template<class P> constexpr iterator insert(P&& x);
8085
+ constexpr iterator insert(const_iterator position, const value_type& x);
8086
+ constexpr iterator insert(const_iterator position, value_type&& x);
8087
+ template<class P> constexpr iterator insert(const_iterator position, P&& x);
8088
  template<class InputIterator>
8089
+ constexpr void insert(InputIterator first, InputIterator last);
8090
  template<container-compatible-range<value_type> R>
8091
+ constexpr void insert_range(R&& rg);
8092
+ constexpr void insert(initializer_list<value_type>);
8093
 
8094
+ constexpr node_type extract(const_iterator position);
8095
+ constexpr node_type extract(const key_type& x);
8096
  template<class K> node_type extract(K&& x);
8097
+ constexpr iterator insert(node_type&& nh);
8098
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
8099
 
8100
+ constexpr iterator erase(iterator position);
8101
+ constexpr iterator erase(const_iterator position);
8102
+ constexpr size_type erase(const key_type& x);
8103
+ template<class K> constexpr size_type erase(K&& x);
8104
+ constexpr iterator erase(const_iterator first, const_iterator last);
8105
+ constexpr void swap(multimap&)
8106
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8107
  is_nothrow_swappable_v<Compare>);
8108
+ constexpr void clear() noexcept;
8109
 
8110
  template<class C2>
8111
+ constexpr void merge(multimap<Key, T, C2, Allocator>& source);
8112
  template<class C2>
8113
+ constexpr void merge(multimap<Key, T, C2, Allocator>&& source);
8114
  template<class C2>
8115
+ constexpr void merge(map<Key, T, C2, Allocator>& source);
8116
  template<class C2>
8117
+ constexpr void merge(map<Key, T, C2, Allocator>&& source);
8118
 
8119
  // observers
8120
+ constexpr key_compare key_comp() const;
8121
+ constexpr value_compare value_comp() const;
8122
 
8123
  // map operations
8124
+ constexpr iterator find(const key_type& x);
8125
+ constexpr const_iterator find(const key_type& x) const;
8126
+ template<class K> constexpr iterator find(const K& x);
8127
+ template<class K> constexpr const_iterator find(const K& x) const;
8128
 
8129
+ constexpr size_type count(const key_type& x) const;
8130
+ template<class K> constexpr size_type count(const K& x) const;
8131
 
8132
+ constexpr bool contains(const key_type& x) const;
8133
+ template<class K> constexpr bool contains(const K& x) const;
8134
 
8135
+ constexpr iterator lower_bound(const key_type& x);
8136
+ constexpr const_iterator lower_bound(const key_type& x) const;
8137
+ template<class K> constexpr iterator lower_bound(const K& x);
8138
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
8139
 
8140
+ constexpr iterator upper_bound(const key_type& x);
8141
+ constexpr const_iterator upper_bound(const key_type& x) const;
8142
+ template<class K> constexpr iterator upper_bound(const K& x);
8143
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
8144
 
8145
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
8146
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
8147
  template<class K>
8148
+ constexpr pair<iterator, iterator> equal_range(const K& x);
8149
  template<class K>
8150
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
8151
  };
8152
 
8153
  template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>,
8154
  class Allocator = allocator<iter-to-alloc-type<InputIterator>>>
8155
  multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
 
8182
  ```
8183
 
8184
  #### Constructors <a id="multimap.cons">[[multimap.cons]]</a>
8185
 
8186
  ``` cpp
8187
+ constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator());
8188
  ```
8189
 
8190
  *Effects:* Constructs an empty `multimap` using the specified comparison
8191
  object and allocator.
8192
 
8193
  *Complexity:* Constant.
8194
 
8195
  ``` cpp
8196
  template<class InputIterator>
8197
+ constexpr multimap(InputIterator first, InputIterator last,
8198
+ const Compare& comp = Compare(), const Allocator& = Allocator());
 
8199
  ```
8200
 
8201
  *Effects:* Constructs an empty `multimap` using the specified comparison
8202
  object and allocator, and inserts elements from the range \[`first`,
8203
  `last`).
 
8206
  sorted with respect to `comp` and otherwise N log N, where N is
8207
  `last - first`.
8208
 
8209
  ``` cpp
8210
  template<container-compatible-range<value_type> R>
8211
+ constexpr multimap(from_range_t, R&& rg,
8212
+ const Compare& comp = Compare(), const Allocator& = Allocator());
8213
  ```
8214
 
8215
  *Effects:* Constructs an empty `multimap` using the specified comparison
8216
  object and allocator, and inserts elements from the range `rg`.
8217
 
 
8219
  `comp` and otherwise N log N, where N is `ranges::distance(rg)`.
8220
 
8221
  #### Modifiers <a id="multimap.modifiers">[[multimap.modifiers]]</a>
8222
 
8223
  ``` cpp
8224
+ template<class P> constexpr iterator insert(P&& x);
8225
+ template<class P> constexpr iterator insert(const_iterator position, P&& x);
8226
  ```
8227
 
8228
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
8229
 
8230
  *Effects:* The first form is equivalent to
 
8234
  #### Erasure <a id="multimap.erasure">[[multimap.erasure]]</a>
8235
 
8236
  ``` cpp
8237
  template<class Key, class T, class Compare, class Allocator, class Predicate>
8238
  typename multimap<Key, T, Compare, Allocator>::size_type
8239
+ constexpr erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
8240
  ```
8241
 
8242
  *Effects:* Equivalent to:
8243
 
8244
  ``` cpp
 
8251
  }
8252
  }
8253
  return original_size - c.size();
8254
  ```
8255
 
8256
+ ### Header `<set>` synopsis <a id="associative.set.syn">[[associative.set.syn]]</a>
8257
+
8258
+ ``` cpp
8259
+ #include <compare> // see [compare.syn]
8260
+ #include <initializer_list> // see [initializer.list.syn]
8261
+
8262
+ namespace std {
8263
+ // [set], class template set
8264
+ template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
8265
+ class set;
8266
+
8267
+ template<class Key, class Compare, class Allocator>
8268
+ constexpr bool operator==(const set<Key, Compare, Allocator>& x,
8269
+ const set<Key, Compare, Allocator>& y);
8270
+ template<class Key, class Compare, class Allocator>
8271
+ constexpr synth-three-way-result<Key>
8272
+ operator<=>(const set<Key, Compare, Allocator>& x,
8273
+ const set<Key, Compare, Allocator>& y);
8274
+
8275
+ template<class Key, class Compare, class Allocator>
8276
+ constexpr void swap(set<Key, Compare, Allocator>& x,
8277
+ set<Key, Compare, Allocator>& y)
8278
+ noexcept(noexcept(x.swap(y)));
8279
+
8280
+ // [set.erasure], erasure for set
8281
+ template<class Key, class Compare, class Allocator, class Predicate>
8282
+ constexpr typename set<Key, Compare, Allocator>::size_type
8283
+ erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
8284
+
8285
+ // [multiset], class template multiset
8286
+ template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
8287
+ class multiset;
8288
+
8289
+ template<class Key, class Compare, class Allocator>
8290
+ constexpr bool operator==(const multiset<Key, Compare, Allocator>& x,
8291
+ const multiset<Key, Compare, Allocator>& y);
8292
+ template<class Key, class Compare, class Allocator>
8293
+ constexpr synth-three-way-result<Key>
8294
+ operator<=>(const multiset<Key, Compare, Allocator>& x,
8295
+ const multiset<Key, Compare, Allocator>& y);
8296
+
8297
+ template<class Key, class Compare, class Allocator>
8298
+ constexpr void swap(multiset<Key, Compare, Allocator>& x,
8299
+ multiset<Key, Compare, Allocator>& y)
8300
+ noexcept(noexcept(x.swap(y)));
8301
+
8302
+ // [multiset.erasure], erasure for multiset
8303
+ template<class Key, class Compare, class Allocator, class Predicate>
8304
+ constexpr typename multiset<Key, Compare, Allocator>::size_type
8305
+ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
8306
+
8307
+ namespace pmr {
8308
+ template<class Key, class Compare = less<Key>>
8309
+ using set = std::set<Key, Compare, polymorphic_allocator<Key>>;
8310
+
8311
+ template<class Key, class Compare = less<Key>>
8312
+ using multiset = std::multiset<Key, Compare, polymorphic_allocator<Key>>;
8313
+ }
8314
+ }
8315
+ ```
8316
+
8317
  ### Class template `set` <a id="set">[[set]]</a>
8318
 
8319
  #### Overview <a id="set.overview">[[set.overview]]</a>
8320
 
8321
  A `set` is an associative container that supports unique keys (i.e.,
 
8324
  iterators.
8325
 
8326
  A `set` meets all of the requirements of a container
8327
  [[container.reqmts]], of a reversible container
8328
  [[container.rev.reqmts]], of an allocator-aware container
8329
+ [[container.alloc.reqmts]], and of an associative container
8330
  [[associative.reqmts]]. A `set` also provides most operations described
8331
  in  [[associative.reqmts]] for unique keys. This means that a `set`
8332
  supports the `a_uniq` operations in  [[associative.reqmts]] but not the
8333
  `a_eq` operations. For a `set<Key>` both the `key_type` and `value_type`
8334
  are `Key`. Descriptions are provided here only for operations on `set`
8335
  that are not described in one of these tables and for operations where
8336
  there is additional semantic information.
8337
 
8338
+ The types `iterator` and `const_iterator` meet the constexpr iterator
8339
+ requirements [[iterator.requirements.general]].
8340
+
8341
  ``` cpp
8342
  namespace std {
8343
  template<class Key, class Compare = less<Key>,
8344
  class Allocator = allocator<Key>>
8345
  class set {
 
8348
  using key_type = Key;
8349
  using key_compare = Compare;
8350
  using value_type = Key;
8351
  using value_compare = Compare;
8352
  using allocator_type = Allocator;
8353
+ using pointer = allocator_traits<Allocator>::pointer;
8354
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
8355
  using reference = value_type&;
8356
  using const_reference = const value_type&;
8357
  using size_type = implementation-defined // type of set::size_type; // see [container.requirements]
8358
  using difference_type = implementation-defined // type of set::difference_type; // see [container.requirements]
8359
  using iterator = implementation-defined // type of set::iterator; // see [container.requirements]
 
8362
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
8363
  using node_type = unspecified;
8364
  using insert_return_type = insert-return-type<iterator, node_type>;
8365
 
8366
  // [set.cons], construct/copy/destroy
8367
+ constexpr set() : set(Compare()) { }
8368
+ constexpr explicit set(const Compare& comp, const Allocator& = Allocator());
8369
  template<class InputIterator>
8370
+ constexpr set(InputIterator first, InputIterator last,
8371
  const Compare& comp = Compare(), const Allocator& = Allocator());
8372
  template<container-compatible-range<value_type> R>
8373
+ constexpr set(from_range_t, R&& rg,
8374
+ const Compare& comp = Compare(), const Allocator& = Allocator());
8375
+ constexpr set(const set& x);
8376
+ constexpr set(set&& x);
8377
+ constexpr explicit set(const Allocator&);
8378
+ constexpr set(const set&, const type_identity_t<Allocator>&);
8379
+ constexpr set(set&&, const type_identity_t<Allocator>&);
8380
+ constexpr set(initializer_list<value_type>,
8381
+ const Compare& = Compare(), const Allocator& = Allocator());
8382
  template<class InputIterator>
8383
+ constexpr set(InputIterator first, InputIterator last, const Allocator& a)
8384
  : set(first, last, Compare(), a) { }
8385
  template<container-compatible-range<value_type> R>
8386
+ constexpr set(from_range_t, R&& rg, const Allocator& a)
8387
  : set(from_range, std::forward<R>(rg), Compare(), a) { }
8388
+ constexpr set(initializer_list<value_type> il, const Allocator& a)
8389
  : set(il, Compare(), a) { }
8390
+ constexpr ~set();
8391
+ constexpr set& operator=(const set& x);
8392
+ constexpr set& operator=(set&& x)
8393
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8394
  is_nothrow_move_assignable_v<Compare>);
8395
+ constexpr set& operator=(initializer_list<value_type>);
8396
+ constexpr allocator_type get_allocator() const noexcept;
8397
 
8398
  // iterators
8399
+ constexpr iterator begin() noexcept;
8400
+ constexpr const_iterator begin() const noexcept;
8401
+ constexpr iterator end() noexcept;
8402
+ constexpr const_iterator end() const noexcept;
8403
 
8404
+ constexpr reverse_iterator rbegin() noexcept;
8405
+ constexpr const_reverse_iterator rbegin() const noexcept;
8406
+ constexpr reverse_iterator rend() noexcept;
8407
+ constexpr const_reverse_iterator rend() const noexcept;
8408
 
8409
+ constexpr const_iterator cbegin() const noexcept;
8410
+ constexpr const_iterator cend() const noexcept;
8411
+ constexpr const_reverse_iterator crbegin() const noexcept;
8412
+ constexpr const_reverse_iterator crend() const noexcept;
8413
 
8414
  // capacity
8415
+ constexpr bool empty() const noexcept;
8416
+ constexpr size_type size() const noexcept;
8417
+ constexpr size_type max_size() const noexcept;
8418
 
8419
+ // [set.modifiers], modifiers
8420
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
8421
+ template<class... Args>
8422
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
8423
+ constexpr pair<iterator,bool> insert(const value_type& x);
8424
+ constexpr pair<iterator,bool> insert(value_type&& x);
8425
+ template<class K> constexpr pair<iterator, bool> insert(K&& x);
8426
+ constexpr iterator insert(const_iterator position, const value_type& x);
8427
+ constexpr iterator insert(const_iterator position, value_type&& x);
8428
+ template<class K> constexpr iterator insert(const_iterator position, K&& x);
8429
  template<class InputIterator>
8430
+ constexpr void insert(InputIterator first, InputIterator last);
8431
  template<container-compatible-range<value_type> R>
8432
+ constexpr void insert_range(R&& rg);
8433
+ constexpr void insert(initializer_list<value_type>);
8434
 
8435
+ constexpr node_type extract(const_iterator position);
8436
+ constexpr node_type extract(const key_type& x);
8437
+ template<class K> constexpr node_type extract(K&& x);
8438
+ constexpr insert_return_type insert(node_type&& nh);
8439
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
8440
 
8441
+ constexpr iterator erase(iterator position)
8442
  requires (!same_as<iterator, const_iterator>);
8443
+ constexpr iterator erase(const_iterator position);
8444
+ constexpr size_type erase(const key_type& x);
8445
+ template<class K> constexpr size_type erase(K&& x);
8446
+ constexpr iterator erase(const_iterator first, const_iterator last);
8447
+ constexpr void swap(set&)
8448
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8449
  is_nothrow_swappable_v<Compare>);
8450
+ constexpr void clear() noexcept;
8451
 
8452
  template<class C2>
8453
+ constexpr void merge(set<Key, C2, Allocator>& source);
8454
  template<class C2>
8455
+ constexpr void merge(set<Key, C2, Allocator>&& source);
8456
  template<class C2>
8457
+ constexpr void merge(multiset<Key, C2, Allocator>& source);
8458
  template<class C2>
8459
+ constexpr void merge(multiset<Key, C2, Allocator>&& source);
8460
 
8461
  // observers
8462
+ constexpr key_compare key_comp() const;
8463
+ constexpr value_compare value_comp() const;
8464
 
8465
  // set operations
8466
+ constexpr iterator find(const key_type& x);
8467
+ constexpr const_iterator find(const key_type& x) const;
8468
+ template<class K> constexpr iterator find(const K& x);
8469
+ template<class K> constexpr const_iterator find(const K& x) const;
8470
 
8471
+ constexpr size_type count(const key_type& x) const;
8472
+ template<class K> constexpr size_type count(const K& x) const;
8473
 
8474
+ constexpr bool contains(const key_type& x) const;
8475
+ template<class K> constexpr bool contains(const K& x) const;
8476
 
8477
+ constexpr iterator lower_bound(const key_type& x);
8478
+ constexpr const_iterator lower_bound(const key_type& x) const;
8479
+ template<class K> constexpr iterator lower_bound(const K& x);
8480
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
8481
 
8482
+ constexpr iterator upper_bound(const key_type& x);
8483
+ constexpr const_iterator upper_bound(const key_type& x) const;
8484
+ template<class K> constexpr iterator upper_bound(const K& x);
8485
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
8486
 
8487
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
8488
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
8489
  template<class K>
8490
+ constexpr pair<iterator, iterator> equal_range(const K& x);
8491
  template<class K>
8492
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
8493
  };
8494
 
8495
  template<class InputIterator,
8496
  class Compare = less<iter-value-type<InputIterator>>,
8497
  class Allocator = allocator<iter-value-type<InputIterator>>>
 
8523
  ```
8524
 
8525
  #### Constructors, copy, and assignment <a id="set.cons">[[set.cons]]</a>
8526
 
8527
  ``` cpp
8528
+ constexpr explicit set(const Compare& comp, const Allocator& = Allocator());
8529
  ```
8530
 
8531
  *Effects:* Constructs an empty `set` using the specified comparison
8532
  object and allocator.
8533
 
8534
  *Complexity:* Constant.
8535
 
8536
  ``` cpp
8537
  template<class InputIterator>
8538
+ constexpr set(InputIterator first, InputIterator last,
8539
  const Compare& comp = Compare(), const Allocator& = Allocator());
8540
  ```
8541
 
8542
  *Effects:* Constructs an empty `set` using the specified comparison
8543
  object and allocator, and inserts elements from the range \[`first`,
 
8547
  sorted with respect to `comp` and otherwise N log N, where N is
8548
  `last - first`.
8549
 
8550
  ``` cpp
8551
  template<container-compatible-range<value_type> R>
8552
+ constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(),
8553
+ const Allocator& = Allocator());
8554
  ```
8555
 
8556
  *Effects:* Constructs an empty `set` using the specified comparison
8557
  object and allocator, and inserts elements from the range `rg`.
8558
 
 
8561
 
8562
  #### Erasure <a id="set.erasure">[[set.erasure]]</a>
8563
 
8564
  ``` cpp
8565
  template<class Key, class Compare, class Allocator, class Predicate>
8566
+ constexpr typename set<Key, Compare, Allocator>::size_type
8567
  erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
8568
  ```
8569
 
8570
  *Effects:* Equivalent to:
8571
 
 
8579
  }
8580
  }
8581
  return original_size - c.size();
8582
  ```
8583
 
8584
+ #### Modifiers <a id="set.modifiers">[[set.modifiers]]</a>
8585
+
8586
+ ``` cpp
8587
+ template<class K> constexpr pair<iterator, bool> insert(K&& x);
8588
+ template<class K> constexpr iterator insert(const_iterator hint, K&& x);
8589
+ ```
8590
+
8591
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
8592
+ denotes a type. For the second overload,
8593
+ `is_convertible_v<K&&, const_iterator>` and
8594
+ `is_convertible_v<K&&, iterator>` are both `false`.
8595
+
8596
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into `set`
8597
+ from `std::forward<K>(x)`.
8598
+
8599
+ *Effects:* If the set already contains an element that is equivalent to
8600
+ `x`, there is no effect. Otherwise, let `r` be `equal_range(x)`.
8601
+ Constructs an object `u` of type `value_type` with `std::forward<K>(x)`.
8602
+ If `equal_range(u) == r` is `false`, the behavior is undefined. Inserts
8603
+ `u` into `*this`.
8604
+
8605
+ *Returns:* For the first overload, the `bool` component of the returned
8606
+ pair is `true` if and only if the insertion took place. The returned
8607
+ iterator points to the set element that is equivalent to `x`.
8608
+
8609
+ *Complexity:* Logarithmic.
8610
+
8611
  ### Class template `multiset` <a id="multiset">[[multiset]]</a>
8612
 
8613
  #### Overview <a id="multiset.overview">[[multiset.overview]]</a>
8614
 
8615
  A `multiset` is an associative container that supports equivalent keys
 
8618
  supports bidirectional iterators.
8619
 
8620
  A `multiset` meets all of the requirements of a container
8621
  [[container.reqmts]], of a reversible container
8622
  [[container.rev.reqmts]], of an allocator-aware container
8623
+ [[container.alloc.reqmts]], and of an associative container
8624
  [[associative.reqmts]]. `multiset` also provides most operations
8625
  described in  [[associative.reqmts]] for duplicate keys. This means that
8626
  a `multiset` supports the `a_eq` operations in  [[associative.reqmts]]
8627
  but not the `a_uniq` operations. For a `multiset<Key>` both the
8628
  `key_type` and `value_type` are `Key`. Descriptions are provided here
8629
  only for operations on `multiset` that are not described in one of these
8630
  tables and for operations where there is additional semantic
8631
  information.
8632
 
8633
+ The types `iterator` and `const_iterator` meet the constexpr iterator
8634
+ requirements [[iterator.requirements.general]].
8635
+
8636
  ``` cpp
8637
  namespace std {
8638
  template<class Key, class Compare = less<Key>,
8639
  class Allocator = allocator<Key>>
8640
  class multiset {
 
8643
  using key_type = Key;
8644
  using key_compare = Compare;
8645
  using value_type = Key;
8646
  using value_compare = Compare;
8647
  using allocator_type = Allocator;
8648
+ using pointer = allocator_traits<Allocator>::pointer;
8649
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
8650
  using reference = value_type&;
8651
  using const_reference = const value_type&;
8652
  using size_type = implementation-defined // type of multiset::size_type; // see [container.requirements]
8653
  using difference_type = implementation-defined // type of multiset::difference_type; // see [container.requirements]
8654
  using iterator = implementation-defined // type of multiset::iterator; // see [container.requirements]
 
8656
  using reverse_iterator = std::reverse_iterator<iterator>;
8657
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
8658
  using node_type = unspecified;
8659
 
8660
  // [multiset.cons], construct/copy/destroy
8661
+ constexpr multiset() : multiset(Compare()) { }
8662
+ constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator());
8663
  template<class InputIterator>
8664
+ constexpr multiset(InputIterator first, InputIterator last,
8665
  const Compare& comp = Compare(), const Allocator& = Allocator());
8666
  template<container-compatible-range<value_type> R>
8667
+ constexpr multiset(from_range_t, R&& rg,
8668
  const Compare& comp = Compare(), const Allocator& = Allocator());
8669
+ constexpr multiset(const multiset& x);
8670
+ constexpr multiset(multiset&& x);
8671
+ constexpr explicit multiset(const Allocator&);
8672
+ constexpr multiset(const multiset&, const type_identity_t<Allocator>&);
8673
+ constexpr multiset(multiset&&, const type_identity_t<Allocator>&);
8674
+ constexpr multiset(initializer_list<value_type>, const Compare& = Compare(),
8675
  const Allocator& = Allocator());
8676
  template<class InputIterator>
8677
+ constexpr multiset(InputIterator first, InputIterator last, const Allocator& a)
8678
  : multiset(first, last, Compare(), a) { }
8679
  template<container-compatible-range<value_type> R>
8680
+ constexpr multiset(from_range_t, R&& rg, const Allocator& a)
8681
  : multiset(from_range, std::forward<R>(rg), Compare(), a) { }
8682
+ constexpr multiset(initializer_list<value_type> il, const Allocator& a)
8683
  : multiset(il, Compare(), a) { }
8684
+ constexpr ~multiset();
8685
+ constexpr multiset& operator=(const multiset& x);
8686
+ constexpr multiset& operator=(multiset&& x)
8687
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8688
  is_nothrow_move_assignable_v<Compare>);
8689
+ constexpr multiset& operator=(initializer_list<value_type>);
8690
+ constexpr allocator_type get_allocator() const noexcept;
8691
 
8692
  // iterators
8693
+ constexpr iterator begin() noexcept;
8694
+ constexpr const_iterator begin() const noexcept;
8695
+ constexpr iterator end() noexcept;
8696
+ constexpr const_iterator end() const noexcept;
8697
 
8698
+ constexpr reverse_iterator rbegin() noexcept;
8699
+ constexpr const_reverse_iterator rbegin() const noexcept;
8700
+ constexpr reverse_iterator rend() noexcept;
8701
+ constexpr const_reverse_iterator rend() const noexcept;
8702
 
8703
+ constexpr const_iterator cbegin() const noexcept;
8704
+ constexpr const_iterator cend() const noexcept;
8705
+ constexpr const_reverse_iterator crbegin() const noexcept;
8706
+ constexpr const_reverse_iterator crend() const noexcept;
8707
 
8708
  // capacity
8709
+ constexpr bool empty() const noexcept;
8710
+ constexpr size_type size() const noexcept;
8711
+ constexpr size_type max_size() const noexcept;
8712
 
8713
  // modifiers
8714
+ template<class... Args> constexpr iterator emplace(Args&&... args);
8715
+ template<class... Args>
8716
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
8717
+ constexpr iterator insert(const value_type& x);
8718
+ constexpr iterator insert(value_type&& x);
8719
+ constexpr iterator insert(const_iterator position, const value_type& x);
8720
+ constexpr iterator insert(const_iterator position, value_type&& x);
8721
  template<class InputIterator>
8722
+ constexpr void insert(InputIterator first, InputIterator last);
8723
  template<container-compatible-range<value_type> R>
8724
+ constexpr void insert_range(R&& rg);
8725
+ constexpr void insert(initializer_list<value_type>);
8726
 
8727
+ constexpr node_type extract(const_iterator position);
8728
+ constexpr node_type extract(const key_type& x);
8729
+ template<class K> constexpr node_type extract(K&& x);
8730
+ constexpr iterator insert(node_type&& nh);
8731
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
8732
 
8733
+ constexpr iterator erase(iterator position)
8734
  requires (!same_as<iterator, const_iterator>);
8735
+ constexpr iterator erase(const_iterator position);
8736
+ constexpr size_type erase(const key_type& x);
8737
+ template<class K> constexpr size_type erase(K&& x);
8738
+ constexpr iterator erase(const_iterator first, const_iterator last);
8739
+ constexpr void swap(multiset&)
8740
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
8741
  is_nothrow_swappable_v<Compare>);
8742
+ constexpr void clear() noexcept;
8743
 
8744
  template<class C2>
8745
+ constexpr void merge(multiset<Key, C2, Allocator>& source);
8746
  template<class C2>
8747
+ constexpr void merge(multiset<Key, C2, Allocator>&& source);
8748
  template<class C2>
8749
+ constexpr void merge(set<Key, C2, Allocator>& source);
8750
  template<class C2>
8751
+ constexpr void merge(set<Key, C2, Allocator>&& source);
8752
 
8753
  // observers
8754
+ constexpr key_compare key_comp() const;
8755
+ constexpr value_compare value_comp() const;
8756
 
8757
  // set operations
8758
+ constexpr iterator find(const key_type& x);
8759
+ constexpr const_iterator find(const key_type& x) const;
8760
+ template<class K> constexpr iterator find(const K& x);
8761
+ template<class K> constexpr const_iterator find(const K& x) const;
8762
 
8763
+ constexpr size_type count(const key_type& x) const;
8764
+ template<class K> constexpr size_type count(const K& x) const;
8765
 
8766
+ constexpr bool contains(const key_type& x) const;
8767
+ template<class K> constexpr bool contains(const K& x) const;
8768
 
8769
+ constexpr iterator lower_bound(const key_type& x);
8770
+ constexpr const_iterator lower_bound(const key_type& x) const;
8771
+ template<class K> constexpr iterator lower_bound(const K& x);
8772
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
8773
 
8774
+ constexpr iterator upper_bound(const key_type& x);
8775
+ constexpr const_iterator upper_bound(const key_type& x) const;
8776
+ template<class K> constexpr iterator upper_bound(const K& x);
8777
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
8778
 
8779
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
8780
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
8781
  template<class K>
8782
+ constexpr pair<iterator, iterator> equal_range(const K& x);
8783
  template<class K>
8784
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
8785
  };
8786
 
8787
  template<class InputIterator,
8788
  class Compare = less<iter-value-type<InputIterator>>,
8789
  class Allocator = allocator<iter-value-type<InputIterator>>>
 
8815
  ```
8816
 
8817
  #### Constructors <a id="multiset.cons">[[multiset.cons]]</a>
8818
 
8819
  ``` cpp
8820
+ constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator());
8821
  ```
8822
 
8823
  *Effects:* Constructs an empty `multiset` using the specified comparison
8824
  object and allocator.
8825
 
8826
  *Complexity:* Constant.
8827
 
8828
  ``` cpp
8829
  template<class InputIterator>
8830
+ constexpr multiset(InputIterator first, InputIterator last,
8831
  const Compare& comp = Compare(), const Allocator& = Allocator());
8832
  ```
8833
 
8834
  *Effects:* Constructs an empty `multiset` using the specified comparison
8835
  object and allocator, and inserts elements from the range \[`first`,
 
8839
  sorted with respect to `comp` and otherwise N log N, where N is
8840
  `last - first`.
8841
 
8842
  ``` cpp
8843
  template<container-compatible-range<value_type> R>
8844
+ constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(),
8845
+ const Allocator& = Allocator());
8846
  ```
8847
 
8848
  *Effects:* Constructs an empty `multiset` using the specified comparison
8849
  object and allocator, and inserts elements from the range `rg`.
8850
 
 
8853
 
8854
  #### Erasure <a id="multiset.erasure">[[multiset.erasure]]</a>
8855
 
8856
  ``` cpp
8857
  template<class Key, class Compare, class Allocator, class Predicate>
8858
+ constexpr typename multiset<Key, Compare, Allocator>::size_type
8859
  erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
8860
  ```
8861
 
8862
  *Effects:* Equivalent to:
8863
 
 
8873
  return original_size - c.size();
8874
  ```
8875
 
8876
  ## Unordered associative containers <a id="unord">[[unord]]</a>
8877
 
8878
+ ### General <a id="unord.general">[[unord.general]]</a>
8879
 
8880
  The header `<unordered_map>` defines the class templates `unordered_map`
8881
  and `unordered_multimap`; the header `<unordered_set>` defines the class
8882
  templates `unordered_set` and `unordered_multiset`.
8883
 
 
8909
  class Pred = equal_to<Key>,
8910
  class Alloc = allocator<pair<const Key, T>>>
8911
  class unordered_multimap;
8912
 
8913
  template<class Key, class T, class Hash, class Pred, class Alloc>
8914
+ constexpr bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
8915
  const unordered_map<Key, T, Hash, Pred, Alloc>& b);
8916
 
8917
  template<class Key, class T, class Hash, class Pred, class Alloc>
8918
+ constexpr bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
8919
  const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
8920
 
8921
  template<class Key, class T, class Hash, class Pred, class Alloc>
8922
+ constexpr void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
8923
  unordered_map<Key, T, Hash, Pred, Alloc>& y)
8924
  noexcept(noexcept(x.swap(y)));
8925
 
8926
  template<class Key, class T, class Hash, class Pred, class Alloc>
8927
+ constexpr void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
8928
  unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
8929
  noexcept(noexcept(x.swap(y)));
8930
 
8931
  // [unord.map.erasure], erasure for unordered_map
8932
  template<class K, class T, class H, class P, class A, class Predicate>
8933
+ constexpr typename unordered_map<K, T, H, P, A>::size_type
8934
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
8935
 
8936
  // [unord.multimap.erasure], erasure for unordered_multimap
8937
  template<class K, class T, class H, class P, class A, class Predicate>
8938
+ constexpr typename unordered_multimap<K, T, H, P, A>::size_type
8939
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
8940
 
8941
  namespace pmr {
8942
  template<class Key,
8943
  class T,
 
8956
 
8957
  }
8958
  }
8959
  ```
8960
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8961
  ### Class template `unordered_map` <a id="unord.map">[[unord.map]]</a>
8962
 
8963
  #### Overview <a id="unord.map.overview">[[unord.map.overview]]</a>
8964
 
8965
  An `unordered_map` is an unordered associative container that supports
 
8978
 
8979
  Subclause  [[unord.map]] only describes operations on `unordered_map`
8980
  that are not described in one of the requirement tables, or for which
8981
  there is additional semantic information.
8982
 
8983
+ The types `iterator` and `const_iterator` meet the constexpr iterator
8984
+ requirements [[iterator.requirements.general]].
8985
+
8986
  ``` cpp
8987
  namespace std {
8988
  template<class Key,
8989
  class T,
8990
  class Hash = hash<Key>,
 
8997
  using mapped_type = T;
8998
  using value_type = pair<const Key, T>;
8999
  using hasher = Hash;
9000
  using key_equal = Pred;
9001
  using allocator_type = Allocator;
9002
+ using pointer = allocator_traits<Allocator>::pointer;
9003
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
9004
  using reference = value_type&;
9005
  using const_reference = const value_type&;
9006
  using size_type = implementation-defined // type of unordered_map::size_type; // see [container.requirements]
9007
  using difference_type = implementation-defined // type of unordered_map::difference_type; // see [container.requirements]
9008
 
 
9012
  using const_local_iterator = implementation-defined // type of unordered_map::const_local_iterator; // see [container.requirements]
9013
  using node_type = unspecified;
9014
  using insert_return_type = insert-return-type<iterator, node_type>;
9015
 
9016
  // [unord.map.cnstr], construct/copy/destroy
9017
+ constexpr unordered_map();
9018
+ constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(),
 
9019
  const key_equal& eql = key_equal(),
9020
  const allocator_type& a = allocator_type());
9021
  template<class InputIterator>
9022
+ constexpr unordered_map(InputIterator f, InputIterator l,
9023
+ size_type n = see below, const hasher& hf = hasher(),
 
9024
  const key_equal& eql = key_equal(),
9025
  const allocator_type& a = allocator_type());
9026
 
9027
  template<container-compatible-range<value_type> R>
9028
+ constexpr unordered_map(from_range_t, R&& rg, size_type n = see below,
9029
  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
9030
  const allocator_type& a = allocator_type());
9031
+ constexpr unordered_map(const unordered_map&);
9032
+ constexpr unordered_map(unordered_map&&);
9033
+ constexpr explicit unordered_map(const Allocator&);
9034
+ constexpr unordered_map(const unordered_map&, const type_identity_t<Allocator>&);
9035
+ constexpr unordered_map(unordered_map&&, const type_identity_t<Allocator>&);
9036
+ constexpr unordered_map(initializer_list<value_type> il, size_type n = see below,
 
9037
  const hasher& hf = hasher(),
9038
  const key_equal& eql = key_equal(),
9039
  const allocator_type& a = allocator_type());
9040
+ constexpr unordered_map(size_type n, const allocator_type& a)
9041
  : unordered_map(n, hasher(), key_equal(), a) { }
9042
+ constexpr unordered_map(size_type n, const hasher& hf, const allocator_type& a)
9043
  : unordered_map(n, hf, key_equal(), a) { }
9044
  template<class InputIterator>
9045
+ constexpr unordered_map(InputIterator f, InputIterator l, size_type n,
9046
+ const allocator_type& a)
9047
  : unordered_map(f, l, n, hasher(), key_equal(), a) { }
9048
  template<class InputIterator>
9049
+ constexpr unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
9050
  const allocator_type& a)
9051
  : unordered_map(f, l, n, hf, key_equal(), a) { }
9052
  template<container-compatible-range<value_type> R>
9053
+ constexpr unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a)
9054
  : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
9055
  template<container-compatible-range<value_type> R>
9056
+ constexpr unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf,
9057
+ const allocator_type& a)
9058
  : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
9059
+ constexpr unordered_map(initializer_list<value_type> il, size_type n,
9060
+ const allocator_type& a)
9061
  : unordered_map(il, n, hasher(), key_equal(), a) { }
9062
+ constexpr unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
9063
  const allocator_type& a)
9064
  : unordered_map(il, n, hf, key_equal(), a) { }
9065
+ constexpr ~unordered_map();
9066
+ constexpr unordered_map& operator=(const unordered_map&);
9067
+ constexpr unordered_map& operator=(unordered_map&&)
9068
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
9069
  is_nothrow_move_assignable_v<Hash> &&
9070
  is_nothrow_move_assignable_v<Pred>);
9071
+ constexpr unordered_map& operator=(initializer_list<value_type>);
9072
+ constexpr allocator_type get_allocator() const noexcept;
9073
 
9074
  // iterators
9075
+ constexpr iterator begin() noexcept;
9076
+ constexpr const_iterator begin() const noexcept;
9077
+ constexpr iterator end() noexcept;
9078
+ constexpr const_iterator end() const noexcept;
9079
+ constexpr const_iterator cbegin() const noexcept;
9080
+ constexpr const_iterator cend() const noexcept;
9081
 
9082
  // capacity
9083
+ constexpr bool empty() const noexcept;
9084
+ constexpr size_type size() const noexcept;
9085
+ constexpr size_type max_size() const noexcept;
9086
 
9087
  // [unord.map.modifiers], modifiers
9088
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
9089
+ template<class... Args>
9090
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
9091
+ constexpr pair<iterator, bool> insert(const value_type& obj);
9092
+ constexpr pair<iterator, bool> insert(value_type&& obj);
9093
+ template<class P> constexpr pair<iterator, bool> insert(P&& obj);
9094
+ constexpr iterator insert(const_iterator hint, const value_type& obj);
9095
+ constexpr iterator insert(const_iterator hint, value_type&& obj);
9096
+ template<class P> constexpr iterator insert(const_iterator hint, P&& obj);
9097
+ template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last);
9098
  template<container-compatible-range<value_type> R>
9099
+ constexpr void insert_range(R&& rg);
9100
+ constexpr void insert(initializer_list<value_type>);
9101
 
9102
+ constexpr node_type extract(const_iterator position);
9103
+ constexpr node_type extract(const key_type& x);
9104
+ template<class K> constexpr node_type extract(K&& x);
9105
+ constexpr insert_return_type insert(node_type&& nh);
9106
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
9107
 
9108
  template<class... Args>
9109
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
9110
  template<class... Args>
9111
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
9112
+ template<class K, class... Args>
9113
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
9114
  template<class... Args>
9115
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
9116
  template<class... Args>
9117
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
9118
+ template<class K, class... Args>
9119
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
9120
  template<class M>
9121
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
9122
  template<class M>
9123
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
9124
+ template<class K, class M>
9125
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
9126
  template<class M>
9127
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
9128
  template<class M>
9129
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
9130
+ template<class K, class M>
9131
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
9132
 
9133
+ constexpr iterator erase(iterator position);
9134
+ constexpr iterator erase(const_iterator position);
9135
+ constexpr size_type erase(const key_type& k);
9136
+ template<class K> constexpr size_type erase(K&& x);
9137
+ constexpr iterator erase(const_iterator first, const_iterator last);
9138
+ constexpr void swap(unordered_map&)
9139
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
9140
+ is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>);
9141
+ constexpr void clear() noexcept;
 
9142
 
9143
  template<class H2, class P2>
9144
+ constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
9145
  template<class H2, class P2>
9146
+ constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
9147
  template<class H2, class P2>
9148
+ constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
9149
  template<class H2, class P2>
9150
+ constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
9151
 
9152
  // observers
9153
+ constexpr hasher hash_function() const;
9154
+ constexpr key_equal key_eq() const;
9155
 
9156
  // map operations
9157
+ constexpr iterator find(const key_type& k);
9158
+ constexpr const_iterator find(const key_type& k) const;
9159
  template<class K>
9160
+ constexpr iterator find(const K& k);
9161
  template<class K>
9162
+ constexpr const_iterator find(const K& k) const;
9163
+ constexpr size_type count(const key_type& k) const;
9164
  template<class K>
9165
+ constexpr size_type count(const K& k) const;
9166
+ constexpr bool contains(const key_type& k) const;
9167
  template<class K>
9168
+ constexpr bool contains(const K& k) const;
9169
+ constexpr pair<iterator, iterator> equal_range(const key_type& k);
9170
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
9171
  template<class K>
9172
+ constexpr pair<iterator, iterator> equal_range(const K& k);
9173
  template<class K>
9174
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const;
9175
 
9176
  // [unord.map.elem], element access
9177
+ constexpr mapped_type& operator[](const key_type& k);
9178
+ constexpr mapped_type& operator[](key_type&& k);
9179
+ template<class K> constexpr mapped_type& operator[](K&& k);
9180
+ constexpr mapped_type& at(const key_type& k);
9181
+ constexpr const mapped_type& at(const key_type& k) const;
9182
+ template<class K> constexpr mapped_type& at(const K& k);
9183
+ template<class K> constexpr const mapped_type& at(const K& k) const;
9184
 
9185
  // bucket interface
9186
+ constexpr size_type bucket_count() const noexcept;
9187
+ constexpr size_type max_bucket_count() const noexcept;
9188
+ constexpr size_type bucket_size(size_type n) const;
9189
+ constexpr size_type bucket(const key_type& k) const;
9190
+ template<class K> constexpr size_type bucket(const K& k) const;
9191
+ constexpr local_iterator begin(size_type n);
9192
+ constexpr const_local_iterator begin(size_type n) const;
9193
+ constexpr local_iterator end(size_type n);
9194
+ constexpr const_local_iterator end(size_type n) const;
9195
+ constexpr const_local_iterator cbegin(size_type n) const;
9196
+ constexpr const_local_iterator cend(size_type n) const;
9197
 
9198
  // hash policy
9199
+ constexpr float load_factor() const noexcept;
9200
+ constexpr float max_load_factor() const noexcept;
9201
+ constexpr void max_load_factor(float z);
9202
+ constexpr void rehash(size_type n);
9203
+ constexpr void reserve(size_type n);
9204
  };
9205
 
9206
  template<class InputIterator,
9207
  class Hash = hash<iter-key-type<InputIterator>>,
9208
  class Pred = equal_to<iter-key-type<InputIterator>>,
 
9279
  deduction guide.
9280
 
9281
  #### Constructors <a id="unord.map.cnstr">[[unord.map.cnstr]]</a>
9282
 
9283
  ``` cpp
9284
+ constexpr unordered_map() : unordered_map(size_type(see below)) { }
9285
+ constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(),
 
9286
  const key_equal& eql = key_equal(),
9287
  const allocator_type& a = allocator_type());
9288
  ```
9289
 
9290
  *Effects:* Constructs an empty `unordered_map` using the specified hash
 
9294
 
9295
  *Complexity:* Constant.
9296
 
9297
  ``` cpp
9298
  template<class InputIterator>
9299
+ constexpr unordered_map(InputIterator f, InputIterator l,
9300
+ size_type n = see below, const hasher& hf = hasher(),
 
9301
  const key_equal& eql = key_equal(),
9302
  const allocator_type& a = allocator_type());
9303
  template<container-compatible-range<value_type> R>
9304
+ constexpr unordered_map(from_range_t, R&& rg,
9305
+ size_type n = see below, const hasher& hf = hasher(),
 
9306
  const key_equal& eql = key_equal(),
9307
  const allocator_type& a = allocator_type());
9308
+ constexpr unordered_map(initializer_list<value_type> il,
9309
+ size_type n = see below, const hasher& hf = hasher(),
 
9310
  const key_equal& eql = key_equal(),
9311
  const allocator_type& a = allocator_type());
9312
  ```
9313
 
9314
  *Effects:* Constructs an empty `unordered_map` using the specified hash
 
9320
  *Complexity:* Average case linear, worst case quadratic.
9321
 
9322
  #### Element access <a id="unord.map.elem">[[unord.map.elem]]</a>
9323
 
9324
  ``` cpp
9325
+ constexpr mapped_type& operator[](const key_type& k);
9326
  ```
9327
 
9328
  *Effects:* Equivalent to: `return try_emplace(k).first->second;`
9329
 
9330
  ``` cpp
9331
+ constexpr mapped_type& operator[](key_type&& k);
9332
  ```
9333
 
9334
  *Effects:* Equivalent to:
9335
  `return try_emplace(std::move(k)).first->second;`
9336
 
9337
  ``` cpp
9338
+ template<class K> constexpr mapped_type& operator[](K&& k);
9339
+ ```
9340
+
9341
+ *Constraints:* The *qualified-id*s `Hash::is_transparent` and
9342
+ `Pred::is_transparent` are valid and denote types.
9343
+
9344
+ *Effects:* Equivalent to:
9345
+ `return try_emplace(std::forward<K>(k)).first->second;`
9346
+
9347
+ ``` cpp
9348
+ constexpr mapped_type& at(const key_type& k);
9349
+ constexpr const mapped_type& at(const key_type& k) const;
9350
  ```
9351
 
9352
  *Returns:* A reference to `x.second`, where `x` is the (unique) element
9353
  whose key is equivalent to `k`.
9354
 
9355
  *Throws:* An exception object of type `out_of_range` if no such element
9356
  is present.
9357
 
9358
+ ``` cpp
9359
+ template<class K> constexpr mapped_type& at(const K& k);
9360
+ template<class K> constexpr const mapped_type& at(const K& k) const;
9361
+ ```
9362
+
9363
+ *Constraints:* The *qualified-id*s `Hash::is_transparent` and
9364
+ `Pred::is_transparent` are valid and denote types.
9365
+
9366
+ *Preconditions:* The expression `find(k)` is well-formed and has
9367
+ well-defined behavior.
9368
+
9369
+ *Returns:* A reference to `find(k)->second`.
9370
+
9371
+ *Throws:* An exception object of type `out_of_range` if
9372
+ `find(k) == end()` is `true`.
9373
+
9374
  #### Modifiers <a id="unord.map.modifiers">[[unord.map.modifiers]]</a>
9375
 
9376
  ``` cpp
9377
  template<class P>
9378
+ constexpr pair<iterator, bool> insert(P&& obj);
9379
  ```
9380
 
9381
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
9382
 
9383
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
9384
 
9385
  ``` cpp
9386
  template<class P>
9387
+ constexpr iterator insert(const_iterator hint, P&& obj);
9388
  ```
9389
 
9390
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
9391
 
9392
  *Effects:* Equivalent to:
9393
  `return emplace_hint(hint, std::forward<P>(obj));`
9394
 
9395
  ``` cpp
9396
  template<class... Args>
9397
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
9398
  template<class... Args>
9399
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
9400
  ```
9401
 
9402
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
9403
  `unordered_map` from `piecewise_construct`, `forward_as_tuple(k)`,
9404
  `forward_as_tuple(std::forward<Args>(args)...)`.
 
9414
 
9415
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9416
 
9417
  ``` cpp
9418
  template<class... Args>
9419
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
9420
  template<class... Args>
9421
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
9422
  ```
9423
 
9424
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
9425
  `unordered_map` from `piecewise_construct`,
9426
  `forward_as_tuple(std::move(k))`,
 
9436
  pair is `true` if and only if the insertion took place. The returned
9437
  iterator points to the map element whose key is equivalent to `k`.
9438
 
9439
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9440
 
9441
+ ``` cpp
9442
+ template<class K, class... Args>
9443
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
9444
+ template<class K, class... Args>
9445
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
9446
+ ```
9447
+
9448
+ *Constraints:* The *qualified-id*s `Hash::is_transparent` and
9449
+ `Pred::is_transparent` are valid and denote types. For the first
9450
+ overload, `is_convertible_v<K&&, const_iterator>` and
9451
+ `is_convertible_v<K&&, iterator>` are both `false`.
9452
+
9453
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
9454
+ `unordered_map` from
9455
+ `piecewise_construct, forward_as_tuple(std::forward<K>(k)), forward_as_tuple(std::forward<Args> (args)...)`.
9456
+
9457
+ *Effects:* If the map already contains an element whose key is
9458
+ equivalent to `k`, there is no effect. Otherwise, let `h` be
9459
+ `hash_function()(k)`. Constructs an object `u` of type `value_type` with
9460
+ `piecewise_construct, forward_as_tuple(std::forward<K>(k)), forward_as_tuple(std::forward<Args>(args)...)`.
9461
+ If `hash_function()(u.first) != h || contains(u.first)` is `true`, the
9462
+ behavior is undefined. Inserts `u` into `*this`.
9463
+
9464
+ *Returns:* For the first overload, the `bool` component of the returned
9465
+ pair is `true` if and only if the insertion took place. The returned
9466
+ iterator points to the map element whose key is equivalent to `k`.
9467
+
9468
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9469
+
9470
  ``` cpp
9471
  template<class M>
9472
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
9473
  template<class M>
9474
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
9475
  ```
9476
 
9477
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
9478
 
9479
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
 
9490
 
9491
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9492
 
9493
  ``` cpp
9494
  template<class M>
9495
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
9496
  template<class M>
9497
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
9498
  ```
9499
 
9500
  *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
9501
 
9502
  *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
 
9511
  pair is `true` if and only if the insertion took place. The returned
9512
  iterator points to the map element whose key is equivalent to `k`.
9513
 
9514
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9515
 
9516
+ ``` cpp
9517
+ template<class K, class M>
9518
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
9519
+ template<class K, class M>
9520
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
9521
+ ```
9522
+
9523
+ *Constraints:* The *qualified-id*s `Hash::is_transparent` and
9524
+ `Pred::is_transparent` are valid and denote types.
9525
+
9526
+ *Mandates:* `is_assignable_v<mapped_type&, M&&>` is `true`.
9527
+
9528
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
9529
+ `unordered_map` from `std::forward<K> (k), std::forward<M>(obj)`.
9530
+
9531
+ *Effects:* If the map already contains an element `e` whose key is
9532
+ equivalent to `k`, assigns `std::forward<M> (obj)` to `e.second`.
9533
+ Otherwise, let `h` be `hash_function()(k)`. Constructs an object `u` of
9534
+ type `value_type` with `std::forward<K>(k), std::forward<M>(obj)`. If
9535
+ `hash_function()(u.first) != h || contains(u.first)` is `true`, the
9536
+ behavior is undefined. Inserts `u` into `*this`.
9537
+
9538
+ *Returns:* For the first overload, the `bool` component of the returned
9539
+ pair is `true` if and only if the insertion took place. The returned
9540
+ iterator points to the map element whose key is equivalent to `k`.
9541
+
9542
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
9543
+
9544
  #### Erasure <a id="unord.map.erasure">[[unord.map.erasure]]</a>
9545
 
9546
  ``` cpp
9547
  template<class K, class T, class H, class P, class A, class Predicate>
9548
+ constexpr typename unordered_map<K, T, H, P, A>::size_type
9549
  erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
9550
  ```
9551
 
9552
  *Effects:* Equivalent to:
9553
 
 
9584
 
9585
  Subclause  [[unord.multimap]] only describes operations on
9586
  `unordered_multimap` that are not described in one of the requirement
9587
  tables, or for which there is additional semantic information.
9588
 
9589
+ The types `iterator` and `const_iterator` meet the constexpr iterator
9590
+ requirements [[iterator.requirements.general]].
9591
+
9592
  ``` cpp
9593
  namespace std {
9594
  template<class Key,
9595
  class T,
9596
  class Hash = hash<Key>,
 
9603
  using mapped_type = T;
9604
  using value_type = pair<const Key, T>;
9605
  using hasher = Hash;
9606
  using key_equal = Pred;
9607
  using allocator_type = Allocator;
9608
+ using pointer = allocator_traits<Allocator>::pointer;
9609
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
9610
  using reference = value_type&;
9611
  using const_reference = const value_type&;
9612
  using size_type = implementation-defined // type of unordered_multimap::size_type; // see [container.requirements]
9613
  using difference_type = implementation-defined // type of unordered_multimap::difference_type; // see [container.requirements]
9614
 
 
9617
  using local_iterator = implementation-defined // type of unordered_multimap::local_iterator; // see [container.requirements]
9618
  using const_local_iterator = implementation-defined // type of unordered_multimap::const_local_iterator; // see [container.requirements]
9619
  using node_type = unspecified;
9620
 
9621
  // [unord.multimap.cnstr], construct/copy/destroy
9622
+ constexpr unordered_multimap();
9623
+ constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(),
 
9624
  const key_equal& eql = key_equal(),
9625
  const allocator_type& a = allocator_type());
9626
  template<class InputIterator>
9627
+ constexpr unordered_multimap(InputIterator f, InputIterator l,
9628
+ size_type n = see below, const hasher& hf = hasher(),
 
9629
  const key_equal& eql = key_equal(),
9630
  const allocator_type& a = allocator_type());
9631
  template<container-compatible-range<value_type> R>
9632
+ constexpr unordered_multimap(from_range_t, R&& rg,
9633
+ size_type n = see below, const hasher& hf = hasher(),
 
9634
  const key_equal& eql = key_equal(),
9635
  const allocator_type& a = allocator_type());
9636
+ constexpr unordered_multimap(const unordered_multimap&);
9637
+ constexpr unordered_multimap(unordered_multimap&&);
9638
+ constexpr explicit unordered_multimap(const Allocator&);
9639
+ constexpr unordered_multimap(const unordered_multimap&, const type_identity_t<Allocator>&);
9640
+ constexpr unordered_multimap(unordered_multimap&&, const type_identity_t<Allocator>&);
9641
+ constexpr unordered_multimap(initializer_list<value_type> il,
9642
+ size_type n = see below, const hasher& hf = hasher(),
 
9643
  const key_equal& eql = key_equal(),
9644
  const allocator_type& a = allocator_type());
9645
+ constexpr unordered_multimap(size_type n, const allocator_type& a)
9646
  : unordered_multimap(n, hasher(), key_equal(), a) { }
9647
+ constexpr unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
9648
  : unordered_multimap(n, hf, key_equal(), a) { }
9649
  template<class InputIterator>
9650
+ constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n,
9651
+ const allocator_type& a)
9652
  : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
9653
  template<class InputIterator>
9654
+ constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n,
9655
+ const hasher& hf, const allocator_type& a)
9656
  : unordered_multimap(f, l, n, hf, key_equal(), a) { }
9657
  template<container-compatible-range<value_type> R>
9658
+ constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a)
9659
  : unordered_multimap(from_range, std::forward<R>(rg),
9660
  n, hasher(), key_equal(), a) { }
9661
  template<container-compatible-range<value_type> R>
9662
+ constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf,
9663
  const allocator_type& a)
9664
  : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
9665
+ constexpr unordered_multimap(initializer_list<value_type> il, size_type n,
9666
+ const allocator_type& a)
9667
  : unordered_multimap(il, n, hasher(), key_equal(), a) { }
9668
+ constexpr unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
9669
  const allocator_type& a)
9670
  : unordered_multimap(il, n, hf, key_equal(), a) { }
9671
+ constexpr ~unordered_multimap();
9672
+ constexpr unordered_multimap& operator=(const unordered_multimap&);
9673
+ constexpr unordered_multimap& operator=(unordered_multimap&&)
9674
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
9675
+ is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>);
9676
+ constexpr unordered_multimap& operator=(initializer_list<value_type>);
9677
+ constexpr allocator_type get_allocator() const noexcept;
 
9678
 
9679
  // iterators
9680
+ constexpr iterator begin() noexcept;
9681
+ constexpr const_iterator begin() const noexcept;
9682
+ constexpr iterator end() noexcept;
9683
+ constexpr const_iterator end() const noexcept;
9684
+ constexpr const_iterator cbegin() const noexcept;
9685
+ constexpr const_iterator cend() const noexcept;
9686
 
9687
  // capacity
9688
+ constexpr bool empty() const noexcept;
9689
+ constexpr size_type size() const noexcept;
9690
+ constexpr size_type max_size() const noexcept;
9691
 
9692
  // [unord.multimap.modifiers], modifiers
9693
+ template<class... Args> constexpr iterator emplace(Args&&... args);
9694
+ template<class... Args>
9695
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
9696
+ constexpr iterator insert(const value_type& obj);
9697
+ constexpr iterator insert(value_type&& obj);
9698
+ template<class P> constexpr iterator insert(P&& obj);
9699
+ constexpr iterator insert(const_iterator hint, const value_type& obj);
9700
+ constexpr iterator insert(const_iterator hint, value_type&& obj);
9701
+ template<class P> constexpr iterator insert(const_iterator hint, P&& obj);
9702
+ template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last);
9703
  template<container-compatible-range<value_type> R>
9704
+ constexpr void insert_range(R&& rg);
9705
+ constexpr void insert(initializer_list<value_type>);
9706
 
9707
+ constexpr node_type extract(const_iterator position);
9708
+ constexpr node_type extract(const key_type& x);
9709
+ template<class K> constexpr node_type extract(K&& x);
9710
+ constexpr iterator insert(node_type&& nh);
9711
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
9712
 
9713
+ constexpr iterator erase(iterator position);
9714
+ constexpr iterator erase(const_iterator position);
9715
+ constexpr size_type erase(const key_type& k);
9716
+ template<class K> constexpr size_type erase(K&& x);
9717
+ constexpr iterator erase(const_iterator first, const_iterator last);
9718
+ constexpr void swap(unordered_multimap&)
9719
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
9720
+ is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>);
9721
+ constexpr void clear() noexcept;
 
9722
 
9723
  template<class H2, class P2>
9724
+ constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
9725
  template<class H2, class P2>
9726
+ constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
9727
  template<class H2, class P2>
9728
+ constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
9729
  template<class H2, class P2>
9730
+ constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
9731
 
9732
  // observers
9733
+ constexpr hasher hash_function() const;
9734
+ constexpr key_equal key_eq() const;
9735
 
9736
  // map operations
9737
+ constexpr iterator find(const key_type& k);
9738
+ constexpr const_iterator find(const key_type& k) const;
9739
  template<class K>
9740
+ constexpr iterator find(const K& k);
9741
  template<class K>
9742
+ constexpr const_iterator find(const K& k) const;
9743
+ constexpr size_type count(const key_type& k) const;
9744
  template<class K>
9745
+ constexpr size_type count(const K& k) const;
9746
+ constexpr bool contains(const key_type& k) const;
9747
  template<class K>
9748
+ constexpr bool contains(const K& k) const;
9749
+ constexpr pair<iterator, iterator> equal_range(const key_type& k);
9750
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
9751
  template<class K>
9752
+ constexpr pair<iterator, iterator> equal_range(const K& k);
9753
  template<class K>
9754
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const;
9755
 
9756
  // bucket interface
9757
+ constexpr size_type bucket_count() const noexcept;
9758
+ constexpr size_type max_bucket_count() const noexcept;
9759
+ constexpr size_type bucket_size(size_type n) const;
9760
+ constexpr size_type bucket(const key_type& k) const;
9761
+ template<class K> constexpr size_type bucket(const K& k) const;
9762
+ constexpr local_iterator begin(size_type n);
9763
+ constexpr const_local_iterator begin(size_type n) const;
9764
+ constexpr local_iterator end(size_type n);
9765
+ constexpr const_local_iterator end(size_type n) const;
9766
+ constexpr const_local_iterator cbegin(size_type n) const;
9767
+ constexpr const_local_iterator cend(size_type n) const;
9768
 
9769
  // hash policy
9770
+ constexpr float load_factor() const noexcept;
9771
+ constexpr float max_load_factor() const noexcept;
9772
+ constexpr void max_load_factor(float z);
9773
+ constexpr void rehash(size_type n);
9774
+ constexpr void reserve(size_type n);
9775
  };
9776
 
9777
  template<class InputIterator,
9778
  class Hash = hash<iter-key-type<InputIterator>>,
9779
  class Pred = equal_to<iter-key-type<InputIterator>>,
 
9853
  deduction guide.
9854
 
9855
  #### Constructors <a id="unord.multimap.cnstr">[[unord.multimap.cnstr]]</a>
9856
 
9857
  ``` cpp
9858
+ constexpr unordered_multimap() : unordered_multimap(size_type(see below)) { }
9859
+ constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(),
 
9860
  const key_equal& eql = key_equal(),
9861
  const allocator_type& a = allocator_type());
9862
  ```
9863
 
9864
  *Effects:* Constructs an empty `unordered_multimap` using the specified
 
9868
 
9869
  *Complexity:* Constant.
9870
 
9871
  ``` cpp
9872
  template<class InputIterator>
9873
+ constexpr unordered_multimap(InputIterator f, InputIterator l,
9874
+ size_type n = see below, const hasher& hf = hasher(),
 
9875
  const key_equal& eql = key_equal(),
9876
  const allocator_type& a = allocator_type());
9877
  template<container-compatible-range<value_type> R>
9878
+ constexpr unordered_multimap(from_range_t, R&& rg,
9879
+ size_type n = see below, const hasher& hf = hasher(),
 
9880
  const key_equal& eql = key_equal(),
9881
  const allocator_type& a = allocator_type());
9882
+ constexpr unordered_multimap(initializer_list<value_type> il,
9883
+ size_type n = see below, const hasher& hf = hasher(),
 
9884
  const key_equal& eql = key_equal(),
9885
  const allocator_type& a = allocator_type());
9886
  ```
9887
 
9888
  *Effects:* Constructs an empty `unordered_multimap` using the specified
 
9895
 
9896
  #### Modifiers <a id="unord.multimap.modifiers">[[unord.multimap.modifiers]]</a>
9897
 
9898
  ``` cpp
9899
  template<class P>
9900
+ constexpr iterator insert(P&& obj);
9901
  ```
9902
 
9903
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
9904
 
9905
  *Effects:* Equivalent to: `return emplace(std::forward<P>(obj));`
9906
 
9907
  ``` cpp
9908
  template<class P>
9909
+ constexpr iterator insert(const_iterator hint, P&& obj);
9910
  ```
9911
 
9912
  *Constraints:* `is_constructible_v<value_type, P&&>` is `true`.
9913
 
9914
  *Effects:* Equivalent to:
 
9916
 
9917
  #### Erasure <a id="unord.multimap.erasure">[[unord.multimap.erasure]]</a>
9918
 
9919
  ``` cpp
9920
  template<class K, class T, class H, class P, class A, class Predicate>
9921
+ constexpr typename unordered_multimap<K, T, H, P, A>::size_type
9922
  erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
9923
  ```
9924
 
9925
  *Effects:* Equivalent to:
9926
 
 
9934
  }
9935
  }
9936
  return original_size - c.size();
9937
  ```
9938
 
9939
+ ### Header `<unordered_set>` synopsis <a id="unord.set.syn">[[unord.set.syn]]</a>
9940
+
9941
+ ``` cpp
9942
+ #include <compare> // see [compare.syn]
9943
+ #include <initializer_list> // see [initializer.list.syn]
9944
+
9945
+ namespace std {
9946
+ // [unord.set], class template unordered_set
9947
+ template<class Key,
9948
+ class Hash = hash<Key>,
9949
+ class Pred = equal_to<Key>,
9950
+ class Alloc = allocator<Key>>
9951
+ class unordered_set;
9952
+
9953
+ // [unord.multiset], class template unordered_multiset
9954
+ template<class Key,
9955
+ class Hash = hash<Key>,
9956
+ class Pred = equal_to<Key>,
9957
+ class Alloc = allocator<Key>>
9958
+ class unordered_multiset;
9959
+
9960
+ template<class Key, class Hash, class Pred, class Alloc>
9961
+ constexpr bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
9962
+ const unordered_set<Key, Hash, Pred, Alloc>& b);
9963
+
9964
+ template<class Key, class Hash, class Pred, class Alloc>
9965
+ constexpr bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
9966
+ const unordered_multiset<Key, Hash, Pred, Alloc>& b);
9967
+
9968
+ template<class Key, class Hash, class Pred, class Alloc>
9969
+ constexpr void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
9970
+ unordered_set<Key, Hash, Pred, Alloc>& y)
9971
+ noexcept(noexcept(x.swap(y)));
9972
+
9973
+ template<class Key, class Hash, class Pred, class Alloc>
9974
+ constexpr void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
9975
+ unordered_multiset<Key, Hash, Pred, Alloc>& y)
9976
+ noexcept(noexcept(x.swap(y)));
9977
+
9978
+ // [unord.set.erasure], erasure for unordered_set
9979
+ template<class K, class H, class P, class A, class Predicate>
9980
+ constexpr typename unordered_set<K, H, P, A>::size_type
9981
+ erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
9982
+
9983
+ // [unord.multiset.erasure], erasure for unordered_multiset
9984
+ template<class K, class H, class P, class A, class Predicate>
9985
+ constexpr typename unordered_multiset<K, H, P, A>::size_type
9986
+ erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
9987
+
9988
+ namespace pmr {
9989
+ template<class Key,
9990
+ class Hash = hash<Key>,
9991
+ class Pred = equal_to<Key>>
9992
+ using unordered_set = std::unordered_set<Key, Hash, Pred,
9993
+ polymorphic_allocator<Key>>;
9994
+
9995
+ template<class Key,
9996
+ class Hash = hash<Key>,
9997
+ class Pred = equal_to<Key>>
9998
+ using unordered_multiset = std::unordered_multiset<Key, Hash, Pred,
9999
+ polymorphic_allocator<Key>>;
10000
+ }
10001
+ }
10002
+ ```
10003
+
10004
  ### Class template `unordered_set` <a id="unord.set">[[unord.set]]</a>
10005
 
10006
  #### Overview <a id="unord.set.overview">[[unord.set.overview]]</a>
10007
 
10008
  An `unordered_set` is an unordered associative container that supports
 
10010
  and in which the elements’ keys are the elements themselves. The
10011
  `unordered_set` class supports forward iterators.
10012
 
10013
  An `unordered_set` meets all of the requirements of a container
10014
  [[container.reqmts]], of an allocator-aware container
10015
+ [[container.alloc.reqmts]], and of an unordered associative container
10016
  [[unord.req]]. It provides the operations described in the preceding
10017
  requirements table for unique keys; that is, an `unordered_set` supports
10018
  the `a_uniq` operations in that table, not the `a_eq` operations. For an
10019
  `unordered_set<Key>` the `key_type` and the `value_type` are both `Key`.
10020
  The `iterator` and `const_iterator` types are both constant iterator
 
10022
 
10023
  Subclause  [[unord.set]] only describes operations on `unordered_set`
10024
  that are not described in one of the requirement tables, or for which
10025
  there is additional semantic information.
10026
 
10027
+ The types `iterator` and `const_iterator` meet the constexpr iterator
10028
+ requirements [[iterator.requirements.general]].
10029
+
10030
  ``` cpp
10031
  namespace std {
10032
  template<class Key,
10033
  class Hash = hash<Key>,
10034
  class Pred = equal_to<Key>,
 
10039
  using key_type = Key;
10040
  using value_type = Key;
10041
  using hasher = Hash;
10042
  using key_equal = Pred;
10043
  using allocator_type = Allocator;
10044
+ using pointer = allocator_traits<Allocator>::pointer;
10045
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
10046
  using reference = value_type&;
10047
  using const_reference = const value_type&;
10048
  using size_type = implementation-defined // type of unordered_set::size_type; // see [container.requirements]
10049
  using difference_type = implementation-defined // type of unordered_set::difference_type; // see [container.requirements]
10050
 
 
10054
  using const_local_iterator = implementation-defined // type of unordered_set::const_local_iterator; // see [container.requirements]
10055
  using node_type = unspecified;
10056
  using insert_return_type = insert-return-type<iterator, node_type>;
10057
 
10058
  // [unord.set.cnstr], construct/copy/destroy
10059
+ constexpr unordered_set();
10060
+ constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(),
 
10061
  const key_equal& eql = key_equal(),
10062
  const allocator_type& a = allocator_type());
10063
  template<class InputIterator>
10064
+ constexpr unordered_set(InputIterator f, InputIterator l,
10065
+ size_type n = see below, const hasher& hf = hasher(),
 
10066
  const key_equal& eql = key_equal(),
10067
  const allocator_type& a = allocator_type());
10068
  template<container-compatible-range<value_type> R>
10069
+ constexpr unordered_set(from_range_t, R&& rg,
10070
+ size_type n = see below, const hasher& hf = hasher(),
 
10071
  const key_equal& eql = key_equal(),
10072
  const allocator_type& a = allocator_type());
10073
+ constexpr unordered_set(const unordered_set&);
10074
+ constexpr unordered_set(unordered_set&&);
10075
+ constexpr explicit unordered_set(const Allocator&);
10076
+ constexpr unordered_set(const unordered_set&, const type_identity_t<Allocator>&);
10077
+ constexpr unordered_set(unordered_set&&, const type_identity_t<Allocator>&);
10078
+ constexpr unordered_set(initializer_list<value_type> il,
10079
+ size_type n = see below, const hasher& hf = hasher(),
 
10080
  const key_equal& eql = key_equal(),
10081
  const allocator_type& a = allocator_type());
10082
+ constexpr unordered_set(size_type n, const allocator_type& a)
10083
  : unordered_set(n, hasher(), key_equal(), a) { }
10084
+ constexpr unordered_set(size_type n, const hasher& hf, const allocator_type& a)
10085
  : unordered_set(n, hf, key_equal(), a) { }
10086
  template<class InputIterator>
10087
+ constexpr unordered_set(InputIterator f, InputIterator l, size_type n,
10088
+ const allocator_type& a)
10089
  : unordered_set(f, l, n, hasher(), key_equal(), a) { }
10090
  template<class InputIterator>
10091
+ constexpr unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
10092
  const allocator_type& a)
10093
  : unordered_set(f, l, n, hf, key_equal(), a) { }
10094
+ constexpr unordered_set(initializer_list<value_type> il, size_type n,
10095
+ const allocator_type& a)
10096
  : unordered_set(il, n, hasher(), key_equal(), a) { }
10097
  template<container-compatible-range<value_type> R>
10098
+ constexpr unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a)
10099
  : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }
10100
  template<container-compatible-range<value_type> R>
10101
+ constexpr unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf,
10102
+ const allocator_type& a)
10103
  : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
10104
+ constexpr unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
10105
  const allocator_type& a)
10106
  : unordered_set(il, n, hf, key_equal(), a) { }
10107
+ constexpr ~unordered_set();
10108
+ constexpr unordered_set& operator=(const unordered_set&);
10109
+ constexpr unordered_set& operator=(unordered_set&&)
10110
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
10111
+ is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>);
10112
+ constexpr unordered_set& operator=(initializer_list<value_type>);
10113
+ constexpr allocator_type get_allocator() const noexcept;
 
10114
 
10115
  // iterators
10116
+ constexpr iterator begin() noexcept;
10117
+ constexpr const_iterator begin() const noexcept;
10118
+ constexpr iterator end() noexcept;
10119
+ constexpr const_iterator end() const noexcept;
10120
+ constexpr const_iterator cbegin() const noexcept;
10121
+ constexpr const_iterator cend() const noexcept;
10122
 
10123
  // capacity
10124
+ constexpr bool empty() const noexcept;
10125
+ constexpr size_type size() const noexcept;
10126
+ constexpr size_type max_size() const noexcept;
10127
 
10128
+ // [unord.set.modifiers], modifiers
10129
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
10130
+ template<class... Args>
10131
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
10132
+ constexpr pair<iterator, bool> insert(const value_type& obj);
10133
+ constexpr pair<iterator, bool> insert(value_type&& obj);
10134
+ template<class K> constexpr pair<iterator, bool> insert(K&& obj);
10135
+ constexpr iterator insert(const_iterator hint, const value_type& obj);
10136
+ constexpr iterator insert(const_iterator hint, value_type&& obj);
10137
+ template<class K> constexpr iterator insert(const_iterator hint, K&& obj);
10138
+ template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last);
10139
  template<container-compatible-range<value_type> R>
10140
+ constexpr void insert_range(R&& rg);
10141
+ constexpr void insert(initializer_list<value_type>);
10142
 
10143
+ constexpr node_type extract(const_iterator position);
10144
+ constexpr node_type extract(const key_type& x);
10145
+ template<class K> constexpr node_type extract(K&& x);
10146
+ constexpr insert_return_type insert(node_type&& nh);
10147
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
10148
 
10149
+ constexpr iterator erase(iterator position)
10150
  requires (!same_as<iterator, const_iterator>);
10151
+ constexpr iterator erase(const_iterator position);
10152
+ constexpr size_type erase(const key_type& k);
10153
+ template<class K> constexpr size_type erase(K&& x);
10154
+ constexpr iterator erase(const_iterator first, const_iterator last);
10155
+ constexpr void swap(unordered_set&)
10156
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
10157
+ is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>);
10158
+ constexpr void clear() noexcept;
 
10159
 
10160
  template<class H2, class P2>
10161
+ constexpr void merge(unordered_set<Key, H2, P2, Allocator>& source);
10162
  template<class H2, class P2>
10163
+ constexpr void merge(unordered_set<Key, H2, P2, Allocator>&& source);
10164
  template<class H2, class P2>
10165
+ constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
10166
  template<class H2, class P2>
10167
+ constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
10168
 
10169
  // observers
10170
+ constexpr hasher hash_function() const;
10171
+ constexpr key_equal key_eq() const;
10172
 
10173
  // set operations
10174
+ constexpr iterator find(const key_type& k);
10175
+ constexpr const_iterator find(const key_type& k) const;
10176
  template<class K>
10177
+ constexpr iterator find(const K& k);
10178
  template<class K>
10179
+ constexpr const_iterator find(const K& k) const;
10180
+ constexpr size_type count(const key_type& k) const;
10181
  template<class K>
10182
+ constexpr size_type count(const K& k) const;
10183
+ constexpr bool contains(const key_type& k) const;
10184
  template<class K>
10185
+ constexpr bool contains(const K& k) const;
10186
+ constexpr pair<iterator, iterator> equal_range(const key_type& k);
10187
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
10188
  template<class K>
10189
+ constexpr pair<iterator, iterator> equal_range(const K& k);
10190
  template<class K>
10191
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const;
10192
 
10193
  // bucket interface
10194
+ constexpr size_type bucket_count() const noexcept;
10195
+ constexpr size_type max_bucket_count() const noexcept;
10196
+ constexpr size_type bucket_size(size_type n) const;
10197
+ constexpr size_type bucket(const key_type& k) const;
10198
+ template<class K> constexpr size_type bucket(const K& k) const;
10199
+ constexpr local_iterator begin(size_type n);
10200
+ constexpr const_local_iterator begin(size_type n) const;
10201
+ constexpr local_iterator end(size_type n);
10202
+ constexpr const_local_iterator end(size_type n) const;
10203
+ constexpr const_local_iterator cbegin(size_type n) const;
10204
+ constexpr const_local_iterator cend(size_type n) const;
10205
 
10206
  // hash policy
10207
+ constexpr float load_factor() const noexcept;
10208
+ constexpr float max_load_factor() const noexcept;
10209
+ constexpr void max_load_factor(float z);
10210
+ constexpr void rehash(size_type n);
10211
+ constexpr void reserve(size_type n);
10212
  };
10213
 
10214
  template<class InputIterator,
10215
  class Hash = hash<iter-value-type<InputIterator>>,
10216
  class Pred = equal_to<iter-value-type<InputIterator>>,
 
10278
  deduction guide.
10279
 
10280
  #### Constructors <a id="unord.set.cnstr">[[unord.set.cnstr]]</a>
10281
 
10282
  ``` cpp
10283
+ constexpr unordered_set() : unordered_set(size_type(see below)) { }
10284
+ constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(),
 
10285
  const key_equal& eql = key_equal(),
10286
  const allocator_type& a = allocator_type());
10287
  ```
10288
 
10289
  *Effects:* Constructs an empty `unordered_set` using the specified hash
 
10293
 
10294
  *Complexity:* Constant.
10295
 
10296
  ``` cpp
10297
  template<class InputIterator>
10298
+ constexpr unordered_set(InputIterator f, InputIterator l,
10299
+ size_type n = see below, const hasher& hf = hasher(),
 
10300
  const key_equal& eql = key_equal(),
10301
  const allocator_type& a = allocator_type());
10302
  template<container-compatible-range<value_type> R>
10303
+ constexpr unordered_multiset(from_range_t, R&& rg,
10304
+ size_type n = see below, const hasher& hf = hasher(),
 
10305
  const key_equal& eql = key_equal(),
10306
  const allocator_type& a = allocator_type());
10307
+ constexpr unordered_set(initializer_list<value_type> il,
10308
+ size_type n = see below, const hasher& hf = hasher(),
 
10309
  const key_equal& eql = key_equal(),
10310
  const allocator_type& a = allocator_type());
10311
  ```
10312
 
10313
  *Effects:* Constructs an empty `unordered_set` using the specified hash
 
10320
 
10321
  #### Erasure <a id="unord.set.erasure">[[unord.set.erasure]]</a>
10322
 
10323
  ``` cpp
10324
  template<class K, class H, class P, class A, class Predicate>
10325
+ constexpr typename unordered_set<K, H, P, A>::size_type
10326
  erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
10327
  ```
10328
 
10329
  *Effects:* Equivalent to:
10330
 
 
10338
  }
10339
  }
10340
  return original_size - c.size();
10341
  ```
10342
 
10343
+ #### Modifiers <a id="unord.set.modifiers">[[unord.set.modifiers]]</a>
10344
+
10345
+ ``` cpp
10346
+ template<class K> constexpr pair<iterator, bool> insert(K&& obj);
10347
+ template<class K> constexpr iterator insert(const_iterator hint, K&& obj);
10348
+ ```
10349
+
10350
+ *Constraints:* The *qualified-id*s `Hash::is_transparent` and
10351
+ `Pred::is_transparent` are valid and denote types. For the second
10352
+ overload, `is_convertible_v<K&&, const_iterator>` and
10353
+ `is_convertible_v<K&&, iterator>` are both `false`.
10354
+
10355
+ *Preconditions:* `value_type` is *Cpp17EmplaceConstructible* into
10356
+ `unordered_set` from `std::forward<K> (obj)`.
10357
+
10358
+ *Effects:* If the set already contains an element that is equivalent to
10359
+ `obj`, there is no effect. Otherwise, let `h` be `hash_function()(obj)`.
10360
+ Constructs an object `u` of type `value_type` with
10361
+ `std::forward<K>(obj)`. If `hash_function()(u) != h || contains(u)` is
10362
+ `true`, the behavior is undefined. Inserts `u` into `*this`.
10363
+
10364
+ *Returns:* For the first overload, the `bool` component of the returned
10365
+ pair is `true` if and only if the insertion took place. The returned
10366
+ iterator points to the set element that is equivalent to `obj`.
10367
+
10368
+ *Complexity:* Average case constant, worst case linear.
10369
+
10370
  ### Class template `unordered_multiset` <a id="unord.multiset">[[unord.multiset]]</a>
10371
 
10372
  #### Overview <a id="unord.multiset.overview">[[unord.multiset.overview]]</a>
10373
 
10374
  An `unordered_multiset` is an unordered associative container that
 
10390
 
10391
  Subclause  [[unord.multiset]] only describes operations on
10392
  `unordered_multiset` that are not described in one of the requirement
10393
  tables, or for which there is additional semantic information.
10394
 
10395
+ The types `iterator` and `const_iterator` meet the constexpr iterator
10396
+ requirements [[iterator.requirements.general]].
10397
+
10398
  ``` cpp
10399
  namespace std {
10400
  template<class Key,
10401
  class Hash = hash<Key>,
10402
  class Pred = equal_to<Key>,
 
10407
  using key_type = Key;
10408
  using value_type = Key;
10409
  using hasher = Hash;
10410
  using key_equal = Pred;
10411
  using allocator_type = Allocator;
10412
+ using pointer = allocator_traits<Allocator>::pointer;
10413
+ using const_pointer = allocator_traits<Allocator>::const_pointer;
10414
  using reference = value_type&;
10415
  using const_reference = const value_type&;
10416
  using size_type = implementation-defined // type of unordered_multiset::size_type; // see [container.requirements]
10417
  using difference_type = implementation-defined // type of unordered_multiset::difference_type; // see [container.requirements]
10418
 
 
10421
  using local_iterator = implementation-defined // type of unordered_multiset::local_iterator; // see [container.requirements]
10422
  using const_local_iterator = implementation-defined // type of unordered_multiset::const_local_iterator; // see [container.requirements]
10423
  using node_type = unspecified;
10424
 
10425
  // [unord.multiset.cnstr], construct/copy/destroy
10426
+ constexpr unordered_multiset();
10427
+ constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(),
 
10428
  const key_equal& eql = key_equal(),
10429
  const allocator_type& a = allocator_type());
10430
  template<class InputIterator>
10431
+ constexpr unordered_multiset(InputIterator f, InputIterator l,
10432
+ size_type n = see below, const hasher& hf = hasher(),
 
10433
  const key_equal& eql = key_equal(),
10434
  const allocator_type& a = allocator_type());
10435
  template<container-compatible-range<value_type> R>
10436
+ constexpr unordered_multiset(from_range_t, R&& rg,
10437
+ size_type n = see below, const hasher& hf = hasher(),
 
10438
  const key_equal& eql = key_equal(),
10439
  const allocator_type& a = allocator_type());
10440
+ constexpr unordered_multiset(const unordered_multiset&);
10441
+ constexpr unordered_multiset(unordered_multiset&&);
10442
+ constexpr explicit unordered_multiset(const Allocator&);
10443
+ constexpr unordered_multiset(const unordered_multiset&, const type_identity_t<Allocator>&);
10444
+ constexpr unordered_multiset(unordered_multiset&&, const type_identity_t<Allocator>&);
10445
+ constexpr unordered_multiset(initializer_list<value_type> il,
10446
+ size_type n = see below, const hasher& hf = hasher(),
 
10447
  const key_equal& eql = key_equal(),
10448
  const allocator_type& a = allocator_type());
10449
+ constexpr unordered_multiset(size_type n, const allocator_type& a)
10450
  : unordered_multiset(n, hasher(), key_equal(), a) { }
10451
+ constexpr unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
10452
  : unordered_multiset(n, hf, key_equal(), a) { }
10453
  template<class InputIterator>
10454
+ constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n,
10455
+ const allocator_type& a)
10456
  : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
10457
  template<class InputIterator>
10458
+ constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n,
10459
+ const hasher& hf, const allocator_type& a)
10460
  : unordered_multiset(f, l, n, hf, key_equal(), a) { }
10461
  template<container-compatible-range<value_type> R>
10462
+ constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a)
10463
  : unordered_multiset(from_range, std::forward<R>(rg),
10464
  n, hasher(), key_equal(), a) { }
10465
  template<container-compatible-range<value_type> R>
10466
+ constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf,
10467
  const allocator_type& a)
10468
  : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }
10469
+ constexpr unordered_multiset(initializer_list<value_type> il, size_type n,
10470
+ const allocator_type& a)
10471
  : unordered_multiset(il, n, hasher(), key_equal(), a) { }
10472
+ constexpr unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
10473
  const allocator_type& a)
10474
  : unordered_multiset(il, n, hf, key_equal(), a) { }
10475
+ constexpr ~unordered_multiset();
10476
+ constexpr unordered_multiset& operator=(const unordered_multiset&);
10477
+ constexpr unordered_multiset& operator=(unordered_multiset&&)
10478
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
10479
+ is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>);
10480
+ constexpr unordered_multiset& operator=(initializer_list<value_type>);
10481
+ constexpr allocator_type get_allocator() const noexcept;
 
10482
 
10483
  // iterators
10484
+ constexpr iterator begin() noexcept;
10485
+ constexpr const_iterator begin() const noexcept;
10486
+ constexpr iterator end() noexcept;
10487
+ constexpr const_iterator end() const noexcept;
10488
+ constexpr const_iterator cbegin() const noexcept;
10489
+ constexpr const_iterator cend() const noexcept;
10490
 
10491
  // capacity
10492
+ constexpr bool empty() const noexcept;
10493
+ constexpr size_type size() const noexcept;
10494
+ constexpr size_type max_size() const noexcept;
10495
 
10496
  // modifiers
10497
+ template<class... Args> constexpr iterator emplace(Args&&... args);
10498
+ template<class... Args>
10499
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
10500
+ constexpr iterator insert(const value_type& obj);
10501
+ constexpr iterator insert(value_type&& obj);
10502
+ constexpr iterator insert(const_iterator hint, const value_type& obj);
10503
+ constexpr iterator insert(const_iterator hint, value_type&& obj);
10504
+ template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last);
10505
  template<container-compatible-range<value_type> R>
10506
+ constexpr void insert_range(R&& rg);
10507
+ constexpr void insert(initializer_list<value_type>);
10508
 
10509
+ constexpr node_type extract(const_iterator position);
10510
+ constexpr node_type extract(const key_type& x);
10511
+ template<class K> constexpr node_type extract(K&& x);
10512
+ constexpr iterator insert(node_type&& nh);
10513
+ constexpr iterator insert(const_iterator hint, node_type&& nh);
10514
 
10515
+ constexpr iterator erase(iterator position)
10516
  requires (!same_as<iterator, const_iterator>);
10517
+ constexpr iterator erase(const_iterator position);
10518
+ constexpr size_type erase(const key_type& k);
10519
+ template<class K> constexpr size_type erase(K&& x);
10520
+ constexpr iterator erase(const_iterator first, const_iterator last);
10521
+ constexpr void swap(unordered_multiset&)
10522
  noexcept(allocator_traits<Allocator>::is_always_equal::value &&
10523
+ is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>);
10524
+ constexpr void clear() noexcept;
 
10525
 
10526
  template<class H2, class P2>
10527
+ constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
10528
  template<class H2, class P2>
10529
+ constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
10530
  template<class H2, class P2>
10531
+ constexpr void merge(unordered_set<Key, H2, P2, Allocator>& source);
10532
  template<class H2, class P2>
10533
+ constexpr void merge(unordered_set<Key, H2, P2, Allocator>&& source);
10534
 
10535
  // observers
10536
+ constexpr hasher hash_function() const;
10537
+ constexpr key_equal key_eq() const;
10538
 
10539
  // set operations
10540
+ constexpr iterator find(const key_type& k);
10541
+ constexpr const_iterator find(const key_type& k) const;
10542
  template<class K>
10543
+ constexpr iterator find(const K& k);
10544
  template<class K>
10545
+ constexpr const_iterator find(const K& k) const;
10546
+ constexpr size_type count(const key_type& k) const;
10547
  template<class K>
10548
+ constexpr size_type count(const K& k) const;
10549
+ constexpr bool contains(const key_type& k) const;
10550
  template<class K>
10551
+ constexpr bool contains(const K& k) const;
10552
+ constexpr pair<iterator, iterator> equal_range(const key_type& k);
10553
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
10554
  template<class K>
10555
+ constexpr pair<iterator, iterator> equal_range(const K& k);
10556
  template<class K>
10557
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const;
10558
 
10559
  // bucket interface
10560
+ constexpr size_type bucket_count() const noexcept;
10561
+ constexpr size_type max_bucket_count() const noexcept;
10562
+ constexpr size_type bucket_size(size_type n) const;
10563
+ constexpr size_type bucket(const key_type& k) const;
10564
+ template<class K> constexpr size_type bucket(const K& k) const;
10565
+ constexpr local_iterator begin(size_type n);
10566
+ constexpr const_local_iterator begin(size_type n) const;
10567
+ constexpr local_iterator end(size_type n);
10568
+ constexpr const_local_iterator end(size_type n) const;
10569
+ constexpr const_local_iterator cbegin(size_type n) const;
10570
+ constexpr const_local_iterator cend(size_type n) const;
10571
 
10572
  // hash policy
10573
+ constexpr float load_factor() const noexcept;
10574
+ constexpr float max_load_factor() const noexcept;
10575
+ constexpr void max_load_factor(float z);
10576
+ constexpr void rehash(size_type n);
10577
+ constexpr void reserve(size_type n);
10578
  };
10579
 
10580
  template<class InputIterator,
10581
  class Hash = hash<iter-value-type<InputIterator>>,
10582
  class Pred = equal_to<iter-value-type<InputIterator>>,
10583
  class Allocator = allocator<iter-value-type<InputIterator>>>
10584
+ unordered_multiset(InputIterator, InputIterator, typename see below::size_type = see below,
10585
  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
10586
  -> unordered_multiset<iter-value-type<InputIterator>,
10587
  Hash, Pred, Allocator>;
10588
 
10589
  template<ranges::input_range R,
 
10644
  deduction guide.
10645
 
10646
  #### Constructors <a id="unord.multiset.cnstr">[[unord.multiset.cnstr]]</a>
10647
 
10648
  ``` cpp
10649
+ constexpr unordered_multiset() : unordered_multiset(size_type(see below)) { }
10650
+ constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(),
 
10651
  const key_equal& eql = key_equal(),
10652
  const allocator_type& a = allocator_type());
10653
  ```
10654
 
10655
  *Effects:* Constructs an empty `unordered_multiset` using the specified
 
10659
 
10660
  *Complexity:* Constant.
10661
 
10662
  ``` cpp
10663
  template<class InputIterator>
10664
+ constexpr unordered_multiset(InputIterator f, InputIterator l,
10665
+ size_type n = see below, const hasher& hf = hasher(),
 
10666
  const key_equal& eql = key_equal(),
10667
  const allocator_type& a = allocator_type());
10668
  template<container-compatible-range<value_type> R>
10669
+ constexpr unordered_multiset(from_range_t, R&& rg,
10670
+ size_type n = see below, const hasher& hf = hasher(),
 
10671
  const key_equal& eql = key_equal(),
10672
  const allocator_type& a = allocator_type());
10673
+ constexpr unordered_multiset(initializer_list<value_type> il,
10674
+ size_type n = see below, const hasher& hf = hasher(),
 
10675
  const key_equal& eql = key_equal(),
10676
  const allocator_type& a = allocator_type());
10677
  ```
10678
 
10679
  *Effects:* Constructs an empty `unordered_multiset` using the specified
 
10686
 
10687
  #### Erasure <a id="unord.multiset.erasure">[[unord.multiset.erasure]]</a>
10688
 
10689
  ``` cpp
10690
  template<class K, class H, class P, class A, class Predicate>
10691
+ constexpr typename unordered_multiset<K, H, P, A>::size_type
10692
  erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
10693
  ```
10694
 
10695
  *Effects:* Equivalent to:
10696
 
 
10706
  return original_size - c.size();
10707
  ```
10708
 
10709
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
10710
 
10711
+ ### General <a id="container.adaptors.general">[[container.adaptors.general]]</a>
10712
 
10713
  The headers `<queue>`, `<stack>`, `<flat_map>`, and `<flat_set>` define
10714
  the container adaptors `queue` and `priority_queue`, `stack`, `flat_map`
10715
  and `flat_multimap`, and `flat_set` and `flat_multiset`, respectively.
10716
 
 
10781
  The following exposition-only alias template may appear in deduction
10782
  guides for container adaptors:
10783
 
10784
  ``` cpp
10785
  template<class Allocator, class T>
10786
+ using alloc-rebind = allocator_traits<Allocator>::template rebind_alloc<T>; // exposition only
 
10787
  ```
10788
 
10789
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
10790
 
10791
  ``` cpp
 
10795
  namespace std {
10796
  // [queue], class template queue
10797
  template<class T, class Container = deque<T>> class queue;
10798
 
10799
  template<class T, class Container>
10800
+ constexpr bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
10801
  template<class T, class Container>
10802
+ constexpr bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
10803
  template<class T, class Container>
10804
+ constexpr bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
10805
  template<class T, class Container>
10806
+ constexpr bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
10807
  template<class T, class Container>
10808
+ constexpr bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
10809
  template<class T, class Container>
10810
+ constexpr bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
10811
  template<class T, three_way_comparable Container>
10812
+ constexpr compare_three_way_result_t<Container>
10813
  operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
10814
 
10815
  template<class T, class Container>
10816
+ constexpr void swap(queue<T, Container>& x, queue<T, Container>& y)
10817
+ noexcept(noexcept(x.swap(y)));
10818
  template<class T, class Container, class Alloc>
10819
  struct uses_allocator<queue<T, Container>, Alloc>;
10820
 
10821
+ // [container.adaptors.format], formatter specialization for queue
10822
+ template<class charT, class T, formattable<charT> Container>
10823
+ struct formatter<queue<T, Container>, charT>;
10824
+
10825
  // [priority.queue], class template priority_queue
10826
  template<class T, class Container = vector<T>,
10827
  class Compare = less<typename Container::value_type>>
10828
  class priority_queue;
10829
 
10830
  template<class T, class Container, class Compare>
10831
+ constexpr void swap(priority_queue<T, Container, Compare>& x,
10832
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
10833
  template<class T, class Container, class Compare, class Alloc>
10834
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>;
 
 
10835
 
10836
+ // [container.adaptors.format], formatter specialization for priority_queue
10837
+ template<class charT, class T, formattable<charT> Container, class Compare>
10838
+ struct formatter<priority_queue<T, Container, Compare>, charT>;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10839
  }
10840
  ```
10841
 
10842
  ### Class template `queue` <a id="queue">[[queue]]</a>
10843
 
 
10850
  ``` cpp
10851
  namespace std {
10852
  template<class T, class Container = deque<T>>
10853
  class queue {
10854
  public:
10855
+ using value_type = Container::value_type;
10856
+ using reference = Container::reference;
10857
+ using const_reference = Container::const_reference;
10858
+ using size_type = Container::size_type;
10859
  using container_type = Container;
10860
 
10861
  protected:
10862
  Container c;
10863
 
10864
  public:
10865
+ constexpr queue() : queue(Container()) {}
10866
+ constexpr explicit queue(const Container&);
10867
+ constexpr explicit queue(Container&&);
10868
+ template<class InputIterator> constexpr queue(InputIterator first, InputIterator last);
10869
+ template<container-compatible-range<T> R> constexpr queue(from_range_t, R&& rg);
10870
+ template<class Alloc> constexpr explicit queue(const Alloc&);
10871
+ template<class Alloc> constexpr queue(const Container&, const Alloc&);
10872
+ template<class Alloc> constexpr queue(Container&&, const Alloc&);
10873
+ template<class Alloc> constexpr queue(const queue&, const Alloc&);
10874
+ template<class Alloc> constexpr queue(queue&&, const Alloc&);
10875
  template<class InputIterator, class Alloc>
10876
+ constexpr queue(InputIterator first, InputIterator last, const Alloc&);
10877
  template<container-compatible-range<T> R, class Alloc>
10878
+ constexpr queue(from_range_t, R&& rg, const Alloc&);
10879
 
10880
+ constexpr bool empty() const { return c.empty(); }
10881
+ constexpr size_type size() const { return c.size(); }
10882
+ constexpr reference front() { return c.front(); }
10883
+ constexpr const_reference front() const { return c.front(); }
10884
+ constexpr reference back() { return c.back(); }
10885
+ constexpr const_reference back() const { return c.back(); }
10886
+ constexpr void push(const value_type& x) { c.push_back(x); }
10887
+ constexpr void push(value_type&& x) { c.push_back(std::move(x)); }
10888
+ template<container-compatible-range<T> R> constexpr void push_range(R&& rg);
10889
  template<class... Args>
10890
+ constexpr decltype(auto) emplace(Args&&... args)
10891
  { return c.emplace_back(std::forward<Args>(args)...); }
10892
+ constexpr void pop() { c.pop_front(); }
10893
+ constexpr void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
10894
  { using std::swap; swap(c, q.c); }
10895
  };
10896
 
10897
  template<class Container>
10898
  queue(Container) -> queue<typename Container::value_type, Container>;
 
10922
  ```
10923
 
10924
  #### Constructors <a id="queue.cons">[[queue.cons]]</a>
10925
 
10926
  ``` cpp
10927
+ constexpr explicit queue(const Container& cont);
10928
  ```
10929
 
10930
  *Effects:* Initializes `c` with `cont`.
10931
 
10932
  ``` cpp
10933
+ constexpr explicit queue(Container&& cont);
10934
  ```
10935
 
10936
  *Effects:* Initializes `c` with `std::move(cont)`.
10937
 
10938
  ``` cpp
10939
  template<class InputIterator>
10940
+ constexpr queue(InputIterator first, InputIterator last);
10941
  ```
10942
 
10943
  *Effects:* Initializes `c` with `first` as the first argument and `last`
10944
  as the second argument.
10945
 
10946
  ``` cpp
10947
  template<container-compatible-range<T> R>
10948
+ constexpr queue(from_range_t, R&& rg);
10949
  ```
10950
 
10951
  *Effects:* Initializes `c` with
10952
  `ranges::to<Container>(std::forward<R>(rg))`.
10953
 
 
10955
 
10956
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
10957
  in this subclause shall not participate in overload resolution.
10958
 
10959
  ``` cpp
10960
+ template<class Alloc> constexpr explicit queue(const Alloc& a);
10961
  ```
10962
 
10963
  *Effects:* Initializes `c` with `a`.
10964
 
10965
  ``` cpp
10966
+ template<class Alloc> constexpr queue(const container_type& cont, const Alloc& a);
10967
  ```
10968
 
10969
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
10970
  the second argument.
10971
 
10972
  ``` cpp
10973
+ template<class Alloc> constexpr queue(container_type&& cont, const Alloc& a);
10974
  ```
10975
 
10976
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
10977
  and `a` as the second argument.
10978
 
10979
  ``` cpp
10980
+ template<class Alloc> constexpr queue(const queue& q, const Alloc& a);
10981
  ```
10982
 
10983
  *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
10984
  the second argument.
10985
 
10986
  ``` cpp
10987
+ template<class Alloc> constexpr queue(queue&& q, const Alloc& a);
10988
  ```
10989
 
10990
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
10991
  and `a` as the second argument.
10992
 
10993
  ``` cpp
10994
  template<class InputIterator, class Alloc>
10995
+ constexpr queue(InputIterator first, InputIterator last, const Alloc& alloc);
10996
  ```
10997
 
10998
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
10999
  the second argument, and `alloc` as the third argument.
11000
 
11001
  ``` cpp
11002
  template<container-compatible-range<T> R, class Alloc>
11003
+ constexpr queue(from_range_t, R&& rg, const Alloc& a);
11004
  ```
11005
 
11006
  *Effects:* Initializes `c` with
11007
  `ranges::to<Container>(std::forward<R>(rg), a)`.
11008
 
11009
  #### Modifiers <a id="queue.mod">[[queue.mod]]</a>
11010
 
11011
  ``` cpp
11012
  template<container-compatible-range<T> R>
11013
+ constexpr void push_range(R&& rg);
11014
  ```
11015
 
11016
  *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
11017
  is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
11018
 
11019
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
11020
 
11021
  ``` cpp
11022
  template<class T, class Container>
11023
+ constexpr bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
11024
  ```
11025
 
11026
  *Returns:* `x.c == y.c`.
11027
 
11028
  ``` cpp
11029
  template<class T, class Container>
11030
+ constexpr bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
11031
  ```
11032
 
11033
  *Returns:* `x.c != y.c`.
11034
 
11035
  ``` cpp
11036
  template<class T, class Container>
11037
+ constexpr bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
11038
  ```
11039
 
11040
  *Returns:* `x.c < y.c`.
11041
 
11042
  ``` cpp
11043
  template<class T, class Container>
11044
+ constexpr bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
11045
  ```
11046
 
11047
  *Returns:* `x.c > y.c`.
11048
 
11049
  ``` cpp
11050
  template<class T, class Container>
11051
+ constexpr bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
11052
  ```
11053
 
11054
  *Returns:* `x.c <= y.c`.
11055
 
11056
  ``` cpp
11057
  template<class T, class Container>
11058
+ constexpr bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
 
11059
  ```
11060
 
11061
  *Returns:* `x.c >= y.c`.
11062
 
11063
  ``` cpp
11064
  template<class T, three_way_comparable Container>
11065
+ constexpr compare_three_way_result_t<Container>
11066
  operator<=>(const queue<T, Container>& x, const queue<T, Container>& y);
11067
  ```
11068
 
11069
  *Returns:* `x.c <=> y.c`.
11070
 
11071
  #### Specialized algorithms <a id="queue.special">[[queue.special]]</a>
11072
 
11073
  ``` cpp
11074
  template<class T, class Container>
11075
+ constexpr void swap(queue<T, Container>& x, queue<T, Container>& y)
11076
+ noexcept(noexcept(x.swap(y)));
11077
  ```
11078
 
11079
  *Constraints:* `is_swappable_v<Container>` is `true`.
11080
 
11081
  *Effects:* As if by `x.swap(y)`.
 
11096
  namespace std {
11097
  template<class T, class Container = vector<T>,
11098
  class Compare = less<typename Container::value_type>>
11099
  class priority_queue {
11100
  public:
11101
+ using value_type = Container::value_type;
11102
+ using reference = Container::reference;
11103
+ using const_reference = Container::const_reference;
11104
+ using size_type = Container::size_type;
11105
  using container_type = Container;
11106
  using value_compare = Compare;
11107
 
11108
  protected:
11109
  Container c;
11110
  Compare comp;
11111
 
11112
  public:
11113
+ constexpr priority_queue() : priority_queue(Compare()) {}
11114
+ constexpr explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
11115
+ constexpr priority_queue(const Compare& x, const Container&);
11116
+ constexpr priority_queue(const Compare& x, Container&&);
11117
  template<class InputIterator>
11118
+ constexpr priority_queue(InputIterator first, InputIterator last,
11119
+ const Compare& x = Compare());
11120
  template<class InputIterator>
11121
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x,
11122
  const Container&);
11123
  template<class InputIterator>
11124
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x,
11125
  Container&&);
11126
  template<container-compatible-range<T> R>
11127
+ constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
11128
+ template<class Alloc> constexpr explicit priority_queue(const Alloc&);
11129
+ template<class Alloc> constexpr priority_queue(const Compare&, const Alloc&);
11130
+ template<class Alloc>
11131
+ constexpr priority_queue(const Compare&, const Container&, const Alloc&);
11132
+ template<class Alloc> constexpr priority_queue(const Compare&, Container&&, const Alloc&);
11133
+ template<class Alloc> constexpr priority_queue(const priority_queue&, const Alloc&);
11134
+ template<class Alloc> constexpr priority_queue(priority_queue&&, const Alloc&);
11135
  template<class InputIterator, class Alloc>
11136
+ constexpr priority_queue(InputIterator, InputIterator, const Alloc&);
11137
  template<class InputIterator, class Alloc>
11138
+ constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&);
11139
  template<class InputIterator, class Alloc>
11140
+ constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Container&,
11141
  const Alloc&);
11142
  template<class InputIterator, class Alloc>
11143
+ constexpr priority_queue(InputIterator, InputIterator, const Compare&, Container&&,
11144
+ const Alloc&);
11145
  template<container-compatible-range<T> R, class Alloc>
11146
+ constexpr priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&);
11147
  template<container-compatible-range<T> R, class Alloc>
11148
+ constexpr priority_queue(from_range_t, R&& rg, const Alloc&);
11149
 
11150
+ constexpr bool empty() const { return c.empty(); }
11151
+ constexpr size_type size() const { return c.size(); }
11152
+ constexpr const_reference top() const { return c.front(); }
11153
+ constexpr void push(const value_type& x);
11154
+ constexpr void push(value_type&& x);
11155
  template<container-compatible-range<T> R>
11156
+ constexpr void push_range(R&& rg);
11157
+ template<class... Args> constexpr void emplace(Args&&... args);
11158
+ constexpr void pop();
11159
+ constexpr void swap(priority_queue& q)
11160
+ noexcept(is_nothrow_swappable_v<Container> && is_nothrow_swappable_v<Compare>)
11161
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
11162
  };
11163
 
11164
  template<class Compare, class Container>
11165
  priority_queue(Compare, Container)
 
11212
  ```
11213
 
11214
  #### Constructors <a id="priqueue.cons">[[priqueue.cons]]</a>
11215
 
11216
  ``` cpp
11217
+ constexpr priority_queue(const Compare& x, const Container& y);
11218
+ constexpr priority_queue(const Compare& x, Container&& y);
11219
  ```
11220
 
11221
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
11222
 
11223
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
11224
  constructing or move constructing as appropriate); calls
11225
  `make_heap(c.begin(), c.end(), comp)`.
11226
 
11227
  ``` cpp
11228
  template<class InputIterator>
11229
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
11230
  ```
11231
 
11232
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
11233
 
11234
  *Effects:* Initializes `c` with `first` as the first argument and `last`
11235
  as the second argument, and initializes `comp` with `x`; then calls
11236
  `make_heap(c.begin(), c.end(), comp)`.
11237
 
11238
  ``` cpp
11239
  template<class InputIterator>
11240
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x,
11241
+ const Container& y);
11242
  template<class InputIterator>
11243
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x,
11244
+ Container&& y);
11245
  ```
11246
 
11247
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
11248
 
11249
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
 
11251
  `c.insert(c.end(), first, last)`; and finally calls
11252
  `make_heap(c.begin(), c.end(), comp)`.
11253
 
11254
  ``` cpp
11255
  template<container-compatible-range<T> R>
11256
+ constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
11257
  ```
11258
 
11259
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
11260
 
11261
  *Effects:* Initializes `comp` with `x` and `c` with
 
11266
 
11267
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
11268
  in this subclause shall not participate in overload resolution.
11269
 
11270
  ``` cpp
11271
+ template<class Alloc> constexpr explicit priority_queue(const Alloc& a);
11272
  ```
11273
 
11274
  *Effects:* Initializes `c` with `a` and value-initializes `comp`.
11275
 
11276
  ``` cpp
11277
+ template<class Alloc> constexpr priority_queue(const Compare& compare, const Alloc& a);
11278
  ```
11279
 
11280
  *Effects:* Initializes `c` with `a` and initializes `comp` with
11281
  `compare`.
11282
 
11283
  ``` cpp
11284
  template<class Alloc>
11285
+ constexpr priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
11286
  ```
11287
 
11288
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
11289
  the second argument, and initializes `comp` with `compare`; calls
11290
  `make_heap(c.begin(), c.end(), comp)`.
11291
 
11292
  ``` cpp
11293
  template<class Alloc>
11294
+ constexpr priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
11295
  ```
11296
 
11297
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
11298
  and `a` as the second argument, and initializes `comp` with `compare`;
11299
  calls `make_heap(c.begin(), c.end(), comp)`.
11300
 
11301
  ``` cpp
11302
+ template<class Alloc> constexpr priority_queue(const priority_queue& q, const Alloc& a);
11303
  ```
11304
 
11305
  *Effects:* Initializes `c` with `q.c` as the first argument and `a` as
11306
  the second argument, and initializes `comp` with `q.comp`.
11307
 
11308
  ``` cpp
11309
+ template<class Alloc> constexpr priority_queue(priority_queue&& q, const Alloc& a);
11310
  ```
11311
 
11312
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
11313
  and `a` as the second argument, and initializes `comp` with
11314
  `std::move(q.comp)`.
11315
 
11316
  ``` cpp
11317
  template<class InputIterator, class Alloc>
11318
+ constexpr priority_queue(InputIterator first, InputIterator last, const Alloc& a);
11319
  ```
11320
 
11321
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
11322
  the second argument, and `a` as the third argument, and
11323
  value-initializes `comp`; calls `make_heap(c.begin(), c.end(), comp)`.
11324
 
11325
  ``` cpp
11326
  template<class InputIterator, class Alloc>
11327
+ constexpr priority_queue(InputIterator first, InputIterator last,
11328
+ const Compare& compare, const Alloc& a);
11329
  ```
11330
 
11331
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
11332
  the second argument, and `a` as the third argument, and initializes
11333
  `comp` with `compare`; calls `make_heap(c.begin(), c.end(), comp)`.
11334
 
11335
  ``` cpp
11336
  template<class InputIterator, class Alloc>
11337
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare,
11338
  const Container& cont, const Alloc& a);
11339
  ```
11340
 
11341
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
11342
  the second argument, and initializes `comp` with `compare`; calls
11343
  `c.insert(c.end(), first, last)`; and finally calls
11344
  `make_heap(c.begin(), c.end(), comp)`.
11345
 
11346
  ``` cpp
11347
  template<class InputIterator, class Alloc>
11348
+ constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare,
11349
+ Container&& cont, const Alloc& a);
11350
  ```
11351
 
11352
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
11353
  and `a` as the second argument, and initializes `comp` with `compare`;
11354
  calls `c.insert(c.end(), first, last)`; and finally calls
11355
  `make_heap(c.begin(), c.end(), comp)`.
11356
 
11357
  ``` cpp
11358
  template<container-compatible-range<T> R, class Alloc>
11359
+ constexpr priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a);
11360
  ```
11361
 
11362
  *Effects:* Initializes `comp` with `compare` and `c` with
11363
  `ranges::to<Container>(std::forward<R>(rg), a)`; calls
11364
  `make_heap(c.begin(), c.end(), comp)`.
11365
 
11366
  ``` cpp
11367
  template<container-compatible-range<T> R, class Alloc>
11368
+ constexpr priority_queue(from_range_t, R&& rg, const Alloc& a);
11369
  ```
11370
 
11371
  *Effects:* Initializes `c` with
11372
+ `ranges::to<Container>(std::forward<R>(rg), a)` and value-initializes
11373
+ `comp`; calls `make_heap(c.begin(), c.end(), comp)`.
11374
 
11375
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
11376
 
11377
  ``` cpp
11378
+ constexpr void push(const value_type& x);
11379
  ```
11380
 
11381
  *Effects:* As if by:
11382
 
11383
  ``` cpp
11384
  c.push_back(x);
11385
  push_heap(c.begin(), c.end(), comp);
11386
  ```
11387
 
11388
  ``` cpp
11389
+ constexpr void push(value_type&& x);
11390
  ```
11391
 
11392
  *Effects:* As if by:
11393
 
11394
  ``` cpp
 
11396
  push_heap(c.begin(), c.end(), comp);
11397
  ```
11398
 
11399
  ``` cpp
11400
  template<container-compatible-range<T> R>
11401
+ constexpr void push_range(R&& rg);
11402
  ```
11403
 
11404
  *Effects:* Inserts all elements of `rg` in `c` via
11405
  `c.append_range(std::forward<R>(rg))` if that is a valid expression, or
11406
  `ranges::copy(rg, back_inserter(c))` otherwise. Then restores the heap
11407
  property as if by `make_heap(c.begin(), c.end(), comp)`.
11408
 
11409
  *Ensures:* `is_heap(c.begin(), c.end(), comp)` is `true`.
11410
 
11411
  ``` cpp
11412
+ template<class... Args> constexpr void emplace(Args&&... args);
11413
  ```
11414
 
11415
  *Effects:* As if by:
11416
 
11417
  ``` cpp
11418
  c.emplace_back(std::forward<Args>(args)...);
11419
  push_heap(c.begin(), c.end(), comp);
11420
  ```
11421
 
11422
  ``` cpp
11423
+ constexpr void pop();
11424
  ```
11425
 
11426
  *Effects:* As if by:
11427
 
11428
  ``` cpp
 
11432
 
11433
  #### Specialized algorithms <a id="priqueue.special">[[priqueue.special]]</a>
11434
 
11435
  ``` cpp
11436
  template<class T, class Container, class Compare>
11437
+ constexpr void swap(priority_queue<T, Container, Compare>& x,
11438
  priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
11439
  ```
11440
 
11441
  *Constraints:* `is_swappable_v<Container>` is `true` and
11442
  `is_swappable_v<Compare>` is `true`.
11443
 
11444
  *Effects:* As if by `x.swap(y)`.
11445
 
11446
+ ### Header `<stack>` synopsis <a id="stack.syn">[[stack.syn]]</a>
11447
+
11448
+ ``` cpp
11449
+ #include <compare> // see [compare.syn]
11450
+ #include <initializer_list> // see [initializer.list.syn]
11451
+
11452
+ namespace std {
11453
+ // [stack], class template stack
11454
+ template<class T, class Container = deque<T>> class stack;
11455
+
11456
+ template<class T, class Container>
11457
+ constexpr bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
11458
+ template<class T, class Container>
11459
+ constexpr bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
11460
+ template<class T, class Container>
11461
+ constexpr bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
11462
+ template<class T, class Container>
11463
+ constexpr bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
11464
+ template<class T, class Container>
11465
+ constexpr bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
11466
+ template<class T, class Container>
11467
+ constexpr bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
11468
+ template<class T, three_way_comparable Container>
11469
+ constexpr compare_three_way_result_t<Container>
11470
+ operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
11471
+
11472
+ template<class T, class Container>
11473
+ constexpr void swap(stack<T, Container>& x, stack<T, Container>& y)
11474
+ noexcept(noexcept(x.swap(y)));
11475
+ template<class T, class Container, class Alloc>
11476
+ struct uses_allocator<stack<T, Container>, Alloc>;
11477
+
11478
+ // [container.adaptors.format], formatter specialization for stack
11479
+ template<class charT, class T, formattable<charT> Container>
11480
+ struct formatter<stack<T, Container>, charT>;
11481
+ }
11482
+ ```
11483
+
11484
  ### Class template `stack` <a id="stack">[[stack]]</a>
11485
 
11486
  #### General <a id="stack.general">[[stack.general]]</a>
11487
 
11488
  Any sequence container supporting operations `back()`, `push_back()` and
 
11494
  ``` cpp
11495
  namespace std {
11496
  template<class T, class Container = deque<T>>
11497
  class stack {
11498
  public:
11499
+ using value_type = Container::value_type;
11500
+ using reference = Container::reference;
11501
+ using const_reference = Container::const_reference;
11502
+ using size_type = Container::size_type;
11503
  using container_type = Container;
11504
 
11505
  protected:
11506
  Container c;
11507
 
11508
  public:
11509
+ constexpr stack() : stack(Container()) {}
11510
+ constexpr explicit stack(const Container&);
11511
+ constexpr explicit stack(Container&&);
11512
+ template<class InputIterator> constexpr stack(InputIterator first, InputIterator last);
11513
+ template<container-compatible-range<T> R>
11514
+ constexpr stack(from_range_t, R&& rg);
11515
+ template<class Alloc> constexpr explicit stack(const Alloc&);
11516
+ template<class Alloc> constexpr stack(const Container&, const Alloc&);
11517
+ template<class Alloc> constexpr stack(Container&&, const Alloc&);
11518
+ template<class Alloc> constexpr stack(const stack&, const Alloc&);
11519
+ template<class Alloc> constexpr stack(stack&&, const Alloc&);
11520
  template<class InputIterator, class Alloc>
11521
+ constexpr stack(InputIterator first, InputIterator last, const Alloc&);
11522
  template<container-compatible-range<T> R, class Alloc>
11523
+ constexpr stack(from_range_t, R&& rg, const Alloc&);
11524
 
11525
+ constexpr bool empty() const { return c.empty(); }
11526
+ constexpr size_type size() const { return c.size(); }
11527
+ constexpr reference top() { return c.back(); }
11528
+ constexpr const_reference top() const { return c.back(); }
11529
+ constexpr void push(const value_type& x) { c.push_back(x); }
11530
+ constexpr void push(value_type&& x) { c.push_back(std::move(x)); }
11531
  template<container-compatible-range<T> R>
11532
+ constexpr void push_range(R&& rg);
11533
  template<class... Args>
11534
+ constexpr decltype(auto) emplace(Args&&... args)
11535
  { return c.emplace_back(std::forward<Args>(args)...); }
11536
+ constexpr void pop() { c.pop_back(); }
11537
+ constexpr void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
11538
  { using std::swap; swap(c, s.c); }
11539
  };
11540
 
11541
  template<class Container>
11542
  stack(Container) -> stack<typename Container::value_type, Container>;
 
11566
  ```
11567
 
11568
  #### Constructors <a id="stack.cons">[[stack.cons]]</a>
11569
 
11570
  ``` cpp
11571
+ constexpr explicit stack(const Container& cont);
11572
  ```
11573
 
11574
  *Effects:* Initializes `c` with `cont`.
11575
 
11576
  ``` cpp
11577
+ constexpr explicit stack(Container&& cont);
11578
  ```
11579
 
11580
  *Effects:* Initializes `c` with `std::move(cont)`.
11581
 
11582
  ``` cpp
11583
  template<class InputIterator>
11584
+ constexpr stack(InputIterator first, InputIterator last);
11585
  ```
11586
 
11587
  *Effects:* Initializes `c` with `first` as the first argument and `last`
11588
  as the second argument.
11589
 
11590
  ``` cpp
11591
  template<container-compatible-range<T> R>
11592
+ constexpr stack(from_range_t, R&& rg);
11593
  ```
11594
 
11595
  *Effects:* Initializes `c` with
11596
  `ranges::to<Container>(std::forward<R>(rg))`.
11597
 
 
11599
 
11600
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
11601
  in this subclause shall not participate in overload resolution.
11602
 
11603
  ``` cpp
11604
+ template<class Alloc> constexpr explicit stack(const Alloc& a);
11605
  ```
11606
 
11607
  *Effects:* Initializes `c` with `a`.
11608
 
11609
  ``` cpp
11610
+ template<class Alloc> constexpr stack(const container_type& cont, const Alloc& a);
11611
  ```
11612
 
11613
  *Effects:* Initializes `c` with `cont` as the first argument and `a` as
11614
  the second argument.
11615
 
11616
  ``` cpp
11617
+ template<class Alloc> constexpr stack(container_type&& cont, const Alloc& a);
11618
  ```
11619
 
11620
  *Effects:* Initializes `c` with `std::move(cont)` as the first argument
11621
  and `a` as the second argument.
11622
 
11623
  ``` cpp
11624
+ template<class Alloc> constexpr stack(const stack& s, const Alloc& a);
11625
  ```
11626
 
11627
  *Effects:* Initializes `c` with `s.c` as the first argument and `a` as
11628
  the second argument.
11629
 
11630
  ``` cpp
11631
+ template<class Alloc> constexpr stack(stack&& s, const Alloc& a);
11632
  ```
11633
 
11634
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
11635
  and `a` as the second argument.
11636
 
11637
  ``` cpp
11638
  template<class InputIterator, class Alloc>
11639
+ constexpr stack(InputIterator first, InputIterator last, const Alloc& alloc);
11640
  ```
11641
 
11642
  *Effects:* Initializes `c` with `first` as the first argument, `last` as
11643
  the second argument, and `alloc` as the third argument.
11644
 
11645
  ``` cpp
11646
  template<container-compatible-range<T> R, class Alloc>
11647
+ constexpr stack(from_range_t, R&& rg, const Alloc& a);
11648
  ```
11649
 
11650
  *Effects:* Initializes `c` with
11651
  `ranges::to<Container>(std::forward<R>(rg), a)`.
11652
 
11653
  #### Modifiers <a id="stack.mod">[[stack.mod]]</a>
11654
 
11655
  ``` cpp
11656
  template<container-compatible-range<T> R>
11657
+ constexpr void push_range(R&& rg);
11658
  ```
11659
 
11660
  *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
11661
  is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
11662
 
11663
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
11664
 
11665
  ``` cpp
11666
  template<class T, class Container>
11667
+ constexpr bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
11668
  ```
11669
 
11670
  *Returns:* `x.c == y.c`.
11671
 
11672
  ``` cpp
11673
  template<class T, class Container>
11674
+ constexpr bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
11675
  ```
11676
 
11677
  *Returns:* `x.c != y.c`.
11678
 
11679
  ``` cpp
11680
  template<class T, class Container>
11681
+ constexpr bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
11682
  ```
11683
 
11684
  *Returns:* `x.c < y.c`.
11685
 
11686
  ``` cpp
11687
  template<class T, class Container>
11688
+ constexpr bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
11689
  ```
11690
 
11691
  *Returns:* `x.c > y.c`.
11692
 
11693
  ``` cpp
11694
  template<class T, class Container>
11695
+ constexpr bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
11696
  ```
11697
 
11698
  *Returns:* `x.c <= y.c`.
11699
 
11700
  ``` cpp
11701
  template<class T, class Container>
11702
+ constexpr bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
11703
  ```
11704
 
11705
  *Returns:* `x.c >= y.c`.
11706
 
11707
  ``` cpp
11708
  template<class T, three_way_comparable Container>
11709
+ constexpr compare_three_way_result_t<Container>
11710
  operator<=>(const stack<T, Container>& x, const stack<T, Container>& y);
11711
  ```
11712
 
11713
  *Returns:* `x.c <=> y.c`.
11714
 
11715
  #### Specialized algorithms <a id="stack.special">[[stack.special]]</a>
11716
 
11717
  ``` cpp
11718
  template<class T, class Container>
11719
+ constexpr void swap(stack<T, Container>& x, stack<T, Container>& y)
11720
+ noexcept(noexcept(x.swap(y)));
11721
  ```
11722
 
11723
  *Constraints:* `is_swappable_v<Container>` is `true`.
11724
 
11725
  *Effects:* As if by `x.swap(y)`.
11726
 
11727
+ ### Header `<flat_map>` synopsis <a id="flat.map.syn">[[flat.map.syn]]</a>
11728
+
11729
+ ``` cpp
11730
+ #include <compare> // see [compare.syn]
11731
+ #include <initializer_list> // see [initializer.list.syn]
11732
+
11733
+ namespace std {
11734
+ // [flat.map], class template flat_map
11735
+ template<class Key, class T, class Compare = less<Key>,
11736
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
11737
+ class flat_map;
11738
+
11739
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
11740
+ inline constexpr sorted_unique_t sorted_unique{};
11741
+
11742
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11743
+ class Allocator>
11744
+ struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
11745
+ Allocator>;
11746
+
11747
+ // [flat.map.erasure], erasure for flat_map
11748
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11749
+ class Predicate>
11750
+ constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11751
+ erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11752
+
11753
+ // [flat.multimap], class template flat_multimap
11754
+ template<class Key, class T, class Compare = less<Key>,
11755
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
11756
+ class flat_multimap;
11757
+
11758
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
11759
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
11760
+
11761
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11762
+ class Allocator>
11763
+ struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
11764
+ Allocator>;
11765
+
11766
+ // [flat.multimap.erasure], erasure for flat_multimap
11767
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
11768
+ class Predicate>
11769
+ constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
11770
+ erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
11771
+ }
11772
+ ```
11773
+
11774
  ### Class template `flat_map` <a id="flat.map">[[flat.map]]</a>
11775
 
11776
  #### Overview <a id="flat.map.overview">[[flat.map.overview]]</a>
11777
 
11778
  A `flat_map` is a container adaptor that provides an associative
 
11837
 
11838
  The effect of calling a constructor that takes both `key_container_type`
11839
  and `mapped_container_type` arguments with containers of different sizes
11840
  is undefined.
11841
 
11842
+ The effect of calling a member function that takes a `sorted_unique_t`
11843
+ argument with a container, containers, or range that is not sorted with
11844
+ respect to `key_comp()`, or that contains equal elements, is undefined.
11845
+
11846
+ The types `iterator` and `const_iterator` meet the constexpr iterator
11847
+ requirements [[iterator.requirements.general]].
11848
 
11849
  #### Definition <a id="flat.map.defn">[[flat.map.defn]]</a>
11850
 
11851
  ``` cpp
11852
  namespace std {
 
11871
  using mapped_container_type = MappedContainer;
11872
 
11873
  class value_compare {
11874
  private:
11875
  key_compare comp; // exposition only
11876
+ constexpr value_compare(key_compare c) : comp(c) { } // exposition only
11877
 
11878
  public:
11879
+ constexpr bool operator()(const_reference x, const_reference y) const {
11880
  return comp(x.first, y.first);
11881
  }
11882
  };
11883
 
11884
  struct containers {
11885
  key_container_type keys;
11886
  mapped_container_type values;
11887
  };
11888
 
11889
+ // [flat.map.cons], constructors
11890
+ constexpr flat_map() : flat_map(key_compare()) { }
11891
 
11892
+ constexpr explicit flat_map(const key_compare& comp)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11893
  : c(), compare(comp) { }
11894
+
11895
+ constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
11896
+ const key_compare& comp = key_compare());
11897
+
11898
+ constexpr flat_map(sorted_unique_t, key_container_type key_cont,
11899
+ mapped_container_type mapped_cont,
11900
+ const key_compare& comp = key_compare());
11901
 
11902
  template<class InputIterator>
11903
+ constexpr flat_map(InputIterator first, InputIterator last,
11904
+ const key_compare& comp = key_compare())
11905
  : c(), compare(comp) { insert(first, last); }
11906
+
11907
+ template<class InputIterator>
11908
+ constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
11909
+ const key_compare& comp = key_compare())
11910
+ : c(), compare(comp) { insert(sorted_unique, first, last); }
11911
 
11912
  template<container-compatible-range<value_type> R>
11913
+ constexpr flat_map(from_range_t, R&& rg)
11914
+ : flat_map(from_range, std::forward<R>(rg), key_compare()) { }
 
 
11915
  template<container-compatible-range<value_type> R>
11916
+ constexpr flat_map(from_range_t, R&& rg, const key_compare& comp)
11917
  : flat_map(comp) { insert_range(std::forward<R>(rg)); }
 
 
11918
 
11919
+ constexpr flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare())
 
 
 
 
 
 
 
 
 
 
11920
  : flat_map(il.begin(), il.end(), comp) { }
 
 
 
 
11921
 
11922
+ constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
11923
  const key_compare& comp = key_compare())
11924
+ : flat_map(sorted_unique, il.begin(), il.end(), comp) { }
 
 
 
 
 
11925
 
11926
+ // [flat.map.cons.alloc], constructors with allocators
11927
+
11928
+ template<class Alloc>
11929
+ constexpr explicit flat_map(const Alloc& a);
11930
+ template<class Alloc>
11931
+ constexpr flat_map(const key_compare& comp, const Alloc& a);
11932
+ template<class Alloc>
11933
+ constexpr flat_map(const key_container_type& key_cont,
11934
+ const mapped_container_type& mapped_cont,
11935
+ const Alloc& a);
11936
+ template<class Alloc>
11937
+ constexpr flat_map(const key_container_type& key_cont,
11938
+ const mapped_container_type& mapped_cont,
11939
+ const key_compare& comp, const Alloc& a);
11940
+ template<class Alloc>
11941
+ constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
11942
+ const mapped_container_type& mapped_cont, const Alloc& a);
11943
+ template<class Alloc>
11944
+ constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
11945
+ const mapped_container_type& mapped_cont, const key_compare& comp,
11946
+ const Alloc& a);
11947
+ template<class Alloc>
11948
+ constexpr flat_map(const flat_map&, const Alloc& a);
11949
+ template<class Alloc>
11950
+ constexpr flat_map(flat_map&&, const Alloc& a);
11951
+ template<class InputIterator, class Alloc>
11952
+ constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a);
11953
+ template<class InputIterator, class Alloc>
11954
+ constexpr flat_map(InputIterator first, InputIterator last,
11955
+ const key_compare& comp, const Alloc& a);
11956
+ template<class InputIterator, class Alloc>
11957
+ constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
11958
+ const Alloc& a);
11959
+ template<class InputIterator, class Alloc>
11960
+ constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
11961
+ const key_compare& comp, const Alloc& a);
11962
+ template<container-compatible-range<value_type> R, class Alloc>
11963
+ constexpr flat_map(from_range_t, R&& rg, const Alloc& a);
11964
+ template<container-compatible-range<value_type> R, class Alloc>
11965
+ constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
11966
+ template<class Alloc>
11967
+ constexpr flat_map(initializer_list<value_type> il, const Alloc& a);
11968
+ template<class Alloc>
11969
+ constexpr flat_map(initializer_list<value_type> il, const key_compare& comp,
11970
+ const Alloc& a);
11971
+ template<class Alloc>
11972
+ constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
11973
+ template<class Alloc>
11974
+ constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
11975
+ const key_compare& comp, const Alloc& a);
11976
+
11977
+ constexpr flat_map& operator=(initializer_list<value_type>);
11978
 
11979
  // iterators
11980
+ constexpr iterator begin() noexcept;
11981
+ constexpr const_iterator begin() const noexcept;
11982
+ constexpr iterator end() noexcept;
11983
+ constexpr const_iterator end() const noexcept;
11984
 
11985
+ constexpr reverse_iterator rbegin() noexcept;
11986
+ constexpr const_reverse_iterator rbegin() const noexcept;
11987
+ constexpr reverse_iterator rend() noexcept;
11988
+ constexpr const_reverse_iterator rend() const noexcept;
11989
 
11990
+ constexpr const_iterator cbegin() const noexcept;
11991
+ constexpr const_iterator cend() const noexcept;
11992
+ constexpr const_reverse_iterator crbegin() const noexcept;
11993
+ constexpr const_reverse_iterator crend() const noexcept;
11994
 
11995
  // [flat.map.capacity], capacity
11996
+ constexpr bool empty() const noexcept;
11997
+ constexpr size_type size() const noexcept;
11998
+ constexpr size_type max_size() const noexcept;
11999
 
12000
  // [flat.map.access], element access
12001
+ constexpr mapped_type& operator[](const key_type& x);
12002
+ constexpr mapped_type& operator[](key_type&& x);
12003
+ template<class K> constexpr mapped_type& operator[](K&& x);
12004
+ constexpr mapped_type& at(const key_type& x);
12005
+ constexpr const mapped_type& at(const key_type& x) const;
12006
+ template<class K> constexpr mapped_type& at(const K& x);
12007
+ template<class K> constexpr const mapped_type& at(const K& x) const;
12008
 
12009
  // [flat.map.modifiers], modifiers
12010
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
12011
  template<class... Args>
12012
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
12013
 
12014
+ constexpr pair<iterator, bool> insert(const value_type& x)
12015
  { return emplace(x); }
12016
+ constexpr pair<iterator, bool> insert(value_type&& x)
12017
  { return emplace(std::move(x)); }
12018
+ constexpr iterator insert(const_iterator position, const value_type& x)
12019
  { return emplace_hint(position, x); }
12020
+ constexpr iterator insert(const_iterator position, value_type&& x)
12021
  { return emplace_hint(position, std::move(x)); }
12022
 
12023
+ template<class P> constexpr pair<iterator, bool> insert(P&& x);
12024
  template<class P>
12025
+ constexpr iterator insert(const_iterator position, P&&);
12026
  template<class InputIterator>
12027
+ constexpr void insert(InputIterator first, InputIterator last);
12028
  template<class InputIterator>
12029
+ constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
12030
  template<container-compatible-range<value_type> R>
12031
+ constexpr void insert_range(R&& rg);
12032
 
12033
+ constexpr void insert(initializer_list<value_type> il)
12034
  { insert(il.begin(), il.end()); }
12035
+ constexpr void insert(sorted_unique_t, initializer_list<value_type> il)
12036
+ { insert(sorted_unique, il.begin(), il.end()); }
12037
 
12038
+ constexpr containers extract() &&;
12039
+ constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
12040
 
12041
  template<class... Args>
12042
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
12043
  template<class... Args>
12044
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
12045
  template<class K, class... Args>
12046
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
12047
  template<class... Args>
12048
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
12049
  template<class... Args>
12050
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
12051
  template<class K, class... Args>
12052
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
12053
  template<class M>
12054
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
12055
  template<class M>
12056
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
12057
  template<class K, class M>
12058
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
12059
  template<class M>
12060
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
12061
  template<class M>
12062
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
12063
  template<class K, class M>
12064
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
12065
 
12066
+ constexpr iterator erase(iterator position);
12067
+ constexpr iterator erase(const_iterator position);
12068
+ constexpr size_type erase(const key_type& x);
12069
+ template<class K> constexpr size_type erase(K&& x);
12070
+ constexpr iterator erase(const_iterator first, const_iterator last);
12071
 
12072
+ constexpr void swap(flat_map& y) noexcept;
12073
+ constexpr void clear() noexcept;
12074
 
12075
  // observers
12076
+ constexpr key_compare key_comp() const;
12077
+ constexpr value_compare value_comp() const;
12078
 
12079
+ constexpr const key_container_type& keys() const noexcept { return c.keys; }
12080
+ constexpr const mapped_container_type& values() const noexcept { return c.values; }
12081
 
12082
  // map operations
12083
+ constexpr iterator find(const key_type& x);
12084
+ constexpr const_iterator find(const key_type& x) const;
12085
+ template<class K> constexpr iterator find(const K& x);
12086
+ template<class K> constexpr const_iterator find(const K& x) const;
12087
 
12088
+ constexpr size_type count(const key_type& x) const;
12089
+ template<class K> constexpr size_type count(const K& x) const;
12090
 
12091
+ constexpr bool contains(const key_type& x) const;
12092
+ template<class K> constexpr bool contains(const K& x) const;
12093
 
12094
+ constexpr iterator lower_bound(const key_type& x);
12095
+ constexpr const_iterator lower_bound(const key_type& x) const;
12096
+ template<class K> constexpr iterator lower_bound(const K& x);
12097
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
12098
 
12099
+ constexpr iterator upper_bound(const key_type& x);
12100
+ constexpr const_iterator upper_bound(const key_type& x) const;
12101
+ template<class K> constexpr iterator upper_bound(const K& x);
12102
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
12103
 
12104
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
12105
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
12106
+ template<class K> constexpr pair<iterator, iterator> equal_range(const K& x);
12107
+ template<class K>
12108
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
12109
 
12110
+ friend constexpr bool operator==(const flat_map& x, const flat_map& y);
12111
 
12112
+ friend constexpr synth-three-way-result<value_type>
12113
  operator<=>(const flat_map& x, const flat_map& y);
12114
 
12115
+ friend constexpr void swap(flat_map& x, flat_map& y) noexcept
12116
  { x.swap(y); }
12117
 
12118
  private:
12119
  containers c; // exposition only
12120
  key_compare compare; // exposition only
12121
 
12122
+ struct key-equiv { // exposition only
12123
+ constexpr key-equiv(key_compare c) : comp(c) { }
12124
+ constexpr bool operator()(const_reference x, const_reference y) const {
12125
  return !comp(x.first, y.first) && !comp(y.first, x.first);
12126
  }
12127
  key_compare comp;
12128
  };
12129
  };
 
12200
  specified.
12201
 
12202
  #### Constructors <a id="flat.map.cons">[[flat.map.cons]]</a>
12203
 
12204
  ``` cpp
12205
+ constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
12206
  const key_compare& comp = key_compare());
12207
  ```
12208
 
12209
+ *Effects:* Initializes *`c`*`.keys` with `std::move(key_cont)`,
12210
+ *`c`*`.values` with `std::move(mapped_cont)`, and *compare* with `comp`;
12211
+ sorts the range \[`begin()`, `end()`) with respect to `value_comp()`;
12212
+ and finally erases the duplicate elements as if by:
12213
 
12214
  ``` cpp
12215
+ auto zv = views::zip(c.keys, c.values);
12216
+ auto it = ranges::unique(zv, key-equiv(compare)).begin();
12217
  auto dist = distance(zv.begin(), it);
12218
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
12219
  c.values.erase(c.values.begin() + dist, c.values.end());
12220
  ```
12221
 
12222
  *Complexity:* Linear in N if the container arguments are already sorted
12223
  with respect to `value_comp()` and otherwise N log N, where N is the
12224
  value of `key_cont.size()` before this call.
12225
 
12226
  ``` cpp
12227
+ constexpr flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
12228
+ const key_compare& comp = key_compare());
 
 
 
 
12229
  ```
12230
 
12231
+ *Effects:* Initializes *`c`*`.keys` with `std::move(key_cont)`,
12232
+ *`c`*`.values` with `std::move(mapped_cont)`, and *compare* with `comp`.
12233
+
12234
+ *Complexity:* Constant.
12235
+
12236
+ #### Constructors with allocators <a id="flat.map.cons.alloc">[[flat.map.cons.alloc]]</a>
12237
+
12238
+ The constructors in this subclause shall not participate in overload
12239
+ resolution unless `uses_allocator_v<key_container_type, Alloc>` is
12240
+ `true` and `uses_allocator_v<mapped_container_type, Alloc>` is `true`.
12241
+
12242
+ ``` cpp
12243
+ template<class Alloc>
12244
+ constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
12245
+ const Alloc& a);
12246
+ template<class Alloc>
12247
+ constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
12248
+ const key_compare& comp, const Alloc& a);
12249
+ ```
12250
 
12251
  *Effects:* Equivalent to `flat_map(key_cont, mapped_cont)` and
12252
  `flat_map(key_cont, mapped_cont, comp)`, respectively, except that
12253
+ *`c`*`.keys` and *`c`*`.values` are constructed with uses-allocator
12254
  construction [[allocator.uses.construction]].
12255
 
12256
  *Complexity:* Same as `flat_map(key_cont, mapped_cont)` and
12257
  `flat_map(key_cont, mapped_cont, comp)`, respectively.
12258
 
12259
  ``` cpp
12260
+ template<class Alloc>
12261
+ constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
12262
+ const mapped_container_type& mapped_cont, const Alloc& a);
12263
+ template<class Alloc>
12264
+ constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
 
 
 
 
 
 
 
 
 
 
12265
  const mapped_container_type& mapped_cont, const key_compare& comp,
12266
+ const Alloc& a);
12267
  ```
12268
 
12269
+ *Effects:* Equivalent to
12270
+ `flat_map(sorted_unique, key_cont, mapped_cont)` and
12271
+ `flat_map(sorted_unique, key_cont, mapped_cont, comp)`, respectively,
12272
+ except that *`c`*`.keys` and *`c`*`.values` are constructed with
12273
+ uses-allocator construction [[allocator.uses.construction]].
 
 
 
12274
 
12275
  *Complexity:* Linear.
12276
 
12277
  ``` cpp
12278
+ template<class Alloc>
12279
+ constexpr explicit flat_map(const Alloc& a);
12280
+ template<class Alloc>
12281
+ constexpr flat_map(const key_compare& comp, const Alloc& a);
12282
+ template<class Alloc>
12283
+ constexpr flat_map(const flat_map&, const Alloc& a);
12284
+ template<class Alloc>
12285
+ constexpr flat_map(flat_map&&, const Alloc& a);
12286
+ template<class InputIterator, class Alloc>
12287
+ constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a);
12288
+ template<class InputIterator, class Alloc>
12289
+ constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp,
12290
+ const Alloc& a);
12291
+ template<class InputIterator, class Alloc>
12292
+ constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a);
12293
+ template<class InputIterator, class Alloc>
12294
+ constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
12295
+ const key_compare& comp, const Alloc& a);
12296
+ template<container-compatible-range<value_type> R, class Alloc>
12297
+ constexpr flat_map(from_range_t, R&& rg, const Alloc& a);
12298
+ template<container-compatible-range<value_type> R, class Alloc>
12299
+ constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
12300
+ template<class Alloc>
12301
+ constexpr flat_map(initializer_list<value_type> il, const Alloc& a);
12302
+ template<class Alloc>
12303
+ constexpr flat_map(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
12304
+ template<class Alloc>
12305
+ constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
12306
+ template<class Alloc>
12307
+ constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
12308
+ const key_compare& comp, const Alloc& a);
12309
  ```
12310
 
 
 
 
 
12311
  *Effects:* Equivalent to the corresponding non-allocator constructors
12312
+ except that *`c`*`.keys` and *`c`*`.values` are constructed with
12313
+ uses-allocator construction [[allocator.uses.construction]].
12314
 
12315
  #### Capacity <a id="flat.map.capacity">[[flat.map.capacity]]</a>
12316
 
12317
  ``` cpp
12318
+ constexpr size_type size() const noexcept;
12319
  ```
12320
 
12321
+ *Returns:* *`c`*`.keys.size()`.
12322
 
12323
  ``` cpp
12324
+ constexpr size_type max_size() const noexcept;
12325
  ```
12326
 
12327
+ *Returns:*
12328
+ `min<size_type>(`*`c`*`.keys.max_size(), `*`c`*`.values.max_size())`.
12329
 
12330
  #### Access <a id="flat.map.access">[[flat.map.access]]</a>
12331
 
12332
  ``` cpp
12333
+ constexpr mapped_type& operator[](const key_type& x);
12334
  ```
12335
 
12336
  *Effects:* Equivalent to: `return try_emplace(x).first->second;`
12337
 
12338
  ``` cpp
12339
+ constexpr mapped_type& operator[](key_type&& x);
12340
  ```
12341
 
12342
  *Effects:* Equivalent to:
12343
  `return try_emplace(std::move(x)).first->second;`
12344
 
12345
  ``` cpp
12346
+ template<class K> constexpr mapped_type& operator[](K&& x);
12347
  ```
12348
 
12349
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
12350
  denotes a type.
12351
 
12352
  *Effects:* Equivalent to:
12353
  `return try_emplace(std::forward<K>(x)).first->second;`
12354
 
12355
  ``` cpp
12356
+ constexpr mapped_type& at(const key_type& x);
12357
+ constexpr const mapped_type& at(const key_type& x) const;
12358
  ```
12359
 
12360
  *Returns:* A reference to the `mapped_type` corresponding to `x` in
12361
  `*this`.
12362
 
 
12364
  is present.
12365
 
12366
  *Complexity:* Logarithmic.
12367
 
12368
  ``` cpp
12369
+ template<class K> constexpr mapped_type& at(const K& x);
12370
+ template<class K> constexpr const mapped_type& at(const K& x) const;
12371
  ```
12372
 
12373
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
12374
  denotes a type.
12375
 
 
12385
  *Complexity:* Logarithmic.
12386
 
12387
  #### Modifiers <a id="flat.map.modifiers">[[flat.map.modifiers]]</a>
12388
 
12389
  ``` cpp
12390
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
12391
  ```
12392
 
12393
  *Constraints:*
12394
  `is_constructible_v<pair<key_type, mapped_type>, Args...>` is `true`.
12395
 
 
12408
  *Returns:* The `bool` component of the returned pair is `true` if and
12409
  only if the insertion took place, and the iterator component of the pair
12410
  points to the element with key equivalent to `t.first`.
12411
 
12412
  ``` cpp
12413
+ template<class P> constexpr pair<iterator, bool> insert(P&& x);
12414
+ template<class P> constexpr iterator insert(const_iterator position, P&& x);
12415
  ```
12416
 
12417
  *Constraints:* `is_constructible_v<pair<key_type, mapped_type>, P>` is
12418
  `true`.
12419
 
 
12421
  `return emplace(std::forward<P>(x));`. The second form is equivalent to
12422
  `return emplace_hint(position, std::forward<P>(x));`.
12423
 
12424
  ``` cpp
12425
  template<class InputIterator>
12426
+ constexpr void insert(InputIterator first, InputIterator last);
12427
  ```
12428
 
12429
+ *Effects:* Adds elements to *c* as if by:
12430
 
12431
  ``` cpp
12432
  for (; first != last; ++first) {
12433
  value_type value = *first;
12434
  c.keys.insert(c.keys.end(), std::move(value.first));
 
12440
  `value_comp()`; merges the resulting sorted range and the sorted range
12441
  of pre-existing elements into a single sorted range; and finally erases
12442
  the duplicate elements as if by:
12443
 
12444
  ``` cpp
12445
+ auto zv = views::zip(c.keys, c.values);
12446
+ auto it = ranges::unique(zv, key-equiv(compare)).begin();
12447
  auto dist = distance(zv.begin(), it);
12448
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
12449
  c.values.erase(c.values.begin() + dist, c.values.end());
12450
  ```
12451
 
 
12455
  *Remarks:* Since this operation performs an in-place merge, it may
12456
  allocate memory.
12457
 
12458
  ``` cpp
12459
  template<class InputIterator>
12460
+ constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
12461
  ```
12462
 
12463
+ *Effects:* Equivalent to `insert(first, last)`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12464
 
12465
  *Complexity:* Linear in N, where N is `size()` after the operation.
12466
 
 
 
 
12467
  ``` cpp
12468
  template<container-compatible-range<value_type> R>
12469
+ constexpr void insert_range(R&& rg);
12470
  ```
12471
 
12472
+ *Effects:* Adds elements to *c* as if by:
12473
 
12474
  ``` cpp
12475
  for (const auto& e : rg) {
12476
  c.keys.insert(c.keys.end(), e.first);
12477
  c.values.insert(c.values.end(), e.second);
 
12482
  `value_comp()`; merges the resulting sorted range and the sorted range
12483
  of pre-existing elements into a single sorted range; and finally erases
12484
  the duplicate elements as if by:
12485
 
12486
  ``` cpp
12487
+ auto zv = views::zip(c.keys, c.values);
12488
+ auto it = ranges::unique(zv, key-equiv(compare)).begin();
12489
  auto dist = distance(zv.begin(), it);
12490
  c.keys.erase(c.keys.begin() + dist, c.keys.end());
12491
  c.values.erase(c.values.begin() + dist, c.values.end());
12492
  ```
12493
 
 
12497
  *Remarks:* Since this operation performs an in-place merge, it may
12498
  allocate memory.
12499
 
12500
  ``` cpp
12501
  template<class... Args>
12502
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
12503
  template<class... Args>
12504
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
12505
  template<class... Args>
12506
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
12507
  template<class... Args>
12508
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
12509
  ```
12510
 
12511
  *Constraints:* `is_constructible_v<mapped_type, Args...>` is `true`.
12512
 
12513
  *Effects:* If the map already contains an element whose key is
 
12529
  *Complexity:* The same as `emplace` for the first two overloads, and the
12530
  same as `emplace_hint` for the last two overloads.
12531
 
12532
  ``` cpp
12533
  template<class K, class... Args>
12534
+ constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
12535
  template<class K, class... Args>
12536
+ constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
12537
  ```
12538
 
12539
  *Constraints:*
12540
 
12541
  - The *qualified-id* `Compare::is_transparent` is valid and denotes a
 
12551
  *Effects:* If the map already contains an element whose key is
12552
  equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
12553
  equivalent to:
12554
 
12555
  ``` cpp
12556
+ auto key_it = upper_bound(c.keys.begin(), c.keys.end(), k, compare);
12557
  auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
12558
  c.keys.emplace(key_it, std::forward<K>(k));
12559
  c.values.emplace(value_it, std::forward<Args>(args)...);
12560
  ```
12561
 
 
12565
 
12566
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
12567
 
12568
  ``` cpp
12569
  template<class M>
12570
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
12571
  template<class M>
12572
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
12573
  template<class M>
12574
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
12575
  template<class M>
12576
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
12577
  ```
12578
 
12579
  *Constraints:* `is_assignable_v<mapped_type&, M>` is `true` and
12580
  `is_constructible_v<mapped_type, M>` is `true`.
12581
 
 
12603
  *Complexity:* The same as `emplace` for the first two overloads and the
12604
  same as `emplace_hint` for the last two overloads.
12605
 
12606
  ``` cpp
12607
  template<class K, class M>
12608
+ constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
12609
  template<class K, class M>
12610
+ constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
12611
  ```
12612
 
12613
  *Constraints:*
12614
 
12615
  - The *qualified-id* `Compare::is_transparent` is valid and denotes a
 
12642
  iterator points to the map element whose key is equivalent to `k`.
12643
 
12644
  *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
12645
 
12646
  ``` cpp
12647
+ constexpr void swap(flat_map& y) noexcept;
12648
  ```
12649
 
12650
  *Effects:* Equivalent to:
12651
 
12652
  ``` cpp
 
12654
  ranges::swap(c.keys, y.c.keys);
12655
  ranges::swap(c.values, y.c.values);
12656
  ```
12657
 
12658
  ``` cpp
12659
+ constexpr containers extract() &&;
12660
  ```
12661
 
12662
  *Ensures:* `*this` is emptied, even if the function exits via an
12663
  exception.
12664
 
12665
+ *Returns:* `std::move(`*`c`*`)`.
12666
 
12667
  ``` cpp
12668
+ constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
12669
  ```
12670
 
12671
  *Preconditions:* `key_cont.size() == mapped_cont.size()` is `true`, the
12672
+ elements of `key_cont` are sorted with respect to *compare*, and
12673
  `key_cont` contains no equal elements.
12674
 
12675
  *Effects:* Equivalent to:
12676
 
12677
  ``` cpp
 
12682
  #### Erasure <a id="flat.map.erasure">[[flat.map.erasure]]</a>
12683
 
12684
  ``` cpp
12685
  template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
12686
  class Predicate>
12687
+ constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
12688
  erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
12689
  ```
12690
 
12691
  *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
12692
  requirements.
 
12776
 
12777
  The effect of calling a constructor that takes both `key_container_type`
12778
  and `mapped_container_type` arguments with containers of different sizes
12779
  is undefined.
12780
 
12781
+ The effect of calling a member function that takes a
12782
  `sorted_equivalent_t` argument with a container, containers, or range
12783
  that are not sorted with respect to `key_comp()` is undefined.
12784
 
12785
+ The types `iterator` and `const_iterator` meet the constexpr iterator
12786
+ requirements [[iterator.requirements.general]].
12787
+
12788
  #### Definition <a id="flat.multimap.defn">[[flat.multimap.defn]]</a>
12789
 
12790
  ``` cpp
12791
  namespace std {
12792
  template<class Key, class T, class Compare = less<Key>,
 
12810
  using mapped_container_type = MappedContainer;
12811
 
12812
  class value_compare {
12813
  private:
12814
  key_compare comp; // exposition only
12815
+ constexpr value_compare(key_compare c) : comp(c) { } // exposition only
12816
 
12817
  public:
12818
+ constexpr bool operator()(const_reference x, const_reference y) const {
12819
  return comp(x.first, y.first);
12820
  }
12821
  };
12822
 
12823
  struct containers {
12824
  key_container_type keys;
12825
  mapped_container_type values;
12826
  };
12827
 
12828
+ // [flat.multimap.cons], constructors
12829
+ constexpr flat_multimap() : flat_multimap(key_compare()) { }
12830
 
12831
+ constexpr explicit flat_multimap(const key_compare& comp)
12832
+ : c(), compare(comp) { }
12833
+
12834
+ constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
12835
  const key_compare& comp = key_compare());
 
 
 
 
 
 
12836
 
12837
+ constexpr flat_multimap(sorted_equivalent_t,
12838
  key_container_type key_cont, mapped_container_type mapped_cont,
12839
  const key_compare& comp = key_compare());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12840
 
12841
  template<class InputIterator>
12842
+ constexpr flat_multimap(InputIterator first, InputIterator last,
12843
  const key_compare& comp = key_compare())
12844
  : c(), compare(comp)
12845
  { insert(first, last); }
12846
+
12847
+ template<class InputIterator>
12848
+ constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
12849
+ const key_compare& comp = key_compare())
12850
+ : c(), compare(comp) { insert(sorted_equivalent, first, last); }
12851
 
12852
  template<container-compatible-range<value_type> R>
12853
+ constexpr flat_multimap(from_range_t, R&& rg)
12854
+ : flat_multimap(from_range, std::forward<R>(rg), key_compare()) { }
 
 
12855
  template<container-compatible-range<value_type> R>
12856
+ constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp)
12857
  : flat_multimap(comp) { insert_range(std::forward<R>(rg)); }
 
 
12858
 
12859
+ constexpr flat_multimap(initializer_list<value_type> il,
 
12860
  const key_compare& comp = key_compare())
 
 
 
 
 
 
 
 
 
12861
  : flat_multimap(il.begin(), il.end(), comp) { }
 
 
 
 
 
12862
 
12863
+ constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
12864
  const key_compare& comp = key_compare())
12865
+ : flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { }
 
 
 
 
 
12866
 
12867
+ // [flat.multimap.cons.alloc], constructors with allocators
12868
+
12869
+ template<class Alloc>
12870
+ constexpr explicit flat_multimap(const Alloc& a);
12871
+ template<class Alloc>
12872
+ constexpr flat_multimap(const key_compare& comp, const Alloc& a);
12873
+ template<class Alloc>
12874
+ constexpr flat_multimap(const key_container_type& key_cont,
12875
+ const mapped_container_type& mapped_cont, const Alloc& a);
12876
+ template<class Alloc>
12877
+ constexpr flat_multimap(const key_container_type& key_cont,
12878
+ const mapped_container_type& mapped_cont,
12879
+ const key_compare& comp, const Alloc& a);
12880
+ template<class Alloc>
12881
+ constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
12882
+ const mapped_container_type& mapped_cont, const Alloc& a);
12883
+ template<class Alloc>
12884
+ constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
12885
+ const mapped_container_type& mapped_cont,
12886
+ const key_compare& comp, const Alloc& a);
12887
+ template<class Alloc>
12888
+ constexpr flat_multimap(const flat_multimap&, const Alloc& a);
12889
+ template<class Alloc>
12890
+ constexpr flat_multimap(flat_multimap&&, const Alloc& a);
12891
+ template<class InputIterator, class Alloc>
12892
+ constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a);
12893
+ template<class InputIterator, class Alloc>
12894
+ constexpr flat_multimap(InputIterator first, InputIterator last,
12895
+ const key_compare& comp, const Alloc& a);
12896
+ template<class InputIterator, class Alloc>
12897
+ constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
12898
+ const Alloc& a);
12899
+ template<class InputIterator, class Alloc>
12900
+ constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
12901
+ const key_compare& comp, const Alloc& a);
12902
+ template<container-compatible-range<value_type> R, class Alloc>
12903
+ constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a);
12904
+ template<container-compatible-range<value_type> R, class Alloc>
12905
+ constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
12906
+ template<class Alloc>
12907
+ constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a);
12908
+ template<class Alloc>
12909
+ constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp,
12910
+ const Alloc& a);
12911
+ template<class Alloc>
12912
+ constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
12913
+ const Alloc& a);
12914
+ template<class Alloc>
12915
+ constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
12916
+ const key_compare& comp, const Alloc& a);
12917
+
12918
+ flat_multimap& operator=(initializer_list<value_type>);
12919
 
12920
  // iterators
12921
+ constexpr iterator begin() noexcept;
12922
+ constexpr const_iterator begin() const noexcept;
12923
+ constexpr iterator end() noexcept;
12924
+ constexpr const_iterator end() const noexcept;
12925
 
12926
+ constexpr reverse_iterator rbegin() noexcept;
12927
+ constexpr const_reverse_iterator rbegin() const noexcept;
12928
+ constexpr reverse_iterator rend() noexcept;
12929
+ constexpr const_reverse_iterator rend() const noexcept;
12930
 
12931
+ constexpr const_iterator cbegin() const noexcept;
12932
+ constexpr const_iterator cend() const noexcept;
12933
+ constexpr const_reverse_iterator crbegin() const noexcept;
12934
+ constexpr const_reverse_iterator crend() const noexcept;
12935
 
12936
  // capacity
12937
+ constexpr bool empty() const noexcept;
12938
+ constexpr size_type size() const noexcept;
12939
+ constexpr size_type max_size() const noexcept;
12940
 
12941
  // modifiers
12942
+ template<class... Args> constexpr iterator emplace(Args&&... args);
12943
  template<class... Args>
12944
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
12945
 
12946
+ constexpr iterator insert(const value_type& x)
12947
  { return emplace(x); }
12948
+ constexpr iterator insert(value_type&& x)
12949
  { return emplace(std::move(x)); }
12950
+ constexpr iterator insert(const_iterator position, const value_type& x)
12951
  { return emplace_hint(position, x); }
12952
+ constexpr iterator insert(const_iterator position, value_type&& x)
12953
  { return emplace_hint(position, std::move(x)); }
12954
 
12955
+ template<class P> constexpr iterator insert(P&& x);
12956
  template<class P>
12957
+ constexpr iterator insert(const_iterator position, P&&);
12958
  template<class InputIterator>
12959
+ constexpr void insert(InputIterator first, InputIterator last);
12960
  template<class InputIterator>
12961
+ constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
12962
  template<container-compatible-range<value_type> R>
12963
+ constexpr void insert_range(R&& rg);
12964
 
12965
+ constexpr void insert(initializer_list<value_type> il)
12966
  { insert(il.begin(), il.end()); }
12967
+ constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il)
12968
+ { insert(sorted_equivalent, il.begin(), il.end()); }
12969
 
12970
+ constexpr containers extract() &&;
12971
+ constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
12972
 
12973
+ constexpr iterator erase(iterator position);
12974
+ constexpr iterator erase(const_iterator position);
12975
+ constexpr size_type erase(const key_type& x);
12976
+ template<class K> constexpr size_type erase(K&& x);
12977
+ constexpr iterator erase(const_iterator first, const_iterator last);
12978
 
12979
+ constexpr void swap(flat_multimap&) noexcept;
12980
+ constexpr void clear() noexcept;
12981
 
12982
  // observers
12983
+ constexpr key_compare key_comp() const;
12984
+ constexpr value_compare value_comp() const;
12985
 
12986
+ constexpr const key_container_type& keys() const noexcept { return c.keys; }
12987
+ constexpr const mapped_container_type& values() const noexcept { return c.values; }
12988
 
12989
  // map operations
12990
+ constexpr iterator find(const key_type& x);
12991
+ constexpr const_iterator find(const key_type& x) const;
12992
+ template<class K> constexpr iterator find(const K& x);
12993
+ template<class K> constexpr const_iterator find(const K& x) const;
12994
 
12995
+ constexpr size_type count(const key_type& x) const;
12996
+ template<class K> constexpr size_type count(const K& x) const;
12997
 
12998
+ constexpr bool contains(const key_type& x) const;
12999
+ template<class K> constexpr bool contains(const K& x) const;
13000
 
13001
+ constexpr iterator lower_bound(const key_type& x);
13002
+ constexpr const_iterator lower_bound(const key_type& x) const;
13003
+ template<class K> constexpr iterator lower_bound(const K& x);
13004
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
13005
 
13006
+ constexpr iterator upper_bound(const key_type& x);
13007
+ constexpr const_iterator upper_bound(const key_type& x) const;
13008
+ template<class K> constexpr iterator upper_bound(const K& x);
13009
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
13010
 
13011
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
13012
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
13013
  template<class K>
13014
+ constexpr pair<iterator, iterator> equal_range(const K& x);
13015
  template<class K>
13016
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
13017
 
13018
+ friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y);
13019
 
13020
+ friend constexpr synth-three-way-result<value_type>
13021
  operator<=>(const flat_multimap& x, const flat_multimap& y);
13022
 
13023
+ friend constexpr void swap(flat_multimap& x, flat_multimap& y) noexcept
13024
  { x.swap(y); }
13025
 
13026
  private:
13027
  containers c; // exposition only
13028
  key_compare compare; // exposition only
 
13105
  specified.
13106
 
13107
  #### Constructors <a id="flat.multimap.cons">[[flat.multimap.cons]]</a>
13108
 
13109
  ``` cpp
13110
+ constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
13111
  const key_compare& comp = key_compare());
13112
  ```
13113
 
13114
+ *Effects:* Initializes *`c`*`.keys` with `std::move(key_cont)`,
13115
+ *`c`*`.values` with `std::move(mapped_cont)`, and *compare* with `comp`;
13116
+ sorts the range \[`begin()`, `end()`) with respect to `value_comp()`.
13117
 
13118
  *Complexity:* Linear in N if the container arguments are already sorted
13119
  with respect to `value_comp()` and otherwise N log N, where N is the
13120
  value of `key_cont.size()` before this call.
13121
 
13122
  ``` cpp
13123
+ constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont,
13124
+ mapped_container_type mapped_cont,
13125
+ const key_compare& comp = key_compare());
 
 
 
13126
  ```
13127
 
13128
+ *Effects:* Initializes *`c`*`.keys` with `std::move(key_cont)`,
13129
+ *`c`*`.values` with `std::move(mapped_cont)`, and *compare* with `comp`.
13130
+
13131
+ *Complexity:* Constant.
13132
+
13133
+ #### Constructors with allocators <a id="flat.multimap.cons.alloc">[[flat.multimap.cons.alloc]]</a>
13134
+
13135
+ The constructors in this subclause shall not participate in overload
13136
+ resolution unless `uses_allocator_v<key_container_type, Alloc>` is
13137
+ `true` and `uses_allocator_v<mapped_container_type, Alloc>` is `true`.
13138
+
13139
+ ``` cpp
13140
+ template<class Alloc>
13141
+ constexpr flat_multimap(const key_container_type& key_cont,
13142
+ const mapped_container_type& mapped_cont, const Alloc& a);
13143
+ template<class Alloc>
13144
+ constexpr flat_multimap(const key_container_type& key_cont,
13145
+ const mapped_container_type& mapped_cont,
13146
+ const key_compare& comp, const Alloc& a);
13147
+ ```
13148
 
13149
  *Effects:* Equivalent to `flat_multimap(key_cont, mapped_cont)` and
13150
  `flat_multimap(key_cont, mapped_cont, comp)`, respectively, except that
13151
+ *`c`*`.keys` and *`c`*`.values` are constructed with uses-allocator
13152
  construction [[allocator.uses.construction]].
13153
 
13154
  *Complexity:* Same as `flat_multimap(key_cont, mapped_cont)` and
13155
  `flat_multimap(key_cont, mapped_cont, comp)`, respectively.
13156
 
13157
  ``` cpp
13158
+ template<class Alloc>
13159
+ constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
13160
+ const mapped_container_type& mapped_cont, const Alloc& a);
13161
+ template<class Alloc>
13162
+ constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
 
 
 
 
 
 
 
 
 
 
13163
  const mapped_container_type& mapped_cont, const key_compare& comp,
13164
+ const Alloc& a);
13165
  ```
13166
 
13167
+ *Effects:* Equivalent to
13168
+ `flat_multimap(sorted_equivalent, key_cont, mapped_cont)` and
13169
+ `flat_multimap(sorted_equivalent, key_cont, mapped_cont, comp)`,
13170
+ respectively, except that *`c`*`.keys` and *`c`*`.values` are
13171
+ constructed with uses-allocator
 
 
13172
  construction [[allocator.uses.construction]].
13173
 
13174
  *Complexity:* Linear.
13175
 
13176
  ``` cpp
13177
+ template<class Alloc>
13178
+ constexpr explicit flat_multimap(const Alloc& a);
13179
+ template<class Alloc>
13180
+ constexpr flat_multimap(const key_compare& comp, const Alloc& a);
13181
+ template<class Alloc>
13182
+ constexpr flat_multimap(const flat_multimap&, const Alloc& a);
13183
+ template<class Alloc>
13184
+ constexpr flat_multimap(flat_multimap&&, const Alloc& a);
13185
+ template<class InputIterator, class Alloc>
13186
+ constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a);
13187
+ template<class InputIterator, class Alloc>
13188
+ constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
13189
+ const Alloc& a);
13190
+ template<class InputIterator, class Alloc>
13191
+ constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
13192
+ const Alloc& a);
13193
+ template<class InputIterator, class Alloc>
13194
+ constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
13195
+ const key_compare& comp, const Alloc& a);
13196
+ template<container-compatible-range<value_type> R, class Alloc>
13197
+ constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a);
13198
+ template<container-compatible-range<value_type> R, class Alloc>
13199
+ constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
13200
+ template<class Alloc>
13201
+ constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a);
13202
+ template<class Alloc>
13203
+ constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp,
13204
+ const Alloc& a);
13205
+ template<class Alloc>
13206
+ constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a);
13207
+ template<class Alloc>
13208
+ constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
13209
+ const key_compare& comp, const Alloc& a);
13210
  ```
13211
 
 
 
 
 
13212
  *Effects:* Equivalent to the corresponding non-allocator constructors
13213
+ except that *`c`*`.keys` and *`c`*`.values` are constructed with
13214
+ uses-allocator construction [[allocator.uses.construction]].
13215
 
13216
  #### Erasure <a id="flat.multimap.erasure">[[flat.multimap.erasure]]</a>
13217
 
13218
  ``` cpp
13219
  template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
13220
  class Predicate>
13221
+ constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
13222
  erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
13223
  ```
13224
 
13225
  *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
13226
  requirements.
 
13237
  state [[defns.valid]].
13238
 
13239
  [*Note 1*: `c` still meets its invariants, but can be
13240
  empty. — *end note*]
13241
 
13242
+ ### Header `<flat_set>` synopsis <a id="flat.set.syn">[[flat.set.syn]]</a>
13243
+
13244
+ ``` cpp
13245
+ #include <compare> // see [compare.syn]
13246
+ #include <initializer_list> // see [initializer.list.syn]
13247
+
13248
+ namespace std {
13249
+ // [flat.set], class template flat_set
13250
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
13251
+ class flat_set;
13252
+
13253
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
13254
+ inline constexpr sorted_unique_t sorted_unique{};
13255
+
13256
+ template<class Key, class Compare, class KeyContainer, class Allocator>
13257
+ struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
13258
+
13259
+ // [flat.set.erasure], erasure for flat_set
13260
+ template<class Key, class Compare, class KeyContainer, class Predicate>
13261
+ constexpr typename flat_set<Key, Compare, KeyContainer>::size_type
13262
+ erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
13263
+
13264
+ // [flat.multiset], class template flat_multiset
13265
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
13266
+ class flat_multiset;
13267
+
13268
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
13269
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
13270
+
13271
+ template<class Key, class Compare, class KeyContainer, class Allocator>
13272
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>;
13273
+
13274
+ // [flat.multiset.erasure], erasure for flat_multiset
13275
+ template<class Key, class Compare, class KeyContainer, class Predicate>
13276
+ constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type
13277
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
13278
+ }
13279
+ ```
13280
+
13281
  ### Class template `flat_set` <a id="flat.set">[[flat.set]]</a>
13282
 
13283
  #### Overview <a id="flat.set.overview">[[flat.set.overview]]</a>
13284
 
13285
  A `flat_set` is a container adaptor that provides an associative
 
13332
  [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
13333
 
13334
  The program is ill-formed if `Key` is not the same type as
13335
  `KeyContainer::value_type`.
13336
 
13337
+ The effect of calling a member function that takes a `sorted_unique_t`
13338
+ argument with a range that is not sorted with respect to `key_comp()`,
13339
+ or that contains equal elements, is undefined.
13340
+
13341
+ The types `iterator` and `const_iterator` meet the constexpr iterator
13342
+ requirements [[iterator.requirements.general]].
13343
 
13344
  #### Definition <a id="flat.set.defn">[[flat.set.defn]]</a>
13345
 
13346
  ``` cpp
13347
  namespace std {
 
13353
  using value_type = Key;
13354
  using key_compare = Compare;
13355
  using value_compare = Compare;
13356
  using reference = value_type&;
13357
  using const_reference = const value_type&;
13358
+ using size_type = KeyContainer::size_type;
13359
+ using difference_type = KeyContainer::difference_type;
13360
  using iterator = implementation-defined // type of flat_set::iterator; // see [container.requirements]
13361
  using const_iterator = implementation-defined // type of flat_set::const_iterator; // see [container.requirements]
13362
  using reverse_iterator = std::reverse_iterator<iterator>;
13363
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
13364
  using container_type = KeyContainer;
13365
 
13366
  // [flat.set.cons], constructors
13367
+ constexpr flat_set() : flat_set(key_compare()) { }
13368
 
13369
+ constexpr explicit flat_set(const key_compare& comp)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13370
  : c(), compare(comp) { }
13371
+
13372
+ constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare());
13373
+
13374
+ constexpr flat_set(sorted_unique_t, container_type cont,
13375
+ const key_compare& comp = key_compare())
13376
+ : c(std::move(cont)), compare(comp) { }
13377
 
13378
  template<class InputIterator>
13379
+ constexpr flat_set(InputIterator first, InputIterator last,
13380
+ const key_compare& comp = key_compare())
13381
  : c(), compare(comp)
13382
  { insert(first, last); }
13383
+
13384
+ template<class InputIterator>
13385
+ constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
13386
+ const key_compare& comp = key_compare())
13387
+ : c(first, last), compare(comp) { }
13388
 
13389
  template<container-compatible-range<value_type> R>
13390
+ constexpr flat_set(from_range_t, R&& rg)
13391
+ : flat_set(from_range, std::forward<R>(rg), key_compare()) { }
 
 
13392
  template<container-compatible-range<value_type> R>
13393
+ constexpr flat_set(from_range_t, R&& rg, const key_compare& comp)
13394
  : flat_set(comp)
13395
  { insert_range(std::forward<R>(rg)); }
 
 
13396
 
13397
+ constexpr flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare())
 
 
 
 
 
 
 
 
 
 
13398
  : flat_set(il.begin(), il.end(), comp) { }
 
 
 
 
13399
 
13400
+ constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
13401
  const key_compare& comp = key_compare())
13402
+ : flat_set(sorted_unique, il.begin(), il.end(), comp) { }
 
 
 
 
 
13403
 
13404
+ // [flat.set.cons.alloc], constructors with allocators
13405
+
13406
+ template<class Alloc>
13407
+ constexpr explicit flat_set(const Alloc& a);
13408
+ template<class Alloc>
13409
+ constexpr flat_set(const key_compare& comp, const Alloc& a);
13410
+ template<class Alloc>
13411
+ constexpr flat_set(const container_type& cont, const Alloc& a);
13412
+ template<class Alloc>
13413
+ constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a);
13414
+ template<class Alloc>
13415
+ constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a);
13416
+ template<class Alloc>
13417
+ constexpr flat_set(sorted_unique_t, const container_type& cont,
13418
+ const key_compare& comp, const Alloc& a);
13419
+ template<class Alloc>
13420
+ constexpr flat_set(const flat_set&, const Alloc& a);
13421
+ template<class Alloc>
13422
+ constexpr flat_set(flat_set&&, const Alloc& a);
13423
+ template<class InputIterator, class Alloc>
13424
+ constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a);
13425
+ template<class InputIterator, class Alloc>
13426
+ constexpr flat_set(InputIterator first, InputIterator last,
13427
+ const key_compare& comp, const Alloc& a);
13428
+ template<class InputIterator, class Alloc>
13429
+ constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
13430
+ const Alloc& a);
13431
+ template<class InputIterator, class Alloc>
13432
+ constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
13433
+ const key_compare& comp, const Alloc& a);
13434
+ template<container-compatible-range<value_type> R, class Alloc>
13435
+ constexpr flat_set(from_range_t, R&& rg, const Alloc& a);
13436
+ template<container-compatible-range<value_type> R, class Alloc>
13437
+ constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
13438
+ template<class Alloc>
13439
+ constexpr flat_set(initializer_list<value_type> il, const Alloc& a);
13440
+ template<class Alloc>
13441
+ constexpr flat_set(initializer_list<value_type> il, const key_compare& comp,
13442
+ const Alloc& a);
13443
+ template<class Alloc>
13444
+ constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
13445
+ template<class Alloc>
13446
+ constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
13447
+ const key_compare& comp, const Alloc& a);
13448
+
13449
+ constexpr flat_set& operator=(initializer_list<value_type>);
13450
 
13451
  // iterators
13452
+ constexpr iterator begin() noexcept;
13453
+ constexpr const_iterator begin() const noexcept;
13454
+ constexpr iterator end() noexcept;
13455
+ constexpr const_iterator end() const noexcept;
13456
 
13457
+ constexpr reverse_iterator rbegin() noexcept;
13458
+ constexpr const_reverse_iterator rbegin() const noexcept;
13459
+ constexpr reverse_iterator rend() noexcept;
13460
+ constexpr const_reverse_iterator rend() const noexcept;
13461
 
13462
+ constexpr const_iterator cbegin() const noexcept;
13463
+ constexpr const_iterator cend() const noexcept;
13464
+ constexpr const_reverse_iterator crbegin() const noexcept;
13465
+ constexpr const_reverse_iterator crend() const noexcept;
13466
 
13467
  // capacity
13468
+ constexpr bool empty() const noexcept;
13469
+ constexpr size_type size() const noexcept;
13470
+ constexpr size_type max_size() const noexcept;
13471
 
13472
  // [flat.set.modifiers], modifiers
13473
+ template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
13474
  template<class... Args>
13475
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
13476
 
13477
+ constexpr pair<iterator, bool> insert(const value_type& x)
13478
  { return emplace(x); }
13479
+ constexpr pair<iterator, bool> insert(value_type&& x)
13480
  { return emplace(std::move(x)); }
13481
+ template<class K> constexpr pair<iterator, bool> insert(K&& x);
13482
+ constexpr iterator insert(const_iterator position, const value_type& x)
13483
  { return emplace_hint(position, x); }
13484
+ constexpr iterator insert(const_iterator position, value_type&& x)
13485
  { return emplace_hint(position, std::move(x)); }
13486
+ template<class K> constexpr iterator insert(const_iterator hint, K&& x);
13487
 
13488
  template<class InputIterator>
13489
+ constexpr void insert(InputIterator first, InputIterator last);
13490
  template<class InputIterator>
13491
+ constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
13492
  template<container-compatible-range<value_type> R>
13493
+ constexpr void insert_range(R&& rg);
13494
 
13495
+ constexpr void insert(initializer_list<value_type> il)
13496
  { insert(il.begin(), il.end()); }
13497
+ constexpr void insert(sorted_unique_t, initializer_list<value_type> il)
13498
+ { insert(sorted_unique, il.begin(), il.end()); }
13499
 
13500
+ constexpr container_type extract() &&;
13501
+ constexpr void replace(container_type&&);
13502
 
13503
+ constexpr iterator erase(iterator position);
13504
+ constexpr iterator erase(const_iterator position);
13505
+ constexpr size_type erase(const key_type& x);
13506
+ template<class K> constexpr size_type erase(K&& x);
13507
+ constexpr iterator erase(const_iterator first, const_iterator last);
13508
 
13509
+ constexpr void swap(flat_set& y) noexcept;
13510
+ constexpr void clear() noexcept;
13511
 
13512
  // observers
13513
+ constexpr key_compare key_comp() const;
13514
+ constexpr value_compare value_comp() const;
13515
 
13516
  // set operations
13517
+ constexpr iterator find(const key_type& x);
13518
+ constexpr const_iterator find(const key_type& x) const;
13519
+ template<class K> constexpr iterator find(const K& x);
13520
+ template<class K> constexpr const_iterator find(const K& x) const;
13521
 
13522
+ constexpr size_type count(const key_type& x) const;
13523
+ template<class K> constexpr size_type count(const K& x) const;
13524
 
13525
+ constexpr bool contains(const key_type& x) const;
13526
+ template<class K> constexpr bool contains(const K& x) const;
13527
 
13528
+ constexpr iterator lower_bound(const key_type& x);
13529
+ constexpr const_iterator lower_bound(const key_type& x) const;
13530
+ template<class K> constexpr iterator lower_bound(const K& x);
13531
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
13532
 
13533
+ constexpr iterator upper_bound(const key_type& x);
13534
+ constexpr const_iterator upper_bound(const key_type& x) const;
13535
+ template<class K> constexpr iterator upper_bound(const K& x);
13536
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
13537
 
13538
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
13539
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
13540
  template<class K>
13541
+ constexpr pair<iterator, iterator> equal_range(const K& x);
13542
  template<class K>
13543
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
13544
 
13545
+ friend constexpr bool operator==(const flat_set& x, const flat_set& y);
13546
 
13547
+ friend constexpr synth-three-way-result<value_type>
13548
  operator<=>(const flat_set& x, const flat_set& y);
13549
 
13550
+ friend constexpr void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); }
13551
 
13552
  private:
13553
  container_type c; // exposition only
13554
  key_compare compare; // exposition only
13555
  };
 
13612
  ```
13613
 
13614
  #### Constructors <a id="flat.set.cons">[[flat.set.cons]]</a>
13615
 
13616
  ``` cpp
13617
+ constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare());
13618
  ```
13619
 
13620
  *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
13621
  `comp`, sorts the range \[`begin()`, `end()`) with respect to *compare*,
13622
  and finally erases all but the first element from each group of
13623
  consecutive equivalent elements.
13624
 
13625
+ *Complexity:* Linear in N if `cont` is already sorted with respect to
13626
+ *compare* and otherwise N log N, where N is the value of `cont.size()`
13627
+ before this call.
13628
+
13629
+ #### Constructors with allocators <a id="flat.set.cons.alloc">[[flat.set.cons.alloc]]</a>
13630
+
13631
+ The constructors in this subclause shall not participate in overload
13632
+ resolution unless `uses_allocator_v<container_type, Alloc>` is `true`.
13633
 
13634
  ``` cpp
13635
+ template<class Alloc>
13636
+ constexpr flat_set(const container_type& cont, const Alloc& a);
13637
+ template<class Alloc>
13638
+ constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a);
13639
  ```
13640
 
 
 
13641
  *Effects:* Equivalent to `flat_set(cont)` and `flat_set(cont, comp)`,
13642
  respectively, except that *c* is constructed with uses-allocator
13643
  construction [[allocator.uses.construction]].
13644
 
13645
  *Complexity:* Same as `flat_set(cont)` and `flat_set(cont, comp)`,
13646
  respectively.
13647
 
13648
  ``` cpp
13649
+ template<class Alloc>
13650
+ constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a);
13651
+ template<class Alloc>
13652
+ constexpr flat_set(sorted_unique_t, const container_type& cont,
13653
+ const key_compare& comp, const Alloc& a);
13654
  ```
13655
 
13656
+ *Effects:* Equivalent to `flat_set(sorted_unique, cont)` and
13657
+ `flat_set(sorted_unique, cont,comp)`, respectively, except that *c* is
13658
+ constructed with uses-allocator
13659
+ construction [[allocator.uses.construction]].
 
13660
 
13661
  *Complexity:* Linear.
13662
 
13663
  ``` cpp
13664
+ template<class Alloc>
13665
+ constexpr explicit flat_set(const Alloc& a);
13666
+ template<class Alloc>
13667
+ constexpr flat_set(const key_compare& comp, const Alloc& a);
13668
+ template<class Alloc>
13669
+ constexpr flat_set(const flat_set&, const Alloc& a);
13670
+ template<class Alloc>
13671
+ constexpr flat_set(flat_set&&, const Alloc& a);
13672
+ template<class InputIterator, class Alloc>
13673
+ constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a);
13674
+ template<class InputIterator, class Alloc>
13675
+ constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp,
13676
+ const Alloc& a);
13677
+ template<class InputIterator, class Alloc>
13678
+ constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a);
13679
+ template<class InputIterator, class Alloc>
13680
+ constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
13681
+ const key_compare& comp, const Alloc& a);
13682
+ template<container-compatible-range<value_type> R, class Alloc>
13683
+ constexpr flat_set(from_range_t, R&& rg, const Alloc& a);
13684
+ template<container-compatible-range<value_type> R, class Alloc>
13685
+ constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
13686
+ template<class Alloc>
13687
+ constexpr flat_set(initializer_list<value_type> il, const Alloc& a);
13688
+ template<class Alloc>
13689
+ constexpr flat_set(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
13690
+ template<class Alloc>
13691
+ constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
13692
+ template<class Alloc>
13693
+ constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
13694
+ const key_compare& comp, const Alloc& a);
13695
  ```
13696
 
 
 
13697
  *Effects:* Equivalent to the corresponding non-allocator constructors
13698
  except that *c* is constructed with uses-allocator
13699
  construction [[allocator.uses.construction]].
13700
 
13701
  #### Modifiers <a id="flat.set.modifiers">[[flat.set.modifiers]]</a>
13702
 
13703
  ``` cpp
13704
+ template<class K> constexpr pair<iterator, bool> insert(K&& x);
13705
+ template<class K> constexpr iterator insert(const_iterator hint, K&& x);
13706
  ```
13707
 
13708
  *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
13709
  denotes a type. `is_constructible_v<value_type, K>` is `true`.
13710
 
13711
  *Preconditions:* The conversion from `x` into `value_type` constructs an
13712
+ object `u`, for which `find(x) == find(u)` is `true`.
13713
 
13714
  *Effects:* If the set already contains an element equivalent to `x`,
13715
  `*this` and `x` are unchanged. Otherwise, inserts a new element as if by
13716
  `emplace(std::forward<K>(x))`.
13717
 
 
13719
  pair is `true` if and only if the insertion took place. The returned
13720
  iterator points to the element whose key is equivalent to `x`.
13721
 
13722
  ``` cpp
13723
  template<class InputIterator>
13724
+ constexpr void insert(InputIterator first, InputIterator last);
13725
  ```
13726
 
13727
  *Effects:* Adds elements to *c* as if by:
13728
 
13729
  ``` cpp
 
13742
  *Remarks:* Since this operation performs an in-place merge, it may
13743
  allocate memory.
13744
 
13745
  ``` cpp
13746
  template<class InputIterator>
13747
+ constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
13748
  ```
13749
 
13750
  *Effects:* Equivalent to `insert(first, last)`.
13751
 
13752
  *Complexity:* Linear.
13753
 
13754
  ``` cpp
13755
  template<container-compatible-range<value_type> R>
13756
+ constexpr void insert_range(R&& rg);
13757
  ```
13758
 
13759
  *Effects:* Adds elements to *c* as if by:
13760
 
13761
  ``` cpp
 
13775
 
13776
  *Remarks:* Since this operation performs an in-place merge, it may
13777
  allocate memory.
13778
 
13779
  ``` cpp
13780
+ constexpr void swap(flat_set& y) noexcept;
13781
  ```
13782
 
13783
  *Effects:* Equivalent to:
13784
 
13785
  ``` cpp
13786
  ranges::swap(compare, y.compare);
13787
  ranges::swap(c, y.c);
13788
  ```
13789
 
13790
  ``` cpp
13791
+ constexpr container_type extract() &&;
13792
  ```
13793
 
13794
  *Ensures:* `*this` is emptied, even if the function exits via an
13795
  exception.
13796
 
13797
  *Returns:* `std::move(`*`c`*`)`.
13798
 
13799
  ``` cpp
13800
+ constexpr void replace(container_type&& cont);
13801
  ```
13802
 
13803
  *Preconditions:* The elements of `cont` are sorted with respect to
13804
  *compare*, and `cont` contains no equal elements.
13805
 
 
13807
 
13808
  #### Erasure <a id="flat.set.erasure">[[flat.set.erasure]]</a>
13809
 
13810
  ``` cpp
13811
  template<class Key, class Compare, class KeyContainer, class Predicate>
13812
+ constexpr typename flat_set<Key, Compare, KeyContainer>::size_type
13813
  erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
13814
  ```
13815
 
13816
  *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
13817
 
 
13884
  [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
13885
 
13886
  The program is ill-formed if `Key` is not the same type as
13887
  `KeyContainer::value_type`.
13888
 
13889
+ The effect of calling a member function that takes a
13890
  `sorted_equivalent_t` argument with a range that is not sorted with
13891
  respect to `key_comp()` is undefined.
13892
 
13893
+ The types `iterator` and `const_iterator` meet the constexpr iterator
13894
+ requirements [[iterator.requirements.general]].
13895
+
13896
  #### Definition <a id="flat.multiset.defn">[[flat.multiset.defn]]</a>
13897
 
13898
  ``` cpp
13899
  namespace std {
13900
  template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
 
13905
  using value_type = Key;
13906
  using key_compare = Compare;
13907
  using value_compare = Compare;
13908
  using reference = value_type&;
13909
  using const_reference = const value_type&;
13910
+ using size_type = KeyContainer::size_type;
13911
+ using difference_type = KeyContainer::difference_type;
13912
  using iterator = implementation-defined // type of flat_multiset::iterator; // see [container.requirements]
13913
  using const_iterator = implementation-defined // type of flat_multiset::const_iterator; // see [container.requirements]
13914
  using reverse_iterator = std::reverse_iterator<iterator>;
13915
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
13916
  using container_type = KeyContainer;
13917
 
13918
  // [flat.multiset.cons], constructors
13919
+ constexpr flat_multiset() : flat_multiset(key_compare()) { }
13920
 
13921
+ constexpr explicit flat_multiset(const key_compare& comp)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13922
  : c(), compare(comp) { }
13923
+
13924
+ constexpr explicit flat_multiset(container_type cont,
13925
+ const key_compare& comp = key_compare());
13926
+
13927
+ constexpr flat_multiset(sorted_equivalent_t, container_type cont,
13928
+ const key_compare& comp = key_compare())
13929
+ : c(std::move(cont)), compare(comp) { }
13930
 
13931
  template<class InputIterator>
13932
+ constexpr flat_multiset(InputIterator first, InputIterator last,
13933
  const key_compare& comp = key_compare())
13934
  : c(), compare(comp)
13935
  { insert(first, last); }
13936
+
13937
+ template<class InputIterator>
13938
+ constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
13939
+ const key_compare& comp = key_compare())
13940
+ : c(first, last), compare(comp) { }
13941
 
13942
  template<container-compatible-range<value_type> R>
13943
+ constexpr flat_multiset(from_range_t, R&& rg)
13944
+ : flat_multiset(from_range, std::forward<R>(rg), key_compare()) { }
 
 
13945
  template<container-compatible-range<value_type> R>
13946
+ constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp)
13947
  : flat_multiset(comp)
13948
  { insert_range(std::forward<R>(rg)); }
 
 
13949
 
13950
+ constexpr flat_multiset(initializer_list<value_type> il,
 
13951
  const key_compare& comp = key_compare())
 
 
 
 
 
 
 
 
 
13952
  : flat_multiset(il.begin(), il.end(), comp) { }
 
 
 
 
 
13953
 
13954
+ constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
13955
  const key_compare& comp = key_compare())
13956
+ : flat_multiset(sorted_equivalent, il.begin(), il.end(), comp) { }
 
 
 
 
 
13957
 
13958
+ // [flat.multiset.cons.alloc], constructors with allocators
13959
+
13960
+ template<class Alloc>
13961
+ constexpr explicit flat_multiset(const Alloc& a);
13962
+ template<class Alloc>
13963
+ constexpr flat_multiset(const key_compare& comp, const Alloc& a);
13964
+ template<class Alloc>
13965
+ constexpr flat_multiset(const container_type& cont, const Alloc& a);
13966
+ template<class Alloc>
13967
+ constexpr flat_multiset(const container_type& cont, const key_compare& comp,
13968
+ const Alloc& a);
13969
+ template<class Alloc>
13970
+ constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a);
13971
+ template<class Alloc>
13972
+ constexpr flat_multiset(sorted_equivalent_t, const container_type& cont,
13973
+ const key_compare& comp, const Alloc& a);
13974
+ template<class Alloc>
13975
+ constexpr flat_multiset(const flat_multiset&, const Alloc& a);
13976
+ template<class Alloc>
13977
+ constexpr flat_multiset(flat_multiset&&, const Alloc& a);
13978
+ template<class InputIterator, class Alloc>
13979
+ constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a);
13980
+ template<class InputIterator, class Alloc>
13981
+ constexpr flat_multiset(InputIterator first, InputIterator last,
13982
+ const key_compare& comp, const Alloc& a);
13983
+ template<class InputIterator, class Alloc>
13984
+ constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
13985
+ const Alloc& a);
13986
+ template<class InputIterator, class Alloc>
13987
+ constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
13988
+ const key_compare& comp, const Alloc& a);
13989
+ template<container-compatible-range<value_type> R, class Alloc>
13990
+ constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a);
13991
+ template<container-compatible-range<value_type> R, class Alloc>
13992
+ constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
13993
+ template<class Alloc>
13994
+ constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a);
13995
+ template<class Alloc>
13996
+ constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp,
13997
+ const Alloc& a);
13998
+ template<class Alloc>
13999
+ constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
14000
+ const Alloc& a);
14001
+ template<class Alloc>
14002
+ constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
14003
+ const key_compare& comp, const Alloc& a);
14004
+
14005
+ constexpr flat_multiset& operator=(initializer_list<value_type>);
14006
 
14007
  // iterators
14008
+ constexpr iterator begin() noexcept;
14009
+ constexpr const_iterator begin() const noexcept;
14010
+ constexpr iterator end() noexcept;
14011
+ constexpr const_iterator end() const noexcept;
14012
 
14013
+ constexpr reverse_iterator rbegin() noexcept;
14014
+ constexpr const_reverse_iterator rbegin() const noexcept;
14015
+ constexpr reverse_iterator rend() noexcept;
14016
+ constexpr const_reverse_iterator rend() const noexcept;
14017
 
14018
+ constexpr const_iterator cbegin() const noexcept;
14019
+ constexpr const_iterator cend() const noexcept;
14020
+ constexpr const_reverse_iterator crbegin() const noexcept;
14021
+ constexpr const_reverse_iterator crend() const noexcept;
14022
 
14023
  // capacity
14024
+ constexpr bool empty() const noexcept;
14025
+ constexpr size_type size() const noexcept;
14026
+ constexpr size_type max_size() const noexcept;
14027
 
14028
  // [flat.multiset.modifiers], modifiers
14029
+ template<class... Args> constexpr iterator emplace(Args&&... args);
14030
  template<class... Args>
14031
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
14032
 
14033
+ constexpr iterator insert(const value_type& x)
14034
  { return emplace(x); }
14035
+ constexpr iterator insert(value_type&& x)
14036
  { return emplace(std::move(x)); }
14037
+ constexpr iterator insert(const_iterator position, const value_type& x)
14038
  { return emplace_hint(position, x); }
14039
+ constexpr iterator insert(const_iterator position, value_type&& x)
14040
  { return emplace_hint(position, std::move(x)); }
14041
 
14042
  template<class InputIterator>
14043
+ constexpr void insert(InputIterator first, InputIterator last);
14044
  template<class InputIterator>
14045
+ constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
14046
  template<container-compatible-range<value_type> R>
14047
+ constexpr void insert_range(R&& rg);
14048
 
14049
+ constexpr void insert(initializer_list<value_type> il)
14050
  { insert(il.begin(), il.end()); }
14051
+ constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il)
14052
+ { insert(sorted_equivalent, il.begin(), il.end()); }
14053
 
14054
+ constexpr container_type extract() &&;
14055
+ constexpr void replace(container_type&&);
14056
 
14057
+ constexpr iterator erase(iterator position);
14058
+ constexpr iterator erase(const_iterator position);
14059
+ constexpr size_type erase(const key_type& x);
14060
+ template<class K> constexpr size_type erase(K&& x);
14061
+ constexpr iterator erase(const_iterator first, const_iterator last);
14062
 
14063
+ constexpr void swap(flat_multiset& y) noexcept;
14064
+ constexpr void clear() noexcept;
14065
 
14066
  // observers
14067
+ constexpr key_compare key_comp() const;
14068
+ constexpr value_compare value_comp() const;
14069
 
14070
  // set operations
14071
+ constexpr iterator find(const key_type& x);
14072
+ constexpr const_iterator find(const key_type& x) const;
14073
+ template<class K> constexpr iterator find(const K& x);
14074
+ template<class K> constexpr const_iterator find(const K& x) const;
14075
 
14076
+ constexpr size_type count(const key_type& x) const;
14077
+ template<class K> constexpr size_type count(const K& x) const;
14078
 
14079
+ constexpr bool contains(const key_type& x) const;
14080
+ template<class K> constexpr bool contains(const K& x) const;
14081
 
14082
+ constexpr iterator lower_bound(const key_type& x);
14083
+ constexpr const_iterator lower_bound(const key_type& x) const;
14084
+ template<class K> constexpr iterator lower_bound(const K& x);
14085
+ template<class K> constexpr const_iterator lower_bound(const K& x) const;
14086
 
14087
+ constexpr iterator upper_bound(const key_type& x);
14088
+ constexpr const_iterator upper_bound(const key_type& x) const;
14089
+ template<class K> constexpr iterator upper_bound(const K& x);
14090
+ template<class K> constexpr const_iterator upper_bound(const K& x) const;
14091
 
14092
+ constexpr pair<iterator, iterator> equal_range(const key_type& x);
14093
+ constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
14094
  template<class K>
14095
+ constexpr pair<iterator, iterator> equal_range(const K& x);
14096
  template<class K>
14097
+ constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const;
14098
 
14099
+ friend constexpr bool operator==(const flat_multiset& x, const flat_multiset& y);
14100
 
14101
+ friend constexpr synth-three-way-result<value_type>
14102
  operator<=>(const flat_multiset& x, const flat_multiset& y);
14103
 
14104
+ friend constexpr void swap(flat_multiset& x, flat_multiset& y) noexcept
14105
  { x.swap(y); }
14106
 
14107
  private:
14108
  container_type c; // exposition only
14109
  key_compare compare; // exposition only
 
14131
  flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
14132
  -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
14133
 
14134
  template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
14135
  flat_multiset(InputIterator, InputIterator, Compare = Compare())
14136
+ -> flat_multiset<iter-value-type<InputIterator>, Compare>;
14137
 
14138
  template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
14139
  flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
14140
+ -> flat_multiset<iter-value-type<InputIterator>, Compare>;
14141
 
14142
  template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
14143
  class Allocator = allocator<ranges::range_value_t<R>>>
14144
  flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
14145
  -> flat_multiset<ranges::range_value_t<R>, Compare,
 
14167
  ```
14168
 
14169
  #### Constructors <a id="flat.multiset.cons">[[flat.multiset.cons]]</a>
14170
 
14171
  ``` cpp
14172
+ constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
14173
  ```
14174
 
14175
  *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
14176
  `comp`, and sorts the range \[`begin()`, `end()`) with respect to
14177
  *compare*.
14178
 
14179
+ *Complexity:* Linear in N if `cont` is already sorted with respect to
14180
+ *compare* and otherwise N log N, where N is the value of `cont.size()`
14181
+ before this call.
14182
+
14183
+ #### Constructors with allocators <a id="flat.multiset.cons.alloc">[[flat.multiset.cons.alloc]]</a>
14184
+
14185
+ The constructors in this subclause shall not participate in overload
14186
+ resolution unless `uses_allocator_v<container_type, Alloc>` is `true`.
14187
 
14188
  ``` cpp
14189
+ template<class Alloc>
14190
+ constexpr flat_multiset(const container_type& cont, const Alloc& a);
14191
+ template<class Alloc>
14192
+ constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a);
14193
  ```
14194
 
 
 
14195
  *Effects:* Equivalent to `flat_multiset(cont)` and
14196
  `flat_multiset(cont, comp)`, respectively, except that *c* is
14197
  constructed with uses-allocator
14198
  construction [[allocator.uses.construction]].
14199
 
14200
  *Complexity:* Same as `flat_multiset(cont)` and
14201
  `flat_multiset(cont, comp)`, respectively.
14202
 
14203
  ``` cpp
14204
+ template<class Alloc>
14205
+ constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a);
14206
+ template<class Alloc>
14207
+ constexpr flat_multiset(sorted_equivalent_t, const container_type& cont,
14208
+ const key_compare& comp, const Alloc& a);
14209
  ```
14210
 
14211
+ *Effects:* Equivalent to `flat_multiset(sorted_equivalent, cont)` and
14212
+ `flat_multiset(sorted_equivalent, cont, comp)`, respectively, except
14213
+ that *c* is constructed with uses-allocator
 
 
14214
  construction [[allocator.uses.construction]].
14215
 
14216
  *Complexity:* Linear.
14217
 
14218
  ``` cpp
14219
+ template<class Alloc>
14220
+ constexpr explicit flat_multiset(const Alloc& a);
14221
+ template<class Alloc>
14222
+ constexpr flat_multiset(const key_compare& comp, const Alloc& a);
14223
+ template<class Alloc>
14224
+ constexpr flat_multiset(const flat_multiset&, const Alloc& a);
14225
+ template<class Alloc>
14226
+ constexpr flat_multiset(flat_multiset&&, const Alloc& a);
14227
+ template<class InputIterator, class Alloc>
14228
+ constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a);
14229
+ template<class InputIterator, class Alloc>
14230
+ constexpr flat_multiset(InputIterator first, InputIterator last,
14231
+ const key_compare& comp, const Alloc& a);
14232
+ template<class InputIterator, class Alloc>
14233
+ constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
14234
+ const Alloc& a);
14235
+ template<class InputIterator, class Alloc>
14236
+ constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
14237
+ const key_compare& comp, const Alloc& a);
14238
+ template<container-compatible-range<value_type> R, class Alloc>
14239
+ constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a);
14240
+ template<container-compatible-range<value_type> R, class Alloc>
14241
+ constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
14242
+ template<class Alloc>
14243
+ constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a);
14244
+ template<class Alloc>
14245
+ constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp,
14246
+ const Alloc& a);
14247
+ template<class Alloc>
14248
+ constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a);
14249
+ template<class Alloc>
14250
+ constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
14251
+ const key_compare& comp, const Alloc& a);
14252
  ```
14253
 
 
 
14254
  *Effects:* Equivalent to the corresponding non-allocator constructors
14255
  except that *c* is constructed with uses-allocator
14256
  construction [[allocator.uses.construction]].
14257
 
14258
  #### Modifiers <a id="flat.multiset.modifiers">[[flat.multiset.modifiers]]</a>
14259
 
14260
  ``` cpp
14261
+ template<class... Args> constexpr iterator emplace(Args&&... args);
14262
  ```
14263
 
14264
  *Constraints:* `is_constructible_v<value_type, Args...>` is `true`.
14265
 
14266
  *Effects:* First, initializes an object `t` of type `value_type` with
 
14273
 
14274
  *Returns:* An iterator that points to the inserted element.
14275
 
14276
  ``` cpp
14277
  template<class InputIterator>
14278
+ constexpr void insert(InputIterator first, InputIterator last);
14279
  ```
14280
 
14281
  *Effects:* Adds elements to *c* as if by:
14282
 
14283
  ``` cpp
 
14294
  *Remarks:* Since this operation performs an in-place merge, it may
14295
  allocate memory.
14296
 
14297
  ``` cpp
14298
  template<class InputIterator>
14299
+ constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
14300
  ```
14301
 
14302
  *Effects:* Equivalent to `insert(first, last)`.
14303
 
14304
  *Complexity:* Linear.
14305
 
14306
  ``` cpp
14307
+ constexpr void swap(flat_multiset& y) noexcept;
14308
  ```
14309
 
14310
  *Effects:* Equivalent to:
14311
 
14312
  ``` cpp
14313
  ranges::swap(compare, y.compare);
14314
  ranges::swap(c, y.c);
14315
  ```
14316
 
14317
  ``` cpp
14318
+ constexpr container_type extract() &&;
14319
  ```
14320
 
14321
  *Ensures:* `*this` is emptied, even if the function exits via an
14322
  exception.
14323
 
14324
+ *Returns:* `std::move(`*`c`*`)`.
14325
 
14326
  ``` cpp
14327
+ constexpr void replace(container_type&& cont);
14328
  ```
14329
 
14330
  *Preconditions:* The elements of `cont` are sorted with respect to
14331
  *compare*.
14332
 
14333
+ *Effects:* Equivalent to: *`c`*` = std::move(cont);`
14334
 
14335
  #### Erasure <a id="flat.multiset.erasure">[[flat.multiset.erasure]]</a>
14336
 
14337
  ``` cpp
14338
  template<class Key, class Compare, class KeyContainer, class Predicate>
14339
+ constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type
14340
  erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
14341
  ```
14342
 
14343
  *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
14344
 
 
14413
  ### Contiguous access <a id="views.contiguous">[[views.contiguous]]</a>
14414
 
14415
  #### Header `<span>` synopsis <a id="span.syn">[[span.syn]]</a>
14416
 
14417
  ``` cpp
14418
+ #include <initializer_list> // see [initializer.list.syn]
14419
+
14420
+ // mostly freestanding
14421
  namespace std {
14422
  // constants
14423
  inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
14424
 
14425
+ template<class T>
14426
+ concept integral-constant-like = // exposition only
14427
+ is_integral_v<remove_cvref_t<decltype(T::value)>> &&
14428
+ !is_same_v<bool, remove_const_t<decltype(T::value)>> &&
14429
+ convertible_to<T, decltype(T::value)> &&
14430
+ equality_comparable_with<T, decltype(T::value)> &&
14431
+ bool_constant<T() == T::value>::value &&
14432
+ bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value;
14433
+
14434
+ template<class T>
14435
+ constexpr size_t maybe-static-ext = dynamic_extent; // exposition only
14436
+ template<integral-constant-like T>
14437
+ constexpr size_t maybe-static-ext<T> = {T::value};
14438
+
14439
  // [views.span], class template span
14440
  template<class ElementType, size_t Extent = dynamic_extent>
14441
+ class span; // partially freestanding
14442
 
14443
  template<class ElementType, size_t Extent>
14444
+ constexpr bool ranges::\libspec{enable_view}{span}<span<ElementType, Extent>> = true;
14445
  template<class ElementType, size_t Extent>
14446
+ constexpr bool ranges::\libspec{enable_borrowed_range}{span}<span<ElementType, Extent>> = true;
14447
 
14448
  // [span.objectrep], views of object representation
14449
  template<class ElementType, size_t Extent>
14450
  span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
14451
  as_bytes(span<ElementType, Extent> s) noexcept;
 
14497
  constexpr span(array<T, N>& arr) noexcept;
14498
  template<class T, size_t N>
14499
  constexpr span(const array<T, N>& arr) noexcept;
14500
  template<class R>
14501
  constexpr explicit(extent != dynamic_extent) span(R&& r);
14502
+ constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il);
14503
  constexpr span(const span& other) noexcept = default;
14504
  template<class OtherElementType, size_t OtherExtent>
14505
  constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
14506
 
 
 
14507
  constexpr span& operator=(const span& other) noexcept = default;
14508
 
14509
  // [span.sub], subviews
14510
  template<size_t Count>
14511
  constexpr span<element_type, Count> first() const;
 
14520
  size_type offset, size_type count = dynamic_extent) const;
14521
 
14522
  // [span.obs], observers
14523
  constexpr size_type size() const noexcept;
14524
  constexpr size_type size_bytes() const noexcept;
14525
+ constexpr bool empty() const noexcept;
14526
 
14527
  // [span.elem], element access
14528
  constexpr reference operator[](size_type idx) const;
14529
+ constexpr reference at(size_type idx) const; // freestanding-deleted
14530
  constexpr reference front() const;
14531
  constexpr reference back() const;
14532
  constexpr pointer data() const noexcept;
14533
 
14534
  // [span.iterators], iterator support
 
14545
  pointer data_; // exposition only
14546
  size_type size_; // exposition only
14547
  };
14548
 
14549
  template<class It, class EndOrSize>
14550
+ span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>,
14551
+ maybe-static-ext<EndOrSize>>;
14552
  template<class T, size_t N>
14553
  span(T (&)[N]) -> span<T, N>;
14554
  template<class T, size_t N>
14555
  span(array<T, N>&) -> span<T, N>;
14556
  template<class T, size_t N>
 
14564
  [[term.trivially.copyable.type]].
14565
 
14566
  `ElementType` is required to be a complete object type that is not an
14567
  abstract class type.
14568
 
14569
+ For a `span` `s`, any operation that invalidates a pointer in the range
14570
+ \[`s.data()`, `s.data() + s.size()`) invalidates pointers, iterators,
14571
+ and references to elements of `s`.
14572
+
14573
  ##### Constructors, copy, and assignment <a id="span.cons">[[span.cons]]</a>
14574
 
14575
  ``` cpp
14576
  constexpr span() noexcept;
14577
  ```
 
14594
 
14595
  *Preconditions:*
14596
 
14597
  - \[`first`, `first + count`) is a valid range.
14598
  - `It` models `contiguous_iterator`.
 
 
14599
 
14600
+ If `extent` is not equal to `dynamic_extent`, then `count == extent` is
14601
+ `true`.
14602
+
14603
+ *Effects:* Initializes *data\_* with `to_address(first)` and *size\_*
14604
  with `count`.
14605
 
14606
  *Throws:* Nothing.
14607
 
14608
  ``` cpp
 
14619
  - `End` satisfies `sized_sentinel_for<It>`.
14620
  - `is_convertible_v<End, size_t>` is `false`.
14621
 
14622
  *Preconditions:*
14623
 
 
 
14624
  - \[`first`, `last`) is a valid range.
14625
  - `It` models `contiguous_iterator`.
14626
  - `End` models `sized_sentinel_for<It>`.
14627
 
14628
+ If `extent` is not equal to `dynamic_extent`, then
14629
+ `(last - first) == extent` is `true`.
14630
+
14631
+ *Effects:* Initializes *data\_* with `to_address(first)` and *size\_*
14632
  with `last - first`.
14633
 
14634
  *Throws:* When and what `last - first` throws.
14635
 
14636
  ``` cpp
14637
  template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
14638
  template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
14639
  template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
14640
  ```
14641
 
14642
+ *Constraints:* Let `U` be `remove_pointer_t<decltype(std::data(arr))>`.
14643
 
14644
  - `extent == dynamic_extent || N == extent` is `true`, and
14645
  - `is_convertible_v<U(*)[], element_type(*)[]>` is `true`.
14646
  \[*Note 3*: The intent is to allow only qualification conversions of
14647
  the array element type to `element_type`. — *end note*]
 
14649
  *Effects:* Constructs a `span` that is a view over the supplied array.
14650
 
14651
  [*Note 1*: `type_identity_t` affects class template argument
14652
  deduction. — *end note*]
14653
 
14654
+ *Ensures:* `size() == N && data() == std::data(arr)` is `true`.
14655
 
14656
  ``` cpp
14657
  template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
14658
  ```
14659
 
 
14670
  \[*Note 4*: The intent is to allow only qualification conversions of
14671
  the range reference type to `element_type`. — *end note*]
14672
 
14673
  *Preconditions:*
14674
 
 
 
14675
  - `R` models `ranges::contiguous_range` and `ranges::sized_range`.
14676
  - If `is_const_v<element_type>` is `false`, `R` models
14677
  `ranges::borrowed_range`.
14678
 
14679
+ If `extent` is not equal to `dynamic_extent`, then
14680
+ `ranges::size(r) == extent` is `true`.
14681
+
14682
+ *Effects:* Initializes *data\_* with `ranges::data(r)` and *size\_* with
14683
+ `ranges::size(r)`.
14684
 
14685
  *Throws:* What and when `ranges::data(r)` and `ranges::size(r)` throw.
14686
 
14687
+ ``` cpp
14688
+ constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il);
14689
+ ```
14690
+
14691
+ *Constraints:* `is_const_v<element_type>` is `true`.
14692
+
14693
+ If `extent` is not equal to `dynamic_extent`, then `il.size() == extent`
14694
+ is `true`.
14695
+
14696
+ *Effects:* Initializes *data\_* with `il.begin()` and *size\_* with
14697
+ `il.size()`.
14698
+
14699
  ``` cpp
14700
  constexpr span(const span& other) noexcept = default;
14701
  ```
14702
 
14703
  *Ensures:* `other.size() == size() && other.data() == data()`.
 
14714
  - `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is
14715
  `true`. \[*Note 5*: The intent is to allow only qualification
14716
  conversions of the `OtherElementType` to
14717
  `element_type`. — *end note*]
14718
 
14719
+ If `extent` is not equal to `dynamic_extent`, then `s.size() == extent`
14720
+ is `true`.
14721
 
14722
  *Effects:* Constructs a `span` that is a view over the range
14723
  \[`s.data()`, `s.data() + s.size()`).
14724
 
14725
  *Ensures:* `size() == s.size() && data() == s.data()`.
 
14738
 
14739
  ##### Deduction guides <a id="span.deduct">[[span.deduct]]</a>
14740
 
14741
  ``` cpp
14742
  template<class It, class EndOrSize>
14743
+ span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>,
14744
+ maybe-static-ext<EndOrSize>>;
14745
  ```
14746
 
14747
  *Constraints:* `It` satisfies `contiguous_iterator`.
14748
 
14749
  ``` cpp
 
14759
  template<size_t Count> constexpr span<element_type, Count> first() const;
14760
  ```
14761
 
14762
  *Mandates:* `Count <= Extent` is `true`.
14763
 
14764
+ `Count <= size()` is `true`.
14765
 
14766
  *Effects:* Equivalent to: `return R{data(), Count};` where `R` is the
14767
  return type.
14768
 
14769
  ``` cpp
14770
  template<size_t Count> constexpr span<element_type, Count> last() const;
14771
  ```
14772
 
14773
  *Mandates:* `Count <= Extent` is `true`.
14774
 
14775
+ `Count <= size()` is `true`.
14776
 
14777
  *Effects:* Equivalent to: `return R{data() + (size() - Count), Count};`
14778
  where `R` is the return type.
14779
 
14780
  ``` cpp
 
14788
  Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset)
14789
  ```
14790
 
14791
  is `true`.
14792
 
 
 
14793
  ``` cpp
14794
  Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)
14795
  ```
14796
 
14797
  is `true`.
 
14813
 
14814
  ``` cpp
14815
  constexpr span<element_type, dynamic_extent> first(size_type count) const;
14816
  ```
14817
 
14818
+ `count <= size()` is `true`.
14819
 
14820
  *Effects:* Equivalent to: `return {data(), count};`
14821
 
14822
  ``` cpp
14823
  constexpr span<element_type, dynamic_extent> last(size_type count) const;
14824
  ```
14825
 
14826
+ `count <= size()` is `true`.
14827
 
14828
  *Effects:* Equivalent to: `return {data() + (size() - count), count};`
14829
 
14830
  ``` cpp
14831
  constexpr span<element_type, dynamic_extent> subspan(
14832
  size_type offset, size_type count = dynamic_extent) const;
14833
  ```
14834
 
 
 
14835
  ``` cpp
14836
  offset <= size() && (count == dynamic_extent || count <= size() - offset)
14837
  ```
14838
 
14839
  is `true`.
 
14857
  ```
14858
 
14859
  *Effects:* Equivalent to: `return size() * sizeof(element_type);`
14860
 
14861
  ``` cpp
14862
+ constexpr bool empty() const noexcept;
14863
  ```
14864
 
14865
  *Effects:* Equivalent to: `return size() == 0;`
14866
 
14867
  ##### Element access <a id="span.elem">[[span.elem]]</a>
14868
 
14869
  ``` cpp
14870
  constexpr reference operator[](size_type idx) const;
14871
  ```
14872
 
14873
+ `idx < size()` is `true`.
14874
 
14875
+ *Returns:* `*(data() + idx)`.
14876
+
14877
+ *Throws:* Nothing.
14878
+
14879
+ ``` cpp
14880
+ constexpr reference at(size_type idx) const;
14881
+ ```
14882
+
14883
+ *Returns:* `*(data() + idx)`.
14884
+
14885
+ *Throws:* `out_of_range` if `idx >= size()` is `true`.
14886
 
14887
  ``` cpp
14888
  constexpr reference front() const;
14889
  ```
14890
 
14891
+ `empty()` is `false`.
14892
 
14893
+ *Returns:* `*data()`.
14894
+
14895
+ *Throws:* Nothing.
14896
 
14897
  ``` cpp
14898
  constexpr reference back() const;
14899
  ```
14900
 
14901
+ `empty()` is `false`.
14902
 
14903
+ *Returns:* `*(data() + (size() - 1))`.
14904
+
14905
+ *Throws:* Nothing.
14906
 
14907
  ``` cpp
14908
  constexpr pointer data() const noexcept;
14909
  ```
14910
 
14911
+ *Returns:* *data\_*.
14912
 
14913
  ##### Iterator support <a id="span.iterators">[[span.iterators]]</a>
14914
 
14915
  ``` cpp
14916
  using iterator = implementation-defined // type of span::iterator;
 
14998
  the interval [Lᵢ, Uᵢ) of S.
14999
 
15000
  #### Header `<mdspan>` synopsis <a id="mdspan.syn">[[mdspan.syn]]</a>
15001
 
15002
  ``` cpp
15003
+ // mostly freestanding
15004
  namespace std {
15005
  // [mdspan.extents], class template extents
15006
  template<class IndexType, size_t... Extents>
15007
  class extents;
15008
 
15009
  // [mdspan.extents.dextents], alias template dextents
15010
  template<class IndexType, size_t Rank>
15011
  using dextents = see below;
15012
 
15013
+ // [mdspan.extents.dims], alias template dims
15014
+ template<size_t Rank, class IndexType = size_t>
15015
+ using dims = see below;
15016
+
15017
  // [mdspan.layout], layout mapping
15018
  struct layout_left;
15019
  struct layout_right;
15020
  struct layout_stride;
15021
+ template<size_t PaddingValue = dynamic_extent>
15022
+ struct layout_left_padded;
15023
+ template<size_t PaddingValue = dynamic_extent>
15024
+ struct layout_right_padded;
15025
 
15026
  // [mdspan.accessor.default], class template default_accessor
15027
  template<class ElementType>
15028
  class default_accessor;
15029
 
15030
+ // [mdspan.accessor.aligned], class template aligned_accessor
15031
+ template<class ElementType, size_t ByteAlignment>
15032
+ class aligned_accessor;
15033
+
15034
  // [mdspan.mdspan], class template mdspan
15035
  template<class ElementType, class Extents, class LayoutPolicy = layout_right,
15036
  class AccessorPolicy = default_accessor<ElementType>>
15037
+ class mdspan; // partially freestanding
15038
+
15039
+ // [mdspan.sub], submdspan creation
15040
+ template<class OffsetType, class LengthType, class StrideType>
15041
+ struct strided_slice;
15042
+
15043
+ template<class LayoutMapping>
15044
+ struct submdspan_mapping_result;
15045
+
15046
+ struct full_extent_t { explicit full_extent_t() = default; };
15047
+ inline constexpr full_extent_t full_extent{};
15048
+
15049
+ template<class IndexType, size_t... Extents, class... SliceSpecifiers>
15050
+ constexpr auto submdspan_extents(const extents<IndexType, Extents...>&, SliceSpecifiers...);
15051
+
15052
+ // [mdspan.sub.sub], submdspan function template
15053
+ template<class ElementType, class Extents, class LayoutPolicy,
15054
+ class AccessorPolicy, class... SliceSpecifiers>
15055
+ constexpr auto submdspan(
15056
+ const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
15057
+ SliceSpecifiers... slices) -> see below;
15058
+
15059
+ template<class T, class IndexType>
15060
+ concept index-pair-like = // exposition only
15061
+ pair-like<T> &&
15062
+ convertible_to<tuple_element_t<0, T>, IndexType> &&
15063
+ convertible_to<tuple_element_t<1, T>, IndexType>;
15064
  }
15065
  ```
15066
 
15067
  #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
15068
 
15069
  ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
15070
 
15071
  The class template `extents` represents a multidimensional index space
15072
+ of rank equal to `sizeof...(Extents)`. In  [[views]], `extents` is used
15073
+ synonymously with multidimensional index space.
15074
 
15075
  ``` cpp
15076
  namespace std {
15077
  template<class IndexType, size_t... Extents>
15078
  class extents {
 
15252
 
15253
  - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
15254
  r for which Eᵣ is a static extent, and
15255
  - either
15256
  - `sizeof...(exts) == 0` is `true`, or
15257
+ - each element of `exts` is representable as a nonnegative value of
15258
+ type `index_type`.
15259
 
15260
  *Ensures:* `*this == extents(exts_arr)` is `true`.
15261
 
15262
  ``` cpp
15263
  template<class OtherIndexType, size_t N>
 
15279
 
15280
  - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
15281
  for which Eᵣ is a static extent, and
15282
  - either
15283
  - `N` is zero, or
15284
+ - `exts[`r`]` is representable as a nonnegative value of type
15285
  `index_type` for every rank index r.
15286
 
15287
  *Effects:*
15288
 
15289
+ - If `N` equals `rank_dynamic()`, for all d in the range
15290
  [0, `rank_dynamic()`), direct-non-list-initializes
15291
  *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
15292
  - Otherwise, for all d in the range [0, `rank_dynamic()`),
15293
  direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
15294
  `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
 
15298
  explicit extents(Integrals...) -> see below;
15299
  ```
15300
 
15301
  *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
15302
 
15303
+ *Remarks:* The deduced type is
15304
+ `extents<size_t, maybe-static-ext<Integrals>...>`.
15305
 
15306
  ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
15307
 
15308
  ``` cpp
15309
  static constexpr size_t static_extent(rank_type i) noexcept;
 
15342
 
15343
  *Result:* A type `E` that is a specialization of `extents` such that
15344
  `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
15345
  `E::index_type` denotes `IndexType`.
15346
 
15347
+ ##### Alias template `dims` <a id="mdspan.extents.dims">[[mdspan.extents.dims]]</a>
15348
+
15349
+ ``` cpp
15350
+ template<size_t Rank, class IndexType = size_t>
15351
+ using dims = see below;
15352
+ ```
15353
+
15354
+ *Result:* A type `E` that is a specialization of `extents` such that
15355
+ `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
15356
+ `E::index_type` denotes `IndexType`.
15357
+
15358
  #### Layout mapping <a id="mdspan.layout">[[mdspan.layout]]</a>
15359
 
15360
  ##### General <a id="mdspan.layout.general">[[mdspan.layout.general]]</a>
15361
 
15362
+ In [[mdspan.layout.reqmts]] and [[mdspan.layout.policy.reqmts]]:
 
15363
 
15364
  - `M` denotes a layout mapping class.
15365
  - `m` denotes a (possibly const) value of type `M`.
15366
  - `i` and `j` are packs of (possibly const) integers that are
15367
  multidimensional indices in `m.extents()` [[mdspan.overview]].
 
15370
  - `r` is a (possibly const) rank index of `typename M::extents_type`.
15371
  - `dᵣ` is a pack of (possibly const) integers for which
15372
  `sizeof...(dᵣ) == M::extents_type::rank()` is `true`, the rᵗʰ element
15373
  is equal to 1, and all other elements are equal to 0.
15374
 
15375
+ In [[mdspan.layout.reqmts]] through [[mdspan.layout.stride]]:
15376
+
15377
+ - Let *`is-mapping-of`* be the exposition-only variable template defined
15378
  as follows:
 
15379
  ``` cpp
15380
  template<class Layout, class Mapping>
15381
  constexpr bool is-mapping-of = // exposition only
15382
  is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
15383
  ```
15384
+ - Let *`is-layout-left-padded-mapping-of`* be the exposition-only
15385
+ variable template defined as follows:
15386
+ ``` cpp
15387
+ template<class Mapping>
15388
+ constexpr bool is-layout-left-padded-mapping-of = see below; // exposition only
15389
+ ```
15390
+
15391
+ where `is-layout-left-padded-mapping-of<Mapping>` is `true` if and
15392
+ only if `Mapping` denotes a specialization of
15393
+ `layout_left_padded<S>::mapping` for some value `S` of type `size_t`.
15394
+ - Let *`is-layout-right-padded-mapping-of`* be the exposition-only
15395
+ variable template defined as follows:
15396
+ ``` cpp
15397
+ template<class Mapping>
15398
+ constexpr bool is-layout-right-padded-mapping-of = see below; // exposition only
15399
+ ```
15400
+
15401
+ where `is-layout-right-padded-mapping-of<Mapping>` is `true` if and
15402
+ only if `Mapping` denotes a specialization of
15403
+ `layout_right_padded<S>::mapping` for some value `S` of type `size_t`.
15404
+ - For nonnegative integers x and y, let LEAST-MULTIPLE-AT-LEAST(x, y)
15405
+ denote
15406
+ - y if x is zero,
15407
+ - otherwise, the least multiple of x that is greater than or equal to
15408
+ y.
15409
 
15410
  ##### Requirements <a id="mdspan.layout.reqmts">[[mdspan.layout.reqmts]]</a>
15411
 
15412
  A type `M` meets the *layout mapping* requirements if
15413
 
 
15531
 
15532
  *Result:* `typename M::index_type`
15533
 
15534
  *Returns:* sᵣ as defined in `m.is_strided()` above.
15535
 
15536
+ [*Note 5*: It is not required for `m.stride(r)` to be well-formed if
15537
+ `m.extents().rank()` is zero, even if `m.is_always_strided()` is
15538
+ `true`. — *end note*]
15539
+
15540
  ``` cpp
15541
  M::is_always_unique()
15542
  ```
15543
 
15544
  *Result:* A constant expression [[expr.const]] of type `bool`.
15545
 
15546
  *Returns:* `true` only if `m.is_unique()` is `true` for all possible
15547
  objects `m` of type `M`.
15548
 
15549
+ [*Note 6*: A mapping can return `false` even if the above condition is
15550
  met. For certain layout mappings, it is possibly not feasible to
15551
  determine whether every instance is unique. — *end note*]
15552
 
15553
  ``` cpp
15554
  M::is_always_exhaustive()
 
15557
  *Result:* A constant expression [[expr.const]] of type `bool`.
15558
 
15559
  *Returns:* `true` only if `m.is_exhaustive()` is `true` for all possible
15560
  objects `m` of type `M`.
15561
 
15562
+ [*Note 7*: A mapping can return `false` even if the above condition is
15563
  met. For certain layout mappings, it is possibly not feasible to
15564
  determine whether every instance is exhaustive. — *end note*]
15565
 
15566
  ``` cpp
15567
  M::is_always_strided()
 
15570
  *Result:* A constant expression [[expr.const]] of type `bool`.
15571
 
15572
  *Returns:* `true` only if `m.is_strided()` is `true` for all possible
15573
  objects `m` of type `M`.
15574
 
15575
+ [*Note 8*: A mapping can return `false` even if the above condition is
15576
  met. For certain layout mappings, it is possibly not feasible to
15577
  determine whether every instance is strided. — *end note*]
15578
 
15579
  ##### Layout mapping policy requirements <a id="mdspan.layout.policy.reqmts">[[mdspan.layout.policy.reqmts]]</a>
15580
 
 
15599
  };
15600
  struct layout_stride {
15601
  template<class Extents>
15602
  class mapping;
15603
  };
15604
+
15605
+ template<size_t PaddingValue>
15606
+ struct layout_left_padded {
15607
+ template<class Extents> class mapping;
15608
+ };
15609
+ template<size_t PaddingValue>
15610
+ struct layout_right_padded {
15611
+ template<class Extents> class mapping;
15612
+ };
15613
  }
15614
  ```
15615
 
15616
+ Each of `layout_left`, `layout_right`, and `layout_stride`, as well as
15617
+ each specialization of `layout_left_padded` and `layout_right_padded`,
15618
+ meets the layout mapping policy requirements and is a trivially copyable
15619
+ type. Furthermore, `is_trivially_default_constructible_v<T>` is `true`
15620
+ for any such type `T`.
15621
 
15622
  ##### Class template `layout_left::mapping` <a id="mdspan.layout.left">[[mdspan.layout.left]]</a>
15623
 
15624
  ###### Overview <a id="mdspan.layout.left.overview">[[mdspan.layout.left.overview]]</a>
15625
 
 
15630
  namespace std {
15631
  template<class Extents>
15632
  class layout_left::mapping {
15633
  public:
15634
  using extents_type = Extents;
15635
+ using index_type = extents_type::index_type;
15636
+ using size_type = extents_type::size_type;
15637
+ using rank_type = extents_type::rank_type;
15638
  using layout_type = layout_left;
15639
 
15640
  // [mdspan.layout.left.cons], constructors
15641
  constexpr mapping() noexcept = default;
15642
  constexpr mapping(const mapping&) noexcept = default;
 
15645
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15646
  mapping(const mapping<OtherExtents>&) noexcept;
15647
  template<class OtherExtents>
15648
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15649
  mapping(const layout_right::mapping<OtherExtents>&) noexcept;
15650
+ template<class LayoutLeftPaddedMapping>
15651
+ constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
15652
+ extents_type>)
15653
+ mapping(const LayoutLeftPaddedMapping&) noexcept;
15654
  template<class OtherExtents>
15655
  constexpr explicit(extents_type::rank() > 0)
15656
  mapping(const layout_stride::mapping<OtherExtents>&);
15657
 
15658
  constexpr mapping& operator=(const mapping&) noexcept = default;
 
15678
  template<class OtherExtents>
15679
  friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
15680
 
15681
  private:
15682
  extents_type extents_{}; // exposition only
15683
+
15684
+ // [mdspan.sub.map], submdspan mapping specialization
15685
+ template<class... SliceSpecifiers>
15686
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
15687
+ -> see below;
15688
+
15689
+ template<class... SliceSpecifiers>
15690
+ friend constexpr auto submdspan_mapping(
15691
+ const mapping& src, SliceSpecifiers... slices) {
15692
+ return src.submdspan-mapping-impl(slices...);
15693
+ }
15694
  };
15695
  }
15696
  ```
15697
 
15698
  If `Extents` is not a specialization of `extents`, then the program is
 
15730
 
15731
  *Effects:* Direct-non-list-initializes *extents\_* with
15732
  `other.extents()`.
15733
 
15734
  ``` cpp
15735
+ template<class OtherExtents>
15736
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15737
  mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
15738
  ```
15739
 
15740
  *Constraints:*
 
15746
  value of type `index_type` [[basic.fundamental]].
15747
 
15748
  *Effects:* Direct-non-list-initializes *extents\_* with
15749
  `other.extents()`.
15750
 
15751
+ ``` cpp
15752
+ template<class LayoutLeftPaddedMapping>
15753
+ constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
15754
+ extents_type>)
15755
+ mapping(const LayoutLeftPaddedMapping&) noexcept;
15756
+ ```
15757
+
15758
+ *Constraints:*
15759
+
15760
+ - *`is-layout-left-padded-mapping-of`*`<LayoutLeftPaddedMapping>` is
15761
+ `true`.
15762
+ - `is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>`
15763
+ is `true`.
15764
+
15765
+ *Mandates:* If
15766
+
15767
+ - `Extents::rank()` is greater than one,
15768
+ - `Extents::static_extent(0)` does not equal `dynamic_extent`, and
15769
+ - `LayoutLeftPaddedMapping::`*`static-padding-stride`* does not equal
15770
+ `dynamic_extent`,
15771
+
15772
+ then `Extents::static_extent(0)` equals
15773
+ `LayoutLeftPaddedMapping::`*`static-padding-stride`*.
15774
+
15775
+ *Preconditions:*
15776
+
15777
+ - If `extents_type::rank() > 1` is `true`, then `other.stride(1)` equals
15778
+ `other.extents().extent(0)`.
15779
+ - `other.required_span_size()` is representable as a value of type
15780
+ `index_type`.
15781
+
15782
+ *Effects:* Direct-non-list-initializes `extents_` with
15783
+ `other.extents()`.
15784
+
15785
  ``` cpp
15786
  template<class OtherExtents>
15787
  constexpr explicit(extents_type::rank() > 0)
15788
  mapping(const layout_stride::mapping<OtherExtents>& other);
15789
  ```
 
15835
  ``` cpp
15836
  return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
15837
  ```
15838
 
15839
  ``` cpp
15840
+ constexpr index_type stride(rank_type i) const noexcept;
15841
  ```
15842
 
15843
  *Constraints:* `extents_type::rank() > 0` is `true`.
15844
 
15845
  *Preconditions:* `i < extents_type::rank()` is `true`.
 
15866
  namespace std {
15867
  template<class Extents>
15868
  class layout_right::mapping {
15869
  public:
15870
  using extents_type = Extents;
15871
+ using index_type = extents_type::index_type;
15872
+ using size_type = extents_type::size_type;
15873
+ using rank_type = extents_type::rank_type;
15874
  using layout_type = layout_right;
15875
 
15876
  // [mdspan.layout.right.cons], constructors
15877
  constexpr mapping() noexcept = default;
15878
  constexpr mapping(const mapping&) noexcept = default;
 
15881
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15882
  mapping(const mapping<OtherExtents>&) noexcept;
15883
  template<class OtherExtents>
15884
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
15885
  mapping(const layout_left::mapping<OtherExtents>&) noexcept;
15886
+ template<class LayoutRightPaddedMapping>
15887
+ constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
15888
+ extents_type>)
15889
+ mapping(const LayoutRightPaddedMapping&) noexcept;
15890
  template<class OtherExtents>
15891
  constexpr explicit(extents_type::rank() > 0)
15892
  mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
15893
 
15894
  constexpr mapping& operator=(const mapping&) noexcept = default;
 
15914
  template<class OtherExtents>
15915
  friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
15916
 
15917
  private:
15918
  extents_type extents_{}; // exposition only
15919
+
15920
+ // [mdspan.sub.map], submdspan mapping specialization
15921
+ template<class... SliceSpecifiers>
15922
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
15923
+ -> see below;
15924
+
15925
+ template<class... SliceSpecifiers>
15926
+ friend constexpr auto submdspan_mapping(
15927
+ const mapping& src, SliceSpecifiers... slices) {
15928
+ return src.submdspan-mapping-impl(slices...);
15929
+ }
15930
  };
15931
  }
15932
  ```
15933
 
15934
  If `Extents` is not a specialization of `extents`, then the program is
 
15982
  value of type `index_type` [[basic.fundamental]].
15983
 
15984
  *Effects:* Direct-non-list-initializes *extents\_* with
15985
  `other.extents()`.
15986
 
15987
+ ``` cpp
15988
+ template<class LayoutRightPaddedMapping>
15989
+ constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
15990
+ extents_type>)
15991
+ mapping(const LayoutRightPaddedMapping&) noexcept;
15992
+ ```
15993
+
15994
+ *Constraints:*
15995
+
15996
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
15997
+ `true`.
15998
+ - `is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_- type>`
15999
+ is `true`.
16000
+
16001
+ *Mandates:* If
16002
+
16003
+ - `Extents::rank()` is greater than one,
16004
+ - `Extents::static_extent(Extents::rank() - 1)` does not equal
16005
+ `dynamic_extent`, and
16006
+ - `LayoutRightPaddedMapping::`*`static-padding-stride`* does not equal
16007
+ `dynamic_extent`,
16008
+
16009
+ then `Extents::static_extent(Extents::rank() - 1)` equals
16010
+ `LayoutRightPaddedMapping::`*`static-padding-stride`*.
16011
+
16012
+ *Preconditions:*
16013
+
16014
+ - If `extents_type::rank() > 1` is `true`, then
16015
+ `other.stride(extents_type::rank() - 2)` equals
16016
+ `other.extents().extent(extents_type::rank() - 1)`.
16017
+ - `other.required_span_size()` is representable as a value of type
16018
+ `index_type`.
16019
+
16020
+ *Effects:* Direct-non-list-initializes `extents_` with
16021
+ `other.extents()`.
16022
+
16023
  ``` cpp
16024
  template<class OtherExtents>
16025
  constexpr explicit(extents_type::rank() > 0)
16026
  mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
16027
  ```
 
16041
  `other.extents()`.
16042
 
16043
  ###### Observers <a id="mdspan.layout.right.obs">[[mdspan.layout.right.obs]]</a>
16044
 
16045
  ``` cpp
16046
+ constexpr index_type required_span_size() const noexcept;
16047
  ```
16048
 
16049
  *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
16050
 
16051
  ``` cpp
 
16104
  namespace std {
16105
  template<class Extents>
16106
  class layout_stride::mapping {
16107
  public:
16108
  using extents_type = Extents;
16109
+ using index_type = extents_type::index_type;
16110
+ using size_type = extents_type::size_type;
16111
+ using rank_type = extents_type::rank_type;
16112
  using layout_type = layout_stride;
16113
 
16114
  private:
16115
  static constexpr rank_type rank_ = extents_type::rank(); // exposition only
16116
 
 
16151
  friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
16152
 
16153
  private:
16154
  extents_type extents_{}; // exposition only
16155
  array<index_type, rank_> strides_{}; // exposition only
16156
+
16157
+ // [mdspan.sub.map], submdspan mapping specialization
16158
+ template<class... SliceSpecifiers>
16159
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
16160
+ -> see below;
16161
+
16162
+ template<class... SliceSpecifiers>
16163
+ friend constexpr auto submdspan_mapping(
16164
+ const mapping& src, SliceSpecifiers... slices) {
16165
+ return src.submdspan-mapping-impl(slices...);
16166
+ }
16167
  };
16168
  }
16169
  ```
16170
 
16171
  If `Extents` is not a specialization of `extents`, then the program is
 
16184
 
16185
  - `1`, if `e.rank() == 0` is `true`,
16186
  - otherwise `0`, if the size of the multidimensional index space `e` is
16187
  0,
16188
  - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
16189
+ ``` cpp
16190
+ extents_type::index-cast(strides[r])
16191
+ ```
16192
+
16193
+ for all r in the range [0, `e.rank()`).
16194
 
16195
  Let `OFFSET(m)` be:
16196
 
16197
  - `m()`, if `e.rank() == 0` is `true`,
16198
  - otherwise `0`, if the size of the multidimensional index space `e` is
 
16260
  - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
16261
  `true`.
16262
 
16263
  *Preconditions:*
16264
 
16265
+ - The result of converting `s[`i`]` to `index_type` is greater than `0`
16266
+ for all i in the range [0, rank_).
16267
  - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
16268
  `index_type` [[basic.fundamental]].
16269
  - If *rank\_* is greater than 0, then there exists a permutation P of
16270
  the integers in the range [0, rank_), such that
16271
  `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
 
16293
  - `StridedLayoutMapping::is_always_strided()` is `true`.
16294
 
16295
  *Preconditions:*
16296
 
16297
  - `StridedLayoutMapping` meets the layout mapping
16298
+ requirements [[mdspan.layout.reqmts]],
16299
  - `other.stride(`r`) > 0` is `true` for every rank index r of
16300
  `extents()`,
16301
  - `other.required_span_size()` is representable as a value of type
16302
  `index_type` [[basic.fundamental]], and
16303
  - *`OFFSET`*`(other) == 0` is `true`.
 
16309
 
16310
  Remarks: The expression inside `explicit` is equivalent to:
16311
 
16312
  ``` cpp
16313
  !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
16314
+ (is-mapping-of<layout_left, StridedLayoutMapping> ||
16315
+ is-mapping-of<layout_right, StridedLayoutMapping> ||
16316
+ is-layout-left-padded-mapping-of<StridedLayoutMapping> ||
16317
+ is-layout-right-padded-mapping-of<StridedLayoutMapping> ||
16318
+ is-mapping-of<layout_stride, StridedLayoutMapping>))
16319
  ```
16320
 
16321
  ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
16322
 
16323
  ``` cpp
 
16382
  *Returns:* `true` if `x.extents() == y.extents()` is `true`,
16383
  *`OFFSET`*`(y) == 0` is `true`, and each of
16384
  `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
16385
  [0, `x.extents().rank()`). Otherwise, `false`.
16386
 
16387
+ ##### Class template `layout_left_padded::mapping` <a id="mdspan.layout.leftpad">[[mdspan.layout.leftpad]]</a>
16388
+
16389
+ ###### Overview <a id="mdspan.layout.leftpad.overview">[[mdspan.layout.leftpad.overview]]</a>
16390
+
16391
+ `layout_left_padded` provides a layout mapping that behaves like
16392
+ `layout_left::mapping`, except that the padding stride `stride(1)` can
16393
+ be greater than or equal to `extent(0)`.
16394
+
16395
+ ``` cpp
16396
+ namespace std {
16397
+ template<size_t PaddingValue>
16398
+ template<class Extents>
16399
+ class layout_left_padded<PaddingValue>::mapping {
16400
+ public:
16401
+ static constexpr size_t padding_value = PaddingValue;
16402
+
16403
+ using extents_type = Extents;
16404
+ using index_type = extents_type::index_type;
16405
+ using size_type = extents_type::size_type;
16406
+ using rank_type = extents_type::rank_type;
16407
+ using layout_type = layout_left_padded<PaddingValue>;
16408
+
16409
+ private:
16410
+ static constexpr size_t rank_ = extents_type::rank(); // exposition only
16411
+ static constexpr size_t first-static-extent = // exposition only
16412
+ extents_type::static_extent(0);
16413
+
16414
+ // [mdspan.layout.leftpad.expo], exposition-only members
16415
+ static constexpr size_t static-padding-stride = see below; // exposition only
16416
+
16417
+ public:
16418
+ // [mdspan.layout.leftpad.cons], constructors
16419
+ constexpr mapping() noexcept : mapping(extents_type{}) {}
16420
+ constexpr mapping(const mapping&) noexcept = default;
16421
+ constexpr mapping(const extents_type&);
16422
+ template<class OtherIndexType>
16423
+ constexpr mapping(const extents_type&, OtherIndexType);
16424
+ template<class OtherExtents>
16425
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
16426
+ mapping(const layout_left::mapping<OtherExtents>&);
16427
+ template<class OtherExtents>
16428
+ constexpr explicit(extents_type::rank() > 0)
16429
+ mapping(const layout_stride::mapping<OtherExtents>&);
16430
+ template<class LayoutLeftPaddedMapping>
16431
+ constexpr explicit(see below)
16432
+ mapping(const LayoutLeftPaddedMapping&);
16433
+ template<class LayoutRightPaddedMapping>
16434
+ constexpr explicit(see below)
16435
+ mapping(const LayoutRightPaddedMapping&) noexcept;
16436
+
16437
+ constexpr mapping& operator=(const mapping&) noexcept = default;
16438
+
16439
+ // [mdspan.layout.leftpad.obs], observers
16440
+ constexpr const extents_type& extents() const noexcept { return extents_; }
16441
+ constexpr array<index_type, rank_> strides() const noexcept;
16442
+
16443
+ constexpr index_type required_span_size() const noexcept;
16444
+ template<class... Indices>
16445
+ constexpr index_type operator()(Indices...) const noexcept;
16446
+
16447
+ static constexpr bool is_always_unique() noexcept { return true; }
16448
+ static constexpr bool is_always_exhaustive() noexcept;
16449
+ static constexpr bool is_always_strided() noexcept { return true; }
16450
+
16451
+ static constexpr bool is_unique() noexcept { return true; }
16452
+ constexpr bool is_exhaustive() const noexcept;
16453
+ static constexpr bool is_strided() noexcept { return true; }
16454
+
16455
+ constexpr index_type stride(rank_type) const noexcept;
16456
+
16457
+ template<class LayoutLeftPaddedMapping>
16458
+ friend constexpr bool operator==(const mapping&, const LayoutLeftPaddedMapping&) noexcept;
16459
+
16460
+ private:
16461
+ // [mdspan.layout.leftpad.expo], exposition-only members
16462
+ index_type stride-1 = static-padding-stride; // exposition only
16463
+ extents_type extents_{}; // exposition only
16464
+ // [mdspan.sub.map], submdspan mapping specialization
16465
+ template<class... SliceSpecifiers>
16466
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
16467
+ -> see below;
16468
+
16469
+ template<class... SliceSpecifiers>
16470
+ friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {
16471
+ return src.submdspan-mapping-impl(slices...);
16472
+ }
16473
+ };
16474
+ }
16475
+ ```
16476
+
16477
+ If `Extents` is not a specialization of `extents`, then the program is
16478
+ ill-formed.
16479
+
16480
+ `layout_left_padded::mapping<E>` is a trivially copyable type that
16481
+ models `regular` for each `E`.
16482
+
16483
+ Throughout [[mdspan.layout.leftpad]], let `P_rank` be the following size
16484
+ *`rank_`* parameter pack of `size_`t values:
16485
+
16486
+ - the empty parameter pack, if *`rank_`* equals zero;
16487
+ - otherwise, `0zu`, if *`rank_`* equals one;
16488
+ - otherwise, the parameter pack `0zu`, `1zu`, …, `rank_- 1`.
16489
+
16490
+ *Mandates:*
16491
+
16492
+ - If `rank_dynamic() == 0` is `true`, then the size of the
16493
+ multidimensional index space `Extents()` is representable as a value
16494
+ of type `index_type`.
16495
+ - `padding_value` is representable as a value of type `index_type`.
16496
+ - If
16497
+ - *`rank_`* is greater than one,
16498
+ - `padding_value` does not equal `dynamic_extent`, and
16499
+ - *`first-static-extent`* does not equal `dynamic_extent`,
16500
+
16501
+ then `LEAST-MULTIPLE-AT-LEAST(padding_value, first-static-extent)` is
16502
+ representable as a value of type `size_t`, and is representable as a
16503
+ value of type `index_type`.
16504
+ - If
16505
+ - *`rank_`* is greater than one,
16506
+ - `padding_value` does not equal `dynamic_extent`, and
16507
+ - `extents_type::static_extent(k)` does not equal `dynamic_extent` for
16508
+ all k in the range \[`0`, `extents_type::rank()`),
16509
+
16510
+ then the product of
16511
+ `LEAST-MULTIPLE-AT-LEAST(padding_value, ext.static_extent(0))` and all
16512
+ values `ext.static_extent(k)` with k in the range of \[`1`, *`rank_`*)
16513
+ is representable as a value of type `size_t`, and is representable as
16514
+ a value of type `index_type`.
16515
+
16516
+ ###### Exposition-only members <a id="mdspan.layout.leftpad.expo">[[mdspan.layout.leftpad.expo]]</a>
16517
+
16518
+ ``` cpp
16519
+ static constexpr size_t static-padding-stride = see below;
16520
+ ```
16521
+
16522
+ The value is
16523
+
16524
+ - `0`, if *rank\_* equals zero or one;
16525
+ - otherwise, `dynamic_extent`, if `padding_value` or
16526
+ *first-static-extent* equals `dynamic_extent`;
16527
+ - otherwise, the `size_t` value which is
16528
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, `*`first-static-extent`*`)`.
16529
+
16530
+ ``` cpp
16531
+ index_type stride-1 = static-padding-stride;
16532
+ ```
16533
+
16534
+ *Recommended practice:* Implementations should not store this value if
16535
+ *static-padding-stride* is not `dynamic_extent`.
16536
+
16537
+ [*Note 9*: Using `extents<index_type, `*`static-padding-stride`*`>`
16538
+ instead of `index_type` as the type of *stride-1* would achieve
16539
+ this. — *end note*]
16540
+
16541
+ ###### Constructors <a id="mdspan.layout.leftpad.cons">[[mdspan.layout.leftpad.cons]]</a>
16542
+
16543
+ ``` cpp
16544
+ constexpr mapping(const extents_type& ext);
16545
+ ```
16546
+
16547
+ *Preconditions:*
16548
+
16549
+ - The size of the multidimensional index space `ext` is representable as
16550
+ a value of type `index_type`.
16551
+ - If *rank\_* is greater than one and `padding_value` does not equal
16552
+ `dynamic_extent`, then
16553
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(0))` is
16554
+ representable as a value of type *index_type*.
16555
+ - If *rank\_* is greater than one and `padding_value` does not equal
16556
+ `dynamic_extent`, then the product of
16557
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(0))` and all
16558
+ values `ext.extent(`k`)` with k in the range of \[`1`, *`rank_`*) is
16559
+ representable as a value of type `index_type`.
16560
+
16561
+ *Effects:*
16562
+
16563
+ - Direct-non-list-initializes *extents\_* with `ext`; and
16564
+ - if *rank\_* is greater than one, direct-non-list-initializes
16565
+ *stride-1*
16566
+ - with `ext.extent(0)` if padding_value is `dynamic_extent`,
16567
+ - otherwise with
16568
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(0))`.
16569
+
16570
+ ``` cpp
16571
+ template<class OtherIndexType>
16572
+ constexpr mapping(const extents_type& ext, OtherIndexType pad);
16573
+ ```
16574
+
16575
+ *Constraints:*
16576
+
16577
+ - `is_convertible_v<OtherIndexType, index_type>` is `true`.
16578
+ - `is_nothrow_constructible_v<index_type, OtherIndexType>` is `true`.
16579
+
16580
+ *Preconditions:*
16581
+
16582
+ - `pad` is representable as a value of type `index_type`.
16583
+ - `extents_type::`*`index-cast`*`(pad)` is greater than zero.
16584
+ - If *rank\_* is greater than one, then
16585
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(0))` is representable as
16586
+ a value of type `index_type.`
16587
+ - If *rank\_* is greater than one, then the product of
16588
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(0))` and all values
16589
+ `ext.extent(`k`)` with k in the range of \[`1`, *`rank_`*) is
16590
+ representable as a value of type `index_type`.
16591
+ - If `padding_value` is not equal to `dynamic_extent`, `padding_value`
16592
+ equals `extents_type::`*`index-cast`*`(pad)`.
16593
+
16594
+ *Effects:* Direct-non-list-initializes *extents\_* with `ext`, and if
16595
+ *rank\_* is greater than one, direct-non-list-initializes *stride-1*
16596
+ with *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(0))`.
16597
+
16598
+ ``` cpp
16599
+ template<class OtherExtents>
16600
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
16601
+ mapping(const layout_left::mapping<OtherExtents>& other);
16602
+ ```
16603
+
16604
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
16605
+ `true`.
16606
+
16607
+ *Mandates:* If `OtherExtents::rank()` is greater than `1`, then
16608
+
16609
+ ``` cpp
16610
+ (static-padding-stride == dynamic_extent) ||
16611
+ (OtherExtents::static_extent(0) == dynamic_extent) ||
16612
+ (static-padding-stride == OtherExtents::static_extent(0))
16613
+ ```
16614
+
16615
+ is `true`.
16616
+
16617
+ *Preconditions:*
16618
+
16619
+ - If `extents_type::rank() > 1` is `true` and `padding_value` ==
16620
+ `dynamic_extent` is `false`, then `other.stride(1)` equals
16621
+ ``` cpp
16622
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
16623
+ extents_type::index-cast(other.extents().extent(0)))
16624
+ ```
16625
+
16626
+ and
16627
+ - `other.required_span_size()` is representable as a value of type
16628
+ `index_type`.
16629
+
16630
+ *Effects:* Equivalent to `mapping(other.extents())`.
16631
+
16632
+ ``` cpp
16633
+ template<class OtherExtents>
16634
+ constexpr explicit(rank_ > 0)
16635
+ mapping(const layout_stride::mapping<OtherExtents>& other);
16636
+ ```
16637
+
16638
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
16639
+ `true`.
16640
+
16641
+ *Preconditions:*
16642
+
16643
+ - If *rank\_* is greater than `1` and `padding_value` does not equal
16644
+ `dynamic_extent`, then `other.stride(1)` equals
16645
+ ``` cpp
16646
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
16647
+ extents_type::index-cast(other.extents().extent(0)))
16648
+ ```
16649
+ - If *rank\_* is greater than 0, then `other.stride(0)` equals 1.
16650
+ - If *rank\_* is greater than 2, then for all r in the range \[`2`,
16651
+ *`rank_`*), `other.stride(r)` equals
16652
+ ``` cpp
16653
+ (other.extents().fwd-prod-of-extents(r) / other.extents().extent(0)) * other.stride(1)
16654
+ ```
16655
+ - `other.required_span_size()` is representable as a value of type
16656
+ *index_type*.
16657
+
16658
+ *Effects:*
16659
+
16660
+ - Direct-non-list-initializes *extents\_* with `other.extents()` and
16661
+ - if *rank\_* is greater than one, direct-non-list-initializes
16662
+ *stride-1* with `other.stride(1)`.
16663
+
16664
+ ``` cpp
16665
+ template<class LayoutLeftPaddedMapping>
16666
+ constexpr explicit(see below)
16667
+ mapping(const LayoutLeftPaddedMapping& other);
16668
+ ```
16669
+
16670
+ *Constraints:*
16671
+
16672
+ - *`is-layout-left-padded-mapping-of`*`<LayoutLeftPaddedMapping>` is
16673
+ `true`.
16674
+ - `is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>`
16675
+ is `true`.
16676
+
16677
+ *Mandates:* If *rank\_* is greater than 1, then
16678
+
16679
+ ``` cpp
16680
+ padding_value == dynamic_extent ||
16681
+ LayoutLeftPaddedMapping::padding_value == dynamic_extent ||
16682
+ padding_value == LayoutLeftPaddedMapping::padding_value
16683
+ ```
16684
+
16685
+ is `true`.
16686
+
16687
+ *Preconditions:*
16688
+
16689
+ - If *rank\_* is greater than 1 and `padding_value` does not equal
16690
+ `dynamic_extent`, then `other.stride(1)` equals
16691
+ ``` cpp
16692
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
16693
+ extents_type::index-cast(other.extent(0)))
16694
+ ```
16695
+ - `other.required_span_size()` is representable as a value of type
16696
+ `index_type`.
16697
+
16698
+ *Effects:*
16699
+
16700
+ - Direct-non-list-initializes *extents\_* with `other.extents()` and
16701
+ - if *rank\_* is greater than one, direct-non-list-initializes
16702
+ *stride-1* with `other.stride(1)`.
16703
+
16704
+ *Remarks:* The expression inside `explicit` is equivalent to:
16705
+
16706
+ ``` cpp
16707
+ rank_> 1 &&
16708
+ (padding_value != dynamic_extent ||
16709
+ LayoutLeftPaddedMapping::padding_value == dynamic_extent)
16710
+ ```
16711
+
16712
+ ``` cpp
16713
+ template<class LayoutRightPaddedMapping>
16714
+ constexpr explicit(see below)
16715
+ mapping(const LayoutRightPaddedMapping& other) noexcept;
16716
+ ```
16717
+
16718
+ *Constraints:*
16719
+
16720
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
16721
+ `true` or *`is-mapping-of`*`<layout_right, LayoutRightPaddedMapping>`
16722
+ is `true`.
16723
+ - *rank\_* equals zero or one.
16724
+ - `is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_- type>`
16725
+ is `true`.
16726
+
16727
+ *Preconditions:* `other.required_span_size()` is representable as a
16728
+ value of type `index_type`.
16729
+
16730
+ *Effects:* Direct-non-list-initializes *extents\_* with
16731
+ `other.extents()`.
16732
+
16733
+ *Remarks:* The expression inside `explicit` is equivalent to:
16734
+
16735
+ ``` cpp
16736
+ !is_convertible_v<typename LayoutRightPaddedMapping::extents_type, extents_type>
16737
+ ```
16738
+
16739
+ [*Note 10*: Neither the input mapping nor the mapping to be constructed
16740
+ uses the padding stride in the rank-0 or rank-1 case, so the padding
16741
+ stride does not affect either the constraints or the
16742
+ preconditions. — *end note*]
16743
+
16744
+ ###### Observers <a id="mdspan.layout.leftpad.obs">[[mdspan.layout.leftpad.obs]]</a>
16745
+
16746
+ ``` cpp
16747
+ constexpr array<index_type, rank_> strides() const noexcept;
16748
+ ```
16749
+
16750
+ *Returns:* `array<index_type, `*`rank_`*`>({stride(P_rank)...})`.
16751
+
16752
+ ``` cpp
16753
+ constexpr index_type required_span_size() const noexcept;
16754
+ ```
16755
+
16756
+ *Returns:*
16757
+
16758
+ - `0` if the multidimensional index space *extents\_* is empty,
16759
+ - otherwise,
16760
+ `(*this)(`*`extents_`*`.extent(P_rank) - index_type(1)...) + 1`.
16761
+
16762
+ ``` cpp
16763
+ template<class... Indices>
16764
+ constexpr size_t operator()(Indices... idxs) const noexcept;
16765
+ ```
16766
+
16767
+ *Constraints:*
16768
+
16769
+ - `sizeof...(Indices) == `*`rank_`* is `true`.
16770
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`.
16771
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
16772
+
16773
+ *Preconditions:* `extents_type::`*`index-cast`*`(idxs)` is a
16774
+ multidimensional index in `extents()` [[mdspan.overview]].
16775
+
16776
+ *Returns:*
16777
+ `((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)`.
16778
+
16779
+ ``` cpp
16780
+ static constexpr bool is_always_exhaustive() noexcept;
16781
+ ```
16782
+
16783
+ *Returns:*
16784
+
16785
+ - If *rank\_* equals zero or one, then `true`;
16786
+ - otherwise, if neither *static-padding-stride* nor
16787
+ *first-static-extent* equal `dynamic_extent`, then
16788
+ *`static-padding-stride`*` == `*`first-static-extent`*;
16789
+ - otherwise, `false`.
16790
+
16791
+ ``` cpp
16792
+ constexpr bool is_exhaustive() const noexcept;
16793
+ ```
16794
+
16795
+ *Returns:* `true` if *rank\_* equals zero or one; otherwise,
16796
+ `extents_.extent(0) == stride(1)`.
16797
+
16798
+ ``` cpp
16799
+ constexpr index_type stride(rank_type r) const noexcept;
16800
+ ```
16801
+
16802
+ *Preconditions:* `r` is smaller than *rank\_*.
16803
+
16804
+ *Returns:*
16805
+
16806
+ - If `r` equals zero: 1;
16807
+ - otherwise, if `r` equals one: *stride-1*;
16808
+ - otherwise, the product of *stride-1* and all values
16809
+ `extents_.extent(`k`)` with k in the range \[`1`, `r`).
16810
+
16811
+ ``` cpp
16812
+ template<class LayoutLeftPaddedMapping>
16813
+ friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
16814
+ ```
16815
+
16816
+ *Constraints:*
16817
+
16818
+ - *`is-layout-left-padded-mapping-of`*`<LayoutLeftPaddedMapping>` is
16819
+ `true`.
16820
+ - `LayoutLeftPaddedMapping::extents_type::rank() == rank_` is `true`.
16821
+
16822
+ *Returns:* `true` if `x.extents() == y.extents()` is `true` and
16823
+ *`rank_`*` < 2 || x.stride(1) == y. stride(1)` is `true`. Otherwise,
16824
+ `false`.
16825
+
16826
+ ##### Class template `layout_right_padded::mapping` <a id="mdspan.layout.rightpad">[[mdspan.layout.rightpad]]</a>
16827
+
16828
+ ###### Overview <a id="mdspan.layout.rightpad.overview">[[mdspan.layout.rightpad.overview]]</a>
16829
+
16830
+ `layout_right_padded` provides a layout mapping that behaves like
16831
+ `layout_right::mapping`, except that the padding stride
16832
+ `stride(extents_type::rank() - 2)` can be greater than or equal to
16833
+ `extents_type::extent(extents_type::rank() - 1)`.
16834
+
16835
+ ``` cpp
16836
+ namespace std {
16837
+ template<size_t PaddingValue>
16838
+ template<class Extents>
16839
+ class layout_right_padded<PaddingValue>::mapping {
16840
+ public:
16841
+ static constexpr size_t padding_value = PaddingValue;
16842
+
16843
+ using extents_type = Extents;
16844
+ using index_type = extents_type::index_type;
16845
+ using size_type = extents_type::size_type;
16846
+ using rank_type = extents_type::rank_type;
16847
+ using layout_type = layout_right_padded<PaddingValue>;
16848
+
16849
+ private:
16850
+ static constexpr size_t rank_ = extents_type::rank(); // exposition only
16851
+ static constexpr size_t last-static-extent = // exposition only
16852
+ extents_type::static_extent(rank_ - 1);
16853
+
16854
+ // [mdspan.layout.rightpad.expo], exposition-only members
16855
+ static constexpr size_t static-padding-stride = see below; // exposition only
16856
+
16857
+ public:
16858
+ // [mdspan.layout.rightpad.cons], constructors
16859
+ constexpr mapping() noexcept : mapping(extents_type{}) {}
16860
+ constexpr mapping(const mapping&) noexcept = default;
16861
+ constexpr mapping(const extents_type&);
16862
+ template<class OtherIndexType>
16863
+ constexpr mapping(const extents_type&, OtherIndexType);
16864
+
16865
+ template<class OtherExtents>
16866
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
16867
+ mapping(const layout_right::mapping<OtherExtents>&);
16868
+ template<class OtherExtents>
16869
+ constexpr explicit(rank_ > 0)
16870
+ mapping(const layout_stride::mapping<OtherExtents>&);
16871
+ template<class LayoutRightPaddedMapping>
16872
+ constexpr explicit(see below)
16873
+ mapping(const LayoutRightPaddedMapping&);
16874
+ template<class LayoutLeftPaddedMapping>
16875
+ constexpr explicit(see below)
16876
+ mapping(const LayoutLeftPaddedMapping&) noexcept;
16877
+
16878
+ constexpr mapping& operator=(const mapping&) noexcept = default;
16879
+
16880
+ // [mdspan.layout.rightpad.obs], observers
16881
+ constexpr const extents_type& extents() const noexcept { return extents_; }
16882
+ constexpr array<index_type, rank_> strides() const noexcept;
16883
+
16884
+ constexpr index_type required_span_size() const noexcept;
16885
+
16886
+ template<class... Indices>
16887
+ constexpr index_type operator()(Indices...) const noexcept;
16888
+
16889
+ static constexpr bool is_always_unique() noexcept { return true; }
16890
+ static constexpr bool is_always_exhaustive() noexcept;
16891
+ static constexpr bool is_always_strided() noexcept { return true; }
16892
+
16893
+ static constexpr bool is_unique() noexcept { return true; }
16894
+ constexpr bool is_exhaustive() const noexcept;
16895
+ static constexpr bool is_strided() noexcept { return true; }
16896
+
16897
+ constexpr index_type stride(rank_type) const noexcept;
16898
+
16899
+ template<class LayoutRightPaddedMapping>
16900
+ friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept;
16901
+
16902
+ private:
16903
+ // [mdspan.layout.rightpad.expo], exposition-only members
16904
+ index_type stride-rm2 = static-padding-stride; // exposition only
16905
+ extents_type extents_{}; // exposition only
16906
+
16907
+ // [mdspan.sub.map], submdspan mapping specialization
16908
+ template<class... SliceSpecifiers>
16909
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
16910
+ -> see below;
16911
+
16912
+ template<class... SliceSpecifiers>
16913
+ friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {
16914
+ return src.submdspan-mapping-impl(slices...);
16915
+ }
16916
+ };
16917
+ }
16918
+ ```
16919
+
16920
+ If `Extents` is not a specialization of `extents`, then the program is
16921
+ ill-formed.
16922
+
16923
+ `layout_right_padded::mapping<E>` is a trivially copyable type that
16924
+ models `regular` for each `E`.
16925
+
16926
+ Throughout [[mdspan.layout.rightpad]], let `P_rank` be the following
16927
+ size *`rank_`* parameter pack of `size_`t values:
16928
+
16929
+ - the empty parameter pack, if *`rank_`* equals zero;
16930
+ - otherwise, `0zu`, if *`rank_`* equals one;
16931
+ - otherwise, the parameter pack `0zu`, `1zu`, …, `rank_- 1`.
16932
+
16933
+ *Mandates:*
16934
+
16935
+ - If `rank_dynamic() == 0` is `true`, then the size of the
16936
+ multidimensional index space `Extents()` is representable as a value
16937
+ of type `index_type`.
16938
+ - `padding_value` is representable as a value of type `index_type`.
16939
+ - If
16940
+ - *`rank_`* is greater than one,
16941
+ - `padding_value` does not equal `dynamic_extent`, and
16942
+ - *`last-static-extent`* does not equal `dynamic_extent`,
16943
+
16944
+ then `LEAST-MULTIPLE-AT-LEAST(padding_value, last-static-extent)` is
16945
+ representable as a value of type `size_t`, and is representable as a
16946
+ value of type `index_type`.
16947
+ - If
16948
+ - *`rank_`* is greater than one,
16949
+ - `padding_value` does not equal `dynamic_extent`, and
16950
+ - `extents_type::static_extent(k)` does not equal `dynamic_extent` for
16951
+ all k in the range \[`0`, *`rank_`*),
16952
+
16953
+ then the product of
16954
+ `LEAST-MULTIPLE-AT-LEAST(padding_value, ext.static_extent(rank_ - 1))`
16955
+ and all values `ext.static_extent(k)` with k in the range of \[`0`,
16956
+ *`rank_`*` - 1`) is representable as a value of type `size_t`, and is
16957
+ representable as a value of type `index_type`.
16958
+
16959
+ ###### Exposition-only members <a id="mdspan.layout.rightpad.expo">[[mdspan.layout.rightpad.expo]]</a>
16960
+
16961
+ ``` cpp
16962
+ static constexpr size_t static-padding-stride = see below;
16963
+ ```
16964
+
16965
+ The value is
16966
+
16967
+ - `0`, if *rank\_* equals zero or one;
16968
+ - otherwise, `dynamic_extent`, if `padding_value` or
16969
+ *last-static-extent* equals `dynamic_extent`;
16970
+ - otherwise, the `size_t` value which is
16971
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, `*`last-static-extent`*`)`.
16972
+
16973
+ ``` cpp
16974
+ index_type stride-rm2 = static-padding-stride;
16975
+ ```
16976
+
16977
+ *Recommended practice:* Implementations should not store this value if
16978
+ *static-padding-stride* is not `dynamic_extent`.
16979
+
16980
+ [*Note 11*: Using `extents<index_type, `*`static-padding-stride`*`>`
16981
+ instead of `index_type` as the type of *stride-rm2* would achieve
16982
+ this. — *end note*]
16983
+
16984
+ ###### Constructors <a id="mdspan.layout.rightpad.cons">[[mdspan.layout.rightpad.cons]]</a>
16985
+
16986
+ ``` cpp
16987
+ constexpr mapping(const extents_type& ext);
16988
+ ```
16989
+
16990
+ *Preconditions:*
16991
+
16992
+ - The size of the multidimensional index space `ext` is representable as
16993
+ a value of type `index_type`.
16994
+ - If *rank\_* is greater than one and `padding_value` does not equal
16995
+ `dynamic_extent`, then
16996
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`
16997
+ is representable as a value of type *index_type*.
16998
+ - If *rank\_* is greater than one and `padding_value` does not equal
16999
+ `dynamic_extent`, then the product of
17000
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`
17001
+ and all values `ext.extent(`k`)` with k in the range of \[`0`,
17002
+ *`rank_`*` - 1`) is representable as a value of type `index_type`.
17003
+
17004
+ *Effects:*
17005
+
17006
+ - Direct-non-list-initializes *extents\_* with `ext`; and
17007
+ - if *rank\_* is greater than one, direct-non-list-initializes
17008
+ *stride-rm2*
17009
+ - with `ext.extent(`*`rank_`*` - 1)` if `padding_value` is
17010
+ `dynamic_extent`,
17011
+ - otherwise with
17012
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`.
17013
+
17014
+ ``` cpp
17015
+ template<class OtherIndexType>
17016
+ constexpr mapping(const extents_type& ext, OtherIndexType pad);
17017
+ ```
17018
+
17019
+ *Constraints:*
17020
+
17021
+ - `is_convertible_v<OtherIndexType, index_type>` is `true`.
17022
+ - `is_nothrow_constructible_v<index_type, OtherIndexType>` is `true`.
17023
+
17024
+ *Preconditions:*
17025
+
17026
+ - `pad` is representable as a value of type `index_type`.
17027
+ - `extents_type::`*`index-cast`*`(pad)` is greater than zero.
17028
+ - If *rank\_* is greater than one, then
17029
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))` is
17030
+ representable as a value of type `index_type`.
17031
+ - If *rank\_* is greater than one, then the product of
17032
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))` and
17033
+ all values `ext.extent(`k`)` with k in the range of \[`0`,
17034
+ *`rank_`*` - 1`) is representable as a value of type `index_type`.
17035
+ - If `padding_value` is not equal to `dynamic_extent`, `padding_value`
17036
+ equals `extents_type::`*`index-cast`*`(pad)`.
17037
+
17038
+ *Effects:* Direct-non-list-initializes *extents\_* with `ext`, and if
17039
+ *rank\_* is greater than one, direct-non-list-initializes *stride-rm2*
17040
+ with *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))`.
17041
+
17042
+ ``` cpp
17043
+ template<class OtherExtents>
17044
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
17045
+ mapping(const layout_right::mapping<OtherExtents>& other);
17046
+ ```
17047
+
17048
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
17049
+ `true`.
17050
+
17051
+ *Mandates:* If `OtherExtents::rank()` is greater than 1, then
17052
+
17053
+ ``` cpp
17054
+ (static-padding-stride == dynamic_extent) ||
17055
+ (OtherExtents::static_extent(rank_ - 1) == dynamic_extent) ||
17056
+ (static-padding-stride == OtherExtents::static_extent(rank_ - 1))
17057
+ ```
17058
+
17059
+ is `true`.
17060
+
17061
+ *Preconditions:*
17062
+
17063
+ - If *`rank_`*` > 1` is `true` and `padding_value == dynamic_extent` is
17064
+ `false`, then `other.stride( `*`rank_`*` - 2)` equals
17065
+ ``` cpp
17066
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
17067
+ extents_type::index-cast(other.extents().extent(rank_ - 1)))
17068
+ ```
17069
+
17070
+ and
17071
+ - `other.required_span_size()` is representable as a value of type
17072
+ `index_type`.
17073
+
17074
+ *Effects:* Equivalent to `mapping(other.extents())`.
17075
+
17076
+ ``` cpp
17077
+ template<class OtherExtents>
17078
+ constexpr explicit(rank_ > 0)
17079
+ mapping(const layout_stride::mapping<OtherExtents>& other);
17080
+ ```
17081
+
17082
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
17083
+ `true`.
17084
+
17085
+ *Preconditions:*
17086
+
17087
+ - If *rank\_* is greater than 1 and `padding_value` does not equal
17088
+ `dynamic_extent`, then `other.stride(`*`rank_`*` - 2)` equals
17089
+ ``` cpp
17090
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
17091
+ extents_type::index-cast(other.extents().extent(rank_ - 1)))
17092
+ ```
17093
+ - If *rank\_* is greater than 0, then other.stride(*rank\_* - 1) equals
17094
+ 1.
17095
+ - If *rank\_* is greater than 2, then for all r in the range \[`0`,
17096
+ *`rank_`*` - 2`), `other.stride(`r`)` equals
17097
+ ``` cpp
17098
+ (other.extents().rev-prod-of-extents(r) / other.extents().extent(rank_ - 1)) *
17099
+ other.stride(rank_ - 2)
17100
+ ```
17101
+ - `other.required_span_size()` is representable as a value of type
17102
+ `index_type`.
17103
+
17104
+ *Effects:*
17105
+
17106
+ - Direct-non-list-initializes *extents\_* with `other.extents()`; and
17107
+ - if *rank\_* is greater than one, direct-non-list-initializes
17108
+ *stride-rm2* with `other.stride(`*`rank_`*` - 2)`.
17109
+
17110
+ ``` cpp
17111
+ template<class LayoutRightPaddedMapping>
17112
+ constexpr explicit(see below)
17113
+ mapping(const LayoutRightPaddedMapping& other);
17114
+ ```
17115
+
17116
+ *Constraints:*
17117
+
17118
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
17119
+ `true`.
17120
+ - `is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_- type>`
17121
+ is `true`.
17122
+
17123
+ *Mandates:* If *rank\_* is greater than 1, then
17124
+
17125
+ ``` cpp
17126
+ padding_value == dynamic_extent ||
17127
+ LayoutRightPaddedMapping::padding_value == dynamic_extent ||
17128
+ padding_value == LayoutRightPaddedMapping::padding_value
17129
+ ```
17130
+
17131
+ is `true`.
17132
+
17133
+ *Preconditions:*
17134
+
17135
+ - If *rank\_* is greater than 1 and `padding_value` does not equal
17136
+ `dynamic_extent`, then `other.stride(`*`rank_`*` - 2)` equals
17137
+ ``` cpp
17138
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
17139
+ extents_type::index-cast(other.extent(rank_ - 1)))
17140
+ ```
17141
+ - `other.required_span_size()` is representable as a value of type
17142
+ `index_type`.
17143
+
17144
+ *Effects:*
17145
+
17146
+ - Direct-non-list-initializes *extents\_* with `other.extents()`; and
17147
+ - if *rank\_* is greater than one, direct-non-list-initializes
17148
+ *stride-rm2* with `other.stride(rank_ - 2)`.
17149
+
17150
+ *Remarks:* The expression inside `explicit` is equivalent to:
17151
+
17152
+ ``` cpp
17153
+ rank_ > 1 &&
17154
+ (padding_value != dynamic_extent ||
17155
+ LayoutRightPaddedMapping::padding_value == dynamic_extent)
17156
+ ```
17157
+
17158
+ ``` cpp
17159
+ template<class LayoutLeftPaddedMapping>
17160
+ constexpr explicit(see below)
17161
+ mapping(const LayoutLeftPaddedMapping& other) noexcept;
17162
+ ```
17163
+
17164
+ *Constraints:*
17165
+
17166
+ - *`is-layout-left-padded-mapping-of`*`<LayoutLeftPaddedMapping>` is
17167
+ `true` or *`is-mapping-of`*`<layout_left, LayoutLeftPaddedMapping>` is
17168
+ `true`.
17169
+ - *rank\_* equals zero or one.
17170
+ - `is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>`
17171
+ is `true`.
17172
+
17173
+ *Preconditions:* `other.required_span_size()` is representable as a
17174
+ value of type `index_type`.
17175
+
17176
+ *Effects:* Direct-non-list-initializes *extents\_* with
17177
+ `other.extents()`.
17178
+
17179
+ *Remarks:* The expression inside `explicit` is equivalent to:
17180
+
17181
+ ``` cpp
17182
+ !is_convertible_v<typename LayoutLeftPaddedMapping::extents_type, extents_type>
17183
+ ```
17184
+
17185
+ [*Note 12*: Neither the input mapping nor the mapping to be constructed
17186
+ uses the padding stride in the rank-0 or rank-1 case, so the padding
17187
+ stride affects neither the constraints nor the
17188
+ preconditions. — *end note*]
17189
+
17190
+ ###### Observers <a id="mdspan.layout.rightpad.obs">[[mdspan.layout.rightpad.obs]]</a>
17191
+
17192
+ ``` cpp
17193
+ constexpr array<index_type, rank_> strides() const noexcept;
17194
+ ```
17195
+
17196
+ *Returns:* `array<index_type, `*`rank_`*`>(``stride(P_rank)...``)`.
17197
+
17198
+ ``` cpp
17199
+ constexpr index_type required_span_size() const noexcept;
17200
+ ```
17201
+
17202
+ *Returns:* `0` if the multidimensional index space *extents\_* is empty,
17203
+ otherwise
17204
+ `(*this)(`*`extents_`*`.extent(P_rank) - index_type(1)...) + 1`.
17205
+
17206
+ ``` cpp
17207
+ template<class... Indices>
17208
+ constexpr size_t operator()(Indices... idxs) const noexcept;
17209
+ ```
17210
+
17211
+ *Constraints:*
17212
+
17213
+ - `sizeof...(Indices) == `*`rank_`* is `true`.
17214
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`.
17215
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
17216
+
17217
+ *Preconditions:* `extents_type::`*`index-cast`*`(idxs)` is a
17218
+ multidimensional index in `extents()` [[mdspan.overview]].
17219
+
17220
+ *Returns:*
17221
+ `((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)`.
17222
+
17223
+ ``` cpp
17224
+ static constexpr bool is_always_exhaustive() noexcept;
17225
+ ```
17226
+
17227
+ *Returns:*
17228
+
17229
+ - If *rank\_* equals zero or one, then `true`;
17230
+ - otherwise, if neither *static-padding-stride* nor *last-static-extent*
17231
+ equal `dynamic_extent`, then
17232
+ *`static-padding-stride`*` == `*`last-static-extent`*;
17233
+ - otherwise, `false`.
17234
+
17235
+ ``` cpp
17236
+ constexpr bool is_exhaustive() const noexcept;
17237
+ ```
17238
+
17239
+ *Returns:* `true` if *rank\_* equals zero or one; otherwise,
17240
+
17241
+ ``` cpp
17242
+ extents_.extent(rank_ - 1) == stride(rank_ - 2)
17243
+ ```
17244
+
17245
+ ``` cpp
17246
+ constexpr index_type stride(rank_type r) const noexcept;
17247
+ ```
17248
+
17249
+ *Preconditions:* `r` is smaller than *rank\_*.
17250
+
17251
+ *Returns:*
17252
+
17253
+ - If `r` equals *`rank_`*` - 1`: `1`;
17254
+ - otherwise, if `r` equals *`rank_`*` - 2`: *stride-rm2*;
17255
+ - otherwise, the product of *stride-rm2* and all values
17256
+ `extents_.extent(`k`)` with k in the range of \[`r + 1`,
17257
+ *`rank_`*` - 1`).
17258
+
17259
+ ``` cpp
17260
+ template<class LayoutRightPaddedMapping>
17261
+ friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
17262
+ ```
17263
+
17264
+ *Constraints:*
17265
+
17266
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
17267
+ `true`.
17268
+ - `LayoutRightPaddedMapping::extents_type::rank() == `*`rank_`* is
17269
+ `true`.
17270
+
17271
+ *Returns:* `true` if `x.extents() == y.extents()` is `true` and
17272
+ *`rank_`*` < 2 || x.stride(`*`rank_`*` - 2) == y.stride(`*`rank_`*` - 2)`
17273
+ is `true`. Otherwise, `false`.
17274
+
17275
  #### Accessor policy <a id="mdspan.accessor">[[mdspan.accessor]]</a>
17276
 
17277
  ##### General <a id="mdspan.accessor.general">[[mdspan.accessor.general]]</a>
17278
 
17279
  An *accessor policy* defines types and operations by which a reference
 
17282
 
17283
  A range of indices [0, N) is an *accessible range* of a given data
17284
  handle and an accessor if, for each i in the range, the accessor
17285
  policy’s `access` function produces a valid reference to an object.
17286
 
17287
+ In [[mdspan.accessor.reqmts]],
17288
 
17289
  - `A` denotes an accessor policy.
17290
  - `a` denotes a value of type `A` or `const A`.
17291
  - `p` denotes a value of type `A::data_handle_type` or
17292
  `const A::data_handle_type`. \[*Note 1*: The type
 
17426
  constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
17427
  ```
17428
 
17429
  *Effects:* Equivalent to: `return p + i;`
17430
 
17431
+ ##### Class template `aligned_accessor` <a id="mdspan.accessor.aligned">[[mdspan.accessor.aligned]]</a>
17432
+
17433
+ ###### Overview <a id="mdspan.accessor.aligned.overview">[[mdspan.accessor.aligned.overview]]</a>
17434
+
17435
+ ``` cpp
17436
+ namespace std {
17437
+ template<class ElementType, size_t ByteAlignment>
17438
+ struct aligned_accessor {
17439
+ using offset_policy = default_accessor<ElementType>;
17440
+ using element_type = ElementType;
17441
+ using reference = ElementType&;
17442
+ using data_handle_type = ElementType*;
17443
+
17444
+ static constexpr size_t byte_alignment = ByteAlignment;
17445
+
17446
+ constexpr aligned_accessor() noexcept = default;
17447
+ template<class OtherElementType, size_t OtherByteAlignment>
17448
+ constexpr aligned_accessor(
17449
+ aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
17450
+ template<class OtherElementType>
17451
+ constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
17452
+
17453
+ template<class OtherElementType>
17454
+ constexpr operator default_accessor<OtherElementType>() const noexcept;
17455
+
17456
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
17457
+
17458
+ constexpr typename offset_policy::data_handle_type offset(
17459
+ data_handle_type p, size_t i) const noexcept;
17460
+ };
17461
+ }
17462
+ ```
17463
+
17464
+ *Mandates:*
17465
+
17466
+ - `byte_alignment` is a power of two, and
17467
+ - `byte_alignment >= alignof(ElementType)` is `true`.
17468
+
17469
+ `aligned_accessor` meets the accessor policy requirements.
17470
+
17471
+ `ElementType` is required to be a complete object type that is neither
17472
+ an abstract class type nor an array type.
17473
+
17474
+ Each specialization of `aligned_accessor` is a trivially copyable type
17475
+ that models `semiregular`.
17476
+
17477
+ \[`0`, n) is an accessible range for an object `p` of type
17478
+ `data_handle_type` and an object of type `aligned_accessor` if and only
17479
+ if
17480
+
17481
+ - \[`p`, `p + `n) is a valid range, and,
17482
+ - if n is greater than zero, then
17483
+ `is_sufficiently_aligned<byte_alignment>(p)` is `true`.
17484
+
17485
+ [*Example 1*:
17486
+
17487
+ The following function `compute` uses `is_sufficiently_aligned` to check
17488
+ whether a given `mdspan` with `default_accessor` has a data handle with
17489
+ sufficient alignment to be used with
17490
+ `aligned_accessor<float, 4 * sizeof(float)>`. If so, the function
17491
+ dispatches to a function `compute_using_fourfold_overalignment` that
17492
+ requires fourfold over-alignment of arrays, but can therefore use
17493
+ hardware-specific instructions, such as four-wide SIMD (Single
17494
+ Instruction Multiple Data) instructions. Otherwise, `compute` dispatches
17495
+ to a possibly less optimized function
17496
+ `compute_without_requiring_overalignment` that has no over-alignment
17497
+ requirement.
17498
+
17499
+ ``` cpp
17500
+ void compute_using_fourfold_overalignment(
17501
+ mdspan<float, dims<1>, layout_right, aligned_accessor<float, 4 * alignof(float)>> x);
17502
+
17503
+ void compute_without_requiring_overalignment(
17504
+ mdspan<float, dims<1>, layout_right> x);
17505
+
17506
+ void compute(mdspan<float, dims<1>> x) {
17507
+ constexpr auto byte_alignment = 4 * sizeof(float);
17508
+ auto accessor = aligned_accessor<float, byte_alignment>{};
17509
+ auto x_handle = x.data_handle();
17510
+
17511
+ if (is_sufficiently_aligned<byte_alignment>(x_handle)) {
17512
+ compute_using_fourfold_overalignment(mdspan{x_handle, x.mapping(), accessor});
17513
+ } else {
17514
+ compute_without_requiring_overalignment(x);
17515
+ }
17516
+ }
17517
+ ```
17518
+
17519
+ — *end example*]
17520
+
17521
+ ###### Members <a id="mdspan.accessor.aligned.members">[[mdspan.accessor.aligned.members]]</a>
17522
+
17523
+ ``` cpp
17524
+ template<class OtherElementType, size_t OtherByteAlignment>
17525
+ constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
17526
+ ```
17527
+
17528
+ *Constraints:*
17529
+
17530
+ - `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is
17531
+ `true`.
17532
+ - `OtherByteAlignment >= byte_alignment` is `true`.
17533
+
17534
+ *Effects:* None.
17535
+
17536
+ ``` cpp
17537
+ template<class OtherElementType>
17538
+ constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
17539
+ ```
17540
+
17541
+ *Constraints:*
17542
+ `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is `true`.
17543
+
17544
+ *Effects:* None.
17545
+
17546
+ ``` cpp
17547
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
17548
+ ```
17549
+
17550
+ *Preconditions:* \[`0`, `i + 1`) is an accessible range for `p` and
17551
+ `*this`.
17552
+
17553
+ *Effects:* Equivalent to: `return assume_aligned<byte_alignment>(p)[i];`
17554
+
17555
+ ``` cpp
17556
+ template<class OtherElementType>
17557
+ constexpr operator default_accessor<OtherElementType>() const noexcept;
17558
+ ```
17559
+
17560
+ *Constraints:*
17561
+ `is_convertible_v<element_type(*)[], OtherElementType(*)[]>` is `true`.
17562
+
17563
+ *Effects:* Equivalent to: `return {};`
17564
+
17565
+ ``` cpp
17566
+ constexpr typename offset_policy::data_handle_type
17567
+ offset(data_handle_type p, size_t i) const noexcept;
17568
+ ```
17569
+
17570
+ *Preconditions:* \[`0`, `i + 1`) is an accessible range for `p` and
17571
+ `*this`.
17572
+
17573
+ *Effects:* Equivalent to:
17574
+ `return assume_aligned<byte_alignment>(p) + i;`
17575
+
17576
  #### Class template `mdspan` <a id="mdspan.mdspan">[[mdspan.mdspan]]</a>
17577
 
17578
  ##### Overview <a id="mdspan.mdspan.overview">[[mdspan.mdspan.overview]]</a>
17579
 
17580
  `mdspan` is a view of a multidimensional array of elements.
 
17586
  class mdspan {
17587
  public:
17588
  using extents_type = Extents;
17589
  using layout_type = LayoutPolicy;
17590
  using accessor_type = AccessorPolicy;
17591
+ using mapping_type = layout_type::template mapping<extents_type>;
17592
  using element_type = ElementType;
17593
  using value_type = remove_cv_t<element_type>;
17594
+ using index_type = extents_type::index_type;
17595
+ using size_type = extents_type::size_type;
17596
+ using rank_type = extents_type::rank_type;
17597
+ using data_handle_type = accessor_type::data_handle_type;
17598
+ using reference = accessor_type::reference;
17599
 
17600
  static constexpr rank_type rank() noexcept { return extents_type::rank(); }
17601
  static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
17602
  static constexpr size_t static_extent(rank_type r) noexcept
17603
  { return extents_type::static_extent(r); }
 
17635
  template<class OtherIndexType>
17636
  constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
17637
  template<class OtherIndexType>
17638
  constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
17639
 
17640
+ template<class... OtherIndexTypes>
17641
+ constexpr reference
17642
+ at(OtherIndexTypes... indices) const; // freestanding-deleted
17643
+ template<class OtherIndexType>
17644
+ constexpr reference
17645
+ at(span<OtherIndexType, rank()> indices) const; // freestanding-deleted
17646
+ template<class OtherIndexType>
17647
+ constexpr reference
17648
+ at(const array<OtherIndexType, rank()>& indices) const; // freestanding-deleted
17649
+
17650
  constexpr size_type size() const noexcept;
17651
+ constexpr bool empty() const noexcept;
17652
 
17653
  friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
17654
 
17655
  constexpr const extents_type& extents() const noexcept { return map_.extents(); }
17656
  constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
 
17690
  -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
17691
 
17692
  template<class ElementType, class... Integrals>
17693
  requires ((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
17694
  explicit mdspan(ElementType*, Integrals...)
17695
+ -> mdspan<ElementType, extents<size_t, maybe-static-ext<Integrals>...>>;
17696
 
17697
  template<class ElementType, class OtherIndexType, size_t N>
17698
  mdspan(ElementType*, span<OtherIndexType, N>)
17699
  -> mdspan<ElementType, dextents<size_t, N>>;
17700
 
 
17797
  ```
17798
 
17799
  *Constraints:*
17800
 
17801
  - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
17802
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
17803
+ `true`,
17804
  - `N == rank() || N == rank_dynamic()` is `true`,
17805
  - `is_constructible_v<mapping_type, extents_type>` is `true`, and
17806
  - `is_default_constructible_v<accessor_type>` is `true`.
17807
 
17808
  *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
 
17881
 
17882
  - `is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&>`
17883
  is `true`, and
17884
  - `is_constructible_v<extents_type, OtherExtents>` is `true`.
17885
 
17886
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
17887
+ an accessible range of *ptr\_* and *acc\_* for values of *ptr\_*,
17888
+ *map\_*, and *acc\_* after the invocation of this constructor.
17889
 
17890
+ For each rank index `r` of `extents_type`,
17891
  `static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)`
17892
  is `true`.
 
 
 
17893
 
17894
  *Effects:*
17895
 
17896
  - Direct-non-list-initializes *ptr\_* with `other.`*`ptr_`*,
17897
  - direct-non-list-initializes *map\_* with `other.`*`map_`*, and
 
17918
  `true`, and
17919
  - `sizeof...(OtherIndexTypes) == rank()` is `true`.
17920
 
17921
  Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
17922
 
17923
+ `I` is a multidimensional index in `extents()`.
17924
 
17925
  [*Note 1*: This implies that
17926
  *`map_`*`(I) < `*`map_`*`.required_span_size()` is
17927
  `true`. — *end note*]
17928
 
 
17952
  ```
17953
 
17954
  is `true`. Equivalent to:
17955
 
17956
  ``` cpp
17957
+ return operator[](extents_type::index-cast(as_const(indices[P]))...);
17958
+ ```
17959
+
17960
+ ``` cpp
17961
+ template<class... OtherIndexTypes>
17962
+ constexpr reference at(OtherIndexTypes... indices) const;
17963
+ ```
17964
+
17965
+ *Constraints:*
17966
+
17967
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
17968
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
17969
+ `true`, and
17970
+ - `sizeof...(OtherIndexTypes) == rank()` is `true`.
17971
+
17972
+ Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
17973
+
17974
+ *Returns:* `(*this)[I...]`.
17975
+
17976
+ *Throws:* `out_of_range` if `I` is not a multidimensional index in
17977
+ `extents()`.
17978
+
17979
+ ``` cpp
17980
+ template<class OtherIndexType>
17981
+ constexpr reference at(span<OtherIndexType, rank()> indices) const;
17982
+ template<class OtherIndexType>
17983
+ constexpr reference at(const array<OtherIndexType, rank()>& indices) const;
17984
+ ```
17985
+
17986
+ *Constraints:*
17987
+
17988
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
17989
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
17990
+ `true`.
17991
+
17992
+ *Effects:* Let `P` be a parameter pack such that
17993
+
17994
+ ``` cpp
17995
+ is_same_v<make_index_sequence<rank()>, index_sequence<P...>>
17996
+ ```
17997
+
17998
+ is `true`. Equivalent to:
17999
+
18000
+ ``` cpp
18001
+ return at(extents_type::index-cast(as_const(indices[P]))...);
18002
  ```
18003
 
18004
  ``` cpp
18005
  constexpr size_type size() const noexcept;
18006
  ```
 
18010
  [[basic.fundamental]].
18011
 
18012
  *Returns:* `extents().`*`fwd-prod-of-extents`*`(rank())`.
18013
 
18014
  ``` cpp
18015
+ constexpr bool empty() const noexcept;
18016
  ```
18017
 
18018
  *Returns:* `true` if the size of the multidimensional index space
18019
  `extents()` is 0, otherwise `false`.
18020
 
 
18028
  swap(x.ptr_, y.ptr_);
18029
  swap(x.map_, y.map_);
18030
  swap(x.acc_, y.acc_);
18031
  ```
18032
 
18033
+ #### `submdspan` <a id="mdspan.sub">[[mdspan.sub]]</a>
18034
+
18035
+ ##### Overview <a id="mdspan.sub.overview">[[mdspan.sub.overview]]</a>
18036
+
18037
+ The `submdspan` facilities create a new `mdspan` viewing a subset of
18038
+ elements of an existing input `mdspan`. The subset viewed by the created
18039
+ `mdspan` is determined by the `SliceSpecifier` arguments.
18040
+
18041
+ For each function defined in [[mdspan.sub]] that takes a parameter pack
18042
+ named `slices` as an argument:
18043
+
18044
+ - let `index_type` be
18045
+ - `M::index_type` if the function is a member of a class `M`,
18046
+ - otherwise, `remove_reference_t<decltype(src)>::index_type` if the
18047
+ function has a parameter named `src`,
18048
+ - otherwise, the same type as the function’s template argument
18049
+ `IndexType`;
18050
+ - let `rank` be the number of elements in `slices`;
18051
+ - let sₖ be the kᵗʰ element of `slices`;
18052
+ - let Sₖ be the type of sₖ; and
18053
+ - let `map-rank` be an `array<size_t, rank>` such that for each k in the
18054
+ range \[`0`, `rank`), `map-rank[k]` equals:
18055
+ - `dynamic_extent` if Sₖ models `convertible_to<index_type>`,
18056
+ - otherwise, the number of types Sⱼ with j < k that do not model
18057
+ `convertible_to<index_type>`.
18058
+
18059
+ ##### `strided_slice` <a id="mdspan.sub.strided.slice">[[mdspan.sub.strided.slice]]</a>
18060
+
18061
+ `strided_slice` represents a set of `extent` regularly spaced integer
18062
+ indices. The indices start at `offset`, and increase by increments of
18063
+ `stride`.
18064
+
18065
+ ``` cpp
18066
+ namespace std {
18067
+ template<class OffsetType, class ExtentType, class StrideType>
18068
+ struct strided_slice {
18069
+ using offset_type = OffsetType;
18070
+ using extent_type = ExtentType;
18071
+ using stride_type = StrideType;
18072
+
18073
+ [[no_unique_address]] offset_type offset{};
18074
+ [[no_unique_address]] extent_type extent{};
18075
+ [[no_unique_address]] stride_type stride{};
18076
+ };
18077
+ }
18078
+ ```
18079
+
18080
+ `strided_slice` has the data members and special members specified
18081
+ above. It has no base classes or members other than those specified.
18082
+
18083
+ *Mandates:* `OffsetType`, `ExtentType`, and `StrideType` are signed or
18084
+ unsigned integer types, or model `integral-constant-like`.
18085
+
18086
+ [*Note 1*:
18087
+
18088
+ `strided_slice{.offset = 1, .extent = 10, .stride = 3}`
18089
+
18090
+ indicates the indices `1`, `4`, `7`, and `10`. Indices are selected from
18091
+ the half-open interval \[`1`, `1 + 10`).
18092
+
18093
+ — *end note*]
18094
+
18095
+ ##### `submdspan_mapping_result` <a id="mdspan.sub.map.result">[[mdspan.sub.map.result]]</a>
18096
+
18097
+ Specializations of `submdspan_mapping_result` are returned by overloads
18098
+ of `submdspan_mapping`.
18099
+
18100
+ ``` cpp
18101
+ namespace std {
18102
+ template<class LayoutMapping>
18103
+ struct submdspan_mapping_result {
18104
+ [[no_unique_address]] LayoutMapping mapping = LayoutMapping();
18105
+ size_t offset{};
18106
+ };
18107
+ }
18108
+ ```
18109
+
18110
+ `submdspan_mapping_result` has the data members and special members
18111
+ specified above. It has no base classes or members other than those
18112
+ specified.
18113
+
18114
+ `LayoutMapping` shall meet the layout mapping requirements
18115
+ [[mdspan.layout.policy.reqmts]].
18116
+
18117
+ ##### Exposition-only helpers <a id="mdspan.sub.helpers">[[mdspan.sub.helpers]]</a>
18118
+
18119
+ ``` cpp
18120
+ template<class T>
18121
+ constexpr T de-ice(T val) { return val; }
18122
+ template<integral-constant-like T>
18123
+ constexpr auto de-ice(T) { return T::value; }
18124
+
18125
+ template<class IndexType, size_t k, class... SliceSpecifiers>
18126
+ constexpr IndexType first_(SliceSpecifiers... slices);
18127
+ ```
18128
+
18129
+ *Mandates:* `IndexType` is a signed or unsigned integer type.
18130
+
18131
+ Let φₖ denote the following value:
18132
+
18133
+ - sₖ if Sₖ models `convertible_to<IndexType>`;
18134
+ - otherwise, `get<0>(`sₖ`)` if Sₖ models `index-pair-like<IndexType>`;
18135
+ - otherwise, *`de-ice`*`(`sₖ`.offset)` if Sₖ is a specialization of
18136
+ `strided_slice`;
18137
+ - otherwise, `0`.
18138
+
18139
+ *Preconditions:* φₖ is representable as a value of type `IndexType`.
18140
+
18141
+ *Returns:* `extents<IndexType>::`*`index-cast`*`(`φₖ`)`.
18142
+
18143
+ ``` cpp
18144
+ template<size_t k, class Extents, class... SliceSpecifiers>
18145
+ constexpr auto last_(const Extents& src, SliceSpecifiers... slices);
18146
+ ```
18147
+
18148
+ *Mandates:* `Extents` is a specialization of `extents`.
18149
+
18150
+ Let `index_type` be `typename Extents::index_type`.
18151
+
18152
+ Let λₖ denote the following value:
18153
+
18154
+ - *`de-ice`*`(`sₖ`) + 1` if Sₖ models `convertible_to<index_type>`;
18155
+ otherwise
18156
+ - `get<1>(`sₖ`)` if Sₖ models `index-pair-like<index_type>`; otherwise
18157
+ - *`de-ice`*`(`sₖ`.offset)` `+` *`de-ice`*`(`sₖ`.extent)` if Sₖ is a
18158
+ specialization of `strided_slice`; otherwise
18159
+ - `src.extent(k)`.
18160
+
18161
+ *Preconditions:* λₖ is representable as a value of type `index_type`.
18162
+
18163
+ *Returns:* `Extents::`*`index-cast`*`(`λₖ`)`.
18164
+
18165
+ ``` cpp
18166
+ template<class IndexType, size_t N, class... SliceSpecifiers>
18167
+ constexpr array<IndexType, sizeof...(SliceSpecifiers)>
18168
+ src-indices(const array<IndexType, N>& indices, SliceSpecifiers... slices);
18169
+ ```
18170
+
18171
+ *Mandates:* `IndexType` is a signed or unsigned integer type.
18172
+
18173
+ *Returns:* An `array<IndexType, sizeof...(SliceSpecifiers)> src_idx`
18174
+ such that for each k in the range \[`0`, `sizeof...(SliceSpecifiers)`),
18175
+ `src_idx[`k`]` equals
18176
+
18177
+ - *`first_`*`<IndexType, `k`>(slices...)` for each k where
18178
+ *`map-rank`*`[`k`]` equals `dynamic_extent`,
18179
+ - otherwise, *`first_`*`<IndexType, `k`>(slices...)` `+`
18180
+ `indices[`*`map-rank`*`[`k`]]`.
18181
+
18182
+ ##### `submdspan_extents` function <a id="mdspan.sub.extents">[[mdspan.sub.extents]]</a>
18183
+
18184
+ ``` cpp
18185
+ template<class IndexType, size_t... Extents, class... SliceSpecifiers>
18186
+ constexpr auto submdspan_extents(const extents<IndexType, Extents...>& src,
18187
+ SliceSpecifiers... slices);
18188
+ ```
18189
+
18190
+ *Constraints:* `sizeof...(slices)` equals `sizeof...(Extents)`.
18191
+
18192
+ *Mandates:* For each rank index k of `src.extents()`, exactly one of the
18193
+ following is true:
18194
+
18195
+ - Sₖ models `convertible_to<IndexType>`,
18196
+ - Sₖ models `index-pair-like<IndexType>`,
18197
+ - `is_convertible_v<`Sₖ`, full_extent_t>` is `true`, or
18198
+ - Sₖ is a specialization of `strided_slice`.
18199
+
18200
+ *Preconditions:* For each rank index k of `src.extents()`, all of the
18201
+ following are `true`:
18202
+
18203
+ - if Sₖ is a specialization of `strided_slice`
18204
+ - `$s_k$.extent` = 0, or
18205
+ - `$s_k$.stride` > 0
18206
+ - $0 \le \texttt{\textit{first_}<IndexType, $k$>(slices...)}$
18207
+ $\le \texttt{\textit{last_}<$k$>(src, slices...)}$ ≤ `src.extent($k$)`
18208
+
18209
+ Let `SubExtents` be a specialization of `extents` such that:
18210
+
18211
+ - `SubExtents::rank()` equals the number of k such that Sₖ does not
18212
+ model `convertible_to<IndexType>`; and
18213
+ - for each rank index k of `Extents` such that
18214
+ *`map-rank`*`[`k`] != dynamic_extent` is `true`,
18215
+ `SubExtents::static_extent(`*`map-rank`*`[`k`])` equals:
18216
+ - `Extents::static_extent(`k`)` if
18217
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; otherwise
18218
+ - *`de-ice`*`(tuple_element_t<1, `Sₖ`>()) -`
18219
+ *`de-ice`*`(tuple_element_t<0, `Sₖ`>())` if Sₖ models
18220
+ `index-pair-like<IndexType>`, and both `tuple_element_t<0, `Sₖ`>`
18221
+ and `tuple_element_t<1, `Sₖ`>` model `integral-constant-like`;
18222
+ otherwise
18223
+ - `0`, if Sₖ is a specialization of `strided_slice`, whose
18224
+ `extent_type` models *`integral-constant-like`*, for which
18225
+ `extent_type()` equals zero; otherwise
18226
+ - `1 + (`*`de-ice`*`(`Sₖ`::extent_type()) - 1) /`
18227
+ *`de-ice`*`(`Sₖ`::stride_type())`, if Sₖ is a specialization of
18228
+ `strided_slice` whose `extent_type` and `stride_type` model
18229
+ *`integral-constant-like`*;
18230
+ - otherwise, `dynamic_extent`.
18231
+
18232
+ *Returns:* A value `ext` of type `SubExtents` such that for each k for
18233
+ which *`map-rank`*`[`k`] != dynamic_extent` is `true`,
18234
+ `ext.extent(`*`map-rank`*`[`k`])` equals:
18235
+
18236
+ - sₖ`.extent == 0 ? 0 : 1 + (`*`de-ice`*`(`sₖ`.extent) - 1) / `*`de-ice`*`(`sₖ`.stride)`
18237
+ if Sₖ is a specialization of `strided_slice`,
18238
+ - otherwise,
18239
+ *`last_`*`<`k`>(src, slices...) - `*`first_`*`<IndexType, `k`>(slices...)`.
18240
+
18241
+ ##### Specializations of `submdspan_mapping` <a id="mdspan.sub.map">[[mdspan.sub.map]]</a>
18242
+
18243
+ ###### Common <a id="mdspan.sub.map.common">[[mdspan.sub.map.common]]</a>
18244
+
18245
+ The following elements apply to all functions in [[mdspan.sub.map]].
18246
+
18247
+ *Constraints:* `sizeof...(slices)` equals `extents_type::rank()`.
18248
+
18249
+ *Mandates:* For each rank index k of `extents()`, exactly one of the
18250
+ following is true:
18251
+
18252
+ - Sₖ models `convertible_to<index_type>`,
18253
+ - Sₖ models `index-pair-like<index_type>`,
18254
+ - `is_convertible_v<Sₖ, full_extent_t>` is `true`, or
18255
+ - Sₖ is a specialization of `strided_slice`.
18256
+
18257
+ *Preconditions:* For each rank index k of `extents()`, all of the
18258
+ following are `true`:
18259
+
18260
+ - if Sₖ is a specialization of `strided_slice`, `sₖ.extent` is equal to
18261
+ zero or `sₖ.stride` is greater than zero; and
18262
+ - $0 \leq \tcode{\exposid{first_}<index_type, $k$>(slices...)} \\
18263
+ \hphantom{0 } \leq \tcode{\exposid{last_}<$k$>(extents(), slices...)} \\
18264
+ \hphantom{0 } \leq \tcode{extents().extent($k$)}$
18265
+
18266
+ Let `sub_ext` be the result of `submdspan_extents(extents(), slices...)`
18267
+ and let `SubExtents` be `decltype(sub_ext)`.
18268
+
18269
+ Let `sub_strides` be an
18270
+ `array<SubExtents::index_type, SubExtents::rank()>` such that for each
18271
+ rank index k of `extents()` for which `map-rank[k]` is not
18272
+ `dynamic_extent`, `sub_strides[map-rank[k]]` equals:
18273
+
18274
+ - `stride(k) * de-ice(sₖ.stride)` if Sₖ is a specialization of
18275
+ `strided_slice` and `sₖ.stride < sₖ.extent` is `true`;
18276
+ - otherwise, `stride(k)`.
18277
+
18278
+ Let `P` be a parameter pack such that
18279
+ `is_same_v<make_index_sequence<rank()>, index_sequence<P...>>` is
18280
+ `true`.
18281
+
18282
+ If `first_<index_type, k>(slices...)` equals `extents().extent(k)` for
18283
+ any rank index k of `extents()`, then let `offset` be a value of type
18284
+ `size_t` equal to `(*this).required_span_size()`. Otherwise, let
18285
+ `offset` be a value of type `size_t` equal to
18286
+ `(*this)(first_<index_type, P>(slices...)...)`.
18287
+
18288
+ Given a layout mapping type `M`, a type `S` is a *unit-stride slice for
18289
+ `M`* if
18290
+
18291
+ - `S` is a specialization of `strided_slice` where `S::stride_type`
18292
+ models `integral-constant-like` and `S::stride_type::value` equals
18293
+ `1`,
18294
+ - `S` models `index-pair-like<M::index_type>`, or
18295
+ - `is_convertible_v<S, full_extent_t>` is `true`.
18296
+
18297
+ ###### `layout_left` specialization of `submdspan_mapping` <a id="mdspan.sub.map.left">[[mdspan.sub.map.left]]</a>
18298
+
18299
+ ``` cpp
18300
+ template<class Extents>
18301
+ template<class... SliceSpecifiers>
18302
+ constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl(
18303
+ SliceSpecifiers... slices) const -> see below;
18304
+ ```
18305
+
18306
+ *Returns:*
18307
+
18308
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
18309
+ `true`;
18310
+ - otherwise,
18311
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
18312
+ `SubExtents::rank() == 0` is `true`;
18313
+ - otherwise,
18314
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
18315
+ - for each k in the range \[`0`, `SubExtents::rank() - 1)`),
18316
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
18317
+ - for k equal to `SubExtents::rank() - 1`, Sₖ is a unit-stride slice
18318
+ for `mapping`;
18319
+
18320
+ \[*Note 2*: If the above conditions are true, all Sₖ with k larger
18321
+ than `SubExtents::rank() - 1` are convertible to
18322
+ `index_type`. — *end note*]
18323
+ - otherwise,
18324
+ ``` cpp
18325
+ submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
18326
+ offset}
18327
+ ```
18328
+
18329
+ if for a value u for which u+1 is the smallest value p larger than
18330
+ zero for which Sₚ is a unit-stride slice for `mapping`, the following
18331
+ conditions are met:
18332
+ - S₀ is a unit-stride slice for `mapping`; and
18333
+ - for each k in the range \[u` + 1`, u` + SubExtents::rank() - 1`),
18334
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
18335
+ - for k equal to u` + SubExtents::rank() - 1`, Sₖ is a unit-stride
18336
+ slice for `mapping`;
18337
+
18338
+ and where `S_static` is:
18339
+ - `dynamic_extent`, if `static_extent(`k`)` is `dynamic_extent` for
18340
+ any k in the range \[`0`, u` + 1`),
18341
+ - otherwise, the product of all values `static_extent(`k`)` for k in
18342
+ the range \[`0`, u` + 1`);
18343
+ - otherwise,
18344
+ ``` cpp
18345
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
18346
+ ```
18347
+
18348
+ ###### `layout_right` specialization of `submdspan_mapping` <a id="mdspan.sub.map.right">[[mdspan.sub.map.right]]</a>
18349
+
18350
+ ``` cpp
18351
+ template<class Extents>
18352
+ template<class... SliceSpecifiers>
18353
+ constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl(
18354
+ SliceSpecifiers... slices) const -> see below;
18355
+ ```
18356
+
18357
+ *Returns:*
18358
+
18359
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
18360
+ `true`;
18361
+ - otherwise,
18362
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
18363
+ `SubExtents::rank() == 0` is `true`;
18364
+ - otherwise,
18365
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
18366
+ - for each k in the range \[*`rank_`*` - SubExtents::rank() + 1`,
18367
+ *`rank_`*), `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
18368
+ - for k equal to *rank\_* - `SubExtents::rank()`, Sₖ is a unit-stride
18369
+ slice for `mapping`;
18370
+
18371
+ \[*Note 3*: If the above conditions are true, all Sₖ with
18372
+ $k < \texttt{\textit{rank_} - SubExtents::rank()}$ are convertible to
18373
+ `index_type`. — *end note*]
18374
+ - otherwise,
18375
+ ``` cpp
18376
+ submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
18377
+ stride(rank_ - u - 2)), offset}
18378
+ ```
18379
+
18380
+ if for a value u for which rank_ - u - 2 is the largest value p
18381
+ smaller than *`rank_`*` - 1` for which Sₚ is a unit-stride slice for
18382
+ `mapping`, the following conditions are met:
18383
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
18384
+ `mapping`; and
18385
+ - for each k in the range
18386
+ \[*`rank_`*` - SubExtents::rank() - `u` + 1`,
18387
+ *`rank_`*` - `u` - 1`), `is_convertible_v<`Sₖ`, full_extent_t>` is
18388
+ `true`; and
18389
+ - for k equal to *`rank_`*` - SubExtents::rank() - `u, Sₖ is a
18390
+ unit-stride slice for `mapping`;
18391
+
18392
+ and where `S_static` is:
18393
+ - `dynamic_extent`, if `static_extent(`k`)` is `dynamic_extent` for
18394
+ any k in the range \[*`rank_`*` - `u` - 1`, *`rank_`*),
18395
+ - otherwise, the product of all values `static_extent(`k`)` for k in
18396
+ the range \[*`rank_`*` - `u` - 1`, *`rank_`*);
18397
+ - otherwise,
18398
+ ``` cpp
18399
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
18400
+ ```
18401
+
18402
+ ###### `layout_stride` specialization of `submdspan_mapping` <a id="mdspan.sub.map.stride">[[mdspan.sub.map.stride]]</a>
18403
+
18404
+ ``` cpp
18405
+ template<class Extents>
18406
+ template<class... SliceSpecifiers>
18407
+ constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl(
18408
+ SliceSpecifiers... slices) const -> see below;
18409
+ ```
18410
+
18411
+ *Returns:*
18412
+
18413
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
18414
+ `true`;
18415
+ - otherwise,
18416
+ ``` cpp
18417
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
18418
+ ```
18419
+
18420
+ ###### `layout_left_padded` specialization of `submdspan_mapping` <a id="mdspan.sub.map.leftpad">[[mdspan.sub.map.leftpad]]</a>
18421
+
18422
+ ``` cpp
18423
+ template<class Extents>
18424
+ template<class... SliceSpecifiers>
18425
+ constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl(
18426
+ SliceSpecifiers... slices) const -> see below;
18427
+ ```
18428
+
18429
+ *Returns:*
18430
+
18431
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
18432
+ `true`;
18433
+ - otherwise,
18434
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
18435
+ *`rank_`*` == 1` is `true` or `SubExtents::rank() == 0` is `true`;
18436
+ - otherwise,
18437
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
18438
+ - `SubExtents::rank() == 1` is `true` and
18439
+ - S₀ is a unit-stride slice for `mapping`;
18440
+ - otherwise,
18441
+ ``` cpp
18442
+ submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
18443
+ offset}
18444
+ ```
18445
+
18446
+ if for a value u for which u` + 1` is the smallest value p larger than
18447
+ zero for which Sₚ is a unit-stride slice for `mapping`, the following
18448
+ conditions are met:
18449
+ - S₀ is a unit-stride slice for `mapping`; and
18450
+ - for each k in the range \[u` + 1`, u` + SubExtents::rank() - 1`),
18451
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
18452
+ - for k equal to u` + SubExtents::rank() - 1`, Sₖ is a unit-stride
18453
+ slice for `mapping`;
18454
+
18455
+ where `S_static` is:
18456
+ - `dynamic_extent`, if *static-padding-stride* is `dynamic_extent` or
18457
+ `static_extent(`k`)` is `dynamic_extent` for any k in the range
18458
+ \[`1`, u` + 1`),
18459
+ - otherwise, the product of *static-padding-stride* and all values
18460
+ `static_extent(`k`)` for k in the range \[`1`, u` + 1`);
18461
+ - otherwise,
18462
+ ``` cpp
18463
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
18464
+ ```
18465
+
18466
+ ###### `layout_right_padded` specialization of `submdspan_mapping` <a id="mdspan.sub.map.rightpad">[[mdspan.sub.map.rightpad]]</a>
18467
+
18468
+ ``` cpp
18469
+ template<class Extents>
18470
+ template<class... SliceSpecifiers>
18471
+ constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl(
18472
+ SliceSpecifiers... slices) const -> see below;
18473
+ ```
18474
+
18475
+ *Returns:*
18476
+
18477
+ - `submdspan_mapping_result{*this, 0}`, if *`rank_`*` == 0` is `true`;
18478
+ - otherwise,
18479
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
18480
+ *`rank_`*` == 1` is `true` or `SubExtents::rank() == 0` is `true`;
18481
+ - otherwise,
18482
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
18483
+ - `SubExtents::rank() == 1` is `true` and
18484
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
18485
+ `mapping`;
18486
+ - otherwise,
18487
+ ``` cpp
18488
+ submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
18489
+ stride(rank_ - u - 2)), offset}
18490
+ ```
18491
+
18492
+ if for a value u for which *`rank_`*` - `u` - 2` is the largest value
18493
+ p smaller than *`rank_`*` - 1` for which Sₚ is a unit-stride slice for
18494
+ `mapping`, the following conditions are met:
18495
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
18496
+ `mapping`; and
18497
+ - for each k in the range
18498
+ \[*`rank_`*` - SubExtents::rank() - `u` + 1`,
18499
+ *`rank_`*` - `u` - 1)`), `is_convertible_v<`Sₖ`, full_extent_t>` is
18500
+ `true`; and
18501
+ - for k equal to *`rank_`*` - SubExtents::rank() - `u, Sₖ is a
18502
+ unit-stride slice for `mapping`;
18503
+
18504
+ and where `S_static` is:
18505
+ - `dynamic_extent` if *static-padding-stride* is `dynamic_extent` or
18506
+ for any k in the range \[*`rank_`*` - `u` - 1`, *`rank_`*` - 1`)
18507
+ `static_extent(`k`)` is `dynamic_extent`,
18508
+ - otherwise, the product of *static-padding-stride* and all values
18509
+ `static_extent(`k`)` with k in the range \[*`rank_`*` - `u` - 1`,
18510
+ *`rank_`*` - 1`);
18511
+ - otherwise,
18512
+ ``` cpp
18513
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
18514
+ ```
18515
+
18516
+ ##### `submdspan` function template <a id="mdspan.sub.sub">[[mdspan.sub.sub]]</a>
18517
+
18518
+ ``` cpp
18519
+ template<class ElementType, class Extents, class LayoutPolicy,
18520
+ class AccessorPolicy, class... SliceSpecifiers>
18521
+ constexpr auto submdspan(
18522
+ const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
18523
+ SliceSpecifiers... slices) -> see below;
18524
+ ```
18525
+
18526
+ Let `index_type` be `typename Extents::index_type`.
18527
+
18528
+ Let `sub_map_offset` be the result of
18529
+ `submdspan_mapping(src.mapping(), slices...)`.
18530
+
18531
+ [*Note 1*: This invocation of `submdspan_mapping` selects a function
18532
+ call via overload resolution on a candidate set that includes the lookup
18533
+ set found by argument-dependent
18534
+ lookup [[basic.lookup.argdep]]. — *end note*]
18535
+
18536
+ *Constraints:*
18537
+
18538
+ - `sizeof...(slices)` equals `Extents::rank()`, and
18539
+ - the expression `submdspan_mapping(src.mapping(), slices...)` is
18540
+ well-formed when treated as an unevaluated operand.
18541
+
18542
+ *Mandates:*
18543
+
18544
+ - `decltype(submdspan_mapping(src.mapping(), slices...))` is a
18545
+ specialization of `submd-span_mapping_result`.
18546
+ - `is_same_v<remove_cvref_t<decltype(sub_map_offset.mapping.extents())>,`
18547
+ `decltype(submdspan_extents(src.mapping(), slices...))>` is `true`.
18548
+ - For each rank index k of `src.extents()`, exactly one of the following
18549
+ is true:
18550
+ - Sₖ models `convertible_to<index_type>`,
18551
+ - Sₖ models `index-pair-like<index_type>`,
18552
+ - `is_convertible_v<`Sₖ`, full_extent_t>` is `true`, or
18553
+ - Sₖ is a specialization of `strided_slice`.
18554
+
18555
+ *Preconditions:*
18556
+
18557
+ - For each rank index k of `src.extents()`, all of the following are
18558
+ `true`:
18559
+ - if Sₖ is a specialization of `strided_slice`
18560
+ - `$s_k$.extent` = 0, or
18561
+ - `$s_k$.stride` > 0
18562
+ - $0 \le \texttt{\textit{first_}<index_type, $k$>(slices...)}$
18563
+ $\le \texttt{\textit{last_}<$k$>(src.extents(), slices...)}$
18564
+ ≤ `{}src.extent($k$)`
18565
+ - `sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...)`
18566
+ is `true`; and
18567
+ - for each integer pack `I` which is a multidimensional index in
18568
+ `sub_map_offset.mapping.extents()`,
18569
+ ``` cpp
18570
+ sub_map_offset.mapping(I...) + sub_map_offset.offset ==
18571
+ src.mapping()(src-indices(array{I...}, slices...))
18572
+ ```
18573
+
18574
+ is `true`.
18575
+
18576
+ [*Note 2*: These conditions ensure that the mapping returned by
18577
+ `submdspan_mapping` matches the algorithmically expected index-mapping
18578
+ given the slice specifiers. — *end note*]
18579
+
18580
+ *Effects:* Equivalent to:
18581
+
18582
+ ``` cpp
18583
+ auto sub_map_result = submdspan_mapping(src.mapping(), slices...);
18584
+ return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset),
18585
+ sub_map_result.mapping,
18586
+ typename AccessorPolicy::offset_policy(src.accessor()));
18587
+ ```
18588
+
18589
+ [*Example 1*:
18590
+
18591
+ Given a rank-3 `mdspan grid3d` representing a three-dimensional grid of
18592
+ regularly spaced points in a rectangular prism, the function
18593
+ `zero_surface` sets all elements on the surface of the 3-dimensional
18594
+ shape to zero. It does so by reusing a function `zero_2d` that takes a
18595
+ rank-2 `mdspan`.
18596
+
18597
+ ``` cpp
18598
+ // zero out all elements in an mdspan
18599
+ template<class T, class E, class L, class A>
18600
+ void zero_2d(mdspan<T, E, L, A> a) {
18601
+ static_assert(a.rank() == 2);
18602
+ for (int i = 0; i < a.extent(0); i++)
18603
+ for (int j = 0; j < a.extent(1); j++)
18604
+ a[i, j] = 0;
18605
+ }
18606
+
18607
+ // zero out just the surface
18608
+ template<class T, class E, class L, class A>
18609
+ void zero_surface(mdspan<T, E, L, A> grid3d) {
18610
+ static_assert(grid3d.rank() == 3);
18611
+ zero_2d(submdspan(grid3d, 0, full_extent, full_extent));
18612
+ zero_2d(submdspan(grid3d, full_extent, 0, full_extent));
18613
+ zero_2d(submdspan(grid3d, full_extent, full_extent, 0));
18614
+ zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent));
18615
+ zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent));
18616
+ zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1));
18617
+ }
18618
+ ```
18619
+
18620
+ — *end example*]
18621
+
18622
  <!-- Link reference definitions -->
18623
  [alg.equal]: algorithms.md#alg.equal
18624
  [alg.sorting]: algorithms.md#alg.sorting
18625
  [algorithm.stable]: library.md#algorithm.stable
18626
  [algorithms]: algorithms.md#algorithms
 
18644
  [associative.reqmts]: #associative.reqmts
18645
  [associative.reqmts.except]: #associative.reqmts.except
18646
  [associative.reqmts.general]: #associative.reqmts.general
18647
  [associative.set.syn]: #associative.set.syn
18648
  [basic.fundamental]: basic.md#basic.fundamental
18649
+ [basic.lookup.argdep]: basic.md#basic.lookup.argdep
18650
  [basic.string]: strings.md#basic.string
18651
  [class.copy.ctor]: class.md#class.copy.ctor
18652
  [class.default.ctor]: class.md#class.default.ctor
18653
  [class.dtor]: class.md#class.dtor
18654
  [container.adaptors]: #container.adaptors
18655
  [container.adaptors.format]: #container.adaptors.format
18656
  [container.adaptors.general]: #container.adaptors.general
18657
  [container.alloc.reqmts]: #container.alloc.reqmts
 
18658
  [container.insert.return]: #container.insert.return
18659
+ [container.intro.reqmts]: #container.intro.reqmts
18660
  [container.node]: #container.node
18661
  [container.node.compat]: #container.node.compat
18662
  [container.node.cons]: #container.node.cons
18663
  [container.node.dtor]: #container.node.dtor
18664
  [container.node.modifiers]: #container.node.modifiers
 
18686
  [expr.const]: expr.md#expr.const
18687
  [flat.map]: #flat.map
18688
  [flat.map.access]: #flat.map.access
18689
  [flat.map.capacity]: #flat.map.capacity
18690
  [flat.map.cons]: #flat.map.cons
18691
+ [flat.map.cons.alloc]: #flat.map.cons.alloc
18692
  [flat.map.defn]: #flat.map.defn
18693
  [flat.map.erasure]: #flat.map.erasure
18694
  [flat.map.modifiers]: #flat.map.modifiers
18695
  [flat.map.overview]: #flat.map.overview
18696
  [flat.map.syn]: #flat.map.syn
18697
  [flat.multimap]: #flat.multimap
18698
  [flat.multimap.cons]: #flat.multimap.cons
18699
+ [flat.multimap.cons.alloc]: #flat.multimap.cons.alloc
18700
  [flat.multimap.defn]: #flat.multimap.defn
18701
  [flat.multimap.erasure]: #flat.multimap.erasure
18702
  [flat.multimap.overview]: #flat.multimap.overview
18703
  [flat.multiset]: #flat.multiset
18704
  [flat.multiset.cons]: #flat.multiset.cons
18705
+ [flat.multiset.cons.alloc]: #flat.multiset.cons.alloc
18706
  [flat.multiset.defn]: #flat.multiset.defn
18707
  [flat.multiset.erasure]: #flat.multiset.erasure
18708
  [flat.multiset.modifiers]: #flat.multiset.modifiers
18709
  [flat.multiset.overview]: #flat.multiset.overview
18710
  [flat.set]: #flat.set
18711
  [flat.set.cons]: #flat.set.cons
18712
+ [flat.set.cons.alloc]: #flat.set.cons.alloc
18713
  [flat.set.defn]: #flat.set.defn
18714
  [flat.set.erasure]: #flat.set.erasure
18715
  [flat.set.modifiers]: #flat.set.modifiers
18716
  [flat.set.overview]: #flat.set.overview
18717
  [flat.set.syn]: #flat.set.syn
 
18724
  [forward.list.modifiers]: #forward.list.modifiers
18725
  [forward.list.ops]: #forward.list.ops
18726
  [forward.list.overview]: #forward.list.overview
18727
  [forward.list.syn]: #forward.list.syn
18728
  [hash.requirements]: library.md#hash.requirements
18729
+ [hive]: #hive
18730
+ [hive.capacity]: #hive.capacity
18731
+ [hive.cons]: #hive.cons
18732
+ [hive.erasure]: #hive.erasure
18733
+ [hive.modifiers]: #hive.modifiers
18734
+ [hive.operations]: #hive.operations
18735
+ [hive.overview]: #hive.overview
18736
+ [hive.syn]: #hive.syn
18737
+ [inplace.vector]: #inplace.vector
18738
+ [inplace.vector.capacity]: #inplace.vector.capacity
18739
+ [inplace.vector.cons]: #inplace.vector.cons
18740
+ [inplace.vector.data]: #inplace.vector.data
18741
+ [inplace.vector.erasure]: #inplace.vector.erasure
18742
+ [inplace.vector.modifiers]: #inplace.vector.modifiers
18743
+ [inplace.vector.overview]: #inplace.vector.overview
18744
+ [inplace.vector.syn]: #inplace.vector.syn
18745
  [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
18746
  [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
18747
  [iterator.requirements]: iterators.md#iterator.requirements
18748
  [iterator.requirements.general]: iterators.md#iterator.requirements.general
18749
  [list]: #list
 
18759
  [map.cons]: #map.cons
18760
  [map.erasure]: #map.erasure
18761
  [map.modifiers]: #map.modifiers
18762
  [map.overview]: #map.overview
18763
  [mdspan.accessor]: #mdspan.accessor
18764
+ [mdspan.accessor.aligned]: #mdspan.accessor.aligned
18765
+ [mdspan.accessor.aligned.members]: #mdspan.accessor.aligned.members
18766
+ [mdspan.accessor.aligned.overview]: #mdspan.accessor.aligned.overview
18767
  [mdspan.accessor.default]: #mdspan.accessor.default
18768
  [mdspan.accessor.default.members]: #mdspan.accessor.default.members
18769
  [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
18770
  [mdspan.accessor.general]: #mdspan.accessor.general
18771
  [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
18772
  [mdspan.extents]: #mdspan.extents
18773
  [mdspan.extents.cmp]: #mdspan.extents.cmp
18774
  [mdspan.extents.cons]: #mdspan.extents.cons
18775
  [mdspan.extents.dextents]: #mdspan.extents.dextents
18776
+ [mdspan.extents.dims]: #mdspan.extents.dims
18777
  [mdspan.extents.expo]: #mdspan.extents.expo
18778
  [mdspan.extents.obs]: #mdspan.extents.obs
18779
  [mdspan.extents.overview]: #mdspan.extents.overview
18780
  [mdspan.layout]: #mdspan.layout
18781
  [mdspan.layout.general]: #mdspan.layout.general
18782
  [mdspan.layout.left]: #mdspan.layout.left
18783
  [mdspan.layout.left.cons]: #mdspan.layout.left.cons
18784
  [mdspan.layout.left.obs]: #mdspan.layout.left.obs
18785
  [mdspan.layout.left.overview]: #mdspan.layout.left.overview
18786
+ [mdspan.layout.leftpad]: #mdspan.layout.leftpad
18787
+ [mdspan.layout.leftpad.cons]: #mdspan.layout.leftpad.cons
18788
+ [mdspan.layout.leftpad.expo]: #mdspan.layout.leftpad.expo
18789
+ [mdspan.layout.leftpad.obs]: #mdspan.layout.leftpad.obs
18790
+ [mdspan.layout.leftpad.overview]: #mdspan.layout.leftpad.overview
18791
  [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
18792
  [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
18793
  [mdspan.layout.reqmts]: #mdspan.layout.reqmts
18794
  [mdspan.layout.right]: #mdspan.layout.right
18795
  [mdspan.layout.right.cons]: #mdspan.layout.right.cons
18796
  [mdspan.layout.right.obs]: #mdspan.layout.right.obs
18797
  [mdspan.layout.right.overview]: #mdspan.layout.right.overview
18798
+ [mdspan.layout.rightpad]: #mdspan.layout.rightpad
18799
+ [mdspan.layout.rightpad.cons]: #mdspan.layout.rightpad.cons
18800
+ [mdspan.layout.rightpad.expo]: #mdspan.layout.rightpad.expo
18801
+ [mdspan.layout.rightpad.obs]: #mdspan.layout.rightpad.obs
18802
+ [mdspan.layout.rightpad.overview]: #mdspan.layout.rightpad.overview
18803
  [mdspan.layout.stride]: #mdspan.layout.stride
18804
  [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
18805
  [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
18806
  [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
18807
  [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
18808
  [mdspan.mdspan]: #mdspan.mdspan
18809
  [mdspan.mdspan.cons]: #mdspan.mdspan.cons
18810
  [mdspan.mdspan.members]: #mdspan.mdspan.members
18811
  [mdspan.mdspan.overview]: #mdspan.mdspan.overview
18812
  [mdspan.overview]: #mdspan.overview
18813
+ [mdspan.sub]: #mdspan.sub
18814
+ [mdspan.sub.extents]: #mdspan.sub.extents
18815
+ [mdspan.sub.helpers]: #mdspan.sub.helpers
18816
+ [mdspan.sub.map]: #mdspan.sub.map
18817
+ [mdspan.sub.map.common]: #mdspan.sub.map.common
18818
+ [mdspan.sub.map.left]: #mdspan.sub.map.left
18819
+ [mdspan.sub.map.leftpad]: #mdspan.sub.map.leftpad
18820
+ [mdspan.sub.map.result]: #mdspan.sub.map.result
18821
+ [mdspan.sub.map.right]: #mdspan.sub.map.right
18822
+ [mdspan.sub.map.rightpad]: #mdspan.sub.map.rightpad
18823
+ [mdspan.sub.map.stride]: #mdspan.sub.map.stride
18824
+ [mdspan.sub.overview]: #mdspan.sub.overview
18825
+ [mdspan.sub.strided.slice]: #mdspan.sub.strided.slice
18826
+ [mdspan.sub.sub]: #mdspan.sub.sub
18827
  [mdspan.syn]: #mdspan.syn
18828
  [multimap]: #multimap
18829
  [multimap.cons]: #multimap.cons
18830
  [multimap.erasure]: #multimap.erasure
18831
  [multimap.modifiers]: #multimap.modifiers
 
18847
  [queue.mod]: #queue.mod
18848
  [queue.ops]: #queue.ops
18849
  [queue.special]: #queue.special
18850
  [queue.syn]: #queue.syn
18851
  [random.access.iterators]: iterators.md#random.access.iterators
18852
+ [re.results]: text.md#re.results
18853
  [res.on.data.races]: library.md#res.on.data.races
18854
  [sequence.reqmts]: #sequence.reqmts
18855
  [sequences]: #sequences
18856
  [sequences.general]: #sequences.general
18857
  [set]: #set
18858
  [set.cons]: #set.cons
18859
  [set.erasure]: #set.erasure
18860
+ [set.modifiers]: #set.modifiers
18861
  [set.overview]: #set.overview
18862
  [span.cons]: #span.cons
18863
  [span.deduct]: #span.deduct
18864
  [span.elem]: #span.elem
18865
  [span.iterators]: #span.iterators
 
18875
  [stack.general]: #stack.general
18876
  [stack.mod]: #stack.mod
18877
  [stack.ops]: #stack.ops
18878
  [stack.special]: #stack.special
18879
  [stack.syn]: #stack.syn
18880
+ [stacktrace.basic]: diagnostics.md#stacktrace.basic
18881
  [strings]: strings.md#strings
18882
  [swappable.requirements]: library.md#swappable.requirements
18883
  [temp.deduct]: temp.md#temp.deduct
 
18884
  [temp.type]: temp.md#temp.type
18885
+ [term.structural.type]: temp.md#term.structural.type
18886
  [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
18887
  [unord]: #unord
18888
  [unord.general]: #unord.general
18889
  [unord.hash]: utilities.md#unord.hash
18890
  [unord.map]: #unord.map
 
18907
  [unord.req.except]: #unord.req.except
18908
  [unord.req.general]: #unord.req.general
18909
  [unord.set]: #unord.set
18910
  [unord.set.cnstr]: #unord.set.cnstr
18911
  [unord.set.erasure]: #unord.set.erasure
18912
+ [unord.set.modifiers]: #unord.set.modifiers
18913
  [unord.set.overview]: #unord.set.overview
18914
  [unord.set.syn]: #unord.set.syn
18915
  [vector]: #vector
18916
  [vector.bool]: #vector.bool
18917
  [vector.bool.fmt]: #vector.bool.fmt