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