1// -*- C++ -*-
2//===-------------------------- unordered_set -----------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_UNORDERED_SET
11#define _LIBCPP_UNORDERED_SET
12
13/*
14
15    unordered_set synopsis
16
17#include <initializer_list>
18
19namespace std
20{
21
22template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
23          class Alloc = allocator<Value>>
24class unordered_set
25{
26public:
27    // types
28    typedef Value                                                      key_type;
29    typedef key_type                                                   value_type;
30    typedef Hash                                                       hasher;
31    typedef Pred                                                       key_equal;
32    typedef Alloc                                                      allocator_type;
33    typedef value_type&                                                reference;
34    typedef const value_type&                                          const_reference;
35    typedef typename allocator_traits<allocator_type>::pointer         pointer;
36    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
37    typedef typename allocator_traits<allocator_type>::size_type       size_type;
38    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
39
40    typedef /unspecified/ iterator;
41    typedef /unspecified/ const_iterator;
42    typedef /unspecified/ local_iterator;
43    typedef /unspecified/ const_local_iterator;
44
45    typedef unspecified node_type unspecified;                            // C++17
46    typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type;   // C++17
47
48    unordered_set()
49        noexcept(
50            is_nothrow_default_constructible<hasher>::value &&
51            is_nothrow_default_constructible<key_equal>::value &&
52            is_nothrow_default_constructible<allocator_type>::value);
53    explicit unordered_set(size_type n, const hasher& hf = hasher(),
54                           const key_equal& eql = key_equal(),
55                           const allocator_type& a = allocator_type());
56    template <class InputIterator>
57        unordered_set(InputIterator f, InputIterator l,
58                      size_type n = 0, const hasher& hf = hasher(),
59                      const key_equal& eql = key_equal(),
60                      const allocator_type& a = allocator_type());
61    explicit unordered_set(const allocator_type&);
62    unordered_set(const unordered_set&);
63    unordered_set(const unordered_set&, const Allocator&);
64    unordered_set(unordered_set&&)
65        noexcept(
66            is_nothrow_move_constructible<hasher>::value &&
67            is_nothrow_move_constructible<key_equal>::value &&
68            is_nothrow_move_constructible<allocator_type>::value);
69    unordered_set(unordered_set&&, const Allocator&);
70    unordered_set(initializer_list<value_type>, size_type n = 0,
71                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
72                  const allocator_type& a = allocator_type());
73    unordered_set(size_type n, const allocator_type& a); // C++14
74    unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14
75    template <class InputIterator>
76      unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
77    template <class InputIterator>
78      unordered_set(InputIterator f, InputIterator l, size_type n,
79                    const hasher& hf,  const allocator_type& a); // C++14
80    unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
81    unordered_set(initializer_list<value_type> il, size_type n,
82                  const hasher& hf,  const allocator_type& a); // C++14
83    ~unordered_set();
84    unordered_set& operator=(const unordered_set&);
85    unordered_set& operator=(unordered_set&&)
86        noexcept(
87            allocator_type::propagate_on_container_move_assignment::value &&
88            is_nothrow_move_assignable<allocator_type>::value &&
89            is_nothrow_move_assignable<hasher>::value &&
90            is_nothrow_move_assignable<key_equal>::value);
91    unordered_set& operator=(initializer_list<value_type>);
92
93    allocator_type get_allocator() const noexcept;
94
95    bool      empty() const noexcept;
96    size_type size() const noexcept;
97    size_type max_size() const noexcept;
98
99    iterator       begin() noexcept;
100    iterator       end() noexcept;
101    const_iterator begin()  const noexcept;
102    const_iterator end()    const noexcept;
103    const_iterator cbegin() const noexcept;
104    const_iterator cend()   const noexcept;
105
106    template <class... Args>
107        pair<iterator, bool> emplace(Args&&... args);
108    template <class... Args>
109        iterator emplace_hint(const_iterator position, Args&&... args);
110    pair<iterator, bool> insert(const value_type& obj);
111    pair<iterator, bool> insert(value_type&& obj);
112    iterator insert(const_iterator hint, const value_type& obj);
113    iterator insert(const_iterator hint, value_type&& obj);
114    template <class InputIterator>
115        void insert(InputIterator first, InputIterator last);
116    void insert(initializer_list<value_type>);
117
118    node_type extract(const_iterator position);                       // C++17
119    node_type extract(const key_type& x);                             // C++17
120    insert_return_type insert(node_type&& nh);                        // C++17
121    iterator           insert(const_iterator hint, node_type&& nh);   // C++17
122
123    iterator erase(const_iterator position);
124    iterator erase(iterator position);  // C++14
125    size_type erase(const key_type& k);
126    iterator erase(const_iterator first, const_iterator last);
127    void clear() noexcept;
128
129    template<class H2, class P2>
130      void merge(unordered_set<Key, H2, P2, Allocator>& source);         // C++17
131    template<class H2, class P2>
132      void merge(unordered_set<Key, H2, P2, Allocator>&& source);        // C++17
133    template<class H2, class P2>
134      void merge(unordered_multiset<Key, H2, P2, Allocator>& source);    // C++17
135    template<class H2, class P2>
136      void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);   // C++17
137
138    void swap(unordered_set&)
139       noexcept(allocator_traits<Allocator>::is_always_equal::value &&
140                 noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
141                 noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
142
143    hasher hash_function() const;
144    key_equal key_eq() const;
145
146    iterator       find(const key_type& k);
147    const_iterator find(const key_type& k) const;
148    template<typename K>
149        iterator find(const K& x);              // C++20
150    template<typename K>
151        const_iterator find(const K& x) const;  // C++20
152    size_type count(const key_type& k) const;
153    template<typename K>
154        size_type count(const K& k) const; // C++20
155    bool contains(const key_type& k) const; // C++20
156    template<typename K>
157        bool contains(const K& k) const; // C++20
158    pair<iterator, iterator>             equal_range(const key_type& k);
159    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
160    template<typename K>
161        pair<iterator, iterator>             equal_range(const K& k); // C++20
162    template<typename K>
163        pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20
164
165    size_type bucket_count() const noexcept;
166    size_type max_bucket_count() const noexcept;
167
168    size_type bucket_size(size_type n) const;
169    size_type bucket(const key_type& k) const;
170
171    local_iterator       begin(size_type n);
172    local_iterator       end(size_type n);
173    const_local_iterator begin(size_type n) const;
174    const_local_iterator end(size_type n) const;
175    const_local_iterator cbegin(size_type n) const;
176    const_local_iterator cend(size_type n) const;
177
178    float load_factor() const noexcept;
179    float max_load_factor() const noexcept;
180    void max_load_factor(float z);
181    void rehash(size_type n);
182    void reserve(size_type n);
183};
184
185template <class Value, class Hash, class Pred, class Alloc>
186    void swap(unordered_set<Value, Hash, Pred, Alloc>& x,
187              unordered_set<Value, Hash, Pred, Alloc>& y)
188              noexcept(noexcept(x.swap(y)));
189
190template <class Value, class Hash, class Pred, class Alloc>
191    bool
192    operator==(const unordered_set<Value, Hash, Pred, Alloc>& x,
193               const unordered_set<Value, Hash, Pred, Alloc>& y);
194
195template <class Value, class Hash, class Pred, class Alloc>
196    bool
197    operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,
198               const unordered_set<Value, Hash, Pred, Alloc>& y);
199
200template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
201          class Alloc = allocator<Value>>
202class unordered_multiset
203{
204public:
205    // types
206    typedef Value                                                      key_type;
207    typedef key_type                                                   value_type;
208    typedef Hash                                                       hasher;
209    typedef Pred                                                       key_equal;
210    typedef Alloc                                                      allocator_type;
211    typedef value_type&                                                reference;
212    typedef const value_type&                                          const_reference;
213    typedef typename allocator_traits<allocator_type>::pointer         pointer;
214    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
215    typedef typename allocator_traits<allocator_type>::size_type       size_type;
216    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
217
218    typedef /unspecified/ iterator;
219    typedef /unspecified/ const_iterator;
220    typedef /unspecified/ local_iterator;
221    typedef /unspecified/ const_local_iterator;
222
223    typedef unspecified node_type unspecified;   // C++17
224
225    unordered_multiset()
226        noexcept(
227            is_nothrow_default_constructible<hasher>::value &&
228            is_nothrow_default_constructible<key_equal>::value &&
229            is_nothrow_default_constructible<allocator_type>::value);
230    explicit unordered_multiset(size_type n, const hasher& hf = hasher(),
231                           const key_equal& eql = key_equal(),
232                           const allocator_type& a = allocator_type());
233    template <class InputIterator>
234        unordered_multiset(InputIterator f, InputIterator l,
235                      size_type n = 0, const hasher& hf = hasher(),
236                      const key_equal& eql = key_equal(),
237                      const allocator_type& a = allocator_type());
238    explicit unordered_multiset(const allocator_type&);
239    unordered_multiset(const unordered_multiset&);
240    unordered_multiset(const unordered_multiset&, const Allocator&);
241    unordered_multiset(unordered_multiset&&)
242        noexcept(
243            is_nothrow_move_constructible<hasher>::value &&
244            is_nothrow_move_constructible<key_equal>::value &&
245            is_nothrow_move_constructible<allocator_type>::value);
246    unordered_multiset(unordered_multiset&&, const Allocator&);
247    unordered_multiset(initializer_list<value_type>, size_type n = /see below/,
248                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
249                  const allocator_type& a = allocator_type());
250    unordered_multiset(size_type n, const allocator_type& a); // C++14
251    unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14
252    template <class InputIterator>
253      unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
254    template <class InputIterator>
255      unordered_multiset(InputIterator f, InputIterator l, size_type n,
256                         const hasher& hf, const allocator_type& a); // C++14
257    unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
258    unordered_multiset(initializer_list<value_type> il, size_type n,
259                       const hasher& hf,  const allocator_type& a); // C++14
260    ~unordered_multiset();
261    unordered_multiset& operator=(const unordered_multiset&);
262    unordered_multiset& operator=(unordered_multiset&&)
263        noexcept(
264            allocator_type::propagate_on_container_move_assignment::value &&
265            is_nothrow_move_assignable<allocator_type>::value &&
266            is_nothrow_move_assignable<hasher>::value &&
267            is_nothrow_move_assignable<key_equal>::value);
268    unordered_multiset& operator=(initializer_list<value_type>);
269
270    allocator_type get_allocator() const noexcept;
271
272    bool      empty() const noexcept;
273    size_type size() const noexcept;
274    size_type max_size() const noexcept;
275
276    iterator       begin() noexcept;
277    iterator       end() noexcept;
278    const_iterator begin()  const noexcept;
279    const_iterator end()    const noexcept;
280    const_iterator cbegin() const noexcept;
281    const_iterator cend()   const noexcept;
282
283    template <class... Args>
284        iterator emplace(Args&&... args);
285    template <class... Args>
286        iterator emplace_hint(const_iterator position, Args&&... args);
287    iterator insert(const value_type& obj);
288    iterator insert(value_type&& obj);
289    iterator insert(const_iterator hint, const value_type& obj);
290    iterator insert(const_iterator hint, value_type&& obj);
291    template <class InputIterator>
292        void insert(InputIterator first, InputIterator last);
293    void insert(initializer_list<value_type>);
294
295    node_type extract(const_iterator position);             // C++17
296    node_type extract(const key_type& x);                   // C++17
297    iterator insert(node_type&& nh);                        // C++17
298    iterator insert(const_iterator hint, node_type&& nh);   // C++17
299
300    iterator erase(const_iterator position);
301    iterator erase(iterator position);  // C++14
302    size_type erase(const key_type& k);
303    iterator erase(const_iterator first, const_iterator last);
304    void clear() noexcept;
305
306    template<class H2, class P2>
307      void merge(unordered_multiset<Key, H2, P2, Allocator>& source);    // C++17
308    template<class H2, class P2>
309      void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);   // C++17
310    template<class H2, class P2>
311      void merge(unordered_set<Key, H2, P2, Allocator>& source);         // C++17
312    template<class H2, class P2>
313      void merge(unordered_set<Key, H2, P2, Allocator>&& source);        // C++17
314
315    void swap(unordered_multiset&)
316       noexcept(allocator_traits<Allocator>::is_always_equal::value &&
317                 noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
318                 noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
319
320    hasher hash_function() const;
321    key_equal key_eq() const;
322
323    iterator       find(const key_type& k);
324    const_iterator find(const key_type& k) const;
325    template<typename K>
326        iterator find(const K& x);              // C++20
327    template<typename K>
328        const_iterator find(const K& x) const;  // C++20
329    size_type count(const key_type& k) const;
330    template<typename K>
331        size_type count(const K& k) const; // C++20
332    bool contains(const key_type& k) const; // C++20
333    template<typename K>
334        bool contains(const K& k) const; // C++20
335    pair<iterator, iterator>             equal_range(const key_type& k);
336    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
337    template<typename K>
338        pair<iterator, iterator>             equal_range(const K& k); // C++20
339    template<typename K>
340        pair<const_iterator, const_iterator> equal_range(const K& k) const; // C++20
341
342    size_type bucket_count() const noexcept;
343    size_type max_bucket_count() const noexcept;
344
345    size_type bucket_size(size_type n) const;
346    size_type bucket(const key_type& k) const;
347
348    local_iterator       begin(size_type n);
349    local_iterator       end(size_type n);
350    const_local_iterator begin(size_type n) const;
351    const_local_iterator end(size_type n) const;
352    const_local_iterator cbegin(size_type n) const;
353    const_local_iterator cend(size_type n) const;
354
355    float load_factor() const noexcept;
356    float max_load_factor() const noexcept;
357    void max_load_factor(float z);
358    void rehash(size_type n);
359    void reserve(size_type n);
360};
361
362template <class Value, class Hash, class Pred, class Alloc>
363    void swap(unordered_multiset<Value, Hash, Pred, Alloc>& x,
364              unordered_multiset<Value, Hash, Pred, Alloc>& y)
365              noexcept(noexcept(x.swap(y)));
366
367template <class K, class T, class H, class P, class A, class Predicate>
368    typename unordered_set<K, T, H, P, A>::size_type
369    erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred);       // C++20
370
371template <class K, class T, class H, class P, class A, class Predicate>
372    typename unordered_multiset<K, T, H, P, A>::size_type
373    erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred);  // C++20
374
375
376template <class Value, class Hash, class Pred, class Alloc>
377    bool
378    operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
379               const unordered_multiset<Value, Hash, Pred, Alloc>& y);
380
381template <class Value, class Hash, class Pred, class Alloc>
382    bool
383    operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
384               const unordered_multiset<Value, Hash, Pred, Alloc>& y);
385}  // std
386
387*/
388
389#include <__config>
390#include <__debug>
391#include <__functional/is_transparent.h>
392#include <__hash_table>
393#include <__node_handle>
394#include <__utility/forward.h>
395#include <compare>
396#include <functional>
397#include <iterator> // __libcpp_erase_if_container
398#include <version>
399
400#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
401#pragma GCC system_header
402#endif
403
404_LIBCPP_BEGIN_NAMESPACE_STD
405
406template <class _Value, class _Hash, class _Pred, class _Alloc>
407class unordered_multiset;
408
409template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
410          class _Alloc = allocator<_Value> >
411class _LIBCPP_TEMPLATE_VIS unordered_set
412{
413public:
414    // types
415    typedef _Value                                                     key_type;
416    typedef key_type                                                   value_type;
417    typedef __identity_t<_Hash>                                        hasher;
418    typedef __identity_t<_Pred>                                        key_equal;
419    typedef __identity_t<_Alloc>                                       allocator_type;
420    typedef value_type&                                                reference;
421    typedef const value_type&                                          const_reference;
422    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
423                  "Invalid allocator::value_type");
424
425private:
426    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
427
428    __table __table_;
429
430public:
431    typedef typename __table::pointer         pointer;
432    typedef typename __table::const_pointer   const_pointer;
433    typedef typename __table::size_type       size_type;
434    typedef typename __table::difference_type difference_type;
435
436    typedef typename __table::const_iterator       iterator;
437    typedef typename __table::const_iterator       const_iterator;
438    typedef typename __table::const_local_iterator local_iterator;
439    typedef typename __table::const_local_iterator const_local_iterator;
440
441#if _LIBCPP_STD_VER > 14
442    typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
443    typedef __insert_return_type<iterator, node_type> insert_return_type;
444#endif
445
446    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
447        friend class _LIBCPP_TEMPLATE_VIS unordered_set;
448    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
449        friend class _LIBCPP_TEMPLATE_VIS unordered_multiset;
450
451    _LIBCPP_INLINE_VISIBILITY
452    unordered_set()
453        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
454        {
455#if _LIBCPP_DEBUG_LEVEL == 2
456            __get_db()->__insert_c(this);
457#endif
458        }
459    explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
460                           const key_equal& __eql = key_equal());
461#if _LIBCPP_STD_VER > 11
462    inline _LIBCPP_INLINE_VISIBILITY
463    unordered_set(size_type __n, const allocator_type& __a)
464        : unordered_set(__n, hasher(), key_equal(), __a) {}
465    inline _LIBCPP_INLINE_VISIBILITY
466    unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)
467        : unordered_set(__n, __hf, key_equal(), __a) {}
468#endif
469    unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
470                  const allocator_type& __a);
471    template <class _InputIterator>
472        unordered_set(_InputIterator __first, _InputIterator __last);
473    template <class _InputIterator>
474        unordered_set(_InputIterator __first, _InputIterator __last,
475                      size_type __n, const hasher& __hf = hasher(),
476                      const key_equal& __eql = key_equal());
477    template <class _InputIterator>
478        unordered_set(_InputIterator __first, _InputIterator __last,
479                      size_type __n, const hasher& __hf, const key_equal& __eql,
480                      const allocator_type& __a);
481#if _LIBCPP_STD_VER > 11
482    template <class _InputIterator>
483    inline _LIBCPP_INLINE_VISIBILITY
484        unordered_set(_InputIterator __first, _InputIterator __last,
485                    size_type __n, const allocator_type& __a)
486            : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}
487    template <class _InputIterator>
488        unordered_set(_InputIterator __first, _InputIterator __last,
489                      size_type __n, const hasher& __hf, const allocator_type& __a)
490            : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}
491#endif
492    _LIBCPP_INLINE_VISIBILITY
493    explicit unordered_set(const allocator_type& __a);
494    unordered_set(const unordered_set& __u);
495    unordered_set(const unordered_set& __u, const allocator_type& __a);
496#ifndef _LIBCPP_CXX03_LANG
497    _LIBCPP_INLINE_VISIBILITY
498    unordered_set(unordered_set&& __u)
499        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
500    unordered_set(unordered_set&& __u, const allocator_type& __a);
501    unordered_set(initializer_list<value_type> __il);
502    unordered_set(initializer_list<value_type> __il, size_type __n,
503                  const hasher& __hf = hasher(),
504                  const key_equal& __eql = key_equal());
505    unordered_set(initializer_list<value_type> __il, size_type __n,
506                  const hasher& __hf, const key_equal& __eql,
507                  const allocator_type& __a);
508#if _LIBCPP_STD_VER > 11
509    inline _LIBCPP_INLINE_VISIBILITY
510    unordered_set(initializer_list<value_type> __il, size_type __n,
511                                                      const allocator_type& __a)
512        : unordered_set(__il, __n, hasher(), key_equal(), __a) {}
513    inline _LIBCPP_INLINE_VISIBILITY
514    unordered_set(initializer_list<value_type> __il, size_type __n,
515                                  const hasher& __hf, const allocator_type& __a)
516        : unordered_set(__il, __n, __hf, key_equal(), __a) {}
517#endif
518#endif // _LIBCPP_CXX03_LANG
519    _LIBCPP_INLINE_VISIBILITY
520    ~unordered_set() {
521        static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
522    }
523
524    _LIBCPP_INLINE_VISIBILITY
525    unordered_set& operator=(const unordered_set& __u)
526    {
527        __table_ = __u.__table_;
528        return *this;
529    }
530#ifndef _LIBCPP_CXX03_LANG
531    _LIBCPP_INLINE_VISIBILITY
532    unordered_set& operator=(unordered_set&& __u)
533        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
534    _LIBCPP_INLINE_VISIBILITY
535    unordered_set& operator=(initializer_list<value_type> __il);
536#endif // _LIBCPP_CXX03_LANG
537
538    _LIBCPP_INLINE_VISIBILITY
539    allocator_type get_allocator() const _NOEXCEPT
540        {return allocator_type(__table_.__node_alloc());}
541
542    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
543    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
544    _LIBCPP_INLINE_VISIBILITY
545    size_type size() const _NOEXCEPT  {return __table_.size();}
546    _LIBCPP_INLINE_VISIBILITY
547    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
548
549    _LIBCPP_INLINE_VISIBILITY
550    iterator       begin() _NOEXCEPT        {return __table_.begin();}
551    _LIBCPP_INLINE_VISIBILITY
552    iterator       end() _NOEXCEPT          {return __table_.end();}
553    _LIBCPP_INLINE_VISIBILITY
554    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
555    _LIBCPP_INLINE_VISIBILITY
556    const_iterator end()    const _NOEXCEPT {return __table_.end();}
557    _LIBCPP_INLINE_VISIBILITY
558    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
559    _LIBCPP_INLINE_VISIBILITY
560    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
561
562#ifndef _LIBCPP_CXX03_LANG
563    template <class... _Args>
564        _LIBCPP_INLINE_VISIBILITY
565        pair<iterator, bool> emplace(_Args&&... __args)
566            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
567    template <class... _Args>
568        _LIBCPP_INLINE_VISIBILITY
569#if _LIBCPP_DEBUG_LEVEL == 2
570        iterator emplace_hint(const_iterator __p, _Args&&... __args)
571        {
572            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
573                "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
574                " referring to this unordered_set");
575            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
576        }
577#else
578        iterator emplace_hint(const_iterator, _Args&&... __args)
579            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}
580#endif
581
582    _LIBCPP_INLINE_VISIBILITY
583    pair<iterator, bool> insert(value_type&& __x)
584        {return __table_.__insert_unique(_VSTD::move(__x));}
585    _LIBCPP_INLINE_VISIBILITY
586#if _LIBCPP_DEBUG_LEVEL == 2
587    iterator insert(const_iterator __p, value_type&& __x)
588        {
589            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
590                "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
591                " referring to this unordered_set");
592            return insert(_VSTD::move(__x)).first;
593        }
594#else
595    iterator insert(const_iterator, value_type&& __x)
596        {return insert(_VSTD::move(__x)).first;}
597#endif
598    _LIBCPP_INLINE_VISIBILITY
599    void insert(initializer_list<value_type> __il)
600        {insert(__il.begin(), __il.end());}
601#endif // _LIBCPP_CXX03_LANG
602    _LIBCPP_INLINE_VISIBILITY
603    pair<iterator, bool> insert(const value_type& __x)
604        {return __table_.__insert_unique(__x);}
605
606    _LIBCPP_INLINE_VISIBILITY
607#if _LIBCPP_DEBUG_LEVEL == 2
608    iterator insert(const_iterator __p, const value_type& __x)
609        {
610            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
611                "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
612                " referring to this unordered_set");
613            return insert(__x).first;
614        }
615#else
616    iterator insert(const_iterator, const value_type& __x)
617        {return insert(__x).first;}
618#endif
619    template <class _InputIterator>
620        _LIBCPP_INLINE_VISIBILITY
621        void insert(_InputIterator __first, _InputIterator __last);
622
623    _LIBCPP_INLINE_VISIBILITY
624    iterator erase(const_iterator __p) {return __table_.erase(__p);}
625    _LIBCPP_INLINE_VISIBILITY
626    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
627    _LIBCPP_INLINE_VISIBILITY
628    iterator erase(const_iterator __first, const_iterator __last)
629        {return __table_.erase(__first, __last);}
630    _LIBCPP_INLINE_VISIBILITY
631    void clear() _NOEXCEPT {__table_.clear();}
632
633#if _LIBCPP_STD_VER > 14
634    _LIBCPP_INLINE_VISIBILITY
635    insert_return_type insert(node_type&& __nh)
636    {
637        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
638            "node_type with incompatible allocator passed to unordered_set::insert()");
639        return __table_.template __node_handle_insert_unique<
640            node_type, insert_return_type>(_VSTD::move(__nh));
641    }
642    _LIBCPP_INLINE_VISIBILITY
643    iterator insert(const_iterator __h, node_type&& __nh)
644    {
645        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
646            "node_type with incompatible allocator passed to unordered_set::insert()");
647        return __table_.template __node_handle_insert_unique<node_type>(
648            __h, _VSTD::move(__nh));
649    }
650    _LIBCPP_INLINE_VISIBILITY
651    node_type extract(key_type const& __key)
652    {
653        return __table_.template __node_handle_extract<node_type>(__key);
654    }
655    _LIBCPP_INLINE_VISIBILITY
656    node_type extract(const_iterator __it)
657    {
658        return __table_.template __node_handle_extract<node_type>(__it);
659    }
660
661    template<class _H2, class _P2>
662    _LIBCPP_INLINE_VISIBILITY
663    void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
664    {
665        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
666                       "merging container with incompatible allocator");
667        __table_.__node_handle_merge_unique(__source.__table_);
668    }
669    template<class _H2, class _P2>
670    _LIBCPP_INLINE_VISIBILITY
671    void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
672    {
673        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
674                       "merging container with incompatible allocator");
675        __table_.__node_handle_merge_unique(__source.__table_);
676    }
677    template<class _H2, class _P2>
678    _LIBCPP_INLINE_VISIBILITY
679    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
680    {
681        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
682                       "merging container with incompatible allocator");
683        __table_.__node_handle_merge_unique(__source.__table_);
684    }
685    template<class _H2, class _P2>
686    _LIBCPP_INLINE_VISIBILITY
687    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
688    {
689        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
690                       "merging container with incompatible allocator");
691        __table_.__node_handle_merge_unique(__source.__table_);
692    }
693#endif
694
695    _LIBCPP_INLINE_VISIBILITY
696    void swap(unordered_set& __u)
697        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
698        {__table_.swap(__u.__table_);}
699
700    _LIBCPP_INLINE_VISIBILITY
701    hasher hash_function() const {return __table_.hash_function();}
702    _LIBCPP_INLINE_VISIBILITY
703    key_equal key_eq() const {return __table_.key_eq();}
704
705    _LIBCPP_INLINE_VISIBILITY
706    iterator       find(const key_type& __k)       {return __table_.find(__k);}
707    _LIBCPP_INLINE_VISIBILITY
708    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
709    #if _LIBCPP_STD_VER > 17
710        template <typename _K2>
711        _LIBCPP_INLINE_VISIBILITY
712        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator>
713        find(const _K2& __k)       {return __table_.find(__k);}
714        template <typename _K2>
715        _LIBCPP_INLINE_VISIBILITY
716        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator>
717        find(const _K2& __k) const {return __table_.find(__k);}
718    #endif // _LIBCPP_STD_VER > 17
719    _LIBCPP_INLINE_VISIBILITY
720    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
721    #if _LIBCPP_STD_VER > 17
722        template <typename _K2>
723        _LIBCPP_INLINE_VISIBILITY
724        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type>
725        count(const _K2& __k) const {return __table_.__count_unique(__k);}
726    #endif // _LIBCPP_STD_VER > 17
727    #if _LIBCPP_STD_VER > 17
728        _LIBCPP_INLINE_VISIBILITY
729        bool contains(const key_type& __k) const {return find(__k) != end();}
730
731        template <typename _K2>
732        _LIBCPP_INLINE_VISIBILITY
733        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool>
734        contains(const _K2& __k) const {return find(__k) != end();}
735    #endif // _LIBCPP_STD_VER > 17
736    _LIBCPP_INLINE_VISIBILITY
737    pair<iterator, iterator>             equal_range(const key_type& __k)
738        {return __table_.__equal_range_unique(__k);}
739    _LIBCPP_INLINE_VISIBILITY
740    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
741        {return __table_.__equal_range_unique(__k);}
742    #if _LIBCPP_STD_VER > 17
743        template <typename _K2>
744        _LIBCPP_INLINE_VISIBILITY
745        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>>
746        equal_range(const _K2& __k)       {return __table_.__equal_range_unique(__k);}
747        template <typename _K2>
748        _LIBCPP_INLINE_VISIBILITY
749        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>>
750        equal_range(const _K2& __k) const {return __table_.__equal_range_unique(__k);}
751    #endif // _LIBCPP_STD_VER > 17
752
753    _LIBCPP_INLINE_VISIBILITY
754    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
755    _LIBCPP_INLINE_VISIBILITY
756    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
757
758    _LIBCPP_INLINE_VISIBILITY
759    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
760    _LIBCPP_INLINE_VISIBILITY
761    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
762
763    _LIBCPP_INLINE_VISIBILITY
764    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
765    _LIBCPP_INLINE_VISIBILITY
766    local_iterator       end(size_type __n)          {return __table_.end(__n);}
767    _LIBCPP_INLINE_VISIBILITY
768    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
769    _LIBCPP_INLINE_VISIBILITY
770    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
771    _LIBCPP_INLINE_VISIBILITY
772    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
773    _LIBCPP_INLINE_VISIBILITY
774    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
775
776    _LIBCPP_INLINE_VISIBILITY
777    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
778    _LIBCPP_INLINE_VISIBILITY
779    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
780    _LIBCPP_INLINE_VISIBILITY
781    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
782    _LIBCPP_INLINE_VISIBILITY
783    void rehash(size_type __n) {__table_.rehash(__n);}
784    _LIBCPP_INLINE_VISIBILITY
785    void reserve(size_type __n) {__table_.reserve(__n);}
786
787#if _LIBCPP_DEBUG_LEVEL == 2
788
789    bool __dereferenceable(const const_iterator* __i) const
790        {return __table_.__dereferenceable(__i);}
791    bool __decrementable(const const_iterator* __i) const
792        {return __table_.__decrementable(__i);}
793    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
794        {return __table_.__addable(__i, __n);}
795    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
796        {return __table_.__addable(__i, __n);}
797
798#endif // _LIBCPP_DEBUG_LEVEL == 2
799
800};
801
802#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
803template<class _InputIterator,
804         class _Hash = hash<__iter_value_type<_InputIterator>>,
805         class _Pred = equal_to<__iter_value_type<_InputIterator>>,
806         class _Allocator = allocator<__iter_value_type<_InputIterator>>,
807         class = _EnableIf<!__is_allocator<_Hash>::value>,
808         class = _EnableIf<!is_integral<_Hash>::value>,
809         class = _EnableIf<!__is_allocator<_Pred>::value>,
810         class = _EnableIf<__is_allocator<_Allocator>::value>>
811unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0,
812              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
813  -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
814
815template<class _Tp, class _Hash = hash<_Tp>,
816         class _Pred = equal_to<_Tp>,
817         class _Allocator = allocator<_Tp>,
818         class = _EnableIf<!__is_allocator<_Hash>::value>,
819         class = _EnableIf<!is_integral<_Hash>::value>,
820         class = _EnableIf<!__is_allocator<_Pred>::value>,
821         class = _EnableIf<__is_allocator<_Allocator>::value>>
822unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0,
823              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
824  -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
825
826template<class _InputIterator, class _Allocator,
827         class = _EnableIf<__is_allocator<_Allocator>::value>>
828unordered_set(_InputIterator, _InputIterator,
829              typename allocator_traits<_Allocator>::size_type, _Allocator)
830  -> unordered_set<__iter_value_type<_InputIterator>,
831                   hash<__iter_value_type<_InputIterator>>,
832                   equal_to<__iter_value_type<_InputIterator>>,
833                   _Allocator>;
834
835template<class _InputIterator, class _Hash, class _Allocator,
836         class = _EnableIf<!__is_allocator<_Hash>::value>,
837         class = _EnableIf<!is_integral<_Hash>::value>,
838         class = _EnableIf<__is_allocator<_Allocator>::value>>
839unordered_set(_InputIterator, _InputIterator,
840              typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
841  -> unordered_set<__iter_value_type<_InputIterator>, _Hash,
842                   equal_to<__iter_value_type<_InputIterator>>,
843                   _Allocator>;
844
845template<class _Tp, class _Allocator,
846         class = _EnableIf<__is_allocator<_Allocator>::value>>
847unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
848  -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
849
850template<class _Tp, class _Hash, class _Allocator,
851         class = _EnableIf<!__is_allocator<_Hash>::value>,
852         class = _EnableIf<!is_integral<_Hash>::value>,
853         class = _EnableIf<__is_allocator<_Allocator>::value>>
854unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
855  -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
856#endif
857
858template <class _Value, class _Hash, class _Pred, class _Alloc>
859unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
860        const hasher& __hf, const key_equal& __eql)
861    : __table_(__hf, __eql)
862{
863#if _LIBCPP_DEBUG_LEVEL == 2
864    __get_db()->__insert_c(this);
865#endif
866    __table_.rehash(__n);
867}
868
869template <class _Value, class _Hash, class _Pred, class _Alloc>
870unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
871        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
872    : __table_(__hf, __eql, __a)
873{
874#if _LIBCPP_DEBUG_LEVEL == 2
875    __get_db()->__insert_c(this);
876#endif
877    __table_.rehash(__n);
878}
879
880template <class _Value, class _Hash, class _Pred, class _Alloc>
881template <class _InputIterator>
882unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
883        _InputIterator __first, _InputIterator __last)
884{
885#if _LIBCPP_DEBUG_LEVEL == 2
886    __get_db()->__insert_c(this);
887#endif
888    insert(__first, __last);
889}
890
891template <class _Value, class _Hash, class _Pred, class _Alloc>
892template <class _InputIterator>
893unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
894        _InputIterator __first, _InputIterator __last, size_type __n,
895        const hasher& __hf, const key_equal& __eql)
896    : __table_(__hf, __eql)
897{
898#if _LIBCPP_DEBUG_LEVEL == 2
899    __get_db()->__insert_c(this);
900#endif
901    __table_.rehash(__n);
902    insert(__first, __last);
903}
904
905template <class _Value, class _Hash, class _Pred, class _Alloc>
906template <class _InputIterator>
907unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
908        _InputIterator __first, _InputIterator __last, size_type __n,
909        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
910    : __table_(__hf, __eql, __a)
911{
912#if _LIBCPP_DEBUG_LEVEL == 2
913    __get_db()->__insert_c(this);
914#endif
915    __table_.rehash(__n);
916    insert(__first, __last);
917}
918
919template <class _Value, class _Hash, class _Pred, class _Alloc>
920inline
921unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
922        const allocator_type& __a)
923    : __table_(__a)
924{
925#if _LIBCPP_DEBUG_LEVEL == 2
926    __get_db()->__insert_c(this);
927#endif
928}
929
930template <class _Value, class _Hash, class _Pred, class _Alloc>
931unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
932        const unordered_set& __u)
933    : __table_(__u.__table_)
934{
935#if _LIBCPP_DEBUG_LEVEL == 2
936    __get_db()->__insert_c(this);
937#endif
938    __table_.rehash(__u.bucket_count());
939    insert(__u.begin(), __u.end());
940}
941
942template <class _Value, class _Hash, class _Pred, class _Alloc>
943unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
944        const unordered_set& __u, const allocator_type& __a)
945    : __table_(__u.__table_, __a)
946{
947#if _LIBCPP_DEBUG_LEVEL == 2
948    __get_db()->__insert_c(this);
949#endif
950    __table_.rehash(__u.bucket_count());
951    insert(__u.begin(), __u.end());
952}
953
954#ifndef _LIBCPP_CXX03_LANG
955
956template <class _Value, class _Hash, class _Pred, class _Alloc>
957inline
958unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
959        unordered_set&& __u)
960    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
961    : __table_(_VSTD::move(__u.__table_))
962{
963#if _LIBCPP_DEBUG_LEVEL == 2
964    __get_db()->__insert_c(this);
965    __get_db()->swap(this, &__u);
966#endif
967}
968
969template <class _Value, class _Hash, class _Pred, class _Alloc>
970unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
971        unordered_set&& __u, const allocator_type& __a)
972    : __table_(_VSTD::move(__u.__table_), __a)
973{
974#if _LIBCPP_DEBUG_LEVEL == 2
975    __get_db()->__insert_c(this);
976#endif
977    if (__a != __u.get_allocator())
978    {
979        iterator __i = __u.begin();
980        while (__u.size() != 0)
981            __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
982    }
983#if _LIBCPP_DEBUG_LEVEL == 2
984    else
985        __get_db()->swap(this, &__u);
986#endif
987}
988
989template <class _Value, class _Hash, class _Pred, class _Alloc>
990unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
991        initializer_list<value_type> __il)
992{
993#if _LIBCPP_DEBUG_LEVEL == 2
994    __get_db()->__insert_c(this);
995#endif
996    insert(__il.begin(), __il.end());
997}
998
999template <class _Value, class _Hash, class _Pred, class _Alloc>
1000unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1001        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1002        const key_equal& __eql)
1003    : __table_(__hf, __eql)
1004{
1005#if _LIBCPP_DEBUG_LEVEL == 2
1006    __get_db()->__insert_c(this);
1007#endif
1008    __table_.rehash(__n);
1009    insert(__il.begin(), __il.end());
1010}
1011
1012template <class _Value, class _Hash, class _Pred, class _Alloc>
1013unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1014        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1015        const key_equal& __eql, const allocator_type& __a)
1016    : __table_(__hf, __eql, __a)
1017{
1018#if _LIBCPP_DEBUG_LEVEL == 2
1019    __get_db()->__insert_c(this);
1020#endif
1021    __table_.rehash(__n);
1022    insert(__il.begin(), __il.end());
1023}
1024
1025template <class _Value, class _Hash, class _Pred, class _Alloc>
1026inline
1027unordered_set<_Value, _Hash, _Pred, _Alloc>&
1028unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)
1029    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
1030{
1031    __table_ = _VSTD::move(__u.__table_);
1032    return *this;
1033}
1034
1035template <class _Value, class _Hash, class _Pred, class _Alloc>
1036inline
1037unordered_set<_Value, _Hash, _Pred, _Alloc>&
1038unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(
1039        initializer_list<value_type> __il)
1040{
1041    __table_.__assign_unique(__il.begin(), __il.end());
1042    return *this;
1043}
1044
1045#endif // _LIBCPP_CXX03_LANG
1046
1047template <class _Value, class _Hash, class _Pred, class _Alloc>
1048template <class _InputIterator>
1049inline
1050void
1051unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1052                                                    _InputIterator __last)
1053{
1054    for (; __first != __last; ++__first)
1055        __table_.__insert_unique(*__first);
1056}
1057
1058template <class _Value, class _Hash, class _Pred, class _Alloc>
1059inline _LIBCPP_INLINE_VISIBILITY
1060void
1061swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1062     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1063    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1064{
1065    __x.swap(__y);
1066}
1067
1068#if _LIBCPP_STD_VER > 17
1069template <class _Value, class _Hash, class _Pred, class _Alloc,
1070          class _Predicate>
1071inline _LIBCPP_INLINE_VISIBILITY
1072    typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type
1073    erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c,
1074             _Predicate __pred) {
1075  return _VSTD::__libcpp_erase_if_container(__c, __pred);
1076}
1077#endif
1078
1079template <class _Value, class _Hash, class _Pred, class _Alloc>
1080bool
1081operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1082           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1083{
1084    if (__x.size() != __y.size())
1085        return false;
1086    typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
1087                                                                 const_iterator;
1088    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
1089            __i != __ex; ++__i)
1090    {
1091        const_iterator __j = __y.find(*__i);
1092        if (__j == __ey || !(*__i == *__j))
1093            return false;
1094    }
1095    return true;
1096}
1097
1098template <class _Value, class _Hash, class _Pred, class _Alloc>
1099inline _LIBCPP_INLINE_VISIBILITY
1100bool
1101operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1102           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1103{
1104    return !(__x == __y);
1105}
1106
1107template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
1108          class _Alloc = allocator<_Value> >
1109class _LIBCPP_TEMPLATE_VIS unordered_multiset
1110{
1111public:
1112    // types
1113    typedef _Value                                                     key_type;
1114    typedef key_type                                                   value_type;
1115    typedef __identity_t<_Hash>                                        hasher;
1116    typedef __identity_t<_Pred>                                        key_equal;
1117    typedef __identity_t<_Alloc>                                       allocator_type;
1118    typedef value_type&                                                reference;
1119    typedef const value_type&                                          const_reference;
1120    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1121                  "Invalid allocator::value_type");
1122
1123private:
1124    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
1125
1126    __table __table_;
1127
1128public:
1129    typedef typename __table::pointer         pointer;
1130    typedef typename __table::const_pointer   const_pointer;
1131    typedef typename __table::size_type       size_type;
1132    typedef typename __table::difference_type difference_type;
1133
1134    typedef typename __table::const_iterator       iterator;
1135    typedef typename __table::const_iterator       const_iterator;
1136    typedef typename __table::const_local_iterator local_iterator;
1137    typedef typename __table::const_local_iterator const_local_iterator;
1138
1139#if _LIBCPP_STD_VER > 14
1140    typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
1141#endif
1142
1143    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
1144        friend class _LIBCPP_TEMPLATE_VIS unordered_set;
1145    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
1146        friend class _LIBCPP_TEMPLATE_VIS unordered_multiset;
1147
1148    _LIBCPP_INLINE_VISIBILITY
1149    unordered_multiset()
1150        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
1151        {
1152#if _LIBCPP_DEBUG_LEVEL == 2
1153            __get_db()->__insert_c(this);
1154#endif
1155        }
1156    explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
1157                                const key_equal& __eql = key_equal());
1158    unordered_multiset(size_type __n, const hasher& __hf,
1159                       const key_equal& __eql, const allocator_type& __a);
1160#if _LIBCPP_STD_VER > 11
1161    inline _LIBCPP_INLINE_VISIBILITY
1162    unordered_multiset(size_type __n, const allocator_type& __a)
1163        : unordered_multiset(__n, hasher(), key_equal(), __a) {}
1164    inline _LIBCPP_INLINE_VISIBILITY
1165    unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a)
1166        : unordered_multiset(__n, __hf, key_equal(), __a) {}
1167#endif
1168    template <class _InputIterator>
1169        unordered_multiset(_InputIterator __first, _InputIterator __last);
1170    template <class _InputIterator>
1171        unordered_multiset(_InputIterator __first, _InputIterator __last,
1172                      size_type __n, const hasher& __hf = hasher(),
1173                      const key_equal& __eql = key_equal());
1174    template <class _InputIterator>
1175        unordered_multiset(_InputIterator __first, _InputIterator __last,
1176                      size_type __n , const hasher& __hf,
1177                      const key_equal& __eql, const allocator_type& __a);
1178#if _LIBCPP_STD_VER > 11
1179    template <class _InputIterator>
1180    inline _LIBCPP_INLINE_VISIBILITY
1181    unordered_multiset(_InputIterator __first, _InputIterator __last,
1182                       size_type __n, const allocator_type& __a)
1183        : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {}
1184    template <class _InputIterator>
1185    inline _LIBCPP_INLINE_VISIBILITY
1186    unordered_multiset(_InputIterator __first, _InputIterator __last,
1187                       size_type __n, const hasher& __hf, const allocator_type& __a)
1188        : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
1189#endif
1190    _LIBCPP_INLINE_VISIBILITY
1191    explicit unordered_multiset(const allocator_type& __a);
1192    unordered_multiset(const unordered_multiset& __u);
1193    unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
1194#ifndef _LIBCPP_CXX03_LANG
1195    _LIBCPP_INLINE_VISIBILITY
1196    unordered_multiset(unordered_multiset&& __u)
1197        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1198    unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
1199    unordered_multiset(initializer_list<value_type> __il);
1200    unordered_multiset(initializer_list<value_type> __il, size_type __n,
1201                       const hasher& __hf = hasher(),
1202                       const key_equal& __eql = key_equal());
1203    unordered_multiset(initializer_list<value_type> __il, size_type __n,
1204                       const hasher& __hf, const key_equal& __eql,
1205                       const allocator_type& __a);
1206#if _LIBCPP_STD_VER > 11
1207    inline _LIBCPP_INLINE_VISIBILITY
1208    unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
1209      : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
1210    inline _LIBCPP_INLINE_VISIBILITY
1211    unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)
1212      : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}
1213#endif
1214#endif // _LIBCPP_CXX03_LANG
1215    _LIBCPP_INLINE_VISIBILITY
1216    ~unordered_multiset() {
1217        static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
1218    }
1219
1220    _LIBCPP_INLINE_VISIBILITY
1221    unordered_multiset& operator=(const unordered_multiset& __u)
1222    {
1223        __table_ = __u.__table_;
1224        return *this;
1225    }
1226#ifndef _LIBCPP_CXX03_LANG
1227    _LIBCPP_INLINE_VISIBILITY
1228    unordered_multiset& operator=(unordered_multiset&& __u)
1229        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1230    unordered_multiset& operator=(initializer_list<value_type> __il);
1231#endif // _LIBCPP_CXX03_LANG
1232
1233    _LIBCPP_INLINE_VISIBILITY
1234    allocator_type get_allocator() const _NOEXCEPT
1235        {return allocator_type(__table_.__node_alloc());}
1236
1237    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1238    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
1239    _LIBCPP_INLINE_VISIBILITY
1240    size_type size() const _NOEXCEPT  {return __table_.size();}
1241    _LIBCPP_INLINE_VISIBILITY
1242    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
1243
1244    _LIBCPP_INLINE_VISIBILITY
1245    iterator       begin() _NOEXCEPT        {return __table_.begin();}
1246    _LIBCPP_INLINE_VISIBILITY
1247    iterator       end() _NOEXCEPT          {return __table_.end();}
1248    _LIBCPP_INLINE_VISIBILITY
1249    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
1250    _LIBCPP_INLINE_VISIBILITY
1251    const_iterator end()    const _NOEXCEPT {return __table_.end();}
1252    _LIBCPP_INLINE_VISIBILITY
1253    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
1254    _LIBCPP_INLINE_VISIBILITY
1255    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
1256
1257#ifndef _LIBCPP_CXX03_LANG
1258    template <class... _Args>
1259        _LIBCPP_INLINE_VISIBILITY
1260        iterator emplace(_Args&&... __args)
1261            {return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}
1262    template <class... _Args>
1263        _LIBCPP_INLINE_VISIBILITY
1264        iterator emplace_hint(const_iterator __p, _Args&&... __args)
1265            {return __table_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
1266
1267    _LIBCPP_INLINE_VISIBILITY
1268    iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}
1269    _LIBCPP_INLINE_VISIBILITY
1270    iterator insert(const_iterator __p, value_type&& __x)
1271        {return __table_.__insert_multi(__p, _VSTD::move(__x));}
1272    _LIBCPP_INLINE_VISIBILITY
1273    void insert(initializer_list<value_type> __il)
1274        {insert(__il.begin(), __il.end());}
1275#endif // _LIBCPP_CXX03_LANG
1276
1277    _LIBCPP_INLINE_VISIBILITY
1278    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
1279
1280    _LIBCPP_INLINE_VISIBILITY
1281    iterator insert(const_iterator __p, const value_type& __x)
1282        {return __table_.__insert_multi(__p, __x);}
1283
1284    template <class _InputIterator>
1285        _LIBCPP_INLINE_VISIBILITY
1286        void insert(_InputIterator __first, _InputIterator __last);
1287
1288#if _LIBCPP_STD_VER > 14
1289    _LIBCPP_INLINE_VISIBILITY
1290    iterator insert(node_type&& __nh)
1291    {
1292        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1293            "node_type with incompatible allocator passed to unordered_multiset::insert()");
1294        return __table_.template __node_handle_insert_multi<node_type>(
1295            _VSTD::move(__nh));
1296    }
1297    _LIBCPP_INLINE_VISIBILITY
1298    iterator insert(const_iterator __hint, node_type&& __nh)
1299    {
1300        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1301            "node_type with incompatible allocator passed to unordered_multiset::insert()");
1302        return __table_.template __node_handle_insert_multi<node_type>(
1303            __hint, _VSTD::move(__nh));
1304    }
1305    _LIBCPP_INLINE_VISIBILITY
1306    node_type extract(const_iterator __position)
1307    {
1308        return __table_.template __node_handle_extract<node_type>(
1309            __position);
1310    }
1311    _LIBCPP_INLINE_VISIBILITY
1312    node_type extract(key_type const& __key)
1313    {
1314        return __table_.template __node_handle_extract<node_type>(__key);
1315    }
1316
1317    template <class _H2, class _P2>
1318    _LIBCPP_INLINE_VISIBILITY
1319    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
1320    {
1321        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1322                       "merging container with incompatible allocator");
1323        return __table_.__node_handle_merge_multi(__source.__table_);
1324    }
1325    template <class _H2, class _P2>
1326    _LIBCPP_INLINE_VISIBILITY
1327    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
1328    {
1329        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1330                       "merging container with incompatible allocator");
1331        return __table_.__node_handle_merge_multi(__source.__table_);
1332    }
1333    template <class _H2, class _P2>
1334    _LIBCPP_INLINE_VISIBILITY
1335    void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
1336    {
1337        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1338                       "merging container with incompatible allocator");
1339        return __table_.__node_handle_merge_multi(__source.__table_);
1340    }
1341    template <class _H2, class _P2>
1342    _LIBCPP_INLINE_VISIBILITY
1343    void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
1344    {
1345        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1346                       "merging container with incompatible allocator");
1347        return __table_.__node_handle_merge_multi(__source.__table_);
1348    }
1349#endif
1350
1351    _LIBCPP_INLINE_VISIBILITY
1352    iterator erase(const_iterator __p) {return __table_.erase(__p);}
1353    _LIBCPP_INLINE_VISIBILITY
1354    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
1355    _LIBCPP_INLINE_VISIBILITY
1356    iterator erase(const_iterator __first, const_iterator __last)
1357        {return __table_.erase(__first, __last);}
1358    _LIBCPP_INLINE_VISIBILITY
1359    void clear() _NOEXCEPT {__table_.clear();}
1360
1361    _LIBCPP_INLINE_VISIBILITY
1362    void swap(unordered_multiset& __u)
1363        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
1364        {__table_.swap(__u.__table_);}
1365
1366    _LIBCPP_INLINE_VISIBILITY
1367    hasher hash_function() const {return __table_.hash_function();}
1368    _LIBCPP_INLINE_VISIBILITY
1369    key_equal key_eq() const {return __table_.key_eq();}
1370
1371    _LIBCPP_INLINE_VISIBILITY
1372    iterator       find(const key_type& __k)       {return __table_.find(__k);}
1373    _LIBCPP_INLINE_VISIBILITY
1374    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
1375    #if _LIBCPP_STD_VER > 17
1376        template <typename _K2>
1377        _LIBCPP_INLINE_VISIBILITY
1378        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, iterator>
1379        find(const _K2& __k)       {return __table_.find(__k);}
1380        template <typename _K2>
1381        _LIBCPP_INLINE_VISIBILITY
1382        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, const_iterator>
1383        find(const _K2& __k) const {return __table_.find(__k);}
1384    #endif // _LIBCPP_STD_VER > 17
1385    _LIBCPP_INLINE_VISIBILITY
1386    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
1387    #if _LIBCPP_STD_VER > 17
1388        template <typename _K2>
1389        _LIBCPP_INLINE_VISIBILITY
1390        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, size_type>
1391        count(const _K2& __k) const {return __table_.__count_multi(__k);}
1392    #endif // _LIBCPP_STD_VER > 17
1393    #if _LIBCPP_STD_VER > 17
1394        _LIBCPP_INLINE_VISIBILITY
1395        bool contains(const key_type& __k) const {return find(__k) != end();}
1396
1397        template <typename _K2>
1398        _LIBCPP_INLINE_VISIBILITY
1399        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, bool>
1400        contains(const _K2& __k) const {return find(__k) != end();}
1401    #endif // _LIBCPP_STD_VER > 17
1402    _LIBCPP_INLINE_VISIBILITY
1403    pair<iterator, iterator>             equal_range(const key_type& __k)
1404        {return __table_.__equal_range_multi(__k);}
1405    _LIBCPP_INLINE_VISIBILITY
1406    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
1407        {return __table_.__equal_range_multi(__k);}
1408    #if _LIBCPP_STD_VER > 17
1409        template <typename _K2>
1410        _LIBCPP_INLINE_VISIBILITY
1411        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<iterator, iterator>>
1412        equal_range(const _K2& __k)       {return __table_.__equal_range_multi(__k);}
1413        template <typename _K2>
1414        _LIBCPP_INLINE_VISIBILITY
1415        _EnableIf<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value, pair<const_iterator, const_iterator>>
1416        equal_range(const _K2& __k) const {return __table_.__equal_range_multi(__k);}
1417    #endif // _LIBCPP_STD_VER > 17
1418
1419    _LIBCPP_INLINE_VISIBILITY
1420    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
1421    _LIBCPP_INLINE_VISIBILITY
1422    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
1423
1424    _LIBCPP_INLINE_VISIBILITY
1425    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
1426    _LIBCPP_INLINE_VISIBILITY
1427    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
1428
1429    _LIBCPP_INLINE_VISIBILITY
1430    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
1431    _LIBCPP_INLINE_VISIBILITY
1432    local_iterator       end(size_type __n)          {return __table_.end(__n);}
1433    _LIBCPP_INLINE_VISIBILITY
1434    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
1435    _LIBCPP_INLINE_VISIBILITY
1436    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
1437    _LIBCPP_INLINE_VISIBILITY
1438    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
1439    _LIBCPP_INLINE_VISIBILITY
1440    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
1441
1442    _LIBCPP_INLINE_VISIBILITY
1443    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
1444    _LIBCPP_INLINE_VISIBILITY
1445    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
1446    _LIBCPP_INLINE_VISIBILITY
1447    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
1448    _LIBCPP_INLINE_VISIBILITY
1449    void rehash(size_type __n) {__table_.rehash(__n);}
1450    _LIBCPP_INLINE_VISIBILITY
1451    void reserve(size_type __n) {__table_.reserve(__n);}
1452
1453#if _LIBCPP_DEBUG_LEVEL == 2
1454
1455    bool __dereferenceable(const const_iterator* __i) const
1456        {return __table_.__dereferenceable(__i);}
1457    bool __decrementable(const const_iterator* __i) const
1458        {return __table_.__decrementable(__i);}
1459    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1460        {return __table_.__addable(__i, __n);}
1461    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1462        {return __table_.__addable(__i, __n);}
1463
1464#endif // _LIBCPP_DEBUG_LEVEL == 2
1465
1466};
1467
1468#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1469template<class _InputIterator,
1470         class _Hash = hash<__iter_value_type<_InputIterator>>,
1471         class _Pred = equal_to<__iter_value_type<_InputIterator>>,
1472         class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1473         class = _EnableIf<!__is_allocator<_Hash>::value>,
1474         class = _EnableIf<!is_integral<_Hash>::value>,
1475         class = _EnableIf<!__is_allocator<_Pred>::value>,
1476         class = _EnableIf<__is_allocator<_Allocator>::value>>
1477unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0,
1478              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1479  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
1480
1481template<class _Tp, class _Hash = hash<_Tp>,
1482         class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>,
1483         class = _EnableIf<!__is_allocator<_Hash>::value>,
1484         class = _EnableIf<!is_integral<_Hash>::value>,
1485         class = _EnableIf<!__is_allocator<_Pred>::value>,
1486         class = _EnableIf<__is_allocator<_Allocator>::value>>
1487unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0,
1488              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1489  -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1490
1491template<class _InputIterator, class _Allocator,
1492         class = _EnableIf<__is_allocator<_Allocator>::value>>
1493unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
1494  -> unordered_multiset<__iter_value_type<_InputIterator>,
1495                   hash<__iter_value_type<_InputIterator>>,
1496                   equal_to<__iter_value_type<_InputIterator>>,
1497                   _Allocator>;
1498
1499template<class _InputIterator, class _Hash, class _Allocator,
1500         class = _EnableIf<!__is_allocator<_Hash>::value>,
1501         class = _EnableIf<!is_integral<_Hash>::value>,
1502         class = _EnableIf<__is_allocator<_Allocator>::value>>
1503unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type,
1504              _Hash, _Allocator)
1505  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash,
1506                   equal_to<__iter_value_type<_InputIterator>>,
1507                   _Allocator>;
1508
1509template<class _Tp, class _Allocator,
1510         class = _EnableIf<__is_allocator<_Allocator>::value>>
1511unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
1512  -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1513
1514template<class _Tp, class _Hash, class _Allocator,
1515         class = _EnableIf<!__is_allocator<_Hash>::value>,
1516         class = _EnableIf<!is_integral<_Hash>::value>,
1517         class = _EnableIf<__is_allocator<_Allocator>::value>>
1518unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1519  -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1520#endif
1521
1522template <class _Value, class _Hash, class _Pred, class _Alloc>
1523unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1524        size_type __n, const hasher& __hf, const key_equal& __eql)
1525    : __table_(__hf, __eql)
1526{
1527#if _LIBCPP_DEBUG_LEVEL == 2
1528    __get_db()->__insert_c(this);
1529#endif
1530    __table_.rehash(__n);
1531}
1532
1533template <class _Value, class _Hash, class _Pred, class _Alloc>
1534unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1535        size_type __n, const hasher& __hf, const key_equal& __eql,
1536        const allocator_type& __a)
1537    : __table_(__hf, __eql, __a)
1538{
1539#if _LIBCPP_DEBUG_LEVEL == 2
1540    __get_db()->__insert_c(this);
1541#endif
1542    __table_.rehash(__n);
1543}
1544
1545template <class _Value, class _Hash, class _Pred, class _Alloc>
1546template <class _InputIterator>
1547unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1548        _InputIterator __first, _InputIterator __last)
1549{
1550#if _LIBCPP_DEBUG_LEVEL == 2
1551    __get_db()->__insert_c(this);
1552#endif
1553    insert(__first, __last);
1554}
1555
1556template <class _Value, class _Hash, class _Pred, class _Alloc>
1557template <class _InputIterator>
1558unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1559        _InputIterator __first, _InputIterator __last, size_type __n,
1560        const hasher& __hf, const key_equal& __eql)
1561    : __table_(__hf, __eql)
1562{
1563#if _LIBCPP_DEBUG_LEVEL == 2
1564    __get_db()->__insert_c(this);
1565#endif
1566    __table_.rehash(__n);
1567    insert(__first, __last);
1568}
1569
1570template <class _Value, class _Hash, class _Pred, class _Alloc>
1571template <class _InputIterator>
1572unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1573        _InputIterator __first, _InputIterator __last, size_type __n,
1574        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
1575    : __table_(__hf, __eql, __a)
1576{
1577#if _LIBCPP_DEBUG_LEVEL == 2
1578    __get_db()->__insert_c(this);
1579#endif
1580    __table_.rehash(__n);
1581    insert(__first, __last);
1582}
1583
1584template <class _Value, class _Hash, class _Pred, class _Alloc>
1585inline
1586unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1587        const allocator_type& __a)
1588    : __table_(__a)
1589{
1590#if _LIBCPP_DEBUG_LEVEL == 2
1591    __get_db()->__insert_c(this);
1592#endif
1593}
1594
1595template <class _Value, class _Hash, class _Pred, class _Alloc>
1596unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1597        const unordered_multiset& __u)
1598    : __table_(__u.__table_)
1599{
1600#if _LIBCPP_DEBUG_LEVEL == 2
1601    __get_db()->__insert_c(this);
1602#endif
1603    __table_.rehash(__u.bucket_count());
1604    insert(__u.begin(), __u.end());
1605}
1606
1607template <class _Value, class _Hash, class _Pred, class _Alloc>
1608unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1609        const unordered_multiset& __u, const allocator_type& __a)
1610    : __table_(__u.__table_, __a)
1611{
1612#if _LIBCPP_DEBUG_LEVEL == 2
1613    __get_db()->__insert_c(this);
1614#endif
1615    __table_.rehash(__u.bucket_count());
1616    insert(__u.begin(), __u.end());
1617}
1618
1619#ifndef _LIBCPP_CXX03_LANG
1620
1621template <class _Value, class _Hash, class _Pred, class _Alloc>
1622inline
1623unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1624        unordered_multiset&& __u)
1625    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
1626    : __table_(_VSTD::move(__u.__table_))
1627{
1628#if _LIBCPP_DEBUG_LEVEL == 2
1629    __get_db()->__insert_c(this);
1630    __get_db()->swap(this, &__u);
1631#endif
1632}
1633
1634template <class _Value, class _Hash, class _Pred, class _Alloc>
1635unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1636        unordered_multiset&& __u, const allocator_type& __a)
1637    : __table_(_VSTD::move(__u.__table_), __a)
1638{
1639#if _LIBCPP_DEBUG_LEVEL == 2
1640    __get_db()->__insert_c(this);
1641#endif
1642    if (__a != __u.get_allocator())
1643    {
1644        iterator __i = __u.begin();
1645        while (__u.size() != 0)
1646            __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
1647    }
1648#if _LIBCPP_DEBUG_LEVEL == 2
1649    else
1650        __get_db()->swap(this, &__u);
1651#endif
1652}
1653
1654template <class _Value, class _Hash, class _Pred, class _Alloc>
1655unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1656        initializer_list<value_type> __il)
1657{
1658#if _LIBCPP_DEBUG_LEVEL == 2
1659    __get_db()->__insert_c(this);
1660#endif
1661    insert(__il.begin(), __il.end());
1662}
1663
1664template <class _Value, class _Hash, class _Pred, class _Alloc>
1665unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1666        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1667        const key_equal& __eql)
1668    : __table_(__hf, __eql)
1669{
1670#if _LIBCPP_DEBUG_LEVEL == 2
1671    __get_db()->__insert_c(this);
1672#endif
1673    __table_.rehash(__n);
1674    insert(__il.begin(), __il.end());
1675}
1676
1677template <class _Value, class _Hash, class _Pred, class _Alloc>
1678unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1679        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1680        const key_equal& __eql, const allocator_type& __a)
1681    : __table_(__hf, __eql, __a)
1682{
1683#if _LIBCPP_DEBUG_LEVEL == 2
1684    __get_db()->__insert_c(this);
1685#endif
1686    __table_.rehash(__n);
1687    insert(__il.begin(), __il.end());
1688}
1689
1690template <class _Value, class _Hash, class _Pred, class _Alloc>
1691inline
1692unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
1693unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
1694        unordered_multiset&& __u)
1695    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
1696{
1697    __table_ = _VSTD::move(__u.__table_);
1698    return *this;
1699}
1700
1701template <class _Value, class _Hash, class _Pred, class _Alloc>
1702inline
1703unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
1704unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
1705        initializer_list<value_type> __il)
1706{
1707    __table_.__assign_multi(__il.begin(), __il.end());
1708    return *this;
1709}
1710
1711#endif // _LIBCPP_CXX03_LANG
1712
1713template <class _Value, class _Hash, class _Pred, class _Alloc>
1714template <class _InputIterator>
1715inline
1716void
1717unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1718                                                         _InputIterator __last)
1719{
1720    for (; __first != __last; ++__first)
1721        __table_.__insert_multi(*__first);
1722}
1723
1724template <class _Value, class _Hash, class _Pred, class _Alloc>
1725inline _LIBCPP_INLINE_VISIBILITY
1726void
1727swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1728     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1729    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1730{
1731    __x.swap(__y);
1732}
1733
1734#if _LIBCPP_STD_VER > 17
1735template <class _Value, class _Hash, class _Pred, class _Alloc,
1736          class _Predicate>
1737inline _LIBCPP_INLINE_VISIBILITY
1738    typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type
1739    erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c,
1740             _Predicate __pred) {
1741  return _VSTD::__libcpp_erase_if_container(__c, __pred);
1742}
1743#endif
1744
1745template <class _Value, class _Hash, class _Pred, class _Alloc>
1746bool
1747operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1748           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1749{
1750    if (__x.size() != __y.size())
1751        return false;
1752    typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
1753                                                                 const_iterator;
1754    typedef pair<const_iterator, const_iterator> _EqRng;
1755    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
1756    {
1757        _EqRng __xeq = __x.equal_range(*__i);
1758        _EqRng __yeq = __y.equal_range(*__i);
1759        if (_VSTD::distance(__xeq.first, __xeq.second) !=
1760            _VSTD::distance(__yeq.first, __yeq.second) ||
1761                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
1762            return false;
1763        __i = __xeq.second;
1764    }
1765    return true;
1766}
1767
1768template <class _Value, class _Hash, class _Pred, class _Alloc>
1769inline _LIBCPP_INLINE_VISIBILITY
1770bool
1771operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1772           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1773{
1774    return !(__x == __y);
1775}
1776
1777_LIBCPP_END_NAMESPACE_STD
1778
1779#endif // _LIBCPP_UNORDERED_SET
1780