From Jason Turner

[container.adaptors]

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

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqe4kvbl3/{from.md → to.md} +2971 -29
tmp/tmpqe4kvbl3/{from.md → to.md} RENAMED
@@ -1,46 +1,94 @@
1
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
2
 
3
  ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
4
 
5
- The headers `<queue>` and `<stack>` define the container adaptors
6
- `queue`, `priority_queue`, and `stack`.
 
7
 
8
- The container adaptors each take a `Container` template parameter, and
9
- each constructor takes a `Container` reference argument. This container
10
- is copied into the `Container` member of each adaptor. If the container
11
- takes an allocator, then a compatible allocator may be passed in to the
12
- adaptor’s constructor. Otherwise, normal copy or move construction is
13
- used for the container argument. The first template parameter `T` of the
14
- container adaptors shall denote the same type as
15
- `Container::value_type`.
 
 
 
 
16
 
17
  For container adaptors, no `swap` function throws an exception unless
18
- that exception is thrown by the swap of the adaptor’s `Container` or
19
- `Compare` object (if any).
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  A deduction guide for a container adaptor shall not participate in
22
  overload resolution if any of the following are true:
23
 
24
  - It has an `InputIterator` template parameter and a type that does not
25
  qualify as an input iterator is deduced for that parameter.
26
  - It has a `Compare` template parameter and a type that qualifies as an
27
  allocator is deduced for that parameter.
28
- - It has a `Container` template parameter and a type that qualifies as
29
- an allocator is deduced for that parameter.
30
- - It has an `Allocator` template parameter and a type that does not
31
- qualify as an allocator is deduced for that parameter.
 
 
32
  - It has both `Container` and `Allocator` template parameters, and
33
  `uses_allocator_v<Container, Allocator>` is `false`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
36
 
37
  ``` cpp
38
  #include <compare> // see [compare.syn]
39
  #include <initializer_list> // see [initializer.list.syn]
40
 
41
  namespace std {
 
42
  template<class T, class Container = deque<T>> class queue;
43
 
44
  template<class T, class Container>
45
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
46
  template<class T, class Container>
@@ -60,10 +108,11 @@ namespace std {
60
  template<class T, class Container>
61
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
62
  template<class T, class Container, class Alloc>
63
  struct uses_allocator<queue<T, Container>, Alloc>;
64
 
 
65
  template<class T, class Container = vector<T>,
66
  class Compare = less<typename Container::value_type>>
67
  class priority_queue;
68
 
69
  template<class T, class Container, class Compare>
@@ -79,10 +128,11 @@ namespace std {
79
  ``` cpp
80
  #include <compare> // see [compare.syn]
81
  #include <initializer_list> // see [initializer.list.syn]
82
 
83
  namespace std {
 
84
  template<class T, class Container = deque<T>> class stack;
85
 
86
  template<class T, class Container>
87
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
88
  template<class T, class Container>
@@ -104,10 +154,96 @@ namespace std {
104
  template<class T, class Container, class Alloc>
105
  struct uses_allocator<stack<T, Container>, Alloc>;
106
  }
107
  ```
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  ### Class template `queue` <a id="queue">[[queue]]</a>
110
 
111
  #### Definition <a id="queue.defn">[[queue.defn]]</a>
112
 
113
  Any sequence container supporting operations `front()`, `back()`,
@@ -130,24 +266,31 @@ namespace std {
130
 
131
  public:
132
  queue() : queue(Container()) {}
133
  explicit queue(const Container&);
134
  explicit queue(Container&&);
 
 
135
  template<class Alloc> explicit queue(const Alloc&);
136
  template<class Alloc> queue(const Container&, const Alloc&);
137
  template<class Alloc> queue(Container&&, const Alloc&);
138
  template<class Alloc> queue(const queue&, const Alloc&);
139
  template<class Alloc> queue(queue&&, const Alloc&);
 
 
 
 
140
 
141
  [[nodiscard]] bool empty() const { return c.empty(); }
142
  size_type size() const { return c.size(); }
143
  reference front() { return c.front(); }
144
  const_reference front() const { return c.front(); }
145
  reference back() { return c.back(); }
146
  const_reference back() const { return c.back(); }
147
  void push(const value_type& x) { c.push_back(x); }
148
  void push(value_type&& x) { c.push_back(std::move(x)); }
 
149
  template<class... Args>
150
  decltype(auto) emplace(Args&&... args)
151
  { return c.emplace_back(std::forward<Args>(args)...); }
152
  void pop() { c.pop_front(); }
153
  void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
@@ -155,15 +298,27 @@ namespace std {
155
  };
156
 
157
  template<class Container>
158
  queue(Container) -> queue<typename Container::value_type, Container>;
159
 
 
 
 
 
 
 
160
  template<class Container, class Allocator>
161
  queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
162
 
163
- template<class T, class Container>
164
- void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
 
 
 
 
 
 
165
 
166
  template<class T, class Container, class Alloc>
167
  struct uses_allocator<queue<T, Container>, Alloc>
168
  : uses_allocator<Container, Alloc>::type { };
169
  }
@@ -181,10 +336,26 @@ explicit queue(const Container& cont);
181
  explicit queue(Container&& cont);
182
  ```
183
 
184
  *Effects:* Initializes `c` with `std::move(cont)`.
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  #### Constructors with allocators <a id="queue.cons.alloc">[[queue.cons.alloc]]</a>
187
 
188
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
189
  in this subclause shall not participate in overload resolution.
190
 
@@ -220,10 +391,36 @@ template<class Alloc> queue(queue&& q, const Alloc& a);
220
  ```
221
 
222
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
223
  and `a` as the second argument.
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
226
 
227
  ``` cpp
228
  template<class T, class Container>
229
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
@@ -318,28 +515,47 @@ namespace std {
318
  public:
319
  priority_queue() : priority_queue(Compare()) {}
320
  explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
321
  priority_queue(const Compare& x, const Container&);
322
  priority_queue(const Compare& x, Container&&);
 
 
323
  template<class InputIterator>
324
  priority_queue(InputIterator first, InputIterator last, const Compare& x,
325
  const Container&);
326
  template<class InputIterator>
327
- priority_queue(InputIterator first, InputIterator last,
328
- const Compare& x = Compare(), Container&& = Container());
 
 
329
  template<class Alloc> explicit priority_queue(const Alloc&);
330
  template<class Alloc> priority_queue(const Compare&, const Alloc&);
331
  template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
332
  template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
333
  template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
334
  template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
 
 
 
 
 
 
 
 
 
 
 
 
 
335
 
336
  [[nodiscard]] bool empty() const { return c.empty(); }
337
  size_type size() const { return c.size(); }
338
  const_reference top() const { return c.front(); }
339
  void push(const value_type& x);
340
  void push(value_type&& x);
 
 
341
  template<class... Args> void emplace(Args&&... args);
342
  void pop();
343
  void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
344
  is_nothrow_swappable_v<Compare>)
345
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
@@ -348,25 +564,49 @@ namespace std {
348
  template<class Compare, class Container>
349
  priority_queue(Compare, Container)
350
  -> priority_queue<typename Container::value_type, Container, Compare>;
351
 
352
  template<class InputIterator,
353
- class Compare = less<typename iterator_traits<InputIterator>::value_type>,
354
- class Container = vector<typename iterator_traits<InputIterator>::value_type>>
355
  priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
356
- -> priority_queue<typename iterator_traits<InputIterator>::value_type, Container, Compare>;
 
 
 
 
357
 
358
  template<class Compare, class Container, class Allocator>
359
  priority_queue(Compare, Container, Allocator)
360
  -> priority_queue<typename Container::value_type, Container, Compare>;
361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  // no equality is provided
363
 
364
- template<class T, class Container, class Compare>
365
- void swap(priority_queue<T, Container, Compare>& x,
366
- priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
367
-
368
  template<class T, class Container, class Compare, class Alloc>
369
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
370
  : uses_allocator<Container, Alloc>::type { };
371
  }
372
  ```
@@ -382,25 +622,46 @@ priority_queue(const Compare& x, Container&& y);
382
 
383
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
384
  constructing or move constructing as appropriate); calls
385
  `make_heap(c.begin(), c.end(), comp)`.
386
 
 
 
 
 
 
 
 
 
 
 
 
387
  ``` cpp
388
  template<class InputIterator>
389
  priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y);
390
  template<class InputIterator>
391
- priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(),
392
- Container&& y = Container());
393
  ```
394
 
395
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
396
 
397
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
398
  constructing or move constructing as appropriate); calls
399
  `c.insert(c.end(), first, last)`; and finally calls
400
  `make_heap(c.begin(), c.end(), comp)`.
401
 
 
 
 
 
 
 
 
 
 
 
 
402
  #### Constructors with allocators <a id="priqueue.cons.alloc">[[priqueue.cons.alloc]]</a>
403
 
404
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
405
  in this subclause shall not participate in overload resolution.
406
 
@@ -448,10 +709,68 @@ template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
448
 
449
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
450
  and `a` as the second argument, and initializes `comp` with
451
  `std::move(q.comp)`.
452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
454
 
455
  ``` cpp
456
  void push(const value_type& x);
457
  ```
@@ -472,10 +791,22 @@ void push(value_type&& x);
472
  ``` cpp
473
  c.push_back(std::move(x));
474
  push_heap(c.begin(), c.end(), comp);
475
  ```
476
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  ``` cpp
478
  template<class... Args> void emplace(Args&&... args);
479
  ```
480
 
481
  *Effects:* As if by:
@@ -509,10 +840,12 @@ template<class T, class Container, class Compare>
509
 
510
  *Effects:* As if by `x.swap(y)`.
511
 
512
  ### Class template `stack` <a id="stack">[[stack]]</a>
513
 
 
 
514
  Any sequence container supporting operations `back()`, `push_back()` and
515
  `pop_back()` can be used to instantiate `stack`. In particular, `vector`
516
  [[vector]], `list` [[list]] and `deque` [[deque]] can be used.
517
 
518
  #### Definition <a id="stack.defn">[[stack.defn]]</a>
@@ -533,22 +866,30 @@ namespace std {
533
 
534
  public:
535
  stack() : stack(Container()) {}
536
  explicit stack(const Container&);
537
  explicit stack(Container&&);
 
 
538
  template<class Alloc> explicit stack(const Alloc&);
539
  template<class Alloc> stack(const Container&, const Alloc&);
540
  template<class Alloc> stack(Container&&, const Alloc&);
541
  template<class Alloc> stack(const stack&, const Alloc&);
542
  template<class Alloc> stack(stack&&, const Alloc&);
 
 
 
 
543
 
544
  [[nodiscard]] bool empty() const { return c.empty(); }
545
  size_type size() const { return c.size(); }
546
  reference top() { return c.back(); }
547
  const_reference top() const { return c.back(); }
548
  void push(const value_type& x) { c.push_back(x); }
549
  void push(value_type&& x) { c.push_back(std::move(x)); }
 
 
550
  template<class... Args>
551
  decltype(auto) emplace(Args&&... args)
552
  { return c.emplace_back(std::forward<Args>(args)...); }
553
  void pop() { c.pop_back(); }
554
  void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
@@ -556,13 +897,28 @@ namespace std {
556
  };
557
 
558
  template<class Container>
559
  stack(Container) -> stack<typename Container::value_type, Container>;
560
 
 
 
 
 
 
 
561
  template<class Container, class Allocator>
562
  stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
563
 
 
 
 
 
 
 
 
 
 
564
  template<class T, class Container, class Alloc>
565
  struct uses_allocator<stack<T, Container>, Alloc>
566
  : uses_allocator<Container, Alloc>::type { };
567
  }
568
  ```
@@ -579,10 +935,26 @@ explicit stack(const Container& cont);
579
  explicit stack(Container&& cont);
580
  ```
581
 
582
  *Effects:* Initializes `c` with `std::move(cont)`.
583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
  #### Constructors with allocators <a id="stack.cons.alloc">[[stack.cons.alloc]]</a>
585
 
586
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
587
  in this subclause shall not participate in overload resolution.
588
 
@@ -618,10 +990,36 @@ template<class Alloc> stack(stack&& s, const Alloc& a);
618
  ```
619
 
620
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
621
  and `a` as the second argument.
622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
624
 
625
  ``` cpp
626
  template<class T, class Container>
627
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
@@ -681,5 +1079,2549 @@ template<class T, class Container>
681
 
682
  *Constraints:* `is_swappable_v<Container>` is `true`.
683
 
684
  *Effects:* As if by `x.swap(y)`.
685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ## Container adaptors <a id="container.adaptors">[[container.adaptors]]</a>
2
 
3
  ### In general <a id="container.adaptors.general">[[container.adaptors.general]]</a>
4
 
5
+ The headers `<queue>`, `<stack>`, `<flat_map>`, and `<flat_set>` define
6
+ the container adaptors `queue` and `priority_queue`, `stack`, `flat_map`
7
+ and `flat_multimap`, and `flat_set` and `flat_multiset`, respectively.
8
 
9
+ Each container adaptor takes one or more template parameters named
10
+ `Container`, `KeyContainer`, or `MappedContainer` that denote the types
11
+ of containers that the container adaptor adapts. Each container adaptor
12
+ has at least one constructor that takes a reference argument to one or
13
+ more such template parameters. For each constructor reference argument
14
+ to a container `C`, the constructor copies the container into the
15
+ container adaptor. If `C` takes an allocator, then a compatible
16
+ allocator may be passed in to the adaptor’s constructor. Otherwise,
17
+ normal copy or move construction is used for the container argument. For
18
+ the container adaptors that take a single container template parameter
19
+ `Container`, the first template parameter `T` of the container adaptor
20
+ shall denote the same type as `Container::value_type`.
21
 
22
  For container adaptors, no `swap` function throws an exception unless
23
+ that exception is thrown by the swap of the adaptor’s `Container`,
24
+ `KeyContainer`, `MappedContainer`, or `Compare` object (if any).
25
+
26
+ A constructor template of a container adaptor shall not participate in
27
+ overload resolution if it has an `InputIterator` template parameter and
28
+ a type that does not qualify as an input iterator is deduced for that
29
+ parameter.
30
+
31
+ For container adaptors that have them, the `insert`, `emplace`, and
32
+ `erase` members affect the validity of iterators, references, and
33
+ pointers to the adaptor’s container(s) in the same way that the
34
+ containers’ respective `insert`, `emplace`, and `erase` members do.
35
+
36
+ [*Example 1*: A call to `flat_map<Key, T>::insert` can invalidate all
37
+ iterators to the `flat_map`. — *end example*]
38
 
39
  A deduction guide for a container adaptor shall not participate in
40
  overload resolution if any of the following are true:
41
 
42
  - It has an `InputIterator` template parameter and a type that does not
43
  qualify as an input iterator is deduced for that parameter.
44
  - It has a `Compare` template parameter and a type that qualifies as an
45
  allocator is deduced for that parameter.
46
+ - It has a `Container`, `KeyContainer`, or `MappedContainer` template
47
+ parameter and a type that qualifies as an allocator is deduced for
48
+ that parameter.
49
+ - It has no `Container`, `KeyContainer`, or `MappedContainer` template
50
+ parameter, and it has an `Allocator` template parameter, and a type
51
+ that does not qualify as an allocator is deduced for that parameter.
52
  - It has both `Container` and `Allocator` template parameters, and
53
  `uses_allocator_v<Container, Allocator>` is `false`.
54
+ - It has both `KeyContainer` and `Allocator` template parameters, and
55
+ `uses_allocator_v<KeyContainer, Allocator>` is `false`.
56
+ - It has both `KeyContainer` and `Compare` template parameters, and
57
+ ``` cpp
58
+ is_invocable_v<const Compare&,
59
+ const typename KeyContainer::value_type&,
60
+ const typename KeyContainer::value_type&>
61
+ ```
62
+
63
+ is not a valid expression or is `false`.
64
+ - It has both `MappedContainer` and `Allocator` template parameters, and
65
+ `uses_allocator_v<MappedContainer, Allocator>` is `false`.
66
+
67
+ The exposition-only alias template *`iter-value-type`* defined in
68
+ [[sequences.general]] and the exposition-only alias templates
69
+ *`iter-key-type`*, *`iter-mapped-type`*, *`range-key-type`*, and
70
+ *`range-mapped-type`* defined in [[associative.general]] may appear in
71
+ deduction guides for container adaptors.
72
+
73
+ The following exposition-only alias template may appear in deduction
74
+ guides for container adaptors:
75
+
76
+ ``` cpp
77
+ template<class Allocator, class T>
78
+ using alloc-rebind = // exposition only
79
+ typename allocator_traits<Allocator>::template rebind_alloc<T>;
80
+ ```
81
 
82
  ### Header `<queue>` synopsis <a id="queue.syn">[[queue.syn]]</a>
83
 
84
  ``` cpp
85
  #include <compare> // see [compare.syn]
86
  #include <initializer_list> // see [initializer.list.syn]
87
 
