1// -*- C++ -*-
2//===---------------------------- set -------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SET
11#define _LIBCPP_SET
12
13/*
14
15 set synopsis
16
17namespace std
18{
19
20template <class Key, class Compare = less<Key>,
21 class Allocator = allocator<Key>>
22class set
23{
24public:
25 // types:
26 typedef Key key_type;
27 typedef key_type value_type;
28 typedef Compare key_compare;
29 typedef key_compare value_compare;
30 typedef Allocator allocator_type;
31 typedef typename allocator_type::reference reference;
32 typedef typename allocator_type::const_reference const_reference;
33 typedef typename allocator_type::size_type size_type;
34 typedef typename allocator_type::difference_type difference_type;
35 typedef typename allocator_type::pointer pointer;
36 typedef typename allocator_type::const_pointer const_pointer;
37
38 typedef implementation-defined iterator;
39 typedef implementation-defined const_iterator;
40 typedef std::reverse_iterator<iterator> reverse_iterator;
41 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
42 typedef unspecified node_type; // C++17
43 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
44
45 // construct/copy/destroy:
46 set()
47 noexcept(
48 is_nothrow_default_constructible<allocator_type>::value &&
49 is_nothrow_default_constructible<key_compare>::value &&
50 is_nothrow_copy_constructible<key_compare>::value);
51 explicit set(const value_compare& comp);
52 set(const value_compare& comp, const allocator_type& a);
53 template <class InputIterator>
54 set(InputIterator first, InputIterator last,
55 const value_compare& comp = value_compare());
56 template <class InputIterator>
57 set(InputIterator first, InputIterator last, const value_compare& comp,
58 const allocator_type& a);
59 set(const set& s);
60 set(set&& s)
61 noexcept(
62 is_nothrow_move_constructible<allocator_type>::value &&
63 is_nothrow_move_constructible<key_compare>::value);
64 explicit set(const allocator_type& a);
65 set(const set& s, const allocator_type& a);
66 set(set&& s, const allocator_type& a);
67 set(initializer_list<value_type> il, const value_compare& comp = value_compare());
68 set(initializer_list<value_type> il, const value_compare& comp,
69 const allocator_type& a);
70 template <class InputIterator>
71 set(InputIterator first, InputIterator last, const allocator_type& a)
72 : set(first, last, Compare(), a) {} // C++14
73 set(initializer_list<value_type> il, const allocator_type& a)
74 : set(il, Compare(), a) {} // C++14
75 ~set();
76
77 set& operator=(const set& s);
78 set& operator=(set&& s)
79 noexcept(
80 allocator_type::propagate_on_container_move_assignment::value &&
81 is_nothrow_move_assignable<allocator_type>::value &&
82 is_nothrow_move_assignable<key_compare>::value);
83 set& operator=(initializer_list<value_type> il);
84
85 // iterators:
86 iterator begin() noexcept;
87 const_iterator begin() const noexcept;
88 iterator end() noexcept;
89 const_iterator end() const noexcept;
90
91 reverse_iterator rbegin() noexcept;
92 const_reverse_iterator rbegin() const noexcept;
93 reverse_iterator rend() noexcept;
94 const_reverse_iterator rend() const noexcept;
95
96 const_iterator cbegin() const noexcept;
97 const_iterator cend() const noexcept;
98 const_reverse_iterator crbegin() const noexcept;
99 const_reverse_iterator crend() const noexcept;
100
101 // capacity:
102 bool empty() const noexcept;
103 size_type size() const noexcept;
104 size_type max_size() const noexcept;
105
106 // modifiers:
107 template <class... Args>
108 pair<iterator, bool> emplace(Args&&... args);
109 template <class... Args>
110 iterator emplace_hint(const_iterator position, Args&&... args);
111 pair<iterator,bool> insert(const value_type& v);
112 pair<iterator,bool> insert(value_type&& v);
113 iterator insert(const_iterator position, const value_type& v);
114 iterator insert(const_iterator position, value_type&& v);
115 template <class InputIterator>
116 void insert(InputIterator first, InputIterator last);
117 void insert(initializer_list<value_type> il);
118
119 node_type extract(const_iterator position); // C++17
120 node_type extract(const key_type& x); // C++17
121 insert_return_type insert(node_type&& nh); // C++17
122 iterator insert(const_iterator hint, node_type&& nh); // C++17
123
124 iterator erase(const_iterator position);
125 iterator erase(iterator position); // C++14
126 size_type erase(const key_type& k);
127 iterator erase(const_iterator first, const_iterator last);
128 void clear() noexcept;
129
130 template<class C2>
131 void merge(set<Key, C2, Allocator>& source); // C++17
132 template<class C2>
133 void merge(set<Key, C2, Allocator>&& source); // C++17
134 template<class C2>
135 void merge(multiset<Key, C2, Allocator>& source); // C++17
136 template<class C2>
137 void merge(multiset<Key, C2, Allocator>&& source); // C++17
138
139 void swap(set& s)
140 noexcept(
141 __is_nothrow_swappable<key_compare>::value &&
142 (!allocator_type::propagate_on_container_swap::value ||
143 __is_nothrow_swappable<allocator_type>::value));
144
145 // observers:
146 allocator_type get_allocator() const noexcept;
147 key_compare key_comp() const;
148 value_compare value_comp() const;
149
150 // set operations:
151 iterator find(const key_type& k);
152 const_iterator find(const key_type& k) const;
153 template<typename K>
154 iterator find(const K& x);
155 template<typename K>
156 const_iterator find(const K& x) const; // C++14
157 template<typename K>
158 size_type count(const K& x) const; // C++14
159 size_type count(const key_type& k) const;
160 bool contains(const key_type& x) const; // C++20
161 iterator lower_bound(const key_type& k);
162 const_iterator lower_bound(const key_type& k) const;
163 template<typename K>
164 iterator lower_bound(const K& x); // C++14
165 template<typename K>
166 const_iterator lower_bound(const K& x) const; // C++14
167
168 iterator upper_bound(const key_type& k);
169 const_iterator upper_bound(const key_type& k) const;
170 template<typename K>
171 iterator upper_bound(const K& x); // C++14
172 template<typename K>
173 const_iterator upper_bound(const K& x) const; // C++14
174 pair<iterator,iterator> equal_range(const key_type& k);
175 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
176 template<typename K>
177 pair<iterator,iterator> equal_range(const K& x); // C++14
178 template<typename K>
179 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
180};
181
182template <class Key, class Compare, class Allocator>
183bool
184operator==(const set<Key, Compare, Allocator>& x,
185 const set<Key, Compare, Allocator>& y);
186
187template <class Key, class Compare, class Allocator>
188bool
189operator< (const set<Key, Compare, Allocator>& x,
190 const set<Key, Compare, Allocator>& y);
191
192template <class Key, class Compare, class Allocator>
193bool
194operator!=(const set<Key, Compare, Allocator>& x,
195 const set<Key, Compare, Allocator>& y);
196
197template <class Key, class Compare, class Allocator>
198bool
199operator> (const set<Key, Compare, Allocator>& x,
200 const set<Key, Compare, Allocator>& y);
201
202template <class Key, class Compare, class Allocator>
203bool
204operator>=(const set<Key, Compare, Allocator>& x,
205 const set<Key, Compare, Allocator>& y);
206
207template <class Key, class Compare, class Allocator>
208bool
209operator<=(const set<Key, Compare, Allocator>& x,
210 const set<Key, Compare, Allocator>& y);
211
212// specialized algorithms:
213template <class Key, class Compare, class Allocator>
214void
215swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
216 noexcept(noexcept(x.swap(y)));
217
218template <class Key, class Compare, class Allocator, class Predicate>
219 void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
220
221template <class Key, class Compare = less<Key>,
222 class Allocator = allocator<Key>>
223class multiset
224{
225public:
226 // types:
227 typedef Key key_type;
228 typedef key_type value_type;
229 typedef Compare key_compare;
230 typedef key_compare value_compare;
231 typedef Allocator allocator_type;
232 typedef typename allocator_type::reference reference;
233 typedef typename allocator_type::const_reference const_reference;
234 typedef typename allocator_type::size_type size_type;
235 typedef typename allocator_type::difference_type difference_type;
236 typedef typename allocator_type::pointer pointer;
237 typedef typename allocator_type::const_pointer const_pointer;
238
239 typedef implementation-defined iterator;
240 typedef implementation-defined const_iterator;
241 typedef std::reverse_iterator<iterator> reverse_iterator;
242 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
243 typedef unspecified node_type; // C++17
244
245 // construct/copy/destroy:
246 multiset()
247 noexcept(
248 is_nothrow_default_constructible<allocator_type>::value &&
249 is_nothrow_default_constructible<key_compare>::value &&
250 is_nothrow_copy_constructible<key_compare>::value);
251 explicit multiset(const value_compare& comp);
252 multiset(const value_compare& comp, const allocator_type& a);
253 template <class InputIterator>
254 multiset(InputIterator first, InputIterator last,
255 const value_compare& comp = value_compare());
256 template <class InputIterator>
257 multiset(InputIterator first, InputIterator last,
258 const value_compare& comp, const allocator_type& a);
259 multiset(const multiset& s);
260 multiset(multiset&& s)
261 noexcept(
262 is_nothrow_move_constructible<allocator_type>::value &&
263 is_nothrow_move_constructible<key_compare>::value);
264 explicit multiset(const allocator_type& a);
265 multiset(const multiset& s, const allocator_type& a);
266 multiset(multiset&& s, const allocator_type& a);
267 multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
268 multiset(initializer_list<value_type> il, const value_compare& comp,
269 const allocator_type& a);
270 template <class InputIterator>
271 multiset(InputIterator first, InputIterator last, const allocator_type& a)
272 : set(first, last, Compare(), a) {} // C++14
273 multiset(initializer_list<value_type> il, const allocator_type& a)
274 : set(il, Compare(), a) {} // C++14
275 ~multiset();
276
277 multiset& operator=(const multiset& s);
278 multiset& operator=(multiset&& s)
279 noexcept(
280 allocator_type::propagate_on_container_move_assignment::value &&
281 is_nothrow_move_assignable<allocator_type>::value &&
282 is_nothrow_move_assignable<key_compare>::value);
283 multiset& operator=(initializer_list<value_type> il);
284
285 // iterators:
286 iterator begin() noexcept;
287 const_iterator begin() const noexcept;
288 iterator end() noexcept;
289 const_iterator end() const noexcept;
290
291 reverse_iterator rbegin() noexcept;
292 const_reverse_iterator rbegin() const noexcept;
293 reverse_iterator rend() noexcept;
294 const_reverse_iterator rend() const noexcept;
295
296 const_iterator cbegin() const noexcept;
297 const_iterator cend() const noexcept;
298 const_reverse_iterator crbegin() const noexcept;
299 const_reverse_iterator crend() const noexcept;
300
301 // capacity:
302 bool empty() const noexcept;
303 size_type size() const noexcept;
304 size_type max_size() const noexcept;
305
306 // modifiers:
307 template <class... Args>
308 iterator emplace(Args&&... args);
309 template <class... Args>
310 iterator emplace_hint(const_iterator position, Args&&... args);
311 iterator insert(const value_type& v);
312 iterator insert(value_type&& v);
313 iterator insert(const_iterator position, const value_type& v);
314 iterator insert(const_iterator position, value_type&& v);
315 template <class InputIterator>
316 void insert(InputIterator first, InputIterator last);
317 void insert(initializer_list<value_type> il);
318
319 node_type extract(const_iterator position); // C++17
320 node_type extract(const key_type& x); // C++17
321 iterator insert(node_type&& nh); // C++17
322 iterator insert(const_iterator hint, node_type&& nh); // C++17
323
324 iterator erase(const_iterator position);
325 iterator erase(iterator position); // C++14
326 size_type erase(const key_type& k);
327 iterator erase(const_iterator first, const_iterator last);
328 void clear() noexcept;
329
330 template<class C2>
331 void merge(multiset<Key, C2, Allocator>& source); // C++17
332 template<class C2>
333 void merge(multiset<Key, C2, Allocator>&& source); // C++17
334 template<class C2>
335 void merge(set<Key, C2, Allocator>& source); // C++17
336 template<class C2>
337 void merge(set<Key, C2, Allocator>&& source); // C++17
338
339 void swap(multiset& s)
340 noexcept(
341 __is_nothrow_swappable<key_compare>::value &&
342 (!allocator_type::propagate_on_container_swap::value ||
343 __is_nothrow_swappable<allocator_type>::value));
344
345 // observers:
346 allocator_type get_allocator() const noexcept;
347 key_compare key_comp() const;
348 value_compare value_comp() const;
349
350 // set operations:
351 iterator find(const key_type& k);
352 const_iterator find(const key_type& k) const;
353 template<typename K>
354 iterator find(const K& x);
355 template<typename K>
356 const_iterator find(const K& x) const; // C++14
357 template<typename K>
358 size_type count(const K& x) const; // C++14
359 size_type count(const key_type& k) const;
360 bool contains(const key_type& x) const; // C++20
361 iterator lower_bound(const key_type& k);
362 const_iterator lower_bound(const key_type& k) const;
363 template<typename K>
364 iterator lower_bound(const K& x); // C++14
365 template<typename K>
366 const_iterator lower_bound(const K& x) const; // C++14
367
368 iterator upper_bound(const key_type& k);
369 const_iterator upper_bound(const key_type& k) const;
370 template<typename K>
371 iterator upper_bound(const K& x); // C++14
372 template<typename K>
373 const_iterator upper_bound(const K& x) const; // C++14
374
375 pair<iterator,iterator> equal_range(const key_type& k);
376 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
377 template<typename K>
378 pair<iterator,iterator> equal_range(const K& x); // C++14
379 template<typename K>
380 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
381};
382
383template <class Key, class Compare, class Allocator>
384bool
385operator==(const multiset<Key, Compare, Allocator>& x,
386 const multiset<Key, Compare, Allocator>& y);
387
388template <class Key, class Compare, class Allocator>
389bool
390operator< (const multiset<Key, Compare, Allocator>& x,
391 const multiset<Key, Compare, Allocator>& y);
392
393template <class Key, class Compare, class Allocator>
394bool
395operator!=(const multiset<Key, Compare, Allocator>& x,
396 const multiset<Key, Compare, Allocator>& y);
397
398template <class Key, class Compare, class Allocator>
399bool
400operator> (const multiset<Key, Compare, Allocator>& x,
401 const multiset<Key, Compare, Allocator>& y);
402
403template <class Key, class Compare, class Allocator>
404bool
405operator>=(const multiset<Key, Compare, Allocator>& x,
406 const multiset<Key, Compare, Allocator>& y);
407
408template <class Key, class Compare, class Allocator>
409bool
410operator<=(const multiset<Key, Compare, Allocator>& x,
411 const multiset<Key, Compare, Allocator>& y);
412
413// specialized algorithms:
414template <class Key, class Compare, class Allocator>
415void
416swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
417 noexcept(noexcept(x.swap(y)));
418
419template <class Key, class Compare, class Allocator, class Predicate>
420 void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
421
422} // std
423
424*/
425
426#include <__config>
427#include <__tree>
428#include <__node_handle>
429#include <functional>
430#include <version>
431
432#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
433#pragma GCC system_header
434#endif
435
436_LIBCPP_BEGIN_NAMESPACE_STD
437
438template <class _Key, class _Compare, class _Allocator>
439class multiset;
440
441template <class _Key, class _Compare = less<_Key>,
442 class _Allocator = allocator<_Key> >
443class _LIBCPP_TEMPLATE_VIS set
444{
445public:
446 // types:
447 typedef _Key key_type;
448 typedef key_type value_type;
449 typedef _Compare key_compare;
450 typedef key_compare value_compare;
451 typedef typename __identity<_Allocator>::type allocator_type;
452 typedef value_type& reference;
453 typedef const value_type& const_reference;
454
455 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
456 "Allocator::value_type must be same type as value_type");
457
458private:
459 typedef __tree<value_type, value_compare, allocator_type> __base;
460 typedef allocator_traits<allocator_type> __alloc_traits;
461 typedef typename __base::__node_holder __node_holder;
462
463 __base __tree_;
464
465public:
466 typedef typename __base::pointer pointer;
467 typedef typename __base::const_pointer const_pointer;
468 typedef typename __base::size_type size_type;
469 typedef typename __base::difference_type difference_type;
470 typedef typename __base::const_iterator iterator;
471 typedef typename __base::const_iterator const_iterator;
472 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
473 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
474
475#if _LIBCPP_STD_VER > 14
476 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
477 typedef __insert_return_type<iterator, node_type> insert_return_type;
478#endif
479
480 template <class _Key2, class _Compare2, class _Alloc2>
481 friend class _LIBCPP_TEMPLATE_VIS set;
482 template <class _Key2, class _Compare2, class _Alloc2>
483 friend class _LIBCPP_TEMPLATE_VIS multiset;
484
485 _LIBCPP_INLINE_VISIBILITY
486 set()
487 _NOEXCEPT_(
488 is_nothrow_default_constructible<allocator_type>::value &&
489 is_nothrow_default_constructible<key_compare>::value &&
490 is_nothrow_copy_constructible<key_compare>::value)
491 : __tree_(value_compare()) {}
492
493 _LIBCPP_INLINE_VISIBILITY
494 explicit set(const value_compare& __comp)
495 _NOEXCEPT_(
496 is_nothrow_default_constructible<allocator_type>::value &&
497 is_nothrow_copy_constructible<key_compare>::value)
498 : __tree_(__comp) {}
499
500 _LIBCPP_INLINE_VISIBILITY
501 explicit set(const value_compare& __comp, const allocator_type& __a)
502 : __tree_(__comp, __a) {}
503 template <class _InputIterator>
504 _LIBCPP_INLINE_VISIBILITY
505 set(_InputIterator __f, _InputIterator __l,
506 const value_compare& __comp = value_compare())
507 : __tree_(__comp)
508 {
509 insert(__f, __l);
510 }
511
512 template <class _InputIterator>
513 _LIBCPP_INLINE_VISIBILITY
514 set(_InputIterator __f, _InputIterator __l, const value_compare& __comp,
515 const allocator_type& __a)
516 : __tree_(__comp, __a)
517 {
518 insert(__f, __l);
519 }
520
521#if _LIBCPP_STD_VER > 11
522 template <class _InputIterator>
523 _LIBCPP_INLINE_VISIBILITY
524 set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
525 : set(__f, __l, key_compare(), __a) {}
526#endif
527
528 _LIBCPP_INLINE_VISIBILITY
529 set(const set& __s)
530 : __tree_(__s.__tree_)
531 {
532 insert(__s.begin(), __s.end());
533 }
534
535 _LIBCPP_INLINE_VISIBILITY
536 set& operator=(const set& __s)
537 {
538 __tree_ = __s.__tree_;
539 return *this;
540 }
541
542#ifndef _LIBCPP_CXX03_LANG
543 _LIBCPP_INLINE_VISIBILITY
544 set(set&& __s)
545 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
546 : __tree_(_VSTD::move(__s.__tree_)) {}
547#endif // _LIBCPP_CXX03_LANG
548
549 _LIBCPP_INLINE_VISIBILITY
550 explicit set(const allocator_type& __a)
551 : __tree_(__a) {}
552
553 _LIBCPP_INLINE_VISIBILITY
554 set(const set& __s, const allocator_type& __a)
555 : __tree_(__s.__tree_.value_comp(), __a)
556 {
557 insert(__s.begin(), __s.end());
558 }
559
560#ifndef _LIBCPP_CXX03_LANG
561 set(set&& __s, const allocator_type& __a);
562
563 _LIBCPP_INLINE_VISIBILITY
564 set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
565 : __tree_(__comp)
566 {
567 insert(__il.begin(), __il.end());
568 }
569
570 _LIBCPP_INLINE_VISIBILITY
571 set(initializer_list<value_type> __il, const value_compare& __comp,
572 const allocator_type& __a)
573 : __tree_(__comp, __a)
574 {
575 insert(__il.begin(), __il.end());
576 }
577
578#if _LIBCPP_STD_VER > 11
579 _LIBCPP_INLINE_VISIBILITY
580 set(initializer_list<value_type> __il, const allocator_type& __a)
581 : set(__il, key_compare(), __a) {}
582#endif
583
584 _LIBCPP_INLINE_VISIBILITY
585 set& operator=(initializer_list<value_type> __il)
586 {
587 __tree_.__assign_unique(__il.begin(), __il.end());
588 return *this;
589 }
590
591 _LIBCPP_INLINE_VISIBILITY
592 set& operator=(set&& __s)
593 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
594 {
595 __tree_ = _VSTD::move(__s.__tree_);
596 return *this;
597 }
598#endif // _LIBCPP_CXX03_LANG
599
600 _LIBCPP_INLINE_VISIBILITY
601 ~set() {
602 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
603 }
604
605 _LIBCPP_INLINE_VISIBILITY
606 iterator begin() _NOEXCEPT {return __tree_.begin();}
607 _LIBCPP_INLINE_VISIBILITY
608 const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
609 _LIBCPP_INLINE_VISIBILITY
610 iterator end() _NOEXCEPT {return __tree_.end();}
611 _LIBCPP_INLINE_VISIBILITY
612 const_iterator end() const _NOEXCEPT {return __tree_.end();}
613
614 _LIBCPP_INLINE_VISIBILITY
615 reverse_iterator rbegin() _NOEXCEPT
616 {return reverse_iterator(end());}
617 _LIBCPP_INLINE_VISIBILITY
618 const_reverse_iterator rbegin() const _NOEXCEPT
619 {return const_reverse_iterator(end());}
620 _LIBCPP_INLINE_VISIBILITY
621 reverse_iterator rend() _NOEXCEPT
622 {return reverse_iterator(begin());}
623 _LIBCPP_INLINE_VISIBILITY
624 const_reverse_iterator rend() const _NOEXCEPT
625 {return const_reverse_iterator(begin());}
626
627 _LIBCPP_INLINE_VISIBILITY
628 const_iterator cbegin() const _NOEXCEPT {return begin();}
629 _LIBCPP_INLINE_VISIBILITY
630 const_iterator cend() const _NOEXCEPT {return end();}
631 _LIBCPP_INLINE_VISIBILITY
632 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
633 _LIBCPP_INLINE_VISIBILITY
634 const_reverse_iterator crend() const _NOEXCEPT {return rend();}
635
636 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
637 bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
638 _LIBCPP_INLINE_VISIBILITY
639 size_type size() const _NOEXCEPT {return __tree_.size();}
640 _LIBCPP_INLINE_VISIBILITY
641 size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
642
643 // modifiers:
644#ifndef _LIBCPP_CXX03_LANG
645 template <class... _Args>
646 _LIBCPP_INLINE_VISIBILITY
647 pair<iterator, bool> emplace(_Args&&... __args)
648 {return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
649 template <class... _Args>
650 _LIBCPP_INLINE_VISIBILITY
651 iterator emplace_hint(const_iterator __p, _Args&&... __args)
652 {return __tree_.__emplace_hint_unique(__p, _VSTD::forward<_Args>(__args)...);}
653#endif // _LIBCPP_CXX03_LANG
654
655 _LIBCPP_INLINE_VISIBILITY
656 pair<iterator,bool> insert(const value_type& __v)
657 {return __tree_.__insert_unique(__v);}
658 _LIBCPP_INLINE_VISIBILITY
659 iterator insert(const_iterator __p, const value_type& __v)
660 {return __tree_.__insert_unique(__p, __v);}
661
662 template <class _InputIterator>
663 _LIBCPP_INLINE_VISIBILITY
664 void insert(_InputIterator __f, _InputIterator __l)
665 {
666 for (const_iterator __e = cend(); __f != __l; ++__f)
667 __tree_.__insert_unique(__e, *__f);
668 }
669
670#ifndef _LIBCPP_CXX03_LANG
671 _LIBCPP_INLINE_VISIBILITY
672 pair<iterator,bool> insert(value_type&& __v)
673 {return __tree_.__insert_unique(_VSTD::move(__v));}
674
675 _LIBCPP_INLINE_VISIBILITY
676 iterator insert(const_iterator __p, value_type&& __v)
677 {return __tree_.__insert_unique(__p, _VSTD::move(__v));}
678
679 _LIBCPP_INLINE_VISIBILITY
680 void insert(initializer_list<value_type> __il)
681 {insert(__il.begin(), __il.end());}
682#endif // _LIBCPP_CXX03_LANG
683
684 _LIBCPP_INLINE_VISIBILITY
685 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
686 _LIBCPP_INLINE_VISIBILITY
687 size_type erase(const key_type& __k)
688 {return __tree_.__erase_unique(__k);}
689 _LIBCPP_INLINE_VISIBILITY
690 iterator erase(const_iterator __f, const_iterator __l)
691 {return __tree_.erase(__f, __l);}
692 _LIBCPP_INLINE_VISIBILITY
693 void clear() _NOEXCEPT {__tree_.clear();}
694
695#if _LIBCPP_STD_VER > 14
696 _LIBCPP_INLINE_VISIBILITY
697 insert_return_type insert(node_type&& __nh)
698 {
699 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
700 "node_type with incompatible allocator passed to set::insert()");
701 return __tree_.template __node_handle_insert_unique<
702 node_type, insert_return_type>(_VSTD::move(__nh));
703 }
704 _LIBCPP_INLINE_VISIBILITY
705 iterator insert(const_iterator __hint, node_type&& __nh)
706 {
707 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
708 "node_type with incompatible allocator passed to set::insert()");
709 return __tree_.template __node_handle_insert_unique<node_type>(
710 __hint, _VSTD::move(__nh));
711 }
712 _LIBCPP_INLINE_VISIBILITY
713 node_type extract(key_type const& __key)
714 {
715 return __tree_.template __node_handle_extract<node_type>(__key);
716 }
717 _LIBCPP_INLINE_VISIBILITY
718 node_type extract(const_iterator __it)
719 {
720 return __tree_.template __node_handle_extract<node_type>(__it);
721 }
722 template <class _Compare2>
723 _LIBCPP_INLINE_VISIBILITY
724 void merge(set<key_type, _Compare2, allocator_type>& __source)
725 {
726 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
727 "merging container with incompatible allocator");
728 __tree_.__node_handle_merge_unique(__source.__tree_);
729 }
730 template <class _Compare2>
731 _LIBCPP_INLINE_VISIBILITY
732 void merge(set<key_type, _Compare2, allocator_type>&& __source)
733 {
734 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
735 "merging container with incompatible allocator");
736 __tree_.__node_handle_merge_unique(__source.__tree_);
737 }
738 template <class _Compare2>
739 _LIBCPP_INLINE_VISIBILITY
740 void merge(multiset<key_type, _Compare2, allocator_type>& __source)
741 {
742 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
743 "merging container with incompatible allocator");
744 __tree_.__node_handle_merge_unique(__source.__tree_);
745 }
746 template <class _Compare2>
747 _LIBCPP_INLINE_VISIBILITY
748 void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
749 {
750 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
751 "merging container with incompatible allocator");
752 __tree_.__node_handle_merge_unique(__source.__tree_);
753 }
754#endif
755
756 _LIBCPP_INLINE_VISIBILITY
757 void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
758 {__tree_.swap(__s.__tree_);}
759
760 _LIBCPP_INLINE_VISIBILITY
761 allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
762 _LIBCPP_INLINE_VISIBILITY
763 key_compare key_comp() const {return __tree_.value_comp();}
764 _LIBCPP_INLINE_VISIBILITY
765 value_compare value_comp() const {return __tree_.value_comp();}
766
767 // set operations:
768 _LIBCPP_INLINE_VISIBILITY
769 iterator find(const key_type& __k) {return __tree_.find(__k);}
770 _LIBCPP_INLINE_VISIBILITY
771 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
772#if _LIBCPP_STD_VER > 11
773 template <typename _K2>
774 _LIBCPP_INLINE_VISIBILITY
775 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
776 find(const _K2& __k) {return __tree_.find(__k);}
777 template <typename _K2>
778 _LIBCPP_INLINE_VISIBILITY
779 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
780 find(const _K2& __k) const {return __tree_.find(__k);}
781#endif
782
783 _LIBCPP_INLINE_VISIBILITY
784 size_type count(const key_type& __k) const
785 {return __tree_.__count_unique(__k);}
786#if _LIBCPP_STD_VER > 11
787 template <typename _K2>
788 _LIBCPP_INLINE_VISIBILITY
789 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
790 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
791#endif
792
793#if _LIBCPP_STD_VER > 17
794 _LIBCPP_INLINE_VISIBILITY
795 bool contains(const key_type& __k) const {return find(__k) != end();}
796#endif // _LIBCPP_STD_VER > 17
797
798 _LIBCPP_INLINE_VISIBILITY
799 iterator lower_bound(const key_type& __k)
800 {return __tree_.lower_bound(__k);}
801 _LIBCPP_INLINE_VISIBILITY
802 const_iterator lower_bound(const key_type& __k) const
803 {return __tree_.lower_bound(__k);}
804#if _LIBCPP_STD_VER > 11
805 template <typename _K2>
806 _LIBCPP_INLINE_VISIBILITY
807 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
808 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
809
810 template <typename _K2>
811 _LIBCPP_INLINE_VISIBILITY
812 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
813 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
814#endif
815
816 _LIBCPP_INLINE_VISIBILITY
817 iterator upper_bound(const key_type& __k)
818 {return __tree_.upper_bound(__k);}
819 _LIBCPP_INLINE_VISIBILITY
820 const_iterator upper_bound(const key_type& __k) const
821 {return __tree_.upper_bound(__k);}
822#if _LIBCPP_STD_VER > 11
823 template <typename _K2>
824 _LIBCPP_INLINE_VISIBILITY
825 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
826 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
827 template <typename _K2>
828 _LIBCPP_INLINE_VISIBILITY
829 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
830 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
831#endif
832
833 _LIBCPP_INLINE_VISIBILITY
834 pair<iterator,iterator> equal_range(const key_type& __k)
835 {return __tree_.__equal_range_unique(__k);}
836 _LIBCPP_INLINE_VISIBILITY
837 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
838 {return __tree_.__equal_range_unique(__k);}
839#if _LIBCPP_STD_VER > 11
840 template <typename _K2>
841 _LIBCPP_INLINE_VISIBILITY
842 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
843 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
844 template <typename _K2>
845 _LIBCPP_INLINE_VISIBILITY
846 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
847 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
848#endif
849};
850
851#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
852template<class _InputIterator,
853 class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
854 class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>,
855 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
856 class = typename enable_if<!__is_allocator<_Compare>::value, void>::type>
857set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
858 -> set<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>;
859
860template<class _Key, class _Compare = less<_Key>,
861 class _Allocator = allocator<_Key>,
862 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
863 class = typename enable_if<!__is_allocator<_Compare>::value, void>::type>
864set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
865 -> set<_Key, _Compare, _Allocator>;
866
867template<class _InputIterator, class _Allocator,
868 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type>
869set(_InputIterator, _InputIterator, _Allocator)
870 -> set<typename iterator_traits<_InputIterator>::value_type,
871 less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>;
872
873template<class _Key, class _Allocator,
874 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type>
875set(initializer_list<_Key>, _Allocator)
876 -> set<_Key, less<_Key>, _Allocator>;
877#endif
878
879#ifndef _LIBCPP_CXX03_LANG
880
881template <class _Key, class _Compare, class _Allocator>
882set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a)
883 : __tree_(_VSTD::move(__s.__tree_), __a)
884{
885 if (__a != __s.get_allocator())
886 {
887 const_iterator __e = cend();
888 while (!__s.empty())
889 insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));
890 }
891}
892
893#endif // _LIBCPP_CXX03_LANG
894
895template <class _Key, class _Compare, class _Allocator>
896inline _LIBCPP_INLINE_VISIBILITY
897bool
898operator==(const set<_Key, _Compare, _Allocator>& __x,
899 const set<_Key, _Compare, _Allocator>& __y)
900{
901 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
902}
903
904template <class _Key, class _Compare, class _Allocator>
905inline _LIBCPP_INLINE_VISIBILITY
906bool
907operator< (const set<_Key, _Compare, _Allocator>& __x,
908 const set<_Key, _Compare, _Allocator>& __y)
909{
910 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
911}
912
913template <class _Key, class _Compare, class _Allocator>
914inline _LIBCPP_INLINE_VISIBILITY
915bool
916operator!=(const set<_Key, _Compare, _Allocator>& __x,
917 const set<_Key, _Compare, _Allocator>& __y)
918{
919 return !(__x == __y);
920}
921
922template <class _Key, class _Compare, class _Allocator>
923inline _LIBCPP_INLINE_VISIBILITY
924bool
925operator> (const set<_Key, _Compare, _Allocator>& __x,
926 const set<_Key, _Compare, _Allocator>& __y)
927{
928 return __y < __x;
929}
930
931template <class _Key, class _Compare, class _Allocator>
932inline _LIBCPP_INLINE_VISIBILITY
933bool
934operator>=(const set<_Key, _Compare, _Allocator>& __x,
935 const set<_Key, _Compare, _Allocator>& __y)
936{
937 return !(__x < __y);
938}
939
940template <class _Key, class _Compare, class _Allocator>
941inline _LIBCPP_INLINE_VISIBILITY
942bool
943operator<=(const set<_Key, _Compare, _Allocator>& __x,
944 const set<_Key, _Compare, _Allocator>& __y)
945{
946 return !(__y < __x);
947}
948
949// specialized algorithms:
950template <class _Key, class _Compare, class _Allocator>
951inline _LIBCPP_INLINE_VISIBILITY
952void
953swap(set<_Key, _Compare, _Allocator>& __x,
954 set<_Key, _Compare, _Allocator>& __y)
955 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
956{
957 __x.swap(__y);
958}
959
960#if _LIBCPP_STD_VER > 17
961template <class _Key, class _Compare, class _Allocator, class _Predicate>
962inline _LIBCPP_INLINE_VISIBILITY
963void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
964{ __libcpp_erase_if_container(__c, __pred); }
965#endif
966
967template <class _Key, class _Compare = less<_Key>,
968 class _Allocator = allocator<_Key> >
969class _LIBCPP_TEMPLATE_VIS multiset
970{
971public:
972 // types:
973 typedef _Key key_type;
974 typedef key_type value_type;
975 typedef _Compare key_compare;
976 typedef key_compare value_compare;
977 typedef typename __identity<_Allocator>::type allocator_type;
978 typedef value_type& reference;
979 typedef const value_type& const_reference;
980
981 static_assert((is_same<typename allocator_type::value_type, value_type>::value),
982 "Allocator::value_type must be same type as value_type");
983
984private:
985 typedef __tree<value_type, value_compare, allocator_type> __base;
986 typedef allocator_traits<allocator_type> __alloc_traits;
987 typedef typename __base::__node_holder __node_holder;
988
989 __base __tree_;
990
991public:
992 typedef typename __base::pointer pointer;
993 typedef typename __base::const_pointer const_pointer;
994 typedef typename __base::size_type size_type;
995 typedef typename __base::difference_type difference_type;
996 typedef typename __base::const_iterator iterator;
997 typedef typename __base::const_iterator const_iterator;
998 typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
999 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
1000
1001#if _LIBCPP_STD_VER > 14
1002 typedef __set_node_handle<typename __base::__node, allocator_type> node_type;
1003#endif
1004
1005 template <class _Key2, class _Compare2, class _Alloc2>
1006 friend class _LIBCPP_TEMPLATE_VIS set;
1007 template <class _Key2, class _Compare2, class _Alloc2>
1008 friend class _LIBCPP_TEMPLATE_VIS multiset;
1009
1010 // construct/copy/destroy:
1011 _LIBCPP_INLINE_VISIBILITY
1012 multiset()
1013 _NOEXCEPT_(
1014 is_nothrow_default_constructible<allocator_type>::value &&
1015 is_nothrow_default_constructible<key_compare>::value &&
1016 is_nothrow_copy_constructible<key_compare>::value)
1017 : __tree_(value_compare()) {}
1018
1019 _LIBCPP_INLINE_VISIBILITY
1020 explicit multiset(const value_compare& __comp)
1021 _NOEXCEPT_(
1022 is_nothrow_default_constructible<allocator_type>::value &&
1023 is_nothrow_copy_constructible<key_compare>::value)
1024 : __tree_(__comp) {}
1025
1026 _LIBCPP_INLINE_VISIBILITY
1027 explicit multiset(const value_compare& __comp, const allocator_type& __a)
1028 : __tree_(__comp, __a) {}
1029 template <class _InputIterator>
1030 _LIBCPP_INLINE_VISIBILITY
1031 multiset(_InputIterator __f, _InputIterator __l,
1032 const value_compare& __comp = value_compare())
1033 : __tree_(__comp)
1034 {
1035 insert(__f, __l);
1036 }
1037
1038#if _LIBCPP_STD_VER > 11
1039 template <class _InputIterator>
1040 _LIBCPP_INLINE_VISIBILITY
1041 multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
1042 : multiset(__f, __l, key_compare(), __a) {}
1043#endif
1044
1045 template <class _InputIterator>
1046 _LIBCPP_INLINE_VISIBILITY
1047 multiset(_InputIterator __f, _InputIterator __l,
1048 const value_compare& __comp, const allocator_type& __a)
1049 : __tree_(__comp, __a)
1050 {
1051 insert(__f, __l);
1052 }
1053
1054 _LIBCPP_INLINE_VISIBILITY
1055 multiset(const multiset& __s)
1056 : __tree_(__s.__tree_.value_comp(),
1057 __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc()))
1058 {
1059 insert(__s.begin(), __s.end());
1060 }
1061
1062 _LIBCPP_INLINE_VISIBILITY
1063 multiset& operator=(const multiset& __s)
1064 {
1065 __tree_ = __s.__tree_;
1066 return *this;
1067 }
1068
1069#ifndef _LIBCPP_CXX03_LANG
1070 _LIBCPP_INLINE_VISIBILITY
1071 multiset(multiset&& __s)
1072 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1073 : __tree_(_VSTD::move(__s.__tree_)) {}
1074
1075 multiset(multiset&& __s, const allocator_type& __a);
1076#endif // _LIBCPP_CXX03_LANG
1077 _LIBCPP_INLINE_VISIBILITY
1078 explicit multiset(const allocator_type& __a)
1079 : __tree_(__a) {}
1080 _LIBCPP_INLINE_VISIBILITY
1081 multiset(const multiset& __s, const allocator_type& __a)
1082 : __tree_(__s.__tree_.value_comp(), __a)
1083 {
1084 insert(__s.begin(), __s.end());
1085 }
1086
1087#ifndef _LIBCPP_CXX03_LANG
1088 _LIBCPP_INLINE_VISIBILITY
1089 multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
1090 : __tree_(__comp)
1091 {
1092 insert(__il.begin(), __il.end());
1093 }
1094
1095 _LIBCPP_INLINE_VISIBILITY
1096 multiset(initializer_list<value_type> __il, const value_compare& __comp,
1097 const allocator_type& __a)
1098 : __tree_(__comp, __a)
1099 {
1100 insert(__il.begin(), __il.end());
1101 }
1102
1103#if _LIBCPP_STD_VER > 11
1104 _LIBCPP_INLINE_VISIBILITY
1105 multiset(initializer_list<value_type> __il, const allocator_type& __a)
1106 : multiset(__il, key_compare(), __a) {}
1107#endif
1108
1109 _LIBCPP_INLINE_VISIBILITY
1110 multiset& operator=(initializer_list<value_type> __il)
1111 {
1112 __tree_.__assign_multi(__il.begin(), __il.end());
1113 return *this;
1114 }
1115
1116 _LIBCPP_INLINE_VISIBILITY
1117 multiset& operator=(multiset&& __s)
1118 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
1119 {
1120 __tree_ = _VSTD::move(__s.__tree_);
1121 return *this;
1122 }
1123#endif // _LIBCPP_CXX03_LANG
1124
1125 _LIBCPP_INLINE_VISIBILITY
1126 ~multiset() {
1127 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), "");
1128 }
1129
1130 _LIBCPP_INLINE_VISIBILITY
1131 iterator begin() _NOEXCEPT {return __tree_.begin();}
1132 _LIBCPP_INLINE_VISIBILITY
1133 const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
1134 _LIBCPP_INLINE_VISIBILITY
1135 iterator end() _NOEXCEPT {return __tree_.end();}
1136 _LIBCPP_INLINE_VISIBILITY
1137 const_iterator end() const _NOEXCEPT {return __tree_.end();}
1138
1139 _LIBCPP_INLINE_VISIBILITY
1140 reverse_iterator rbegin() _NOEXCEPT
1141 {return reverse_iterator(end());}
1142 _LIBCPP_INLINE_VISIBILITY
1143 const_reverse_iterator rbegin() const _NOEXCEPT
1144 {return const_reverse_iterator(end());}
1145 _LIBCPP_INLINE_VISIBILITY
1146 reverse_iterator rend() _NOEXCEPT
1147 {return reverse_iterator(begin());}
1148 _LIBCPP_INLINE_VISIBILITY
1149 const_reverse_iterator rend() const _NOEXCEPT
1150 {return const_reverse_iterator(begin());}
1151
1152 _LIBCPP_INLINE_VISIBILITY
1153 const_iterator cbegin() const _NOEXCEPT {return begin();}
1154 _LIBCPP_INLINE_VISIBILITY
1155 const_iterator cend() const _NOEXCEPT {return end();}
1156 _LIBCPP_INLINE_VISIBILITY
1157 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
1158 _LIBCPP_INLINE_VISIBILITY
1159 const_reverse_iterator crend() const _NOEXCEPT {return rend();}
1160
1161 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1162 bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
1163 _LIBCPP_INLINE_VISIBILITY
1164 size_type size() const _NOEXCEPT {return __tree_.size();}
1165 _LIBCPP_INLINE_VISIBILITY
1166 size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
1167
1168 // modifiers:
1169#ifndef _LIBCPP_CXX03_LANG
1170 template <class... _Args>
1171 _LIBCPP_INLINE_VISIBILITY
1172 iterator emplace(_Args&&... __args)
1173 {return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}
1174 template <class... _Args>
1175 _LIBCPP_INLINE_VISIBILITY
1176 iterator emplace_hint(const_iterator __p, _Args&&... __args)
1177 {return __tree_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
1178#endif // _LIBCPP_CXX03_LANG
1179
1180 _LIBCPP_INLINE_VISIBILITY
1181 iterator insert(const value_type& __v)
1182 {return __tree_.__insert_multi(__v);}
1183 _LIBCPP_INLINE_VISIBILITY
1184 iterator insert(const_iterator __p, const value_type& __v)
1185 {return __tree_.__insert_multi(__p, __v);}
1186
1187 template <class _InputIterator>
1188 _LIBCPP_INLINE_VISIBILITY
1189 void insert(_InputIterator __f, _InputIterator __l)
1190 {
1191 for (const_iterator __e = cend(); __f != __l; ++__f)
1192 __tree_.__insert_multi(__e, *__f);
1193 }
1194
1195#ifndef _LIBCPP_CXX03_LANG
1196 _LIBCPP_INLINE_VISIBILITY
1197 iterator insert(value_type&& __v)
1198 {return __tree_.__insert_multi(_VSTD::move(__v));}
1199
1200 _LIBCPP_INLINE_VISIBILITY
1201 iterator insert(const_iterator __p, value_type&& __v)
1202 {return __tree_.__insert_multi(__p, _VSTD::move(__v));}
1203
1204 _LIBCPP_INLINE_VISIBILITY
1205 void insert(initializer_list<value_type> __il)
1206 {insert(__il.begin(), __il.end());}
1207#endif // _LIBCPP_CXX03_LANG
1208
1209 _LIBCPP_INLINE_VISIBILITY
1210 iterator erase(const_iterator __p) {return __tree_.erase(__p);}
1211 _LIBCPP_INLINE_VISIBILITY
1212 size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
1213 _LIBCPP_INLINE_VISIBILITY
1214 iterator erase(const_iterator __f, const_iterator __l)
1215 {return __tree_.erase(__f, __l);}
1216 _LIBCPP_INLINE_VISIBILITY
1217 void clear() _NOEXCEPT {__tree_.clear();}
1218
1219#if _LIBCPP_STD_VER > 14
1220 _LIBCPP_INLINE_VISIBILITY
1221 iterator insert(node_type&& __nh)
1222 {
1223 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1224 "node_type with incompatible allocator passed to multiset::insert()");
1225 return __tree_.template __node_handle_insert_multi<node_type>(
1226 _VSTD::move(__nh));
1227 }
1228 _LIBCPP_INLINE_VISIBILITY
1229 iterator insert(const_iterator __hint, node_type&& __nh)
1230 {
1231 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1232 "node_type with incompatible allocator passed to multiset::insert()");
1233 return __tree_.template __node_handle_insert_multi<node_type>(
1234 __hint, _VSTD::move(__nh));
1235 }
1236 _LIBCPP_INLINE_VISIBILITY
1237 node_type extract(key_type const& __key)
1238 {
1239 return __tree_.template __node_handle_extract<node_type>(__key);
1240 }
1241 _LIBCPP_INLINE_VISIBILITY
1242 node_type extract(const_iterator __it)
1243 {
1244 return __tree_.template __node_handle_extract<node_type>(__it);
1245 }
1246 template <class _Compare2>
1247 _LIBCPP_INLINE_VISIBILITY
1248 void merge(multiset<key_type, _Compare2, allocator_type>& __source)
1249 {
1250 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1251 "merging container with incompatible allocator");
1252 __tree_.__node_handle_merge_multi(__source.__tree_);
1253 }
1254 template <class _Compare2>
1255 _LIBCPP_INLINE_VISIBILITY
1256 void merge(multiset<key_type, _Compare2, allocator_type>&& __source)
1257 {
1258 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1259 "merging container with incompatible allocator");
1260 __tree_.__node_handle_merge_multi(__source.__tree_);
1261 }
1262 template <class _Compare2>
1263 _LIBCPP_INLINE_VISIBILITY
1264 void merge(set<key_type, _Compare2, allocator_type>& __source)
1265 {
1266 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1267 "merging container with incompatible allocator");
1268 __tree_.__node_handle_merge_multi(__source.__tree_);
1269 }
1270 template <class _Compare2>
1271 _LIBCPP_INLINE_VISIBILITY
1272 void merge(set<key_type, _Compare2, allocator_type>&& __source)
1273 {
1274 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1275 "merging container with incompatible allocator");
1276 __tree_.__node_handle_merge_multi(__source.__tree_);
1277 }
1278#endif
1279
1280 _LIBCPP_INLINE_VISIBILITY
1281 void swap(multiset& __s)
1282 _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
1283 {__tree_.swap(__s.__tree_);}
1284
1285 _LIBCPP_INLINE_VISIBILITY
1286 allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
1287 _LIBCPP_INLINE_VISIBILITY
1288 key_compare key_comp() const {return __tree_.value_comp();}
1289 _LIBCPP_INLINE_VISIBILITY
1290 value_compare value_comp() const {return __tree_.value_comp();}
1291
1292 // set operations:
1293 _LIBCPP_INLINE_VISIBILITY
1294 iterator find(const key_type& __k) {return __tree_.find(__k);}
1295 _LIBCPP_INLINE_VISIBILITY
1296 const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
1297#if _LIBCPP_STD_VER > 11
1298 template <typename _K2>
1299 _LIBCPP_INLINE_VISIBILITY
1300 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1301 find(const _K2& __k) {return __tree_.find(__k);}
1302 template <typename _K2>
1303 _LIBCPP_INLINE_VISIBILITY
1304 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1305 find(const _K2& __k) const {return __tree_.find(__k);}
1306#endif
1307
1308 _LIBCPP_INLINE_VISIBILITY
1309 size_type count(const key_type& __k) const
1310 {return __tree_.__count_multi(__k);}
1311#if _LIBCPP_STD_VER > 11
1312 template <typename _K2>
1313 _LIBCPP_INLINE_VISIBILITY
1314 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
1315 count(const _K2& __k) const {return __tree_.__count_multi(__k);}
1316#endif
1317
1318#if _LIBCPP_STD_VER > 17
1319 _LIBCPP_INLINE_VISIBILITY
1320 bool contains(const key_type& __k) const {return find(__k) != end();}
1321#endif // _LIBCPP_STD_VER > 17
1322
1323 _LIBCPP_INLINE_VISIBILITY
1324 iterator lower_bound(const key_type& __k)
1325 {return __tree_.lower_bound(__k);}
1326 _LIBCPP_INLINE_VISIBILITY
1327 const_iterator lower_bound(const key_type& __k) const
1328 {return __tree_.lower_bound(__k);}
1329#if _LIBCPP_STD_VER > 11
1330 template <typename _K2>
1331 _LIBCPP_INLINE_VISIBILITY
1332 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1333 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);}
1334
1335 template <typename _K2>
1336 _LIBCPP_INLINE_VISIBILITY
1337 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1338 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
1339#endif
1340
1341 _LIBCPP_INLINE_VISIBILITY
1342 iterator upper_bound(const key_type& __k)
1343 {return __tree_.upper_bound(__k);}
1344 _LIBCPP_INLINE_VISIBILITY
1345 const_iterator upper_bound(const key_type& __k) const
1346 {return __tree_.upper_bound(__k);}
1347#if _LIBCPP_STD_VER > 11
1348 template <typename _K2>
1349 _LIBCPP_INLINE_VISIBILITY
1350 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
1351 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);}
1352 template <typename _K2>
1353 _LIBCPP_INLINE_VISIBILITY
1354 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
1355 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
1356#endif
1357
1358 _LIBCPP_INLINE_VISIBILITY
1359 pair<iterator,iterator> equal_range(const key_type& __k)
1360 {return __tree_.__equal_range_multi(__k);}
1361 _LIBCPP_INLINE_VISIBILITY
1362 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
1363 {return __tree_.__equal_range_multi(__k);}
1364#if _LIBCPP_STD_VER > 11
1365 template <typename _K2>
1366 _LIBCPP_INLINE_VISIBILITY
1367 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
1368 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
1369 template <typename _K2>
1370 _LIBCPP_INLINE_VISIBILITY
1371 typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
1372 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
1373#endif
1374};
1375
1376#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1377template<class _InputIterator,
1378 class _Compare = less<typename iterator_traits<_InputIterator>::value_type>,
1379 class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>,
1380 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
1381 class = typename enable_if<!__is_allocator<_Compare>::value, void>::type>
1382multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())
1383 -> multiset<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>;
1384
1385template<class _Key, class _Compare = less<_Key>,
1386 class _Allocator = allocator<_Key>,
1387 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
1388 class = typename enable_if<!__is_allocator<_Compare>::value, void>::type>
1389multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator())
1390 -> multiset<_Key, _Compare, _Allocator>;
1391
1392template<class _InputIterator, class _Allocator,
1393 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type>
1394multiset(_InputIterator, _InputIterator, _Allocator)
1395 -> multiset<typename iterator_traits<_InputIterator>::value_type,
1396 less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>;
1397
1398template<class _Key, class _Allocator,
1399 class = typename enable_if<__is_allocator<_Allocator>::value, void>::type>
1400multiset(initializer_list<_Key>, _Allocator)
1401 -> multiset<_Key, less<_Key>, _Allocator>;
1402#endif
1403
1404#ifndef _LIBCPP_CXX03_LANG
1405
1406template <class _Key, class _Compare, class _Allocator>
1407multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
1408 : __tree_(_VSTD::move(__s.__tree_), __a)
1409{
1410 if (__a != __s.get_allocator())
1411 {
1412 const_iterator __e = cend();
1413 while (!__s.empty())
1414 insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));
1415 }
1416}
1417
1418#endif // _LIBCPP_CXX03_LANG
1419
1420template <class _Key, class _Compare, class _Allocator>
1421inline _LIBCPP_INLINE_VISIBILITY
1422bool
1423operator==(const multiset<_Key, _Compare, _Allocator>& __x,
1424 const multiset<_Key, _Compare, _Allocator>& __y)
1425{
1426 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
1427}
1428
1429template <class _Key, class _Compare, class _Allocator>
1430inline _LIBCPP_INLINE_VISIBILITY
1431bool
1432operator< (const multiset<_Key, _Compare, _Allocator>& __x,
1433 const multiset<_Key, _Compare, _Allocator>& __y)
1434{
1435 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
1436}
1437
1438template <class _Key, class _Compare, class _Allocator>
1439inline _LIBCPP_INLINE_VISIBILITY
1440bool
1441operator!=(const multiset<_Key, _Compare, _Allocator>& __x,
1442 const multiset<_Key, _Compare, _Allocator>& __y)
1443{
1444 return !(__x == __y);
1445}
1446
1447template <class _Key, class _Compare, class _Allocator>
1448inline _LIBCPP_INLINE_VISIBILITY
1449bool
1450operator> (const multiset<_Key, _Compare, _Allocator>& __x,
1451 const multiset<_Key, _Compare, _Allocator>& __y)
1452{
1453 return __y < __x;
1454}
1455
1456template <class _Key, class _Compare, class _Allocator>
1457inline _LIBCPP_INLINE_VISIBILITY
1458bool
1459operator>=(const multiset<_Key, _Compare, _Allocator>& __x,
1460 const multiset<_Key, _Compare, _Allocator>& __y)
1461{
1462 return !(__x < __y);
1463}
1464
1465template <class _Key, class _Compare, class _Allocator>
1466inline _LIBCPP_INLINE_VISIBILITY
1467bool
1468operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
1469 const multiset<_Key, _Compare, _Allocator>& __y)
1470{
1471 return !(__y < __x);
1472}
1473
1474template <class _Key, class _Compare, class _Allocator>
1475inline _LIBCPP_INLINE_VISIBILITY
1476void
1477swap(multiset<_Key, _Compare, _Allocator>& __x,
1478 multiset<_Key, _Compare, _Allocator>& __y)
1479 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1480{
1481 __x.swap(__y);
1482}
1483
1484#if _LIBCPP_STD_VER > 17
1485template <class _Key, class _Compare, class _Allocator, class _Predicate>
1486inline _LIBCPP_INLINE_VISIBILITY
1487void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
1488{ __libcpp_erase_if_container(__c, __pred); }
1489#endif
1490
1491_LIBCPP_END_NAMESPACE_STD
1492
1493#endif // _LIBCPP_SET
1494