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