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