From Jason Turner

[flat.multiset]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpt0kkxb12/{from.md → to.md} +508 -0
tmp/tmpt0kkxb12/{from.md → to.md} RENAMED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class template `flat_multiset` <a id="flat.multiset">[[flat.multiset]]</a>
2
+
3
+ #### Overview <a id="flat.multiset.overview">[[flat.multiset.overview]]</a>
4
+
5
+ A `flat_multiset` is a container adaptor that provides an associative
6
+ container interface that supports equivalent keys (i.e., possibly
7
+ containing multiple copies of the same key value) and provides for fast
8
+ retrieval of the keys themselves. `flat_multiset` supports iterators
9
+ that model the `random_access_iterator` concept
10
+ [[iterator.concept.random.access]].
11
+
12
+ A `flat_multiset` meets all of the requirements for a container
13
+ [[container.reqmts]] and for a reversible container
14
+ [[container.rev.reqmts]], plus the optional container requirements
15
+ [[container.opt.reqmts]]. `flat_multiset` meets the requirements of an
16
+ associative container [[associative.reqmts]], except that:
17
+
18
+ - it does not meet the requirements related to node handles
19
+ [[container.node.overview]],
20
+ - it does not meet the requirements related to iterator invalidation,
21
+ and
22
+ - the time complexity of the operations that insert or erase a single
23
+ element from the set is linear, including the ones that take an
24
+ insertion position iterator.
25
+
26
+ [*Note 1*: A `flat_multiset` does not meet the additional requirements
27
+ of an allocator-aware container, as described in
28
+ [[container.alloc.reqmts]]. — *end note*]
29
+
30
+ A `flat_multiset` also provides most operations described in
31
+ [[associative.reqmts]] for equal keys. This means that a `flat_multiset`
32
+ supports the `a_eq` operations in [[associative.reqmts]] but not the
33
+ `a_uniq` operations. For a `flat_multiset<Key>`, both the `key_type` and
34
+ `value_type` are `Key`.
35
+
36
+ Descriptions are provided here only for operations on `flat_multiset`
37
+ that are not described in one of the general sections or for operations
38
+ where there is additional semantic information.
39
+
40
+ A `flat_multiset` maintains the invariant that the keys are sorted with
41
+ respect to the comparison object.
42
+
43
+ If any member function in [[flat.multiset.defn]] exits via an exception,
44
+ the invariant is restored.
45
+
46
+ [*Note 2*: This can result in the `flat_multiset`’s being
47
+ emptied. — *end note*]
48
+
49
+ Any sequence container [[sequence.reqmts]] supporting
50
+ *Cpp17RandomAccessIterator* can be used to instantiate `flat_multiset`.
51
+ In particular, `vector` [[vector]] and `deque` [[deque]] can be used.
52
+
53
+ [*Note 3*: `vector<bool>` is not a sequence container. — *end note*]
54
+
55
+ The program is ill-formed if `Key` is not the same type as
56
+ `KeyContainer::value_type`.
57
+
58
+ The effect of calling a constructor or member function that takes a
59
+ `sorted_equivalent_t` argument with a range that is not sorted with
60
+ respect to `key_comp()` is undefined.
61
+
62
+ #### Definition <a id="flat.multiset.defn">[[flat.multiset.defn]]</a>
63
+
64
+ ``` cpp
65
+ namespace std {
66
+ template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
67
+ class flat_multiset {
68
+ public:
69
+ // types
70
+ using key_type = Key;
71
+ using value_type = Key;
72
+ using key_compare = Compare;
73
+ using value_compare = Compare;
74
+ using reference = value_type&;
75
+ using const_reference = const value_type&;
76
+ using size_type = typename KeyContainer::size_type;
77
+ using difference_type = typename KeyContainer::difference_type;
78
+ using iterator = implementation-defined // type of flat_multiset::iterator; // see [container.requirements]
79
+ using const_iterator = implementation-defined // type of flat_multiset::const_iterator; // see [container.requirements]
80
+ using reverse_iterator = std::reverse_iterator<iterator>;
81
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
82
+ using container_type = KeyContainer;
83
+
84
+ // [flat.multiset.cons], constructors
85
+ flat_multiset() : flat_multiset(key_compare()) { }
86
+
87
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
88
+ template<class Allocator>
89
+ flat_multiset(const container_type& cont, const Allocator& a);
90
+ template<class Allocator>
91
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
92
+
93
+ flat_multiset(sorted_equivalent_t, container_type cont,
94
+ const key_compare& comp = key_compare())
95
+ : c(std::move(cont)), compare(comp) { }
96
+ template<class Allocator>
97
+ flat_multiset(sorted_equivalent_t, const container_type&, const Allocator& a);
98
+ template<class Allocator>
99
+ flat_multiset(sorted_equivalent_t, const container_type& cont,
100
+ const key_compare& comp, const Allocator& a);
101
+
102
+ explicit flat_multiset(const key_compare& comp)
103
+ : c(), compare(comp) { }
104
+ template<class Allocator>
105
+ flat_multiset(const key_compare& comp, const Allocator& a);
106
+ template<class Allocator>
107
+ explicit flat_multiset(const Allocator& a);
108
+
109
+ template<class InputIterator>
110
+ flat_multiset(InputIterator first, InputIterator last,
111
+ const key_compare& comp = key_compare())
112
+ : c(), compare(comp)
113
+ { insert(first, last); }
114
+ template<class InputIterator, class Allocator>
115
+ flat_multiset(InputIterator first, InputIterator last,
116
+ const key_compare& comp, const Allocator& a);
117
+ template<class InputIterator, class Allocator>
118
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
119
+
120
+ template<container-compatible-range<value_type> R>
121
+ flat_multiset(from_range_t fr, R&& rg)
122
+ : flat_multiset(fr, std::forward<R>(rg), key_compare()) { }
123
+ template<container-compatible-range<value_type> R, class Allocator>
124
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
125
+ template<container-compatible-range<value_type> R>
126
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp)
127
+ : flat_multiset(comp)
128
+ { insert_range(std::forward<R>(rg)); }
129
+ template<container-compatible-range<value_type> R, class Allocator>
130
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
131
+
132
+ template<class InputIterator>
133
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
134
+ const key_compare& comp = key_compare())
135
+ : c(first, last), compare(comp) { }
136
+ template<class InputIterator, class Allocator>
137
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
138
+ const key_compare& comp, const Allocator& a);
139
+ template<class InputIterator, class Allocator>
140
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
141
+ const Allocator& a);
142
+
143
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare())
144
+ : flat_multiset(il.begin(), il.end(), comp) { }
145
+ template<class Allocator>
146
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp,
147
+ const Allocator& a);
148
+ template<class Allocator>
149
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
150
+
151
+ flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il,
152
+ const key_compare& comp = key_compare())
153
+ : flat_multiset(s, il.begin(), il.end(), comp) { }
154
+ template<class Allocator>
155
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
156
+ const key_compare& comp, const Allocator& a);
157
+ template<class Allocator>
158
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
159
+
160
+ flat_multiset& operator=(initializer_list<value_type>);
161
+
162
+ // iterators
163
+ iterator begin() noexcept;
164
+ const_iterator begin() const noexcept;
165
+ iterator end() noexcept;
166
+ const_iterator end() const noexcept;
167
+
168
+ reverse_iterator rbegin() noexcept;
169
+ const_reverse_iterator rbegin() const noexcept;
170
+ reverse_iterator rend() noexcept;
171
+ const_reverse_iterator rend() const noexcept;
172
+
173
+ const_iterator cbegin() const noexcept;
174
+ const_iterator cend() const noexcept;
175
+ const_reverse_iterator crbegin() const noexcept;
176
+ const_reverse_iterator crend() const noexcept;
177
+
178
+ // capacity
179
+ [[nodiscard]] bool empty() const noexcept;
180
+ size_type size() const noexcept;
181
+ size_type max_size() const noexcept;
182
+
183
+ // [flat.multiset.modifiers], modifiers
184
+ template<class... Args> iterator emplace(Args&&... args);
185
+ template<class... Args>
186
+ iterator emplace_hint(const_iterator position, Args&&... args);
187
+
188
+ iterator insert(const value_type& x)
189
+ { return emplace(x); }
190
+ iterator insert(value_type&& x)
191
+ { return emplace(std::move(x)); }
192
+ iterator insert(const_iterator position, const value_type& x)
193
+ { return emplace_hint(position, x); }
194
+ iterator insert(const_iterator position, value_type&& x)
195
+ { return emplace_hint(position, std::move(x)); }
196
+
197
+ template<class InputIterator>
198
+ void insert(InputIterator first, InputIterator last);
199
+ template<class InputIterator>
200
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
201
+ template<container-compatible-range<value_type> R>
202
+ void insert_range(R&& rg);
203
+
204
+ void insert(initializer_list<value_type> il)
205
+ { insert(il.begin(), il.end()); }
206
+ void insert(sorted_equivalent_t s, initializer_list<value_type> il)
207
+ { insert(s, il.begin(), il.end()); }
208
+
209
+ container_type extract() &&;
210
+ void replace(container_type&&);
211
+
212
+ iterator erase(iterator position);
213
+ iterator erase(const_iterator position);
214
+ size_type erase(const key_type& x);
215
+ template<class K> size_type erase(K&& x);
216
+ iterator erase(const_iterator first, const_iterator last);
217
+
218
+ void swap(flat_multiset& y) noexcept;
219
+ void clear() noexcept;
220
+
221
+ // observers
222
+ key_compare key_comp() const;
223
+ value_compare value_comp() const;
224
+
225
+ // set operations
226
+ iterator find(const key_type& x);
227
+ const_iterator find(const key_type& x) const;
228
+ template<class K> iterator find(const K& x);
229
+ template<class K> const_iterator find(const K& x) const;
230
+
231
+ size_type count(const key_type& x) const;
232
+ template<class K> size_type count(const K& x) const;
233
+
234
+ bool contains(const key_type& x) const;
235
+ template<class K> bool contains(const K& x) const;
236
+
237
+ iterator lower_bound(const key_type& x);
238
+ const_iterator lower_bound(const key_type& x) const;
239
+ template<class K> iterator lower_bound(const K& x);
240
+ template<class K> const_iterator lower_bound(const K& x) const;
241
+
242
+ iterator upper_bound(const key_type& x);
243
+ const_iterator upper_bound(const key_type& x) const;
244
+ template<class K> iterator upper_bound(const K& x);
245
+ template<class K> const_iterator upper_bound(const K& x) const;
246
+
247
+ pair<iterator, iterator> equal_range(const key_type& x);
248
+ pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
249
+ template<class K>
250
+ pair<iterator, iterator> equal_range(const K& x);
251
+ template<class K>
252
+ pair<const_iterator, const_iterator> equal_range(const K& x) const;
253
+
254
+ friend bool operator==(const flat_multiset& x, const flat_multiset& y);
255
+
256
+ friend synth-three-way-result<value_type>
257
+ operator<=>(const flat_multiset& x, const flat_multiset& y);
258
+
259
+ friend void swap(flat_multiset& x, flat_multiset& y) noexcept
260
+ { x.swap(y); }
261
+
262
+ private:
263
+ container_type c; // exposition only
264
+ key_compare compare; // exposition only
265
+ };
266
+
267
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
268
+ flat_multiset(KeyContainer, Compare = Compare())
269
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
270
+ template<class KeyContainer, class Allocator>
271
+ flat_multiset(KeyContainer, Allocator)
272
+ -> flat_multiset<typename KeyContainer::value_type,
273
+ less<typename KeyContainer::value_type>, KeyContainer>;
274
+ template<class KeyContainer, class Compare, class Allocator>
275
+ flat_multiset(KeyContainer, Compare, Allocator)
276
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
277
+
278
+ template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>
279
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())
280
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
281
+ template<class KeyContainer, class Allocator>
282
+ flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)
283
+ -> flat_multiset<typename KeyContainer::value_type,
284
+ less<typename KeyContainer::value_type>, KeyContainer>;
285
+ template<class KeyContainer, class Compare, class Allocator>
286
+ flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)
287
+ -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;
288
+
289
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
290
+ flat_multiset(InputIterator, InputIterator, Compare = Compare())
291
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
292
+
293
+ template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>
294
+ flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())
295
+ -> flat_multiset<iter-value-type<InputIterator>, iter-value-type<InputIterator>, Compare>;
296
+
297
+ template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
298
+ class Allocator = allocator<ranges::range_value_t<R>>>
299
+ flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
300
+ -> flat_multiset<ranges::range_value_t<R>, Compare,
301
+ vector<ranges::range_value_t<R>,
302
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
303
+
304
+ template<ranges::input_range R, class Allocator>
305
+ flat_multiset(from_range_t, R&&, Allocator)
306
+ -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
307
+ vector<ranges::range_value_t<R>,
308
+ alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
309
+
310
+ template<class Key, class Compare = less<Key>>
311
+ flat_multiset(initializer_list<Key>, Compare = Compare())
312
+ -> flat_multiset<Key, Compare>;
313
+
314
+ template<class Key, class Compare = less<Key>>
315
+ flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())
316
+ -> flat_multiset<Key, Compare>;
317
+
318
+ template<class Key, class Compare, class KeyContainer, class Allocator>
319
+ struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>
320
+ : bool_constant<uses_allocator_v<KeyContainer, Allocator>> { };
321
+ }
322
+ ```
323
+
324
+ #### Constructors <a id="flat.multiset.cons">[[flat.multiset.cons]]</a>
325
+
326
+ ``` cpp
327
+ explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
328
+ ```
329
+
330
+ *Effects:* Initializes *c* with `std::move(cont)` and *compare* with
331
+ `comp`, and sorts the range \[`begin()`, `end()`) with respect to
332
+ *compare*.
333
+
334
+ *Complexity:* Linear in N if `cont` is sorted with respect to *compare*
335
+ and otherwise N log N, where N is the value of `cont.size()` before this
336
+ call.
337
+
338
+ ``` cpp
339
+ template<class Allocator>
340
+ flat_multiset(const container_type& cont, const Allocator& a);
341
+ template<class Allocator>
342
+ flat_multiset(const container_type& cont, const key_compare& comp, const Allocator& a);
343
+ ```
344
+
345
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
346
+
347
+ *Effects:* Equivalent to `flat_multiset(cont)` and
348
+ `flat_multiset(cont, comp)`, respectively, except that *c* is
349
+ constructed with uses-allocator
350
+ construction [[allocator.uses.construction]].
351
+
352
+ *Complexity:* Same as `flat_multiset(cont)` and
353
+ `flat_multiset(cont, comp)`, respectively.
354
+
355
+ ``` cpp
356
+ template<class Allocator>
357
+ flat_multiset(sorted_equivalent_t s, const container_type& cont, const Allocator& a);
358
+ template<class Allocator>
359
+ flat_multiset(sorted_equivalent_t s, const container_type& cont,
360
+ const key_compare& comp, const Allocator& a);
361
+ ```
362
+
363
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
364
+
365
+ *Effects:* Equivalent to `flat_multiset(s, cont)` and
366
+ `flat_multiset(s, cont, comp)`, respectively, except that *c* is
367
+ constructed with uses-allocator
368
+ construction [[allocator.uses.construction]].
369
+
370
+ *Complexity:* Linear.
371
+
372
+ ``` cpp
373
+ template<class Allocator>
374
+ flat_multiset(const key_compare& comp, const Allocator& a);
375
+ template<class Allocator>
376
+ explicit flat_multiset(const Allocator& a);
377
+ template<class InputIterator, class Allocator>
378
+ flat_multiset(InputIterator first, InputIterator last,
379
+ const key_compare& comp, const Allocator& a);
380
+ template<class InputIterator, class Allocator>
381
+ flat_multiset(InputIterator first, InputIterator last, const Allocator& a);
382
+ template<container-compatible-range<value_type> R, class Allocator>
383
+ flat_multiset(from_range_t, R&& rg, const Allocator& a);
384
+ template<container-compatible-range<value_type> R, class Allocator>
385
+ flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Allocator& a);
386
+ template<class InputIterator, class Allocator>
387
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
388
+ const key_compare& comp, const Allocator& a);
389
+ template<class InputIterator, class Allocator>
390
+ flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Allocator& a);
391
+ template<class Allocator>
392
+ flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Allocator& a);
393
+ template<class Allocator>
394
+ flat_multiset(initializer_list<value_type> il, const Allocator& a);
395
+ template<class Allocator>
396
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
397
+ const key_compare& comp, const Allocator& a);
398
+ template<class Allocator>
399
+ flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Allocator& a);
400
+ ```
401
+
402
+ *Constraints:* `uses_allocator_v<container_type, Allocator>` is `true`.
403
+
404
+ *Effects:* Equivalent to the corresponding non-allocator constructors
405
+ except that *c* is constructed with uses-allocator
406
+ construction [[allocator.uses.construction]].
407
+
408
+ #### Modifiers <a id="flat.multiset.modifiers">[[flat.multiset.modifiers]]</a>
409
+
410
+ ``` cpp
411
+ template<class... Args> iterator emplace(Args&&... args);
412
+ ```
413
+
414
+ *Constraints:* `is_constructible_v<value_type, Args...>` is `true`.
415
+
416
+ *Effects:* First, initializes an object `t` of type `value_type` with
417
+ `std::forward<Args>(args)...`, then inserts `t` as if by:
418
+
419
+ ``` cpp
420
+ auto it = ranges::upper_bound(c, t, compare);
421
+ c.insert(it, std::move(t));
422
+ ```
423
+
424
+ *Returns:* An iterator that points to the inserted element.
425
+
426
+ ``` cpp
427
+ template<class InputIterator>
428
+ void insert(InputIterator first, InputIterator last);
429
+ ```
430
+
431
+ *Effects:* Adds elements to *c* as if by:
432
+
433
+ ``` cpp
434
+ c.insert(c.end(), first, last);
435
+ ```
436
+
437
+ Then, sorts the range of newly inserted elements with respect to
438
+ *compare*, and merges the resulting sorted range and the sorted range of
439
+ pre-existing elements into a single sorted range.
440
+
441
+ *Complexity:* N + M log M, where N is `size()` before the operation and
442
+ M is `distance(first, last)`.
443
+
444
+ *Remarks:* Since this operation performs an in-place merge, it may
445
+ allocate memory.
446
+
447
+ ``` cpp
448
+ template<class InputIterator>
449
+ void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
450
+ ```
451
+
452
+ *Effects:* Equivalent to `insert(first, last)`.
453
+
454
+ *Complexity:* Linear.
455
+
456
+ ``` cpp
457
+ void swap(flat_multiset& y) noexcept;
458
+ ```
459
+
460
+ *Effects:* Equivalent to:
461
+
462
+ ``` cpp
463
+ ranges::swap(compare, y.compare);
464
+ ranges::swap(c, y.c);
465
+ ```
466
+
467
+ ``` cpp
468
+ container_type extract() &&;
469
+ ```
470
+
471
+ *Ensures:* `*this` is emptied, even if the function exits via an
472
+ exception.
473
+
474
+ *Returns:* `std::move(c)`.
475
+
476
+ ``` cpp
477
+ void replace(container_type&& cont);
478
+ ```
479
+
480
+ *Preconditions:* The elements of `cont` are sorted with respect to
481
+ *compare*.
482
+
483
+ *Effects:* Equivalent to: `c = std::move(cont);`
484
+
485
+ #### Erasure <a id="flat.multiset.erasure">[[flat.multiset.erasure]]</a>
486
+
487
+ ``` cpp
488
+ template<class Key, class Compare, class KeyContainer, class Predicate>
489
+ typename flat_multiset<Key, Compare, KeyContainer>::size_type
490
+ erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
491
+ ```
492
+
493
+ *Preconditions:* `Key` meets the *Cpp17MoveAssignable* requirements.
494
+
495
+ *Effects:* Let E be `bool(pred(as_const(e)))`. Erases all elements `e`
496
+ in `c` for which E holds.
497
+
498
+ *Returns:* The number of elements erased.
499
+
500
+ *Complexity:* Exactly `c.size()` applications of the predicate.
501
+
502
+ *Remarks:* Stable [[algorithm.stable]]. If an invocation of `erase_if`
503
+ exits via an exception, `c` is in a valid but unspecified
504
+ state [[defns.valid]].
505
+
506
+ [*Note 1*: `c` still meets its invariants, but can be
507
+ empty. — *end note*]
508
+