88
  namespace std {
89
+ // [queue], class template queue
90
  template<class T, class Container = deque<T>> class queue;
91
 
92
  template<class T, class Container>
93
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
94
  template<class T, class Container>
 
108
  template<class T, class Container>
109
  void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
110
  template<class T, class Container, class Alloc>
111
  struct uses_allocator<queue<T, Container>, Alloc>;
112
 
113
+ // [priority.queue], class template priority_queue
114
  template<class T, class Container = vector<T>,
115
  class Compare = less<typename Container::value_type>>
116
  class priority_queue;
117
 
118
  template<class T, class Container, class Compare>
 
128
  ``` cpp
129
  #include <compare> // see [compare.syn]
130
  #include <initializer_list> // see [initializer.list.syn]
131
 
132
  namespace std {
133
+ // [stack], class template stack
134
  template<class T, class Container = deque<T>> class stack;
135
 
136
  template<class T, class Container>
137
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
138
  template<class T, class Container>
 
154
  template<class T, class Container, class Alloc>
155
  struct uses_allocator<stack<T, Container>, Alloc>;
156
  }
157
  ```
158
 
159
+ ### Header `<flat_map>` synopsis <a id="flat.map.syn">[[flat.map.syn]]</a>
160
+
161
+ ``` cpp
162
+ #include <compare> // see [compare.syn]
163
+ #include <initializer_list> // see [initializer.list.syn]
164
+
165
+ namespace std {
166
+ // [flat.map], class template flat_map
167
+ template<class Key, class T, class Compare = less<Key>,
168
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
169
+ class flat_map;
170
+
171
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
172
+ inline constexpr sorted_unique_t sorted_unique{};
173
+
174
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
175
+ class Allocator>
176
+ struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
177
+ Allocator>;
178
+
179
+ // [flat.map.erasure], erasure for flat_map
180
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
181
+ class Predicate>
182
+ typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
183
+ erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
184
+
185
+ // [flat.multimap], class template flat_multimap
186
+ template<class Key, class T, class Compare = less<Key>,
187
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
188
+ class flat_multimap;
189
+
190
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
191
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
192
+
193
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
194
+ class Allocator>
195
+ struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
196
+ Allocator>;
197
+
198
+ // [flat.multimap.erasure], erasure for flat_multimap
199
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
200
+ class Predicate>
201
+ typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
202
+ erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
203
+ }
204
+ ```
205
+
206
+ ### Header `<flat_set>` synopsis <a id="flat.set.syn">[[flat.set.syn]]</a>
207
+
208
+ ``` cpp
209
+ #include <compare> // see [compare.syn]
210
+ #include <initializer_list> // see [initializer.list.syn]
211
+
212
+ namespace std {
213
+ // [flat.set], class template flat_set
214
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
215
+ class flat_set;
216
+
217
+ struct sorted_unique_t { explicit sorted_unique_t() = default; };
218
+ inline constexpr sorted_unique_t sorted_unique{};
219
+
220
+ template<class Key, class Compare, class KeyContainer, class Allocator>
221
+ struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
222
+
223
+ // [flat.set.erasure], erasure for flat_set
224
+ template<class Key, class Compare, class KeyContainer, class Predicate>
225
+ typename flat_set<Key, Compare, KeyContainer>::size_type
226
+ erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
227
+
228
+ // [flat.multiset], class template flat_multiset
229
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
230
+ class flat_multiset;
231
+
232
+ struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; };
233
+ inline constexpr sorted_equivalent_t sorted_equivalent{};
234
+
235
+ template<class Key, class Compare, class KeyContainer, class Allocator>
236
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>;
237
+
238
+ // [flat.multiset.erasure], erasure for flat_multiset
239
+ template<class Key, class Compare, class KeyContainer, class Predicate>
240
+ typename flat_multiset<Key, Compare, KeyContainer>::size_type
241
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
242
+ }
243
+ ```
244
+
245
  ### Class template `queue` <a id="queue">[[queue]]</a>
246
 
247
  #### Definition <a id="queue.defn">[[queue.defn]]</a>
248
 
249
  Any sequence container supporting operations `front()`, `back()`,
 
266
 
267
  public:
268
  queue() : queue(Container()) {}
269
  explicit queue(const Container&);
270
  explicit queue(Container&&);
271
+ template<class InputIterator> queue(InputIterator first, InputIterator last);
272
+ template<container-compatible-range<T> R> queue(from_range_t, R&& rg);
273
  template<class Alloc> explicit queue(const Alloc&);
274
  template<class Alloc> queue(const Container&, const Alloc&);
275
  template<class Alloc> queue(Container&&, const Alloc&);
276
  template<class Alloc> queue(const queue&, const Alloc&);
277
  template<class Alloc> queue(queue&&, const Alloc&);
278
+ template<class InputIterator, class Alloc>
279
+ queue(InputIterator first, InputIterator last, const Alloc&);
280
+ template<container-compatible-range<T> R, class Alloc>
281
+ queue(from_range_t, R&& rg, const Alloc&);
282
 
283
  [[nodiscard]] bool empty() const { return c.empty(); }
284
  size_type size() const { return c.size(); }
285
  reference front() { return c.front(); }
286
  const_reference front() const { return c.front(); }
287
  reference back() { return c.back(); }
288
  const_reference back() const { return c.back(); }
289
  void push(const value_type& x) { c.push_back(x); }
290
  void push(value_type&& x) { c.push_back(std::move(x)); }
291
+ template<container-compatible-range<T> R> void push_range(R&& rg);
292
  template<class... Args>
293
  decltype(auto) emplace(Args&&... args)
294
  { return c.emplace_back(std::forward<Args>(args)...); }
295
  void pop() { c.pop_front(); }
296
  void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
 
298
  };
299
 
300
  template<class Container>
301
  queue(Container) -> queue<typename Container::value_type, Container>;
302
 
303
+ template<class InputIterator>
304
+ queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>;
305
+
306
+ template<ranges::input_range R>
307
+ queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>;
308
+
309
  template<class Container, class Allocator>
310
  queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
311
 
312
+ template<class InputIterator, class Allocator>
313
+ queue(InputIterator, InputIterator, Allocator)
314
+ -> queue<iter-value-type<InputIterator>, deque<iter-value-type<InputIterator>,
315
+ Allocator>>;
316
+
317
+ template<ranges::input_range R, class Allocator>
318
+ queue(from_range_t, R&&, Allocator)
319
+ -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>;
320
 
321
  template<class T, class Container, class Alloc>
322
  struct uses_allocator<queue<T, Container>, Alloc>
323
  : uses_allocator<Container, Alloc>::type { };
324
  }
 
336
  explicit queue(Container&& cont);
337
  ```
338
 
339
  *Effects:* Initializes `c` with `std::move(cont)`.
340
 
341
+ ``` cpp
342
+ template<class InputIterator>
343
+ queue(InputIterator first, InputIterator last);
344
+ ```
345
+
346
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
347
+ as the second argument.
348
+
349
+ ``` cpp
350
+ template<container-compatible-range<T> R>
351
+ queue(from_range_t, R&& rg);
352
+ ```
353
+
354
+ *Effects:* Initializes `c` with
355
+ `ranges::to<Container>(std::forward<R>(rg))`.
356
+
357
  #### Constructors with allocators <a id="queue.cons.alloc">[[queue.cons.alloc]]</a>
358
 
359
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
360
  in this subclause shall not participate in overload resolution.
361
 
 
391
  ```
392
 
393
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
394
  and `a` as the second argument.
395
 
396
+ ``` cpp
397
+ template<class InputIterator, class Alloc>
398
+ queue(InputIterator first, InputIterator last, const Alloc& alloc);
399
+ ```
400
+
401
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
402
+ the second argument, and `alloc` as the third argument.
403
+
404
+ ``` cpp
405
+ template<container-compatible-range<T> R, class Alloc>
406
+ queue(from_range_t, R&& rg, const Alloc& a);
407
+ ```
408
+
409
+ *Effects:* Initializes `c` with
410
+ `ranges::to<Container>(std::forward<R>(rg), a)`.
411
+
412
+ #### Modifiers <a id="queue.mod">[[queue.mod]]</a>
413
+
414
+ ``` cpp
415
+ template<container-compatible-range<T> R>
416
+ void push_range(R&& rg);
417
+ ```
418
+
419
+ *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
420
+ is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
421
+
422
  #### Operators <a id="queue.ops">[[queue.ops]]</a>
423
 
424
  ``` cpp
425
  template<class T, class Container>
426
  bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
 
515
  public:
516
  priority_queue() : priority_queue(Compare()) {}
517
  explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
518
  priority_queue(const Compare& x, const Container&);
519
  priority_queue(const Compare& x, Container&&);
520
+ template<class InputIterator>
521
+ priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
522
  template<class InputIterator>
523
  priority_queue(InputIterator first, InputIterator last, const Compare& x,
524
  const Container&);
525
  template<class InputIterator>
526
+ priority_queue(InputIterator first, InputIterator last, const Compare& x,
527
+ Container&&);
528
+ template<container-compatible-range<T> R>
529
+ priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
530
  template<class Alloc> explicit priority_queue(const Alloc&);
531
  template<class Alloc> priority_queue(const Compare&, const Alloc&);
532
  template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
533
  template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
534
  template<class Alloc> priority_queue(const priority_queue&, const Alloc&);
535
  template<class Alloc> priority_queue(priority_queue&&, const Alloc&);
536
+ template<class InputIterator, class Alloc>
537
+ priority_queue(InputIterator, InputIterator, const Alloc&);
538
+ template<class InputIterator, class Alloc>
539
+ priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&);
540
+ template<class InputIterator, class Alloc>
541
+ priority_queue(InputIterator, InputIterator, const Compare&, const Container&,
542
+ const Alloc&);
543
+ template<class InputIterator, class Alloc>
544
+ priority_queue(InputIterator, InputIterator, const Compare&, Container&&, const Alloc&);
545
+ template<container-compatible-range<T> R, class Alloc>
546
+ priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&);
547
+ template<container-compatible-range<T> R, class Alloc>
548
+ priority_queue(from_range_t, R&& rg, const Alloc&);
549
 
550
  [[nodiscard]] bool empty() const { return c.empty(); }
551
  size_type size() const { return c.size(); }
552
  const_reference top() const { return c.front(); }
553
  void push(const value_type& x);
554
  void push(value_type&& x);
555
+ template<container-compatible-range<T> R>
556
+ void push_range(R&& rg);
557
  template<class... Args> void emplace(Args&&... args);
558
  void pop();
559
  void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
560
  is_nothrow_swappable_v<Compare>)
561
  { using std::swap; swap(c, q.c); swap(comp, q.comp); }
 
564
  template<class Compare, class Container>
565
  priority_queue(Compare, Container)
566
  -> priority_queue<typename Container::value_type, Container, Compare>;
567
 
568
  template<class InputIterator,
569
+ class Compare = less<iter-value-type<InputIterator>>,
570
+ class Container = vector<iter-value-type<InputIterator>>>
571
  priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
572
+ -> priority_queue<iter-value-type<InputIterator>, Container, Compare>;
573
+
574
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>>
575
+ priority_queue(from_range_t, R&&, Compare = Compare())
576
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>;
577
 
578
  template<class Compare, class Container, class Allocator>
579
  priority_queue(Compare, Container, Allocator)
580
  -> priority_queue<typename Container::value_type, Container, Compare>;
581
 
582
+ template<class InputIterator, class Allocator>
583
+ priority_queue(InputIterator, InputIterator, Allocator)
584
+ -> priority_queue<iter-value-type<InputIterator>,
585
+ vector<iter-value-type<InputIterator>, Allocator>,
586
+ less<iter-value-type<InputIterator>>>;
587
+
588
+ template<class InputIterator, class Compare, class Allocator>
589
+ priority_queue(InputIterator, InputIterator, Compare, Allocator)
590
+ -> priority_queue<iter-value-type<InputIterator>,
591
+ vector<iter-value-type<InputIterator>, Allocator>, Compare>;
592
+
593
+ template<class InputIterator, class Compare, class Container, class Allocator>
594
+ priority_queue(InputIterator, InputIterator, Compare, Container, Allocator)
595
+ -> priority_queue<typename Container::value_type, Container, Compare>;
596
+
597
+ template<ranges::input_range R, class Compare, class Allocator>
598
+ priority_queue(from_range_t, R&&, Compare, Allocator)
599
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>,
600
+ Compare>;
601
+
602
+ template<ranges::input_range R, class Allocator>
603
+ priority_queue(from_range_t, R&&, Allocator)
604
+ -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>;
605
+
606
  // no equality is provided
607
 
 
 
 
 
608
  template<class T, class Container, class Compare, class Alloc>
609
  struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
610
  : uses_allocator<Container, Alloc>::type { };
611
  }
612
  ```
 
622
 
623
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
624
  constructing or move constructing as appropriate); calls
625
  `make_heap(c.begin(), c.end(), comp)`.
626
 
627
+ ``` cpp
628
+ template<class InputIterator>
629
+ priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare());
630
+ ```
631
+
632
+ *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
633
+
634
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
635
+ as the second argument, and initializes `comp` with `x`; then calls
636
+ `make_heap(c.begin(), c.end(), comp)`.
637
+
638
  ``` cpp
639
  template<class InputIterator>
640
  priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y);
641
  template<class InputIterator>
642
+ priority_queue(InputIterator first, InputIterator last, const Compare& x, Container&& y);
 
643
  ```
644
 
645
  *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
646
 
647
  *Effects:* Initializes `comp` with `x` and `c` with `y` (copy
648
  constructing or move constructing as appropriate); calls
649
  `c.insert(c.end(), first, last)`; and finally calls
650
  `make_heap(c.begin(), c.end(), comp)`.
651
 
652
+ ``` cpp
653
+ template<container-compatible-range<T> R>
654
+ priority_queue(from_range_t, R&& rg, const Compare& x = Compare());
655
+ ```
656
+
657
+ *Preconditions:* `x` defines a strict weak ordering [[alg.sorting]].
658
+
659
+ *Effects:* Initializes `comp` with `x` and `c` with
660
+ `ranges::to<Container>(std::forward<R>(rg))` and finally calls
661
+ `make_heap(c.begin(), c.end(), comp)`.
662
+
663
  #### Constructors with allocators <a id="priqueue.cons.alloc">[[priqueue.cons.alloc]]</a>
664
 
665
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
666
  in this subclause shall not participate in overload resolution.
667
 
 
709
 
710
  *Effects:* Initializes `c` with `std::move(q.c)` as the first argument
711
  and `a` as the second argument, and initializes `comp` with
712
  `std::move(q.comp)`.
713
 
714
+ ``` cpp
715
+ template<class InputIterator, class Alloc>
716
+ priority_queue(InputIterator first, InputIterator last, const Alloc& a);
717
+ ```
718
+
719
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
720
+ the second argument, and `a` as the third argument, and
721
+ value-initializes `comp`; calls `make_heap(c.begin(), c.end(), comp)`.
722
+
723
+ ``` cpp
724
+ template<class InputIterator, class Alloc>
725
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare, const Alloc& a);
726
+ ```
727
+
728
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
729
+ the second argument, and `a` as the third argument, and initializes
730
+ `comp` with `compare`; calls `make_heap(c.begin(), c.end(), comp)`.
731
+
732
+ ``` cpp
733
+ template<class InputIterator, class Alloc>
734
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare,
735
+ const Container& cont, const Alloc& a);
736
+ ```
737
+
738
+ *Effects:* Initializes `c` with `cont` as the first argument and `a` as
739
+ the second argument, and initializes `comp` with `compare`; calls
740
+ `c.insert(c.end(), first, last)`; and finally calls
741
+ `make_heap(c.begin(), c.end(), comp)`.
742
+
743
+ ``` cpp
744
+ template<class InputIterator, class Alloc>
745
+ priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& cont,
746
+ const Alloc& a);
747
+ ```
748
+
749
+ *Effects:* Initializes `c` with `std::move(cont)` as the first argument
750
+ and `a` as the second argument, and initializes `comp` with `compare`;
751
+ calls `c.insert(c.end(), first, last)`; and finally calls
752
+ `make_heap(c.begin(), c.end(), comp)`.
753
+
754
+ ``` cpp
755
+ template<container-compatible-range<T> R, class Alloc>
756
+ priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a);
757
+ ```
758
+
759
+ *Effects:* Initializes `comp` with `compare` and `c` with
760
+ `ranges::to<Container>(std::forward<R>(rg), a)`; calls
761
+ `make_heap(c.begin(), c.end(), comp)`.
762
+
763
+ ``` cpp
764
+ template<container-compatible-range<T> R, class Alloc>
765
+ priority_queue(from_range_t, R&& rg, const Alloc& a);
766
+ ```
767
+
768
+ *Effects:* Initializes `c` with
769
+ `ranges::to<Container>(std::forward<R>(rg), a)`; calls
770
+ `make_heap(c.begin(), c.end(), comp)`.
771
+
772
  #### Members <a id="priqueue.members">[[priqueue.members]]</a>
773
 
774
  ``` cpp
775
  void push(const value_type& x);
776
  ```
 
791
  ``` cpp
792
  c.push_back(std::move(x));
793
  push_heap(c.begin(), c.end(), comp);
794
  ```
795
 
796
+ ``` cpp
797
+ template<container-compatible-range<T> R>
798
+ void push_range(R&& rg);
799
+ ```
800
+
801
+ *Effects:* Inserts all elements of `rg` in `c` via
802
+ `c.append_range(std::forward<R>(rg))` if that is a valid expression, or
803
+ `ranges::copy(rg, back_inserter(c))` otherwise. Then restores the heap
804
+ property as if by `make_heap(c.begin(), c.end(), comp)`.
805
+
806
+ *Ensures:* `is_heap(c.begin(), c.end(), comp)` is `true`.
807
+
808
  ``` cpp
809
  template<class... Args> void emplace(Args&&... args);
810
  ```
811
 
812
  *Effects:* As if by:
 
840
 
841
  *Effects:* As if by `x.swap(y)`.
842
 
843
  ### Class template `stack` <a id="stack">[[stack]]</a>
844
 
845
+ #### General <a id="stack.general">[[stack.general]]</a>
846
+
847
  Any sequence container supporting operations `back()`, `push_back()` and
848
  `pop_back()` can be used to instantiate `stack`. In particular, `vector`
849
  [[vector]], `list` [[list]] and `deque` [[deque]] can be used.
850
 
851
  #### Definition <a id="stack.defn">[[stack.defn]]</a>
 
866
 
867
  public:
868
  stack() : stack(Container()) {}
869
  explicit stack(const Container&);
870
  explicit stack(Container&&);
871
+ template<class InputIterator> stack(InputIterator first, InputIterator last);
872
+ template<container-compatible-range<T> R> stack(from_range_t, R&& rg);
873
  template<class Alloc> explicit stack(const Alloc&);
874
  template<class Alloc> stack(const Container&, const Alloc&);
875
  template<class Alloc> stack(Container&&, const Alloc&);
876
  template<class Alloc> stack(const stack&, const Alloc&);
877
  template<class Alloc> stack(stack&&, const Alloc&);
878
+ template<class InputIterator, class Alloc>
879
+ stack(InputIterator first, InputIterator last, const Alloc&);
880
+ template<container-compatible-range<T> R, class Alloc>
881
+ stack(from_range_t, R&& rg, const Alloc&);
882
 
