• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18namespace std
19{
20
21template <class Key, class Compare = less<Key>,
22          class Allocator = allocator<Key>>
23class set
24{
25public:
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
183template <class Key, class Compare, class Allocator>
184bool
185operator==(const set<Key, Compare, Allocator>& x,
186           const set<Key, Compare, Allocator>& y);
187
188template <class Key, class Compare, class Allocator>
189bool
190operator< (const set<Key, Compare, Allocator>& x,
191           const set<Key, Compare, Allocator>& y);
192
193template <class Key, class Compare, class Allocator>
194bool
195operator!=(const set<Key, Compare, Allocator>& x,
196           const set<Key, Compare, Allocator>& y);
197
198template <class Key, class Compare, class Allocator>
199bool
200operator> (const set<Key, Compare, Allocator>& x,
201           const set<Key, Compare, Allocator>& y);
202
203template <class Key, class Compare, class Allocator>
204bool
205operator>=(const set<Key, Compare, Allocator>& x,
206           const set<Key, Compare, Allocator>& y);
207
208template <class Key, class Compare, class Allocator>
209bool
210operator<=(const set<Key, Compare, Allocator>& x,
211           const set<Key, Compare, Allocator>& y);
212
213// specialized algorithms:
214template <class Key, class Compare, class Allocator>
215void
216swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
217    noexcept(noexcept(x.swap(y)));
218
219template <class Key, class Compare, class Allocator, class Predicate>
220  void erase_if(set<Key, Compare, Allocator>& c, Predicate pred);  // C++20
221
222template <class Key, class Compare = less<Key>,
223          class Allocator = allocator<Key>>
224class multiset
225{
226public:
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
382template <class Key, class Compare, class Allocator>
383bool
384operator==(const multiset<Key, Compare, Allocator>& x,
385           const multiset<Key, Compare, Allocator>& y);
386
387template <class Key, class Compare, class Allocator>
388bool
389operator< (const multiset<Key, Compare, Allocator>& x,
390           const multiset<Key, Compare, Allocator>& y);
391
392template <class Key, class Compare, class Allocator>
393bool
394operator!=(const multiset<Key, Compare, Allocator>& x,
395           const multiset<Key, Compare, Allocator>& y);
396
397template <class Key, class Compare, class Allocator>
398bool
399operator> (const multiset<Key, Compare, Allocator>& x,
400           const multiset<Key, Compare, Allocator>& y);
401
402template <class Key, class Compare, class Allocator>
403bool
404operator>=(const multiset<Key, Compare, Allocator>& x,
405           const multiset<Key, Compare, Allocator>& y);
406
407template <class Key, class Compare, class Allocator>
408bool
409operator<=(const multiset<Key, Compare, Allocator>& x,
410           const multiset<Key, Compare, Allocator>& y);
411
412// specialized algorithms:
413template <class Key, class Compare, class Allocator>
414void
415swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
416    noexcept(noexcept(x.swap(y)));
417
418template <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
437template <class _Key, class _Compare, class _Allocator>
438class multiset;
439
440template <class _Key, class _Compare = less<_Key>,
441          class _Allocator = allocator<_Key> >
442class _LIBCPP_TEMPLATE_VIS set
443{
444public:
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
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          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
842template <class _Key, class _Compare, class _Allocator>
843set<_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
856template <class _Key, class _Compare, class _Allocator>
857inline _LIBCPP_INLINE_VISIBILITY
858bool
859operator==(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
865template <class _Key, class _Compare, class _Allocator>
866inline _LIBCPP_INLINE_VISIBILITY
867bool
868operator< (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
874template <class _Key, class _Compare, class _Allocator>
875inline _LIBCPP_INLINE_VISIBILITY
876bool
877operator!=(const set<_Key, _Compare, _Allocator>& __x,
878           const set<_Key, _Compare, _Allocator>& __y)
879{
880    return !(__x == __y);
881}
882
883template <class _Key, class _Compare, class _Allocator>
884inline _LIBCPP_INLINE_VISIBILITY
885bool
886operator> (const set<_Key, _Compare, _Allocator>& __x,
887           const set<_Key, _Compare, _Allocator>& __y)
888{
889    return __y < __x;
890}
891
892template <class _Key, class _Compare, class _Allocator>
893inline _LIBCPP_INLINE_VISIBILITY
894bool
895operator>=(const set<_Key, _Compare, _Allocator>& __x,
896           const set<_Key, _Compare, _Allocator>& __y)
897{
898    return !(__x < __y);
899}
900
901template <class _Key, class _Compare, class _Allocator>
902inline _LIBCPP_INLINE_VISIBILITY
903bool
904operator<=(const set<_Key, _Compare, _Allocator>& __x,
905           const set<_Key, _Compare, _Allocator>& __y)
906{
907    return !(__y < __x);
908}
909
910// specialized algorithms:
911template <class _Key, class _Compare, class _Allocator>
912inline _LIBCPP_INLINE_VISIBILITY
913void
914swap(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
922template <class _Key, class _Compare, class _Allocator, class _Predicate>
923inline _LIBCPP_INLINE_VISIBILITY
924void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
925{ __libcpp_erase_if_container(__c, __pred); }
926#endif
927
928template <class _Key, class _Compare = less<_Key>,
929          class _Allocator = allocator<_Key> >
930class _LIBCPP_TEMPLATE_VIS multiset
931{
932public:
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
946private:
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
953public:
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
1330template <class _Key, class _Compare, class _Allocator>
1331multiset<_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
1344template <class _Key, class _Compare, class _Allocator>
1345inline _LIBCPP_INLINE_VISIBILITY
1346bool
1347operator==(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
1353template <class _Key, class _Compare, class _Allocator>
1354inline _LIBCPP_INLINE_VISIBILITY
1355bool
1356operator< (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
1362template <class _Key, class _Compare, class _Allocator>
1363inline _LIBCPP_INLINE_VISIBILITY
1364bool
1365operator!=(const multiset<_Key, _Compare, _Allocator>& __x,
1366           const multiset<_Key, _Compare, _Allocator>& __y)
1367{
1368    return !(__x == __y);
1369}
1370
1371template <class _Key, class _Compare, class _Allocator>
1372inline _LIBCPP_INLINE_VISIBILITY
1373bool
1374operator> (const multiset<_Key, _Compare, _Allocator>& __x,
1375           const multiset<_Key, _Compare, _Allocator>& __y)
1376{
1377    return __y < __x;
1378}
1379
1380template <class _Key, class _Compare, class _Allocator>
1381inline _LIBCPP_INLINE_VISIBILITY
1382bool
1383operator>=(const multiset<_Key, _Compare, _Allocator>& __x,
1384           const multiset<_Key, _Compare, _Allocator>& __y)
1385{
1386    return !(__x < __y);
1387}
1388
1389template <class _Key, class _Compare, class _Allocator>
1390inline _LIBCPP_INLINE_VISIBILITY
1391bool
1392operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
1393           const multiset<_Key, _Compare, _Allocator>& __y)
1394{
1395    return !(__y < __x);
1396}
1397
1398template <class _Key, class _Compare, class _Allocator>
1399inline _LIBCPP_INLINE_VISIBILITY
1400void
1401swap(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
1409template <class _Key, class _Compare, class _Allocator, class _Predicate>
1410inline _LIBCPP_INLINE_VISIBILITY
1411void 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
1418