883
  [[nodiscard]] bool empty() const { return c.empty(); }
884
  size_type size() const { return c.size(); }
885
  reference top() { return c.back(); }
886
  const_reference top() const { return c.back(); }
887
  void push(const value_type& x) { c.push_back(x); }
888
  void push(value_type&& x) { c.push_back(std::move(x)); }
889
+ template<container-compatible-range<T> R>
890
+ void push_range(R&& rg);
891
  template<class... Args>
892
  decltype(auto) emplace(Args&&... args)
893
  { return c.emplace_back(std::forward<Args>(args)...); }
894
  void pop() { c.pop_back(); }
895
  void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
 
897
  };
898
 
899
  template<class Container>
900
  stack(Container) -> stack<typename Container::value_type, Container>;
901
 
902
+ template<class InputIterator>
903
+ stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>;
904
+
905
+ template<ranges::input_range R>
906
+ stack(from_range_t, R&&) -> stack<ranges::range_value_t<R>>;
907
+
908
  template<class Container, class Allocator>
909
  stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
910
 
911
+ template<class InputIterator, class Allocator>
912
+ stack(InputIterator, InputIterator, Allocator)
913
+ -> stack<iter-value-type<InputIterator>, deque<iter-value-type<InputIterator>,
914
+ Allocator>>;
915
+
916
+ template<ranges::input_range R, class Allocator>
917
+ stack(from_range_t, R&&, Allocator)
918
+ -> stack<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>;
919
+
920
  template<class T, class Container, class Alloc>
921
  struct uses_allocator<stack<T, Container>, Alloc>
922
  : uses_allocator<Container, Alloc>::type { };
923
  }
924
  ```
 
935
  explicit stack(Container&& cont);
936
  ```
937
 
938
  *Effects:* Initializes `c` with `std::move(cont)`.
939
 
940
+ ``` cpp
941
+ template<class InputIterator>
942
+ stack(InputIterator first, InputIterator last);
943
+ ```
944
+
945
+ *Effects:* Initializes `c` with `first` as the first argument and `last`
946
+ as the second argument.
947
+
948
+ ``` cpp
949
+ template<container-compatible-range<T> R>
950
+ stack(from_range_t, R&& rg);
951
+ ```
952
+
953
+ *Effects:* Initializes `c` with
954
+ `ranges::to<Container>(std::forward<R>(rg))`.
955
+
956
  #### Constructors with allocators <a id="stack.cons.alloc">[[stack.cons.alloc]]</a>
957
 
958
  If `uses_allocator_v<container_type, Alloc>` is `false` the constructors
959
  in this subclause shall not participate in overload resolution.
960
 
 
990
  ```
991
 
992
  *Effects:* Initializes `c` with `std::move(s.c)` as the first argument
993
  and `a` as the second argument.
994
 
995
+ ``` cpp
996
+ template<class InputIterator, class Alloc>
997
+ stack(InputIterator first, InputIterator last, const Alloc& alloc);
998
+ ```
999
+
1000
+ *Effects:* Initializes `c` with `first` as the first argument, `last` as
1001
+ the second argument, and `alloc` as the third argument.
1002
+
1003
+ ``` cpp
1004
+ template<container-compatible-range<T> R, class Alloc>
1005
+ stack(from_range_t, R&& rg, const Alloc& a);
1006
+ ```
1007
+
1008
+ *Effects:* Initializes `c` with
1009
+ `ranges::to<Container>(std::forward<R>(rg), a)`.
1010
+
1011
+ #### Modifiers <a id="stack.mod">[[stack.mod]]</a>
1012
+
1013
+ ``` cpp
1014
+ template<container-compatible-range<T> R>
1015
+ void push_range(R&& rg);
1016
+ ```
1017
+
1018
+ *Effects:* Equivalent to `c.append_range(std::forward<R>(rg))` if that
1019
+ is a valid expression, otherwise `ranges::copy(rg, back_inserter(c))`.
1020
+
1021
  #### Operators <a id="stack.ops">[[stack.ops]]</a>
1022
 
1023
  ``` cpp
1024
  template<class T, class Container>
1025
  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
 
1079
 
1080
  *Constraints:* `is_swappable_v<Container>` is `true`.
1081
 
1082
  *Effects:* As if by `x.swap(y)`.
1083
 
1084
+ ### Class template `flat_map` <a id="flat.map">[[flat.map]]</a>
1085
+
1086
+ #### Overview <a id="flat.map.overview">[[flat.map.overview]]</a>
1087
+
1088
+ A `flat_map` is a container adaptor that provides an associative
1089
+ container interface that supports unique keys (i.e., contains at most
1090
+ one of each key value) and provides for fast retrieval of values of
1091
+ another type `T` based on the keys. `flat_map` supports iterators that
1092
+ meet the *Cpp17InputIterator* requirements and model the
1093
+ `random_access_iterator` concept [[iterator.concept.random.access]].
1094
+
1095
+ A `flat_map` meets all of the requirements of a container
1096
+ [[container.reqmts]] and of a reversible container
1097
+ [[container.rev.reqmts]], plus the optional container requirements
1098
+ [[container.opt.reqmts]]. `flat_map` meets the requirements of an
1099
+ associative container [[associative.reqmts]], except that:
1100
+
1101
+ - it does not meet the requirements related to node handles
1102
+ [[container.node]],
1103
+ - it does not meet the requirements related to iterator invalidation,
1104
+ and
1105
+ - the time complexity of the operations that insert or erase a single
1106
+ element from the map is linear, including the ones that take an
1107
+ insertion position iterator.
1108
+
1109
+ [*Note 1*: A `flat_map` does not meet the additional requirements of an
1110
+ allocator-aware container [[container.alloc.reqmts]]. — *end note*]
1111
+
1112
+ A `flat_map` also provides most operations described in
1113
+ [[associative.reqmts]] for unique keys. This means that a `flat_map`
1114
+ supports the `a_uniq` operations in [[associative.reqmts]] but not the
1115
+ `a_eq` operations. For a `flat_map<Key, T>` the `key_type` is `Key` and
1116
+ the `value_type` is `pair<Key, T>`.
1117
+
1118
+ Descriptions are provided here only for operations on `flat_map` that
1119
+ are not described in one of those sets of requirements or for operations
1120
+ where there is additional semantic information.
1121
+
1122
+ A `flat_map` maintains the following invariants:
1123
+
1124
+ - it contains the same number of keys and values;
1125
+ - the keys are sorted with respect to the comparison object; and
1126
+ - the value at offset `off` within the value container is the value
1127
+ associated with the key at offset `off` within the key container.
1128
+
1129
+ If any member function in [[flat.map.defn]] exits via an exception the
1130
+ invariants are restored.
1131
+
1132
+ [*Note 2*: This can result in the `flat_map` being
1133
+ emptied. — *end note*]
1134
+
1135
+ Any type `C` that meets the sequence container requirements
1136
+ [[sequence.reqmts]] can be used to instantiate `flat_map`, as long as
1137
+ `C::iterator` meets the *Cpp17RandomAccessIterator* requirements and
1138
+ invocations of member functions `C::size` and `C::max_size` do not exit
1139
+ via an exception. In particular, `vector` [[vector]] and `deque`
1140
+ [[deque]] can be used.
1141
+
1142
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
1143
+
1144
+ The program is ill-formed if `Key` is not the same type as
1145
+ `KeyContainer::value_type` or `T` is not the same type as
1146
+ `MappedContainer::value_type`.
1147
+
1148
+ The effect of calling a constructor that takes both `key_container_type`
1149
+ and `mapped_container_type` arguments with containers of different sizes
1150
+ is undefined.
1151
+
1152
+ The effect of calling a constructor or member function that takes a
1153
+ `sorted_unique_t` argument with a container, containers, or range that
1154
+ is not sorted with respect to `key_comp()`, or that contains equal
1155
+ elements, is undefined.
1156
+
1157
+ #### Definition <a id="flat.map.defn">[[flat.map.defn]]</a>
1158
+
1159
+ ``` cpp
1160
+ namespace std {
1161
+ template<class Key, class T, class Compare = less<Key>,
1162
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
1163
+ class flat_map {
1164
+ public:
1165
+ // types
1166
+ using key_type = Key;
1167
+ using mapped_type = T;
1168
+ using value_type = pair<key_type, mapped_type>;
1169
+ using key_compare = Compare;
1170
+ using reference = pair<const key_type&, mapped_type&>;
1171
+ using const_reference = pair<const key_type&, const mapped_type&>;
1172
+ using size_type = size_t;
1173
+ using difference_type = ptrdiff_t;
1174
+ using iterator = implementation-defined // type of flat_map::iterator; // see [container.requirements]
1175
+ using const_iterator = implementation-defined // type of flat_map::const_iterator; // see [container.requirements]
1176
+ using reverse_iterator = std::reverse_iterator<iterator>;
1177
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1178
+ using key_container_type = KeyContainer;
1179
+ using mapped_container_type = MappedContainer;
1180
+
1181
+ class value_compare {
1182
+ private:
1183
+ key_compare comp; // exposition only
1184
+ value_compare(key_compare c) : comp(c) { } // exposition only
1185
+
1186
+ public:
1187
+ bool operator()(const_reference x, const_reference y) const {
1188
+ return comp(x.first, y.first);
1189
+ }
1190
+ };
1191
+
1192
+ struct containers {
1193
+ key_container_type keys;
1194
+ mapped_container_type values;
1195
+ };
1196
+
1197
+ // [flat.map.cons], construct/copy/destroy
1198
+ flat_map() : flat_map(key_compare()) { }
1199
+
1200
+ flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
1201
+ const key_compare& comp = key_compare());
1202
+ template<class Allocator>
1203
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
1204
+ const Allocator& a);
1205
+ template<class Allocator>
1206
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
1207
+ const key_compare& comp, const Allocator& a);
1208
+
1209
+ flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
1210
+ const key_compare& comp = key_compare());
1211
+ template<class Allocator>
1212
+ flat_map(sorted_unique_t, const key_container_type& key_cont,
1213
+ const mapped_container_type& mapped_cont, const Allocator& a);
1214
+ template<class Allocator>
1215
+ flat_map(sorted_unique_t, const key_container_type& key_cont,
1216
+ const mapped_container_type& mapped_cont,
1217
+ const key_compare& comp, const Allocator& a);
1218
+
1219
+ explicit flat_map(const key_compare& comp)
1220
+ : c(), compare(comp) { }
1221
+ template<class Allocator>
1222
+ flat_map(const key_compare& comp, const Allocator& a);
1223
+ template<class Allocator>
1224
+ explicit flat_map(const Allocator& a);
1225
+
1226
+ template<class InputIterator>
1227
+ flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
1228
+ : c(), compare(comp) { insert(first, last); }
1229
+ template<class InputIterator, class Allocator>
1230
+ flat_map(InputIterator first, InputIterator last,
1231
+ const key_compare& comp, const Allocator& a);
1232
+ template<class InputIterator, class Allocator>
1233
+ flat_map(InputIterator first, InputIterator last, const Allocator& a);
1234
+
1235
+ template<container-compatible-range<value_type> R>
1236
+ flat_map(from_range_t fr, R&& rg)
1237
+ : flat_map(fr, std::forward<R>(rg), key_compare()) { }
1238
+ template<container-compatible-range<value_type> R, class Allocator>
1239
+ flat_map(from_range_t, R&& rg, const Allocator& a);
1240
+ template<container-compatible-range<value_type> R>
1241
+ flat_map(from_range_t, R&& rg, const key_compare& comp)
1242
+ : flat_map(comp) { insert_range(std::forward<R>(rg)); }
1243
+ template<container-compatible-range<value_type> R, class Allocator>
1244
+ flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
1245
+
1246
+ template<class InputIterator>
1247
+ flat_map(sorted_unique_t s, InputIterator first, InputIterator last,
1248
+ const key_compare& comp = key_compare())
1249
+ : c(), compare(comp) { insert(s, first, last); }
1250
+ template<class InputIterator, class Allocator>
1251
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last,
1252
+ const key_compare& comp, const Allocator& a);
1253
+ template<class InputIterator, class Allocator>
1254
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
1255
+
1256
+ flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare())
1257
+ : flat_map(il.begin(), il.end(), comp) { }
1258
+ template<class Allocator>
1259
+ flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
1260
+ template<class Allocator>
1261
+ flat_map(initializer_list<value_type> il, const Allocator& a);
1262
+
1263
+ flat_map(sorted_unique_t s, initializer_list<value_type> il,
1264
+ const key_compare& comp = key_compare())
1265
+ : flat_map(s, il.begin(), il.end(), comp) { }
1266
+ template<class Allocator>
1267
+ flat_map(sorted_unique_t, initializer_list<value_type> il,
1268
+ const key_compare& comp, const Allocator& a);
1269
+ template<class Allocator>
1270
+ flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
1271
+
1272
+ flat_map& operator=(initializer_list<value_type> il);
1273
+
1274
+ // iterators
1275
+ iterator begin() noexcept;
1276
+ const_iterator begin() const noexcept;
1277
+ iterator end() noexcept;
1278
+ const_iterator end() const noexcept;
1279
+
1280
+ reverse_iterator rbegin() noexcept;
1281
+ const_reverse_iterator rbegin() const noexcept;
1282
+ reverse_iterator rend() noexcept;
1283
+ const_reverse_iterator rend() const noexcept;
1284
+
1285
+ const_iterator cbegin() const noexcept;
1286
+ const_iterator cend() const noexcept;
1287
+ const_reverse_iterator crbegin() const noexcept;
1288
+ const_reverse_iterator crend() const noexcept;
1289
+
1290
+ // [flat.map.capacity], capacity
1291
+ [[nodiscard]] bool empty() const noexcept;
1292
+ size_type size() const noexcept;
1293
+ size_type max_size() const noexcept;
1294
+
1295
+ // [flat.map.access], element access
1296
+ mapped_type& operator[](const key_type& x);
1297
+ mapped_type& operator[](key_type&& x);
1298
+ template<class K> mapped_type& operator[](K&& x);
1299
+ mapped_type& at(const key_type& x);
1300
+ const mapped_type& at(const key_type& x) const;
1301
+ template<class K> mapped_type& at(const K& x);
1302
+ template<class K> const mapped_type& at(const K& x) const;
1303
+
1304
+ // [flat.map.modifiers], modifiers
1305
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
1306
+ template<class... Args>
1307
+ iterator emplace_hint(const_iterator position, Args&&... args);
1308
+
1309
+ pair<iterator, bool> insert(const value_type& x)
1310
+ { return emplace(x); }
1311
+ pair<iterator, bool> insert(value_type&& x)
1312
+ { return emplace(std::move(x)); }
1313
+ iterator insert(const_iterator position, const value_type& x)
1314
+ { return emplace_hint(position, x); }
1315
+ iterator insert(const_iterator position, value_type&& x)
1316
+ { return emplace_hint(position, std::move(x)); }
1317
+
1318
+ template<class P> pair<iterator, bool> insert(P&& x);
1319
+ template<class P>
1320
+ iterator insert(const_iterator position, P&&);
1321
+ template<class InputIterator>
1322
+ void insert(InputIterator first, InputIterator last);
1323
+ template<class InputIterator>
1324
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
1325
+ template<container-compatible-range<value_type> R>
1326
+ void insert_range(R&& rg);
1327
+
1328
+ void insert(initializer_list<value_type> il)
1329
+ { insert(il.begin(), il.end()); }
1330
+ void insert(sorted_unique_t s, initializer_list<value_type> il)
1331
+ { insert(s, il.begin(), il.end()); }
1332
+
1333
+ containers extract() &&;
1334
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
1335
+
1336
+ template<class... Args>
1337
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
1338
+ template<class... Args>
1339
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
1340
+ template<class K, class... Args>
1341
+ pair<iterator, bool> try_emplace(K&& k, Args&&... args);
1342
+ template<class... Args>
1343
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
1344
+ template<class... Args>
1345
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
1346
+ template<class K, class... Args>
1347
+ iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
1348
+ template<class M>
1349
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
1350
+ template<class M>
1351
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
1352
+ template<class K, class M>
1353
+ pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
1354
+ template<class M>
1355
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
1356
+ template<class M>
1357
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
1358
+ template<class K, class M>
1359
+ iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
1360
+
1361
+ iterator erase(iterator position);
1362
+ iterator erase(const_iterator position);
1363
+ size_type erase(const key_type& x);
1364
+ template<class K> size_type erase(K&& x);
1365
+ iterator erase(const_iterator first, const_iterator last);
1366
+
1367
+ void swap(flat_map& y) noexcept;
1368
+ void clear() noexcept;
1369
+
1370
+ // observers
1371
+ key_compare key_comp() const;
1372
+ value_compare value_comp() const;
1373
+
1374
+ const key_container_type& keys() const noexcept { return c.keys; }
1375
+ const mapped_container_type& values() const noexcept { return c.values; }
1376
+
1377
+ // map operations
1378
+ iterator find(const key_type& x);
1379
+ const_iterator find(const key_type& x) const;
1380
+ template<class K> iterator find(const K& x);
1381
+ template<class K> const_iterator find(const K& x) const;
1382
+
1383
+ size_type count(const key_type& x) const;
1384
+ template<class K> size_type count(const K& x) const;
1385
+
1386
+ bool contains(const key_type& x) const;
1387
+ template<class K> bool contains(const K& x) const;
1388
+
1389
+ iterator lower_bound(const key_type& x);
1390
+ const_iterator lower_bound(const key_type& x) const;
1391
+ template<class K> iterator lower_bound(const K& x);
1392
+ template<class K> const_iterator lower_bound(const K& x) const;
1393
+
1394
+ iterator upper_bound(const key_type& x);
1395
+ const_iterator upper_bound(const key_type& x) const;
1396
+ template<class K> iterator upper_bound(const K& x);
1397
+ template<class K> const_iterator upper_bound(const K& x) const;
1398
+
1399
+ pair<iterator, iterator> equal_range(const key_type& x);
1400
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
1401
+ template<class K> pair<iterator, iterator> equal_range(const K& x);
1402
+ template<class K> pair<const_iterator, const_iterator> equal_range(const K& x) const;
1403
+
1404
+ friend bool operator==(const flat_map& x, const flat_map& y);
1405
+
1406
+ friend synth-three-way-result<value_type>
1407
+ operator<=>(const flat_map& x, const flat_map& y);
1408
+
1409
+ friend void swap(flat_map& x, flat_map& y) noexcept
1410
+ { x.swap(y); }
1411
+
1412
+ private:
1413
+ containers c; // exposition only
1414
+ key_compare compare; // exposition only
1415
+
1416
+ struct key_equiv { // exposition only
1417
+ key_equiv(key_compare c) : comp(c) { }
1418
+ bool operator()(const_reference x, const_reference y) const {
1419
+ return !comp(x.first, y.first) && !comp(y.first, x.first);
1420
+ }
1421
+ key_compare comp;
1422
+ };
1423
+ };
1424
+
1425
+ template<class KeyContainer, class MappedContainer,
1426
+ class Compare = less<typename KeyContainer::value_type>>
1427
+ flat_map(KeyContainer, MappedContainer, Compare = Compare())
1428
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1429
+ Compare, KeyContainer, MappedContainer>;
1430
+
1431
+ template<class KeyContainer, class MappedContainer, class Allocator>
1432
+ flat_map(KeyContainer, MappedContainer, Allocator)
1433
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1434
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
1435
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
1436
+ flat_map(KeyContainer, MappedContainer, Compare, Allocator)
1437
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1438
+ Compare, KeyContainer, MappedContainer>;
1439
+
1440
+ template<class KeyContainer, class MappedContainer,
1441
+ class Compare = less<typename KeyContainer::value_type>>
1442
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare = Compare())
1443
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1444
+ Compare, KeyContainer, MappedContainer>;
1445
+
1446
+ template<class KeyContainer, class MappedContainer, class Allocator>
1447
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Allocator)
1448
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1449
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
1450
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
1451
+ flat_map(sorted_unique_t, KeyContainer, MappedContainer, Compare, Allocator)
1452
+ -> flat_map<typename KeyContainer::value_type, typename MappedContainer::value_type,
1453
+ Compare, KeyContainer, MappedContainer>;
1454
+
1455
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
1456
+ flat_map(InputIterator, InputIterator, Compare = Compare())
1457
+ -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
1458
+
1459
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
1460
+ flat_map(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
1461
+ -> flat_map<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
1462
+
1463
+ template<ranges::input_range R, class Compare = less<range-key-type<R>>,
1464
+ class Allocator = allocator<byte>>
1465
+ flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
1466
+ -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare,
1467
+ vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
1468
+ vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
1469
+
1470
+ template<ranges::input_range R, class Allocator>
1471
+ flat_map(from_range_t, R&&, Allocator)
1472
+ -> flat_map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
1473
+ vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
1474
+ vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
1475
+
1476
+ template<class Key, class T, class Compare = less<Key>>
1477
+ flat_map(initializer_list<pair<Key, T>>, Compare = Compare())
1478
+ -> flat_map<Key, T, Compare>;
1479
+
1480
+ template<class Key, class T, class Compare = less<Key>>
1481
+ flat_map(sorted_unique_t, initializer_list<pair<Key, T>>, Compare = Compare())
1482
+ -> flat_map<Key, T, Compare>;
1483
+
1484
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
1485
+ class Allocator>
1486
+ struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>, Allocator>
1487
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
1488
+ uses_allocator_v<MappedContainer, Allocator>> { };
1489
+ }
1490
+ ```
1491
+
1492
+ The member type `containers` has the data members and special members
1493
+ specified above. It has no base classes or members other than those
1494
+ specified.
1495
+
1496
+ #### Constructors <a id="flat.map.cons">[[flat.map.cons]]</a>
1497
+
1498
+ ``` cpp
1499
+ flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
1500
+ const key_compare& comp = key_compare());
1501
+ ```
1502
+
1503
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
1504
+ with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
1505
+ range \[`begin()`, `end()`) with respect to `value_comp()`; and finally
1506
+ erases the duplicate elements as if by:
1507
+
1508
+ ``` cpp
1509
+ auto zv = ranges::zip_view(c.keys, c.values);
1510
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
1511
+ auto dist = distance(zv.begin(), it);
1512
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
1513
+ c.values.erase(c.values.begin() + dist, c.values.end());
1514
+ ```
1515
+
1516
+ *Complexity:* Linear in N if the container arguments are already sorted
1517
+ with respect to `value_comp()` and otherwise N log N, where N is the
1518
+ value of `key_cont.size()` before this call.
1519
+
1520
+ ``` cpp
1521
+ template<class Allocator>
1522
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
1523
+ const Allocator& a);
1524
+ template<class Allocator>
1525
+ flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
1526
+ const key_compare& comp, const Allocator& a);
1527
+ ```
1528
+
1529
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
1530
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
1531
+ `true`.
1532
+
1533
+ *Effects:* Equivalent to `flat_map(key_cont, mapped_cont)` and
1534
+ `flat_map(key_cont, mapped_cont, comp)`, respectively, except that
1535
+ `c.keys` and `c.values` are constructed with uses-allocator
1536
+ construction [[allocator.uses.construction]].
1537
+
1538
+ *Complexity:* Same as `flat_map(key_cont, mapped_cont)` and
1539
+ `flat_map(key_cont, mapped_cont, comp)`, respectively.
1540
+
1541
+ ``` cpp
1542
+ flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
1543
+ const key_compare& comp = key_compare());
1544
+ ```
1545
+
1546
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
1547
+ with `std::move(mapped_cont)`, and `compare` with `comp`.
1548
+
1549
+ *Complexity:* Constant.
1550
+
1551
+ ``` cpp
1552
+ template<class Allocator>
1553
+ flat_map(sorted_unique_t s, const key_container_type& key_cont,
1554
+ const mapped_container_type& mapped_cont, const Allocator& a);
1555
+ template<class Allocator>
1556
+ flat_map(sorted_unique_t s, const key_container_type& key_cont,
1557
+ const mapped_container_type& mapped_cont, const key_compare& comp,
1558
+ const Allocator& a);
1559
+ ```
1560
+
1561
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
1562
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
1563
+ `true`.
1564
+
1565
+ *Effects:* Equivalent to `flat_map(s, key_cont, mapped_cont)` and
1566
+ `flat_map(s, key_cont, mapped_cont, comp)`, respectively, except that
1567
+ `c.keys` and `c.values` are constructed with uses-allocator
1568
+ construction [[allocator.uses.construction]].
1569
+
1570
+ *Complexity:* Linear.
1571
+
1572
+ ``` cpp
1573
+ template<class Allocator>
1574
+ flat_map(const key_compare& comp, const Allocator& a);
1575
+ template<class Allocator>
1576
+ explicit flat_map(const Allocator& a);
1577
+ template<class InputIterator, class Allocator>
1578
+ flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
1579
+ template<class InputIterator, class Allocator>
1580
+ flat_map(InputIterator first, InputIterator last, const Allocator& a);
1581
+ template<container-compatible-range<value_type> R, class Allocator>
1582
+ flat_map(from_range_t, R&& rg, const Allocator& a);
1583
+ template<container-compatible-range<value_type> R, class Allocator>
1584
+ flat_map(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
1585
+ template<class InputIterator, class Allocator>
1586
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last,
1587
+ const key_compare& comp, const Allocator& a);
1588
+ template<class InputIterator, class Allocator>
1589
+ flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
1590
+ template<class Allocator>
1591
+ flat_map(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
1592
+ template<class Allocator>
1593
+ flat_map(initializer_list<value_type> il, const Allocator& a);
1594
+ template<class Allocator>
1595
+ flat_map(sorted_unique_t, initializer_list<value_type> il,
1596
+ const key_compare& comp, const Allocator& a);
1597
+ template<class Allocator>
1598
+ flat_map(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
1599
+ ```
1600
+
1601
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
1602
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
1603
+ `true`.
1604
+
1605
+ *Effects:* Equivalent to the corresponding non-allocator constructors
1606
+ except that `c.keys` and `c.values` are constructed with uses-allocator
1607
+ construction [[allocator.uses.construction]].
1608
+
1609
+ #### Capacity <a id="flat.map.capacity">[[flat.map.capacity]]</a>
1610
+
1611
+ ``` cpp
1612
+ size_type size() const noexcept;
1613
+ ```
1614
+
1615
+ *Returns:* `c.keys.size()`.
1616
+
1617
+ ``` cpp
1618
+ size_type max_size() const noexcept;
1619
+ ```
1620
+
1621
+ *Returns:* `min<size_type>(c.keys.max_size(), c.values.max_size())`.
1622
+
1623
+ #### Access <a id="flat.map.access">[[flat.map.access]]</a>
1624
+
1625
+ ``` cpp
1626
+ mapped_type& operator[](const key_type& x);
1627
+ ```
1628
+
1629
+ *Effects:* Equivalent to: `return try_emplace(x).first->second;`
1630
+
1631
+ ``` cpp
1632
+ mapped_type& operator[](key_type&& x);
1633
+ ```
1634
+
1635
+ *Effects:* Equivalent to:
1636
+ `return try_emplace(std::move(x)).first->second;`
1637
+
1638
+ ``` cpp
1639
+ template<class K> mapped_type& operator[](K&& x);
1640
+ ```
1641
+
1642
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
1643
+ denotes a type.
1644
+
1645
+ *Effects:* Equivalent to:
1646
+ `return try_emplace(std::forward<K>(x)).first->second;`
1647
+
1648
+ ``` cpp
1649
+ mapped_type& at(const key_type& x);
1650
+ const mapped_type& at(const key_type& x) const;
1651
+ ```
1652
+
1653
+ *Returns:* A reference to the `mapped_type` corresponding to `x` in
1654
+ `*this`.
1655
+
1656
+ *Throws:* An exception object of type `out_of_range` if no such element
1657
+ is present.
1658
+
1659
+ *Complexity:* Logarithmic.
1660
+
1661
+ ``` cpp
1662
+ template<class K> mapped_type& at(const K& x);
1663
+ template<class K> const mapped_type& at(const K& x) const;
1664
+ ```
1665
+
1666
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
1667
+ denotes a type.
1668
+
1669
+ *Preconditions:* The expression `find(x)` is well-formed and has
1670
+ well-defined behavior.
1671
+
1672
+ *Returns:* A reference to the `mapped_type` corresponding to `x` in
1673
+ `*this`.
1674
+
1675
+ *Throws:* An exception object of type `out_of_range` if no such element
1676
+ is present.
1677
+
1678
+ *Complexity:* Logarithmic.
1679
+
1680
+ #### Modifiers <a id="flat.map.modifiers">[[flat.map.modifiers]]</a>
1681
+
1682
+ ``` cpp
1683
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
1684
+ ```
1685
+
1686
+ *Constraints:*
1687
+ `is_constructible_v<pair<key_type, mapped_type>, Args...>` is `true`.
1688
+
1689
+ *Effects:* Initializes an object `t` of type
1690
+ `pair<key_type, mapped_type>` with `std::forward<Args>(args)...`; if the
1691
+ map already contains an element whose key is equivalent to `t.first`,
1692
+ `*this` is unchanged. Otherwise, equivalent to:
1693
+
1694
+ ``` cpp
1695
+ auto key_it = ranges::upper_bound(c.keys, t.first, compare);
1696
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
1697
+ c.keys.insert(key_it, std::move(t.first));
1698
+ c.values.insert(value_it, std::move(t.second));
1699
+ ```
1700
+
1701
+ *Returns:* The `bool` component of the returned pair is `true` if and
1702
+ only if the insertion took place, and the iterator component of the pair
1703
+ points to the element with key equivalent to `t.first`.
1704
+
1705
+ ``` cpp
1706
+ template<class P> pair<iterator, bool> insert(P&& x);
1707
+ template<class P> iterator insert(const_iterator position, P&& x);
1708
+ ```
1709
+
1710
+ *Constraints:* `is_constructible_v<pair<key_type, mapped_type>, P>` is
1711
+ `true`.
1712
+
1713
+ *Effects:* The first form is equivalent to
1714
+ `return emplace(std::forward<P>(x));`. The second form is equivalent to
1715
+ `return emplace_hint(position, std::forward<P>(x));`.
1716
+
1717
+ ``` cpp
1718
+ template<class InputIterator>
1719
+ void insert(InputIterator first, InputIterator last);
1720
+ ```
1721
+
1722
+ *Effects:* Adds elements to `c` as if by:
1723
+
1724
+ ``` cpp
1725
+ for (; first != last; ++first) {
1726
+ value_type value = *first;
1727
+ c.keys.insert(c.keys.end(), std::move(value.first));
1728
+ c.values.insert(c.values.end(), std::move(value.second));
1729
+ }
1730
+ ```
1731
+
1732
+ Then, sorts the range of newly inserted elements with respect to
1733
+ `value_comp()`; merges the resulting sorted range and the sorted range
1734
+ of pre-existing elements into a single sorted range; and finally erases
1735
+ the duplicate elements as if by:
1736
+
1737
+ ``` cpp
1738
+ auto zv = ranges::zip_view(c.keys, c.values);
1739
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
1740
+ auto dist = distance(zv.begin(), it);
1741
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
1742
+ c.values.erase(c.values.begin() + dist, c.values.end());
1743
+ ```
1744
+
1745
+ *Complexity:* N + M log M, where N is `size()` before the operation and
1746
+ M is `distance(first, last)`.
1747
+
1748
+ *Remarks:* Since this operation performs an in-place merge, it may
1749
+ allocate memory.
1750
+
1751
+ ``` cpp
1752
+ template<class InputIterator>
1753
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
1754
+ ```
1755
+
1756
+ *Effects:* Adds elements to `c` as if by:
1757
+
1758
+ ``` cpp
1759
+ for (; first != last; ++first) {
1760
+ value_type value = *first;
1761
+ c.keys.insert(c.keys.end(), std::move(value.first));
1762
+ c.values.insert(c.values.end(), std::move(value.second));
1763
+ }
1764
+ ```
1765
+
1766
+ Then, merges the sorted range of newly added elements and the sorted
1767
+ range of pre-existing elements into a single sorted range; and finally
1768
+ erases the duplicate elements as if by:
1769
+
1770
+ ``` cpp
1771
+ auto zv = ranges::zip_view(c.keys, c.values);
1772
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
1773
+ auto dist = distance(zv.begin(), it);
1774
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
1775
+ c.values.erase(c.values.begin() + dist, c.values.end());
1776
+ ```
1777
+
1778
+ *Complexity:* Linear in N, where N is `size()` after the operation.
1779
+
1780
+ *Remarks:* Since this operation performs an in-place merge, it may
1781
+ allocate memory.
1782
+
1783
+ ``` cpp
1784
+ template<container-compatible-range<value_type> R>
1785
+ void insert_range(R&& rg);
1786
+ ```
1787
+
1788
+ *Effects:* Adds elements to `c` as if by:
1789
+
1790
+ ``` cpp
1791
+ for (const auto& e : rg) {
1792
+ c.keys.insert(c.keys.end(), e.first);
1793
+ c.values.insert(c.values.end(), e.second);
1794
+ }
1795
+ ```
1796
+
1797
+ Then, sorts the range of newly inserted elements with respect to
1798
+ `value_comp()`; merges the resulting sorted range and the sorted range
1799
+ of pre-existing elements into a single sorted range; and finally erases
1800
+ the duplicate elements as if by:
1801
+
1802
+ ``` cpp
1803
+ auto zv = ranges::zip_view(c.keys, c.values);
1804
+ auto it = ranges::unique(zv, key_equiv(compare)).begin();
1805
+ auto dist = distance(zv.begin(), it);
1806
+ c.keys.erase(c.keys.begin() + dist, c.keys.end());
1807
+ c.values.erase(c.values.begin() + dist, c.values.end());
1808
+ ```
1809
+
1810
+ *Complexity:* N + M log M, where N is `size()` before the operation and
1811
+ M is `ranges::distance(rg)`.
1812
+
1813
+ *Remarks:* Since this operation performs an in-place merge, it may
1814
+ allocate memory.
1815
+
1816
+ ``` cpp
1817
+ template<class... Args>
1818
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
1819
+ template<class... Args>
1820
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
1821
+ template<class... Args>
1822
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
1823
+ template<class... Args>
1824
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
1825
+ ```
1826
+
1827
+ *Constraints:* `is_constructible_v<mapped_type, Args...>` is `true`.
1828
+
1829
+ *Effects:* If the map already contains an element whose key is
1830
+ equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
1831
+ equivalent to:
1832
+
1833
+ ``` cpp
1834
+ auto key_it = ranges::upper_bound(c.keys, k, compare);
1835
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
1836
+ c.keys.insert(key_it, std::forward<decltype(k)>(k));
1837
+ c.values.emplace(value_it, std::forward<Args>(args)...);
1838
+ ```
1839
+
1840
+ *Returns:* In the first two overloads, the `bool` component of the
1841
+ returned pair is `true` if and only if the insertion took place. The
1842
+ returned iterator points to the map element whose key is equivalent to
1843
+ `k`.
1844
+
1845
+ *Complexity:* The same as `emplace` for the first two overloads, and the
1846
+ same as `emplace_hint` for the last two overloads.
1847
+
1848
+ ``` cpp
1849
+ template<class K, class... Args>
1850
+ pair<iterator, bool> try_emplace(K&& k, Args&&... args);
1851
+ template<class K, class... Args>
1852
+ iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
1853
+ ```
1854
+
1855
+ *Constraints:*
1856
+
1857
+ - The *qualified-id* `Compare::is_transparent` is valid and denotes a
1858
+ type.
1859
+ - `is_constructible_v<key_type, K>` is `true`.
1860
+ - `is_constructible_v<mapped_type, Args...>` is `true`.
1861
+ - For the first overload, `is_convertible_v<K&&, const_iterator>` and
1862
+ `is_convertible_v<K&&, iterator>` are both `false`.
1863
+
1864
+ *Preconditions:* The conversion from `k` into `key_type` constructs an
1865
+ object `u`, for which `find(k) == find(u)` is `true`.
1866
+
1867
+ *Effects:* If the map already contains an element whose key is
1868
+ equivalent to `k`, `*this` and `args...` are unchanged. Otherwise
1869
+ equivalent to:
1870
+
1871
+ ``` cpp
1872
+ auto key_it = ranges::upper_bound(c.keys, k, compare);
1873
+ auto value_it = c.values.begin() + distance(c.keys.begin(), key_it);
1874
+ c.keys.emplace(key_it, std::forward<K>(k));
1875
+ c.values.emplace(value_it, std::forward<Args>(args)...);
1876
+ ```
1877
+
1878
+ *Returns:* In the first overload, the `bool` component of the returned
1879
+ pair is `true` if and only if the insertion took place. The returned
1880
+ iterator points to the map element whose key is equivalent to `k`.
1881
+
1882
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
1883
+
1884
+ ``` cpp
1885
+ template<class M>
1886
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
1887
+ template<class M>
1888
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
1889
+ template<class M>
1890
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
1891
+ template<class M>
1892
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
1893
+ ```
1894
+
1895
+ *Constraints:* `is_assignable_v<mapped_type&, M>` is `true` and
1896
+ `is_constructible_v<mapped_type, M>` is `true`.
1897
+
1898
+ *Effects:* If the map already contains an element `e` whose key is
1899
+ equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
1900
+ Otherwise, equivalent to
1901
+
1902
+ ``` cpp
1903
+ try_emplace(std::forward<decltype(k)>(k), std::forward<M>(obj))
1904
+ ```
1905
+
1906
+ for the first two overloads or
1907
+
1908
+ ``` cpp
1909
+ try_emplace(hint, std::forward<decltype(k)>(k), std::forward<M>(obj))
1910
+ ```
1911
+
1912
+ for the last two overloads.
1913
+
1914
+ *Returns:* In the first two overloads, the `bool` component of the
1915
+ returned pair is `true` if and only if the insertion took place. The
1916
+ returned iterator points to the map element whose key is equivalent to
1917
+ `k`.
1918
+
1919
+ *Complexity:* The same as `emplace` for the first two overloads and the
1920
+ same as `emplace_hint` for the last two overloads.
1921
+
1922
+ ``` cpp
1923
+ template<class K, class M>
1924
+ pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
1925
+ template<class K, class M>
1926
+ iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
1927
+ ```
1928
+
1929
+ *Constraints:*
1930
+
1931
+ - The *qualified-id* `Compare::is_transparent` is valid and denotes a
1932
+ type.
1933
+ - `is_constructible_v<key_type, K>` is `true`.
1934
+ - `is_assignable_v<mapped_type&, M>` is `true`.
1935
+ - `is_constructible_v<mapped_type, M>` is `true`.
1936
+
1937
+ *Preconditions:* The conversion from `k` into `key_type` constructs an
1938
+ object `u`, for which `find(k) == find(u)` is `true`.
1939
+
1940
+ *Effects:* If the map already contains an element `e` whose key is
1941
+ equivalent to `k`, assigns `std::forward<M>(obj)` to `e.second`.
1942
+ Otherwise, equivalent to
1943
+
1944
+ ``` cpp
1945
+ try_emplace(std::forward<K>(k), std::forward<M>(obj))
1946
+ ```
1947
+
1948
+ for the first overload or
1949
+
1950
+ ``` cpp
1951
+ try_emplace(hint, std::forward<K>(k), std::forward<M>(obj))
1952
+ ```
1953
+
1954
+ for the second overload.
1955
+
1956
+ *Returns:* In the first overload, the `bool` component of the returned
1957
+ pair is `true` if and only if the insertion took place. The returned
1958
+ iterator points to the map element whose key is equivalent to `k`.
1959
+
1960
+ *Complexity:* The same as `emplace` and `emplace_hint`, respectively.
1961
+
1962
+ ``` cpp
1963
+ void swap(flat_map& y) noexcept;
1964
+ ```
1965
+
1966
+ *Effects:* Equivalent to:
1967
+
1968
+ ``` cpp
1969
+ ranges::swap(compare, y.compare);
1970
+ ranges::swap(c.keys, y.c.keys);
1971
+ ranges::swap(c.values, y.c.values);
1972
+ ```
1973
+
1974
+ ``` cpp
1975
+ containers extract() &&;
1976
+ ```
1977
+
1978
+ *Ensures:* `*this` is emptied, even if the function exits via an
1979
+ exception.
1980
+
1981
+ *Returns:* `std::move(c)`.
1982
+
1983
+ ``` cpp
1984
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
1985
+ ```
1986
+
1987
+ *Preconditions:* `key_cont.size() == mapped_cont.size()` is `true`, the
1988
+ elements of `key_cont` are sorted with respect to `compare`, and
1989
+ `key_cont` contains no equal elements.
1990
+
1991
+ *Effects:* Equivalent to:
1992
+
1993
+ ``` cpp
1994
+ c.keys = std::move(key_cont);
1995
+ c.values = std::move(mapped_cont);
1996
+ ```
1997
+
1998
+ #### Erasure <a id="flat.map.erasure">[[flat.map.erasure]]</a>
1999
+
2000
+ ``` cpp
2001
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
2002
+ class Predicate>
2003
+ typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
2004
+ erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
2005
+ ```
2006
+
2007
+ *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
2008
+ requirements.
2009
+
2010
+ *Effects:* Let E be `bool(pred(pair<const Key&, const T&>(e)))`. Erases
2011
+ all elements `e` in `c` for which E holds.
2012
+
2013
+ *Returns:* The number of elements erased.
2014
+
2015
+ *Complexity:* Exactly `c.size()` applications of the predicate.
2016
+
2017
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
2018
+ exits via an exception, `c` is in a valid but unspecified
2019
+ state [[defns.valid]].
2020
+
2021
+ [*Note 1*: `c` still meets its invariants, but can be
2022
+ empty. — *end note*]
2023
+
2024
+ ### Class template `flat_multimap` <a id="flat.multimap">[[flat.multimap]]</a>
2025
+
2026
+ #### Overview <a id="flat.multimap.overview">[[flat.multimap.overview]]</a>
2027
+
2028
+ A `flat_multimap` is a container adaptor that provides an associative
2029
+ container interface that supports equivalent keys (i.e., possibly
2030
+ containing multiple copies of the same key value) and provides for fast
2031
+ retrieval of values of another type `T` based on the keys.
2032
+ `flat_multimap` supports iterators that meet the *Cpp17InputIterator*
2033
+ requirements and model the `random_access_iterator` concept
2034
+ [[iterator.concept.random.access]].
2035
+
2036
+ A `flat_multimap` meets all of the requirements for a container
2037
+ [[container.reqmts]] and for a reversible container
2038
+ [[container.rev.reqmts]], plus the optional container requirements
2039
+ [[container.opt.reqmts]]. `flat_multimap` meets the requirements of an
2040
+ associative container [[associative.reqmts]], except that:
2041
+
2042
+ - it does not meet the requirements related to node handles
2043
+ [[container.node]],
2044
+ - it does not meet the requirements related to iterator invalidation,
2045
+ and
2046
+ - the time complexity of the operations that insert or erase a single
2047
+ element from the map is linear, including the ones that take an
2048
+ insertion position iterator.
2049
+
2050
+ [*Note 1*: A `flat_multimap` does not meet the additional requirements
2051
+ of an allocator-aware container
2052
+ [[container.alloc.reqmts]]. — *end note*]
2053
+
2054
+ A `flat_multimap` also provides most operations described in
2055
+ [[associative.reqmts]] for equal keys. This means that a `flat_multimap`
2056
+ supports the `a_eq` operations in [[associative.reqmts]] but not the
2057
+ `a_uniq` operations. For a `flat_multimap<Key, T>` the `key_type` is
2058
+ `Key` and the `value_type` is `pair<Key, T>`.
2059
+
2060
+ Except as otherwise noted, operations on `flat_multimap` are equivalent
2061
+ to those of `flat_map`, except that `flat_multimap` operations do not
2062
+ remove or replace elements with equal keys.
2063
+
2064
+ [*Example 1*: `flat_multimap` constructors and emplace do not erase
2065
+ non-unique elements after sorting them. — *end example*]
2066
+
2067
+ A `flat_multimap` maintains the following invariants:
2068
+
2069
+ - it contains the same number of keys and values;
2070
+ - the keys are sorted with respect to the comparison object; and
2071
+ - the value at offset `off` within the value container is the value
2072
+ associated with the key at offset `off` within the key container.
2073
+
2074
+ If any member function in [[flat.multimap.defn]] exits via an exception,
2075
+ the invariants are restored.
2076
+
2077
+ [*Note 2*: This can result in the `flat_multimap` being
2078
+ emptied. — *end note*]
2079
+
2080
+ Any type `C` that meets the sequence container requirements
2081
+ [[sequence.reqmts]] can be used to instantiate `flat_multimap`, as long
2082
+ as `C::iterator` meets the *Cpp17RandomAccessIterator* requirements and
2083
+ invocations of member functions `C::size` and `C::max_size` do not exit
2084
+ via an exception. In particular, `vector` [[vector]] and `deque`
2085
+ [[deque]] can be used.
2086
+
2087
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
2088
+
2089
+ The program is ill-formed if `Key` is not the same type as
2090
+ `KeyContainer::value_type` or `T` is not the same type as
2091
+ `MappedContainer::value_type`.
2092
+
2093
+ The effect of calling a constructor that takes both `key_container_type`
2094
+ and `mapped_container_type` arguments with containers of different sizes
2095
+ is undefined.
2096
+
2097
+ The effect of calling a constructor or member function that takes a
2098
+ `sorted_equivalent_t` argument with a container, containers, or range
2099
+ that are not sorted with respect to `key_comp()` is undefined.
2100
+
2101
+ #### Definition <a id="flat.multimap.defn">[[flat.multimap.defn]]</a>
2102
+
2103
+ ``` cpp
2104
+ namespace std {
2105
+ template<class Key, class T, class Compare = less<Key>,
2106
+ class KeyContainer = vector<Key>, class MappedContainer = vector<T>>
2107
+ class flat_multimap {
2108
+ public:
2109
+ // types
2110
+ using key_type = Key;
2111
+ using mapped_type = T;
2112
+ using value_type = pair<key_type, mapped_type>;
2113
+ using key_compare = Compare;
2114
+ using reference = pair<const key_type&, mapped_type&>;
2115
+ using const_reference = pair<const key_type&, const mapped_type&>;
2116
+ using size_type = size_t;
2117
+ using difference_type = ptrdiff_t;
2118
+ using iterator = implementation-defined // type of flat_multimap::iterator; // see [container.requirements]
2119
+ using const_iterator = implementation-defined // type of flat_multimap::const_iterator; // see [container.requirements]
2120
+ using reverse_iterator = std::reverse_iterator<iterator>;
2121
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2122
+ using key_container_type = KeyContainer;
2123
+ using mapped_container_type = MappedContainer;
2124
+
2125
+ class value_compare {
2126
+ private:
2127
+ key_compare comp; // exposition only
2128
+ value_compare(key_compare c) : comp(c) { } // exposition only
2129
+
2130
+ public:
2131
+ bool operator()(const_reference x, const_reference y) const {
2132
+ return comp(x.first, y.first);
2133
+ }
2134
+ };
2135
+
2136
+ struct containers {
2137
+ key_container_type keys;
2138
+ mapped_container_type values;
2139
+ };
2140
+
2141
+ // [flat.multimap.cons], construct/copy/destroy
2142
+ flat_multimap() : flat_multimap(key_compare()) { }
2143
+
2144
+ flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
2145
+ const key_compare& comp = key_compare());
2146
+ template<class Allocator>
2147
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
2148
+ const Allocator& a);
2149
+ template<class Allocator>
2150
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
2151
+ const key_compare& comp, const Allocator& a);
2152
+
2153
+ flat_multimap(sorted_equivalent_t,
2154
+ key_container_type key_cont, mapped_container_type mapped_cont,
2155
+ const key_compare& comp = key_compare());
2156
+ template<class Allocator>
2157
+ flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
2158
+ const mapped_container_type& mapped_cont, const Allocator& a);
2159
+ template<class Allocator>
2160
+ flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
2161
+ const mapped_container_type& mapped_cont,
2162
+ const key_compare& comp, const Allocator& a);
2163
+
2164
+ explicit flat_multimap(const key_compare& comp)
2165
+ : c(), compare(comp) { }
2166
+ template<class Allocator>
2167
+ flat_multimap(const key_compare& comp, const Allocator& a);
2168
+ template<class Allocator>
2169
+ explicit flat_multimap(const Allocator& a);
2170
+
2171
+ template<class InputIterator>
2172
+ flat_multimap(InputIterator first, InputIterator last,
2173
+ const key_compare& comp = key_compare())
2174
+ : c(), compare(comp)
2175
+ { insert(first, last); }
2176
+ template<class InputIterator, class Allocator>
2177
+ flat_multimap(InputIterator first, InputIterator last,
2178
+ const key_compare& comp, const Allocator& a);
2179
+ template<class InputIterator, class Allocator>
2180
+ flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
2181
+
2182
+ template<container-compatible-range<value_type> R>
2183
+ flat_multimap(from_range_t fr, R&& rg)
2184
+ : flat_multimap(fr, std::forward<R>(rg), key_compare()) { }
2185
+ template<container-compatible-range<value_type> R, class Allocator>
2186
+ flat_multimap(from_range_t, R&& rg, const Allocator& a);
2187
+ template<container-compatible-range<value_type> R>
2188
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp)
2189
+ : flat_multimap(comp) { insert_range(std::forward<R>(rg)); }
2190
+ template<container-compatible-range<value_type> R, class Allocator>
2191
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
2192
+
2193
+ template<class InputIterator>
2194
+ flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last,
2195
+ const key_compare& comp = key_compare())
2196
+ : c(), compare(comp) { insert(s, first, last); }
2197
+ template<class InputIterator, class Allocator>
2198
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
2199
+ const key_compare& comp, const Allocator& a);
2200
+ template<class InputIterator, class Allocator>
2201
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
2202
+ const Allocator& a);
2203
+
2204
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare())
2205
+ : flat_multimap(il.begin(), il.end(), comp) { }
2206
+ template<class Allocator>
2207
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp,
2208
+ const Allocator& a);
2209
+ template<class Allocator>
2210
+ flat_multimap(initializer_list<value_type> il, const Allocator& a);
2211
+
2212
+ flat_multimap(sorted_equivalent_t s, initializer_list<value_type> il,
2213
+ const key_compare& comp = key_compare())
2214
+ : flat_multimap(s, il.begin(), il.end(), comp) { }
2215
+ template<class Allocator>
2216
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
2217
+ const key_compare& comp, const Allocator& a);
2218
+ template<class Allocator>
2219
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
2220
+
2221
+ flat_multimap& operator=(initializer_list<value_type> il);
2222
+
2223
+ // iterators
2224
+ iterator begin() noexcept;
2225
+ const_iterator begin() const noexcept;
2226
+ iterator end() noexcept;
2227
+ const_iterator end() const noexcept;
2228
+
2229
+ reverse_iterator rbegin() noexcept;
2230
+ const_reverse_iterator rbegin() const noexcept;
2231
+ reverse_iterator rend() noexcept;
2232
+ const_reverse_iterator rend() const noexcept;
2233
+
2234
+ const_iterator cbegin() const noexcept;
2235
+ const_iterator cend() const noexcept;
2236
+ const_reverse_iterator crbegin() const noexcept;
2237
+ const_reverse_iterator crend() const noexcept;
2238
+
2239
+ // capacity
2240
+ [[nodiscard]] bool empty() const noexcept;
2241
+ size_type size() const noexcept;
2242
+ size_type max_size() const noexcept;
2243
+
2244
+ // modifiers
2245
+ template<class... Args> iterator emplace(Args&&... args);
2246
+ template<class... Args>
2247
+ iterator emplace_hint(const_iterator position, Args&&... args);
2248
+
2249
+ iterator insert(const value_type& x)
2250
+ { return emplace(x); }
2251
+ iterator insert(value_type&& x)
2252
+ { return emplace(std::move(x)); }
2253
+ iterator insert(const_iterator position, const value_type& x)
2254
+ { return emplace_hint(position, x); }
2255
+ iterator insert(const_iterator position, value_type&& x)
2256
+ { return emplace_hint(position, std::move(x)); }
2257
+
2258
+ template<class P> iterator insert(P&& x);
2259
+ template<class P>
2260
+ iterator insert(const_iterator position, P&&);
2261
+ template<class InputIterator>
2262
+ void insert(InputIterator first, InputIterator last);
2263
+ template<class InputIterator>
2264
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
2265
+ template<container-compatible-range<value_type> R>
2266
+ void insert_range(R&& rg);
2267
+
2268
+ void insert(initializer_list<value_type> il)
2269
+ { insert(il.begin(), il.end()); }
2270
+ void insert(sorted_equivalent_t s, initializer_list<value_type> il)
2271
+ { insert(s, il.begin(), il.end()); }
2272
+
2273
+ containers extract() &&;
2274
+ void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
2275
+
2276
+ iterator erase(iterator position);
2277
+ iterator erase(const_iterator position);
2278
+ size_type erase(const key_type& x);
2279
+ template<class K> size_type erase(K&& x);
2280
+ iterator erase(const_iterator first, const_iterator last);
2281
+
2282
+ void swap(flat_multimap&) noexcept;
2283
+ void clear() noexcept;
2284
+
2285
+ // observers
2286
+ key_compare key_comp() const;
2287
+ value_compare value_comp() const;
2288
+
2289
+ const key_container_type& keys() const noexcept { return c.keys; }
2290
+ const mapped_container_type& values() const noexcept { return c.values; }
2291
+
2292
+ // map operations
2293
+ iterator find(const key_type& x);
2294
+ const_iterator find(const key_type& x) const;
2295
+ template<class K> iterator find(const K& x);
2296
+ template<class K> const_iterator find(const K& x) const;
2297
+
2298
+ size_type count(const key_type& x) const;
2299
+ template<class K> size_type count(const K& x) const;
2300
+
2301
+ bool contains(const key_type& x) const;
2302
+ template<class K> bool contains(const K& x) const;
2303
+
2304
+ iterator lower_bound(const key_type& x);
2305
+ const_iterator lower_bound(const key_type& x) const;
2306
+ template<class K> iterator lower_bound(const K& x);
2307
+ template<class K> const_iterator lower_bound(const K& x) const;
2308
+
2309
+ iterator upper_bound(const key_type& x);
2310
+ const_iterator upper_bound(const key_type& x) const;
2311
+ template<class K> iterator upper_bound(const K& x);
2312
+ template<class K> const_iterator upper_bound(const K& x) const;
2313
+
2314
+ pair<iterator, iterator> equal_range(const key_type& x);
2315
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
2316
+ template<class K>
2317
+ pair<iterator, iterator> equal_range(const K& x);
2318
+ template<class K>
2319
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
2320
+
2321
+ friend bool operator==(const flat_multimap& x, const flat_multimap& y);
2322
+
2323
+ friend synth-three-way-result<value_type>
2324
+ operator<=>(const flat_multimap& x, const flat_multimap& y);
2325
+
2326
+ friend void swap(flat_multimap& x, flat_multimap& y) noexcept
2327
+ { x.swap(y); }
2328
+
2329
+ private:
2330
+ containers c; // exposition only
2331
+ key_compare compare; // exposition only
2332
+ };
2333
+
2334
+ template<class KeyContainer, class MappedContainer,
2335
+ class Compare = less<typename KeyContainer::value_type>>
2336
+ flat_multimap(KeyContainer, MappedContainer, Compare = Compare())
2337
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2338
+ Compare, KeyContainer, MappedContainer>;
2339
+
2340
+ template<class KeyContainer, class MappedContainer, class Allocator>
2341
+ flat_multimap(KeyContainer, MappedContainer, Allocator)
2342
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2343
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
2344
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
2345
+ flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)
2346
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2347
+ Compare, KeyContainer, MappedContainer>;
2348
+
2349
+ template<class KeyContainer, class MappedContainer,
2350
+ class Compare = less<typename KeyContainer::value_type>>
2351
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())
2352
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2353
+ Compare, KeyContainer, MappedContainer>;
2354
+
2355
+ template<class KeyContainer, class MappedContainer, class Allocator>
2356
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)
2357
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2358
+ less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>;
2359
+ template<class KeyContainer, class MappedContainer, class Compare, class Allocator>
2360
+ flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)
2361
+ -> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
2362
+ Compare, KeyContainer, MappedContainer>;
2363
+
2364
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
2365
+ flat_multimap(InputIterator, InputIterator, Compare = Compare())
2366
+ -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
2367
+
2368
+ template<class InputIterator, class Compare = less<iter-key-type<InputIterator>>>
2369
+ flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
2370
+ -> flat_multimap<iter-key-type<InputIterator>, iter-mapped-type<InputIterator>, Compare>;
2371
+
2372
+ template<ranges::input_range R, class Compare = less<range-key-type<R>>,
2373
+ class Allocator = allocator<byte>>
2374
+ flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
2375
+ -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare,
2376
+ vector<range-key-type<R>,
2377
+ alloc-rebind<Allocator, range-key-type<R>>>,
2378
+ vector<range-mapped-type<R>,
2379
+ alloc-rebind<Allocator, range-mapped-type<R>>>>;
2380
+
2381
+ template<ranges::input_range R, class Allocator>
2382
+ flat_multimap(from_range_t, R&&, Allocator)
2383
+ -> flat_multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
2384
+ vector<range-key-type<R>,
2385
+ alloc-rebind<Allocator, range-key-type<R>>>,
2386
+ vector<range-mapped-type<R>,
2387
+ alloc-rebind<Allocator, range-mapped-type<R>>>>;
2388
+
2389
+ template<class Key, class T, class Compare = less<Key>>
2390
+ flat_multimap(initializer_list<pair<Key, T>>, Compare = Compare())
2391
+ -> flat_multimap<Key, T, Compare>;
2392
+
2393
+ template<class Key, class T, class Compare = less<Key>>
2394
+ flat_multimap(sorted_equivalent_t, initializer_list<pair<Key, T>>, Compare = Compare())
2395
+ -> flat_multimap<Key, T, Compare>;
2396
+
2397
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
2398
+ class Allocator>
2399
+ struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
2400
+ Allocator>
2401
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator> &&
2402
+ uses_allocator_v<MappedContainer, Allocator>> { };
2403
+ }
2404
+ ```
2405
+
2406
+ The member type `containers` has the data members and special members
2407
+ specified above. It has no base classes or members other than those
2408
+ specified.
2409
+
2410
+ #### Constructors <a id="flat.multimap.cons">[[flat.multimap.cons]]</a>
2411
+
2412
+ ``` cpp
2413
+ flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
2414
+ const key_compare& comp = key_compare());
2415
+ ```
2416
+
2417
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
2418
+ with `std::move(mapped_cont)`, and `compare` with `comp`; sorts the
2419
+ range \[`begin()`, `end()`) with respect to `value_comp()`.
2420
+
2421
+ *Complexity:* Linear in N if the container arguments are already sorted
2422
+ with respect to `value_comp()` and otherwise N log N, where N is the
2423
+ value of `key_cont.size()` before this call.
2424
+
2425
+ ``` cpp
2426
+ template<class Allocator>
2427
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
2428
+ const Allocator& a);
2429
+ template<class Allocator>
2430
+ flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
2431
+ const key_compare& comp, const Allocator& a);
2432
+ ```
2433
+
2434
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
2435
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
2436
+ `true`.
2437
+
2438
+ *Effects:* Equivalent to `flat_multimap(key_cont, mapped_cont)` and
2439
+ `flat_multimap(key_cont, mapped_cont, comp)`, respectively, except that
2440
+ `c.keys` and `c.values` are constructed with uses-allocator
2441
+ construction [[allocator.uses.construction]].
2442
+
2443
+ *Complexity:* Same as `flat_multimap(key_cont, mapped_cont)` and
2444
+ `flat_multimap(key_cont, mapped_cont, comp)`, respectively.
2445
+
2446
+ ``` cpp
2447
+ flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont,
2448
+ const key_compare& comp = key_compare());
2449
+ ```
2450
+
2451
+ *Effects:* Initializes `c.keys` with `std::move(key_cont)`, `c.values`
2452
+ with `std::move(mapped_cont)`, and `compare` with `comp`.
2453
+
2454
+ *Complexity:* Constant.
2455
+
2456
+ ``` cpp
2457
+ template<class Allocator>
2458
+ flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
2459
+ const mapped_container_type& mapped_cont, const Allocator& a);
2460
+ template<class Allocator>
2461
+ flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont,
2462
+ const mapped_container_type& mapped_cont, const key_compare& comp,
2463
+ const Allocator& a);
2464
+ ```
2465
+
2466
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
2467
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
2468
+ `true`.
2469
+
2470
+ *Effects:* Equivalent to `flat_multimap(s, key_cont, mapped_cont)` and
2471
+ `flat_multimap(s, key_cont, mapped_cont, comp)`, respectively, except
2472
+ that `c.keys` and `c.values` are constructed with uses-allocator
2473
+ construction [[allocator.uses.construction]].
2474
+
2475
+ *Complexity:* Linear.
2476
+
2477
+ ``` cpp
2478
+ template<class Allocator>
2479
+ flat_multimap(const key_compare& comp, const Allocator& a);
2480
+ template<class Allocator>
2481
+ explicit flat_multimap(const Allocator& a);
2482
+ template<class InputIterator, class Allocator>
2483
+ flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
2484
+ const Allocator& a);
2485
+ template<class InputIterator, class Allocator>
2486
+ flat_multimap(InputIterator first, InputIterator last, const Allocator& a);
2487
+ template<container-compatible-range<value_type> R, class Allocator>
2488
+ flat_multimap(from_range_t, R&& rg, const Allocator& a);
2489
+ template<container-compatible-range<value_type> R, class Allocator>
2490
+ flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
2491
+ template<class InputIterator, class Allocator>
2492
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
2493
+ const key_compare& comp, const Allocator& a);
2494
+ template<class InputIterator, class Allocator>
2495
+ flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
2496
+ const Allocator& a);
2497
+ template<class Allocator>
2498
+ flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
2499
+ template<class Allocator>
2500
+ flat_multimap(initializer_list<value_type> il, const Allocator& a);
2501
+ template<class Allocator>
2502
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
2503
+ const key_compare& comp, const Allocator& a);
2504
+ template<class Allocator>
2505
+ flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
2506
+ ```
2507
+
2508
+ *Constraints:* `uses_allocator_v<key_container_type, Allocator>` is
2509
+ `true` and `uses_allocator_v<mapped_container_type, Allocator>` is
2510
+ `true`.
2511
+
2512
+ *Effects:* Equivalent to the corresponding non-allocator constructors
2513
+ except that `c.keys` and `c.values` are constructed with uses-allocator
2514
+ construction [[allocator.uses.construction]].
2515
+
2516
+ #### Erasure <a id="flat.multimap.erasure">[[flat.multimap.erasure]]</a>
2517
+
2518
+ ``` cpp
2519
+ template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
2520
+ class Predicate>
2521
+ typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
2522
+ erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
2523
+ ```
2524
+
2525
+ *Preconditions:* `Key` and `T` meet the *Cpp17MoveAssignable*
2526
+ requirements.
2527
+
2528
+ *Effects:* Let E be `bool(pred(pair<const Key&, const T&>(e)))`. Erases
2529
+ all elements `e` in `c` for which E holds.
2530
+
2531
+ *Returns:* The number of elements erased.
2532
+
2533
+ *Complexity:* Exactly `c.size()` applications of the predicate.
2534
+
2535
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
2536
+ exits via an exception, `c` is in a valid but unspecified
2537
+ state [[defns.valid]].
2538
+
2539
+ [*Note 1*: `c` still meets its invariants, but can be
2540
+ empty. — *end note*]
2541
+
2542
+ ### Class template `flat_set` <a id="flat.set">[[flat.set]]</a>
2543
+
2544
+ #### Overview <a id="flat.set.overview">[[flat.set.overview]]</a>
2545
+
2546
+ A `flat_set` is a container adaptor that provides an associative
2547
+ container interface that supports unique keys (i.e., contains at most
2548
+ one of each key value) and provides for fast retrieval of the keys
2549
+ themselves. `flat_set` supports iterators that model the
2550
+ `random_access_iterator` concept [[iterator.concept.random.access]].
2551
+
2552
+ A `flat_set` meets all of the requirements for a container
2553
+ [[container.reqmts]] and for a reversible container
2554
+ [[container.rev.reqmts]], plus the optional container requirements
2555
+ [[container.opt.reqmts]]. `flat_set` meets the requirements of an
2556
+ associative container [[associative.reqmts]], except that:
2557
+
2558
+ - it does not meet the requirements related to node handles
2559
+ [[container.node.overview]],
2560
+ - it does not meet the requirements related to iterator invalidation,
2561
+ and
2562
+ - the time complexity of the operations that insert or erase a single
2563
+ element from the set is linear, including the ones that take an
2564
+ insertion position iterator.
2565
+
2566
+ [*Note 1*: A `flat_set` does not meet the additional requirements of an
2567
+ allocator-aware container, as described in
2568
+ [[container.alloc.reqmts]]. — *end note*]
2569
+
2570
+ A `flat_set` also provides most operations described in
2571
+ [[associative.reqmts]] for unique keys. This means that a `flat_set`
2572
+ supports the `a_uniq` operations in [[associative.reqmts]] but not the
2573
+ `a_eq` operations. For a `flat_set<Key>`, both the `key_type` and
2574
+ `value_type` are `Key`.
2575
+
2576
+ Descriptions are provided here only for operations on `flat_set` that
2577
+ are not described in one of those sets of requirements or for operations
2578
+ where there is additional semantic information.
2579
+
2580
+ A `flat_set` maintains the invariant that the keys are sorted with
2581
+ respect to the comparison object.
2582
+
2583
+ If any member function in [[flat.set.defn]] exits via an exception, the
2584
+ invariant is restored.
2585
+
2586
+ [*Note 2*: This can result in the `flat_set`’s being
2587
+ emptied. — *end note*]
2588
+
2589
+ Any sequence container [[sequence.reqmts]] supporting
2590
+ *Cpp17RandomAccessIterator* can be used to instantiate `flat_set`. In
2591
+ particular, `vector` [[vector]] and `deque` [[deque]] can be used.
2592
+
2593
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
2594
+
2595
+ The program is ill-formed if `Key` is not the same type as
2596
+ `KeyContainer::value_type`.
2597
+
2598
+ The effect of calling a constructor or member function that takes a
2599
+ `sorted_unique_t` argument with a range that is not sorted with respect
2600
+ to `key_comp()`, or that contains equal elements, is undefined.
2601
+
2602
+ #### Definition <a id="flat.set.defn">[[flat.set.defn]]</a>
2603
+
2604
+ ``` cpp
2605
+ namespace std {
2606
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
2607
+ class flat_set {
2608
+ public:
2609
+ // types
2610
+ using key_type = Key;
2611
+ using value_type = Key;
2612
+ using key_compare = Compare;
2613
+ using value_compare = Compare;
2614
+ using reference = value_type&;
2615
+ using const_reference = const value_type&;
2616
+ using size_type = typename KeyContainer::size_type;
2617
+ using difference_type = typename KeyContainer::difference_type;
2618
+ using iterator = implementation-defined // type of flat_set::iterator; // see [container.requirements]
2619
+ using const_iterator = implementation-defined // type of flat_set::const_iterator; // see [container.requirements]
2620
+ using reverse_iterator = std::reverse_iterator<iterator>;
2621
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2622
+ using container_type = KeyContainer;
2623
+
2624
+ // [flat.set.cons], constructors
2625
+ flat_set() : flat_set(key_compare()) { }
2626
+
2627
+ explicit flat_set(container_type cont, const key_compare& comp = key_compare());
2628
+ template<class Allocator>
2629
+ flat_set(const container_type& cont, const Allocator& a);
2630
+ template<class Allocator>
2631
+ flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
2632
+
2633
+ flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare())
2634
+ : c(std::move(cont)), compare(comp) { }
2635
+ template<class Allocator>
2636
+ flat_set(sorted_unique_t, const container_type& cont, const Allocator& a);
2637
+ template<class Allocator>
2638
+ flat_set(sorted_unique_t, const container_type& cont,
2639
+ const key_compare& comp, const Allocator& a);
2640
+
2641
+ explicit flat_set(const key_compare& comp)
2642
+ : c(), compare(comp) { }
2643
+ template<class Allocator>
2644
+ flat_set(const key_compare& comp, const Allocator& a);
2645
+ template<class Allocator>
2646
+ explicit flat_set(const Allocator& a);
2647
+
2648
+ template<class InputIterator>
2649
+ flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
2650
+ : c(), compare(comp)
2651
+ { insert(first, last); }
2652
+ template<class InputIterator, class Allocator>
2653
+ flat_set(InputIterator first, InputIterator last,
2654
+ const key_compare& comp, const Allocator& a);
2655
+ template<class InputIterator, class Allocator>
2656
+ flat_set(InputIterator first, InputIterator last, const Allocator& a);
2657
+
2658
+ template<container-compatible-range<value_type> R>
2659
+ flat_set(from_range_t fr, R&& rg)
2660
+ : flat_set(fr, std::forward<R>(rg), key_compare()) { }
2661
+ template<container-compatible-range<value_type> R, class Allocator>
2662
+ flat_set(from_range_t, R&& rg, const Allocator& a);
2663
+ template<container-compatible-range<value_type> R>
2664
+ flat_set(from_range_t, R&& rg, const key_compare& comp)
2665
+ : flat_set(comp)
2666
+ { insert_range(std::forward<R>(rg)); }
2667
+ template<container-compatible-range<value_type> R, class Allocator>
2668
+ flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
2669
+
2670
+ template<class InputIterator>
2671
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
2672
+ const key_compare& comp = key_compare())
2673
+ : c(first, last), compare(comp) { }
2674
+ template<class InputIterator, class Allocator>
2675
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
2676
+ const key_compare& comp, const Allocator& a);
2677
+ template<class InputIterator, class Allocator>
2678
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
2679
+
2680
+ flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare())
2681
+ : flat_set(il.begin(), il.end(), comp) { }
2682
+ template<class Allocator>
2683
+ flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
2684
+ template<class Allocator>
2685
+ flat_set(initializer_list<value_type> il, const Allocator& a);
2686
+
2687
+ flat_set(sorted_unique_t s, initializer_list<value_type> il,
2688
+ const key_compare& comp = key_compare())
2689
+ : flat_set(s, il.begin(), il.end(), comp) { }
2690
+ template<class Allocator>
2691
+ flat_set(sorted_unique_t, initializer_list<value_type> il,
2692
+ const key_compare& comp, const Allocator& a);
2693
+ template<class Allocator>
2694
+ flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
2695
+
2696
+ flat_set& operator=(initializer_list<value_type>);
2697
+
2698
+ // iterators
2699
+ iterator begin() noexcept;
2700
+ const_iterator begin() const noexcept;
2701
+ iterator end() noexcept;
2702
+ const_iterator end() const noexcept;
2703
+
2704
+ reverse_iterator rbegin() noexcept;
2705
+ const_reverse_iterator rbegin() const noexcept;
2706
+ reverse_iterator rend() noexcept;
2707
+ const_reverse_iterator rend() const noexcept;
2708
+
2709
+ const_iterator cbegin() const noexcept;
2710
+ const_iterator cend() const noexcept;
2711
+ const_reverse_iterator crbegin() const noexcept;
2712
+ const_reverse_iterator crend() const noexcept;
2713
+
2714
+ // capacity
2715
+ [[nodiscard]] bool empty() const noexcept;
2716
+ size_type size() const noexcept;
2717
+ size_type max_size() const noexcept;
2718
+
2719
+ // [flat.set.modifiers], modifiers
2720
+ template<class... Args> pair<iterator, bool> emplace(Args&&... args);
2721
+ template<class... Args>
2722
+ iterator emplace_hint(const_iterator position, Args&&... args);
2723
+
2724
+ pair<iterator, bool> insert(const value_type& x)
2725
+ { return emplace(x); }
2726
+ pair<iterator, bool> insert(value_type&& x)
2727
+ { return emplace(std::move(x)); }
2728
+ template<class K> pair<iterator, bool> insert(K&& x);
2729
+ iterator insert(const_iterator position, const value_type& x)
2730
+ { return emplace_hint(position, x); }
2731
+ iterator insert(const_iterator position, value_type&& x)
2732
+ { return emplace_hint(position, std::move(x)); }
2733
+ template<class K> iterator insert(const_iterator hint, K&& x);
2734
+
2735
+ template<class InputIterator>
2736
+ void insert(InputIterator first, InputIterator last);
2737
+ template<class InputIterator>
2738
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
2739
+ template<container-compatible-range<value_type> R>
2740
+ void insert_range(R&& rg);
2741
+
2742
+ void insert(initializer_list<value_type> il)
2743
+ { insert(il.begin(), il.end()); }
2744
+ void insert(sorted_unique_t s, initializer_list<value_type> il)
2745
+ { insert(s, il.begin(), il.end()); }
2746
+
2747
+ container_type extract() &&;
2748
+ void replace(container_type&&);
2749
+
2750
+ iterator erase(iterator position);
2751
+ iterator erase(const_iterator position);
2752
+ size_type erase(const key_type& x);
2753
+ template<class K> size_type erase(K&& x);
2754
+ iterator erase(const_iterator first, const_iterator last);
2755
+
2756
+ void swap(flat_set& y) noexcept;
2757
+ void clear() noexcept;
2758
+
2759
+ // observers
2760
+ key_compare key_comp() const;
2761
+ value_compare value_comp() const;
2762
+
2763
+ // set operations
2764
+ iterator find(const key_type& x);
2765
+ const_iterator find(const key_type& x) const;
2766
+ template<class K> iterator find(const K& x);
2767
+ template<class K> const_iterator find(const K& x) const;
2768
+
2769
+ size_type count(const key_type& x) const;
2770
+ template<class K> size_type count(const K& x) const;
2771
+
2772
+ bool contains(const key_type& x) const;
2773
+ template<class K> bool contains(const K& x) const;
2774
+
2775
+ iterator lower_bound(const key_type& x);
2776
+ const_iterator lower_bound(const key_type& x) const;
2777
+ template<class K> iterator lower_bound(const K& x);
2778
+ template<class K> const_iterator lower_bound(const K& x) const;
2779
+
2780
+ iterator upper_bound(const key_type& x);
2781
+ const_iterator upper_bound(const key_type& x) const;
2782
+ template<class K> iterator upper_bound(const K& x);
2783
+ template<class K> const_iterator upper_bound(const K& x) const;
2784
+
2785
+ pair<iterator, iterator> equal_range(const key_type& x);
2786
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
2787
+ template<class K>
2788
+ pair<iterator, iterator> equal_range(const K& x);
2789
+ template<class K>
2790
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
2791
+
2792
+ friend bool operator==(const flat_set& x, const flat_set& y);
2793
+
2794
+ friend synth-three-way-result<value_type>
2795
+ operator<=>(const flat_set& x, const flat_set& y);
2796
+
2797
+ friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); }
2798
+
2799
+ private:
2800
+ container_type c; // exposition only
2801
+ key_compare compare; // exposition only
2802
+ };
2803
+
2804
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
2805
+ flat_set(KeyContainer, Compare = Compare())
2806
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
2807
+ template<class KeyContainer, class Allocator>
2808
+ flat_set(KeyContainer, Allocator)
2809
+ -> flat_set<typename KeyContainer::value_type,
2810
+ less<typename KeyContainer::value_type>, KeyContainer>;
2811
+ template<class KeyContainer, class Compare, class Allocator>
2812
+ flat_set(KeyContainer, Compare, Allocator)
2813
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
2814
+
2815
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
2816
+ flat_set(sorted_unique_t, KeyContainer, Compare = Compare())
2817
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
2818
+ template<class KeyContainer, class Allocator>
2819
+ flat_set(sorted_unique_t, KeyContainer, Allocator)
2820
+ -> flat_set<typename KeyContainer::value_type,
2821
+ less<typename KeyContainer::value_type>, KeyContainer>;
2822
+ template<class KeyContainer, class Compare, class Allocator>
2823
+ flat_set(sorted_unique_t, KeyContainer, Compare, Allocator)
2824
+ -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;
2825
+
2826
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
2827
+ flat_set(InputIterator, InputIterator, Compare = Compare())
2828
+ -> flat_set<iter-value-type<InputIterator>, Compare>;
2829
+
2830
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
2831
+ flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())
2832
+ -> flat_set<iter-value-type<InputIterator>, Compare>;
2833
+
2834
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
2835
+ class Allocator = allocator<ranges::range_value_t<R>>>
2836
+ flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
2837
+ -> flat_set<ranges::range_value_t<R>, Compare,
2838
+ vector<ranges::range_value_t<R>,
2839
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
2840
+
2841
+ template<ranges::input_range R, class Allocator>
2842
+ flat_set(from_range_t, R&&, Allocator)
2843
+ -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
2844
+ vector<ranges::range_value_t<R>,
2845
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
2846
+
2847
+ template<class Key, class Compare = less<Key>>
2848
+ flat_set(initializer_list<Key>, Compare = Compare())
2849
+ -> flat_set<Key, Compare>;
2850
+
2851
+ template<class Key, class Compare = less<Key>>
2852
+ flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())
2853
+ -> flat_set<Key, Compare>;
2854
+
2855
+ template<class Key, class Compare, class KeyContainer, class Allocator>
2856
+ struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>
2857
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
2858
+ }
2859
+ ```
2860
+
2861
+ #### Constructors <a id="flat.set.cons">[[flat.set.cons]]</a>
2862
+
2863
+ ``` cpp
2864
+ explicit flat_set(container_type cont, const key_compare& comp = key_compare());
2865
+ ```
2866
+
2867
+ *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
2868
+ `comp`, sorts the range \[`begin()`, `end()`) with respect to *compare*,
2869
+ and finally erases all but the first element from each group of
2870
+ consecutive equivalent elements.
2871
+
2872
+ *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
2873
+ and otherwise N log N, where N is the value of `cont.size()` before this
2874
+ call.
2875
+
2876
+ ``` cpp
2877
+ template<class Allocator>
2878
+ flat_set(const container_type& cont, const Allocator& a);
2879
+ template<class Allocator>
2880
+ flat_set(const container_type& cont, const key_compare& comp, const Allocator& a);
2881
+ ```
2882
+
2883
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
2884
+
2885
+ *Effects:* Equivalent to `flat_set(cont)` and `flat_set(cont, comp)`,
2886
+ respectively, except that *c* is constructed with uses-allocator
2887
+ construction [[allocator.uses.construction]].
2888
+
2889
+ *Complexity:* Same as `flat_set(cont)` and `flat_set(cont, comp)`,
2890
+ respectively.
2891
+
2892
+ ``` cpp
2893
+ template<class Allocator>
2894
+ flat_set(sorted_unique_t s, const container_type& cont, const Allocator& a);
2895
+ template<class Allocator>
2896
+ flat_set(sorted_unique_t s, const container_type& cont,
2897
+ const key_compare& comp, const Allocator& a);
2898
+ ```
2899
+
2900
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
2901
+
2902
+ *Effects:* Equivalent to `flat_set(s, cont)` and
2903
+ `flat_set(s, cont, comp)`, respectively, except that *c* is constructed
2904
+ with uses-allocator construction [[allocator.uses.construction]].
2905
+
2906
+ *Complexity:* Linear.
2907
+
2908
+ ``` cpp
2909
+ template<class Allocator>
2910
+ flat_set(const key_compare& comp, const Allocator& a);
2911
+ template<class Allocator>
2912
+ explicit flat_set(const Allocator& a);
2913
+ template<class InputIterator, class Allocator>
2914
+ flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);
2915
+ template<class InputIterator, class Allocator>
2916
+ flat_set(InputIterator first, InputIterator last, const Allocator& a);
2917
+ template<container-compatible-range<value_type> R, class Allocator>
2918
+ flat_set(from_range_t, R&& rg, const Allocator& a);
2919
+ template<container-compatible-range<value_type> R, class Allocator>
2920
+ flat_set(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
2921
+ template<class InputIterator, class Allocator>
2922
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last,
2923
+ const key_compare& comp, const Allocator& a);
2924
+ template<class InputIterator, class Allocator>
2925
+ flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Allocator& a);
2926
+ template<class Allocator>
2927
+ flat_set(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
2928
+ template<class Allocator>
2929
+ flat_set(initializer_list<value_type> il, const Allocator& a);
2930
+ template<class Allocator>
2931
+ flat_set(sorted_unique_t, initializer_list<value_type> il,
2932
+ const key_compare& comp, const Allocator& a);
2933
+ template<class Allocator>
2934
+ flat_set(sorted_unique_t, initializer_list<value_type> il, const Allocator& a);
2935
+ ```
2936
+
2937
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
2938
+
2939
+ *Effects:* Equivalent to the corresponding non-allocator constructors
2940
+ except that *c* is constructed with uses-allocator
2941
+ construction [[allocator.uses.construction]].
2942
+
2943
+ #### Modifiers <a id="flat.set.modifiers">[[flat.set.modifiers]]</a>
2944
+
2945
+ ``` cpp
2946
+ template<class K> pair<iterator, bool> insert(K&& x);
2947
+ template<class K> iterator insert(const_iterator hint, K&& x);
2948
+ ```
2949
+
2950
+ *Constraints:* The *qualified-id* `Compare::is_transparent` is valid and
2951
+ denotes a type. `is_constructible_v<value_type, K>` is `true`.
2952
+
2953
+ *Preconditions:* The conversion from `x` into `value_type` constructs an
2954
+ object `u`, for which `find(x) == find(u)` is true.
2955
+
2956
+ *Effects:* If the set already contains an element equivalent to `x`,
2957
+ `*this` and `x` are unchanged. Otherwise, inserts a new element as if by
2958
+ `emplace(std::forward<K>(x))`.
2959
+
2960
+ *Returns:* In the first overload, the `bool` component of the returned
2961
+ pair is `true` if and only if the insertion took place. The returned
2962
+ iterator points to the element whose key is equivalent to `x`.
2963
+
2964
+ ``` cpp
2965
+ template<class InputIterator>
2966
+ void insert(InputIterator first, InputIterator last);
2967
+ ```
2968
+
2969
+ *Effects:* Adds elements to *c* as if by:
2970
+
2971
+ ``` cpp
2972
+ c.insert(c.end(), first, last);
2973
+ ```
2974
+
2975
+ Then, sorts the range of newly inserted elements with respect to
2976
+ *compare*; merges the resulting sorted range and the sorted range of
2977
+ pre-existing elements into a single sorted range; and finally erases all
2978
+ but the first element from each group of consecutive equivalent
2979
+ elements.
2980
+
2981
+ *Complexity:* N + M log M, where N is `size()` before the operation and
2982
+ M is `distance(first, last)`.
2983
+
2984
+ *Remarks:* Since this operation performs an in-place merge, it may
2985
+ allocate memory.
2986
+
2987
+ ``` cpp
2988
+ template<class InputIterator>
2989
+ void insert(sorted_unique_t, InputIterator first, InputIterator last);
2990
+ ```
2991
+
2992
+ *Effects:* Equivalent to `insert(first, last)`.
2993
+
2994
+ *Complexity:* Linear.
2995
+
2996
+ ``` cpp
2997
+ template<container-compatible-range<value_type> R>
2998
+ void insert_range(R&& rg);
2999
+ ```
3000
+
3001
+ *Effects:* Adds elements to *c* as if by:
3002
+
3003
+ ``` cpp
3004
+ for (const auto& e : rg) {
3005
+ c.insert(c.end(), e);
3006
+ }
3007
+ ```
3008
+
3009
+ Then, sorts the range of newly inserted elements with respect to
3010
+ *compare*; merges the resulting sorted range and the sorted range of
3011
+ pre-existing elements into a single sorted range; and finally erases all
3012
+ but the first element from each group of consecutive equivalent
3013
+ elements.
3014
+
3015
+ *Complexity:* N + M log M, where N is `size()` before the operation and
3016
+ M is `ranges::distance(rg)`.
3017
+
3018
+ *Remarks:* Since this operation performs an in-place merge, it may
3019
+ allocate memory.
3020
+
3021
+ ``` cpp
3022
+ void swap(flat_set& y) noexcept;
3023
+ ```
3024
+
3025
+ *Effects:* Equivalent to:
3026
+
3027
+ ``` cpp
3028
+ ranges::swap(compare, y.compare);
3029
+ ranges::swap(c, y.c);
3030
+ ```
3031
+
3032
+ ``` cpp
3033
+ container_type extract() &&;
3034
+ ```
3035
+
3036
+ *Ensures:* `*this` is emptied, even if the function exits via an
3037
+ exception.
3038
+
3039
+ *Returns:* `std::move(`*`c`*`)`.
3040
+
3041
+ ``` cpp
3042
+ void replace(container_type&& cont);
3043
+ ```
3044
+
3045
+ *Preconditions:* The elements of `cont` are sorted with respect to
3046
+ *compare*, and `cont` contains no equal elements.
3047
+
3048
+ *Effects:* Equivalent to: *`c`*` = std::move(cont);`
3049
+
3050
+ #### Erasure <a id="flat.set.erasure">[[flat.set.erasure]]</a>
3051
+
3052
+ ``` cpp
3053
+ template<class Key, class Compare, class KeyContainer, class Predicate>
3054
+ typename flat_set<Key, Compare, KeyContainer>::size_type
3055
+ erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
3056
+ ```
3057
+
3058
+ *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
3059
+
3060
+ *Effects:* Let E be `bool(pred(as_const(e)))`. Erases all elements `e`
3061
+ in `c` for which E holds.
3062
+
3063
+ *Returns:* The number of elements erased.
3064
+
3065
+ *Complexity:* Exactly `c.size()` applications of the predicate.
3066
+
3067
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
3068
+ exits via an exception, `c` is in a valid but unspecified
3069
+ state [[defns.valid]].
3070
+
3071
+ [*Note 1*: `c` still meets its invariants, but can be
3072
+ empty. — *end note*]
3073
+
3074
+ ### Class template `flat_multiset` <a id="flat.multiset">[[flat.multiset]]</a>
3075
+
3076
+ #### Overview <a id="flat.multiset.overview">[[flat.multiset.overview]]</a>
3077
+
3078
+ A `flat_multiset` is a container adaptor that provides an associative
3079
+ container interface that supports equivalent keys (i.e., possibly
3080
+ containing multiple copies of the same key value) and provides for fast
3081
+ retrieval of the keys themselves. `flat_multiset` supports iterators
3082
+ that model the `random_access_iterator` concept
3083
+ [[iterator.concept.random.access]].
3084
+
3085
+ A `flat_multiset` meets all of the requirements for a container
3086
+ [[container.reqmts]] and for a reversible container
3087
+ [[container.rev.reqmts]], plus the optional container requirements
3088
+ [[container.opt.reqmts]]. `flat_multiset` meets the requirements of an
3089
+ associative container [[associative.reqmts]], except that:
3090
+
3091
+ - it does not meet the requirements related to node handles
3092
+ [[container.node.overview]],
3093
+ - it does not meet the requirements related to iterator invalidation,
3094
+ and
3095
+ - the time complexity of the operations that insert or erase a single
3096
+ element from the set is linear, including the ones that take an
3097
+ insertion position iterator.
3098
+
3099
+ [*Note 1*: A `flat_multiset` does not meet the additional requirements
3100
+ of an allocator-aware container, as described in
3101
+ [[container.alloc.reqmts]]. — *end note*]
3102
+
3103
+ A `flat_multiset` also provides most operations described in
3104
+ [[associative.reqmts]] for equal keys. This means that a `flat_multiset`
3105
+ supports the `a_eq` operations in [[associative.reqmts]] but not the
3106
+ `a_uniq` operations. For a `flat_multiset<Key>`, both the `key_type` and
3107
+ `value_type` are `Key`.
3108
+
3109
+ Descriptions are provided here only for operations on `flat_multiset`
3110
+ that are not described in one of the general sections or for operations
3111
+ where there is additional semantic information.
3112
+
3113
+ A `flat_multiset` maintains the invariant that the keys are sorted with
3114
+ respect to the comparison object.
3115
+
3116
+ If any member function in [[flat.multiset.defn]] exits via an exception,
3117
+ the invariant is restored.
3118
+
3119
+ [*Note 2*: This can result in the `flat_multiset`’s being
3120
+ emptied. — *end note*]
3121
+
3122
+ Any sequence container [[sequence.reqmts]] supporting
3123
+ *Cpp17RandomAccessIterator* can be used to instantiate `flat_multiset`.
3124
+ In particular, `vector` [[vector]] and `deque` [[deque]] can be used.
3125
+
3126
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
3127
+
3128
+ The program is ill-formed if `Key` is not the same type as
3129
+ `KeyContainer::value_type`.
3130
+
3131
+ The effect of calling a constructor or member function that takes a
3132
+ `sorted_equivalent_t` argument with a range that is not sorted with
3133
+ respect to `key_comp()` is undefined.
3134
+
3135
+ #### Definition <a id="flat.multiset.defn">[[flat.multiset.defn]]</a>
3136
+
3137
+ ``` cpp
3138
+ namespace std {
3139
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
3140
+ class flat_multiset {
3141
+ public:
3142
+ // types
3143
+ using key_type = Key;
3144
+ using value_type = Key;
3145
+ using key_compare = Compare;
3146
+ using value_compare = Compare;
3147
+ using reference = value_type&;
3148
+ using const_reference = const value_type&;
3149
+ using size_type = typename KeyContainer::size_type;
3150
+ using difference_type = typename KeyContainer::difference_type;
3151
+ using iterator = implementation-defined // type of flat_multiset::iterator; // see [container.requirements]
3152
+ using const_iterator = implementation-defined // type of flat_multiset::const_iterator; // see [container.requirements]
3153
+ using reverse_iterator = std::reverse_iterator<iterator>;
3154
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
3155
+ using container_type = KeyContainer;
3156
+
3157
+ // [flat.multiset.cons], constructors
3158
+ flat_multiset() : flat_multiset(key_compare()) { }
3159
+
3160
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
3161
+ template<class Allocator>
3162
+ flat_multiset(const container_type& cont, const Allocator& a);
3163
+ template<class Allocator>
3164
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
3165
+
3166
+ flat_multiset(sorted_equivalent_t, container_type cont,
3167
+ const key_compare& comp = key_compare())
3168
+ : c(std::move(cont)), compare(comp) { }
3169
+ template<class Allocator>
3170
+ flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a);
3171
+ template<class Allocator>
3172
+ flat_multiset(sorted_equivalent_t, const container_type& cont,
3173
+ const key_compare& comp, const Allocator& a);
3174
+
3175
+ explicit flat_multiset(const key_compare& comp)
3176
+ : c(), compare(comp) { }
3177
+ template<class Allocator>
3178
+ flat_multiset(const key_compare& comp, const Allocator& a);
3179
+ template<class Allocator>
3180
+ explicit flat_multiset(const Allocator& a);
3181
+
3182
+ template<class InputIterator>
3183
+ flat_multiset(InputIterator first, InputIterator last,
3184
+ const key_compare& comp = key_compare())
3185
+ : c(), compare(comp)
3186
+ { insert(first, last); }
3187
+ template<class InputIterator, class Allocator>
3188
+ flat_multiset(InputIterator first, InputIterator last,
3189
+ const key_compare& comp, const Allocator& a);
3190
+ template<class InputIterator, class Allocator>
3191
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
3192
+
3193
+ template<container-compatible-range<value_type> R>
3194
+ flat_multiset(from_range_t fr, R&& rg)
3195
+ : flat_multiset(fr, std::forward<R>(rg), key_compare()) { }
3196
+ template<container-compatible-range<value_type> R, class Allocator>
3197
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
3198
+ template<container-compatible-range<value_type> R>
3199
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp)
3200
+ : flat_multiset(comp)
3201
+ { insert_range(std::forward<R>(rg)); }
3202
+ template<container-compatible-range<value_type> R, class Allocator>
3203
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
3204
+
3205
+ template<class InputIterator>
3206
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
3207
+ const key_compare& comp = key_compare())
3208
+ : c(first, last), compare(comp) { }
3209
+ template<class InputIterator, class Allocator>
3210
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
3211
+ const key_compare& comp, const Allocator& a);
3212
+ template<class InputIterator, class Allocator>
3213
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
3214
+ const Allocator& a);
3215
+
3216
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare())
3217
+ : flat_multiset(il.begin(), il.end(), comp) { }
3218
+ template<class Allocator>
3219
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp,
3220
+ const Allocator& a);
3221
+ template<class Allocator>
3222
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
3223
+
3224
+ flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il,
3225
+ const key_compare& comp = key_compare())
3226
+ : flat_multiset(s, il.begin(), il.end(), comp) { }
3227
+ template<class Allocator>
3228
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
3229
+ const key_compare& comp, const Allocator& a);
3230
+ template<class Allocator>
3231
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
3232
+
3233
+ flat_multiset& operator=(initializer_list<value_type>);
3234
+
3235
+ // iterators
3236
+ iterator begin() noexcept;
3237
+ const_iterator begin() const noexcept;
3238
+ iterator end() noexcept;
3239
+ const_iterator end() const noexcept;
3240
+
3241
+ reverse_iterator rbegin() noexcept;
3242
+ const_reverse_iterator rbegin() const noexcept;
3243
+ reverse_iterator rend() noexcept;
3244
+ const_reverse_iterator rend() const noexcept;
3245
+
3246
+ const_iterator cbegin() const noexcept;
3247
+ const_iterator cend() const noexcept;
3248
+ const_reverse_iterator crbegin() const noexcept;
3249
+ const_reverse_iterator crend() const noexcept;
3250
+
3251
+ // capacity
3252
+ [[nodiscard]] bool empty() const noexcept;
3253
+ size_type size() const noexcept;
3254
+ size_type max_size() const noexcept;
3255
+
3256
+ // [flat.multiset.modifiers], modifiers
3257
+ template<class... Args> iterator emplace(Args&&... args);
3258
+ template<class... Args>
3259
+ iterator emplace_hint(const_iterator position, Args&&... args);
3260
+
3261
+ iterator insert(const value_type& x)
3262
+ { return emplace(x); }
3263
+ iterator insert(value_type&& x)
3264
+ { return emplace(std::move(x)); }
3265
+ iterator insert(const_iterator position, const value_type& x)
3266
+ { return emplace_hint(position, x); }
3267
+ iterator insert(const_iterator position, value_type&& x)
3268
+ { return emplace_hint(position, std::move(x)); }
3269
+
3270
+ template<class InputIterator>
3271
+ void insert(InputIterator first, InputIterator last);
3272
+ template<class InputIterator>
3273
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
3274
+ template<container-compatible-range<value_type> R>
3275
+ void insert_range(R&& rg);
3276
+
3277
+ void insert(initializer_list<value_type> il)
3278
+ { insert(il.begin(), il.end()); }
3279
+ void insert(sorted_equivalent_t s, initializer_list<value_type> il)
3280
+ { insert(s, il.begin(), il.end()); }
3281
+
3282
+ container_type extract() &&;
3283
+ void replace(container_type&&);
3284
+
3285
+ iterator erase(iterator position);
3286
+ iterator erase(const_iterator position);
3287
+ size_type erase(const key_type& x);
3288
+ template<class K> size_type erase(K&& x);
3289
+ iterator erase(const_iterator first, const_iterator last);
3290
+
3291
+ void swap(flat_multiset& y) noexcept;
3292
+ void clear() noexcept;
3293
+
3294
+ // observers
3295
+ key_compare key_comp() const;
3296
+ value_compare value_comp() const;
3297
+
3298
+ // set operations
3299
+ iterator find(const key_type& x);
3300
+ const_iterator find(const key_type& x) const;
3301
+ template<class K> iterator find(const K& x);
3302
+ template<class K> const_iterator find(const K& x) const;
3303
+
3304
+ size_type count(const key_type& x) const;
3305
+ template<class K> size_type count(const K& x) const;
3306
+
3307
+ bool contains(const key_type& x) const;
3308
+ template<class K> bool contains(const K& x) const;
3309
+
3310
+ iterator lower_bound(const key_type& x);
3311
+ const_iterator lower_bound(const key_type& x) const;
3312
+ template<class K> iterator lower_bound(const K& x);
3313
+ template<class K> const_iterator lower_bound(const K& x) const;
3314
+
3315
+ iterator upper_bound(const key_type& x);
3316
+ const_iterator upper_bound(const key_type& x) const;
3317
+ template<class K> iterator upper_bound(const K& x);
3318
+ template<class K> const_iterator upper_bound(const K& x) const;
3319
+
3320
+ pair<iterator, iterator> equal_range(const key_type& x);
3321
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
3322
+ template<class K>
3323
+ pair<iterator, iterator> equal_range(const K& x);
3324
+ template<class K>
3325
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
3326
+
3327
+ friend bool operator==(const flat_multiset& x, const flat_multiset& y);
3328
+
3329
+ friend synth-three-way-result<value_type>
3330
+ operator<=>(const flat_multiset& x, const flat_multiset& y);
3331
+
3332
+ friend void swap(flat_multiset& x, flat_multiset& y) noexcept
3333
+ { x.swap(y); }
3334
+
3335
+ private:
3336
+ container_type c; // exposition only
3337
+ key_compare compare; // exposition only
3338
+ };
3339
+
3340
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
3341
+ flat_multiset(KeyContainer, Compare = Compare())
3342
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
3343
+ template<class KeyContainer, class Allocator>
3344
+ flat_multiset(KeyContainer, Allocator)
3345
+ -> flat_multiset<typename KeyContainer::value_type,
3346
+ less<typename KeyContainer::value_type>, KeyContainer>;
3347
+ template<class KeyContainer, class Compare, class Allocator>
3348
+ flat_multiset(KeyContainer, Compare, Allocator)
3349
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
3350
+
3351
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
3352
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())
3353
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
3354
+ template<class KeyContainer, class Allocator>
3355
+ flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)
3356
+ -> flat_multiset<typename KeyContainer::value_type,
3357
+ less<typename KeyContainer::value_type>, KeyContainer>;
3358
+ template<class KeyContainer, class Compare, class Allocator>
3359
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
3360
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
3361
+
3362
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
3363
+ flat_multiset(InputIterator, InputIterator, Compare = Compare())
3364
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
3365
+
3366
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
3367
+ flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
3368
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
3369
+
3370
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
3371
+ class Allocator = allocator<ranges::range_value_t<R>>>
3372
+ flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
3373
+ -> flat_multiset<ranges::range_value_t<R>, Compare,
3374
+ vector<ranges::range_value_t<R>,
3375
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
3376
+
3377
+ template<ranges::input_range R, class Allocator>
3378
+ flat_multiset(from_range_t, R&&, Allocator)
3379
+ -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
3380
+ vector<ranges::range_value_t<R>,
3381
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
3382
+
3383
+ template<class Key, class Compare = less<Key>>
3384
+ flat_multiset(initializer_list<Key>, Compare = Compare())
3385
+ -> flat_multiset<Key, Compare>;
3386
+
3387
+ template<class Key, class Compare = less<Key>>
3388
+ flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())
3389
+ -> flat_multiset<Key, Compare>;
3390
+
3391
+ template<class Key, class Compare, class KeyContainer, class Allocator>
3392
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>
3393
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
3394
+ }
3395
+ ```
3396
+
3397
+ #### Constructors <a id="flat.multiset.cons">[[flat.multiset.cons]]</a>
3398
+
3399
+ ``` cpp
3400
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
3401
+ ```
3402
+
3403
+ *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
3404
+ `comp`, and sorts the range \[`begin()`, `end()`) with respect to
3405
+ *compare*.
3406
+
3407
+ *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
3408
+ and otherwise N log N, where N is the value of `cont.size()` before this
3409
+ call.
3410
+
3411
+ ``` cpp
3412
+ template<class Allocator>
3413
+ flat_multiset(const container_type& cont, const Allocator& a);
3414
+ template<class Allocator>
3415
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
3416
+ ```
3417
+
3418
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
3419
+
3420
+ *Effects:* Equivalent to `flat_multiset(cont)` and
3421
+ `flat_multiset(cont, comp)`, respectively, except that *c* is
3422
+ constructed with uses-allocator
3423
+ construction [[allocator.uses.construction]].
3424
+
3425
+ *Complexity:* Same as `flat_multiset(cont)` and
3426
+ `flat_multiset(cont, comp)`, respectively.
3427
+
3428
+ ``` cpp
3429
+ template<class Allocator>
3430
+ flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a);
3431
+ template<class Allocator>
3432
+ flat_multiset(sorted_equivalent_t s, const container_type& cont,
3433
+ const key_compare& comp, const Allocator& a);
3434
+ ```
3435
+
3436
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
3437
+
3438
+ *Effects:* Equivalent to `flat_multiset(s, cont)` and
3439
+ `flat_multiset(s, cont, comp)`, respectively, except that *c* is
3440
+ constructed with uses-allocator
3441
+ construction [[allocator.uses.construction]].
3442
+
3443
+ *Complexity:* Linear.
3444
+
3445
+ ``` cpp
3446
+ template<class Allocator>
3447
+ flat_multiset(const key_compare& comp, const Allocator& a);
3448
+ template<class Allocator>
3449
+ explicit flat_multiset(const Allocator& a);
3450
+ template<class InputIterator, class Allocator>
3451
+ flat_multiset(InputIterator first, InputIterator last,
3452
+ const key_compare& comp, const Allocator& a);
3453
+ template<class InputIterator, class Allocator>
3454
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
3455
+ template<container-compatible-range<value_type> R, class Allocator>
3456
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
3457
+ template<container-compatible-range<value_type> R, class Allocator>
3458
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
3459
+ template<class InputIterator, class Allocator>
3460
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
3461
+ const key_compare& comp, const Allocator& a);
3462
+ template<class InputIterator, class Allocator>
3463
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a);
3464
+ template<class Allocator>
3465
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
3466
+ template<class Allocator>
3467
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
3468
+ template<class Allocator>
3469
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
3470
+ const key_compare& comp, const Allocator& a);
3471
+ template<class Allocator>
3472
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
3473
+ ```
3474
+
3475
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
3476
+
3477
+ *Effects:* Equivalent to the corresponding non-allocator constructors
3478
+ except that *c* is constructed with uses-allocator
3479
+ construction [[allocator.uses.construction]].
3480
+
3481
+ #### Modifiers <a id="flat.multiset.modifiers">[[flat.multiset.modifiers]]</a>
3482
+
3483
+ ``` cpp
3484
+ template<class... Args> iterator emplace(Args&&... args);
3485
+ ```
3486
+
3487
+ *Constraints:* `is_constructible_v<value_type, Args...>` is `true`.
3488
+
3489
+ *Effects:* First, initializes an object `t` of type `value_type` with
3490
+ `std::forward<Args>(args)...`, then inserts `t` as if by:
3491
+
3492
+ ``` cpp
3493
+ auto it = ranges::upper_bound(c, t, compare);
3494
+ c.insert(it, std::move(t));
3495
+ ```
3496
+
3497
+ *Returns:* An iterator that points to the inserted element.
3498
+
3499
+ ``` cpp
3500
+ template<class InputIterator>
3501
+ void insert(InputIterator first, InputIterator last);
3502
+ ```
3503
+
3504
+ *Effects:* Adds elements to *c* as if by:
3505
+
3506
+ ``` cpp
3507
+ c.insert(c.end(), first, last);
3508
+ ```
3509
+
3510
+ Then, sorts the range of newly inserted elements with respect to
3511
+ *compare*, and merges the resulting sorted range and the sorted range of
3512
+ pre-existing elements into a single sorted range.
3513
+
3514
+ *Complexity:* N + M log M, where N is `size()` before the operation and
3515
+ M is `distance(first, last)`.
3516
+
3517
+ *Remarks:* Since this operation performs an in-place merge, it may
3518
+ allocate memory.
3519
+
3520
+ ``` cpp
3521
+ template<class InputIterator>
3522
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
3523
+ ```
3524
+
3525
+ *Effects:* Equivalent to `insert(first, last)`.
3526
+
3527
+ *Complexity:* Linear.
3528
+
3529
+ ``` cpp
3530
+ void swap(flat_multiset& y) noexcept;
3531
+ ```
3532
+
3533
+ *Effects:* Equivalent to:
3534
+
3535
+ ``` cpp
3536
+ ranges::swap(compare, y.compare);
3537
+ ranges::swap(c, y.c);
3538
+ ```
3539
+
3540
+ ``` cpp
3541
+ container_type extract() &&;
3542
+ ```
3543
+
3544
+ *Ensures:* `*this` is emptied, even if the function exits via an
3545
+ exception.
3546
+
3547
+ *Returns:* `std::move(c)`.
3548
+
3549
+ ``` cpp
3550
+ void replace(container_type&& cont);
3551
+ ```
3552
+
3553
+ *Preconditions:* The elements of `cont` are sorted with respect to
3554
+ *compare*.
3555
+
3556
+ *Effects:* Equivalent to: `c = std::move(cont);`
3557
+
3558
+ #### Erasure <a id="flat.multiset.erasure">[[flat.multiset.erasure]]</a>
3559
+
3560
+ ``` cpp
3561
+ template<class Key, class Compare, class KeyContainer, class Predicate>
3562
+ typename flat_multiset<Key, Compare, KeyContainer>::size_type
3563
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
3564
+ ```
3565
+
3566
+ *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
3567
+
3568
+ *Effects:* Let E be `bool(pred(as_const(e)))`. Erases all elements `e`
3569
+ in `c` for which E holds.
3570
+
3571
+ *Returns:* The number of elements erased.
3572
+
3573
+ *Complexity:* Exactly `c.size()` applications of the predicate.
3574
+
3575
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
3576
+ exits via an exception, `c` is in a valid but unspecified
3577
+ state [[defns.valid]].
3578
+
3579
+ [*Note 1*: `c` still meets its invariants, but can be
3580
+ empty. — *end note*]
3581
+
3582
+ ### Container adaptors formatting <a id="container.adaptors.format">[[container.adaptors.format]]</a>
3583
+
3584
+ For each of `queue`, `priority_queue`, and `stack`, the library provides
3585
+ the following formatter specialization where `adaptor-type` is the name
3586
+ of the template:
3587
+
3588
+ ``` cpp
3589
+ namespace std {
3590
+ template<class charT, class T, formattable<charT> Container, class... U>
3591
+ struct formatter<adaptor-type<T, Container, U...>, charT> {
3592
+ private:
3593
+ using maybe-const-container = // exposition only
3594
+ fmt-maybe-const<Container, charT>;
3595
+ using maybe-const-adaptor = // exposition only
3596
+ maybe-const<is_const_v<maybe-const-container>, // see [ranges.syn]
3597
+ adaptor-type<T, Container, U...>>;
3598
+ formatter<ranges::ref_view<maybe-const-container>, charT> underlying_; // exposition only
3599
+
3600
+ public:
3601
+ template<class ParseContext>
3602
+ constexpr typename ParseContext::iterator
3603
+ parse(ParseContext& ctx);
3604
+
3605
+ template<class FormatContext>
3606
+ typename FormatContext::iterator
3607
+ format(maybe-const-adaptor& r, FormatContext& ctx) const;
3608
+ };
3609
+ }
3610
+ ```
3611
+
3612
+ ``` cpp
3613
+ template<class ParseContext>
3614
+ constexpr typename ParseContext::iterator
3615
+ parse(ParseContext& ctx);
3616
+ ```
3617
+
3618
+ *Effects:* Equivalent to: `return `*`underlying_`*`.parse(ctx);`
3619
+
3620
+ ``` cpp
3621
+ template<class FormatContext>
3622
+ typename FormatContext::iterator
3623
+ format(maybe-const-adaptor& r, FormatContext& ctx) const;
3624
+ ```
3625
+
3626
+ *Effects:* Equivalent to: `return `*`underlying_`*`.format(r.c, ctx);`
3627
+