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 <__functional/operations.h>
468#include <__hash_table>
469#include <__memory/addressof.h>
470#include <__node_handle>
471#include <__utility/forward.h>
472#include <compare>
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#ifdef _LIBCPP_ENABLE_DEBUG_MODE
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_ENABLE_DEBUG_MODE
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    std::__debug_db_swap(this, std::addressof(__u));
1011}
1012
1013template <class _Value, class _Hash, class _Pred, class _Alloc>
1014unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1015        unordered_set&& __u, const allocator_type& __a)
1016    : __table_(_VSTD::move(__u.__table_), __a)
1017{
1018    _VSTD::__debug_db_insert_c(this);
1019    if (__a != __u.get_allocator())
1020    {
1021        iterator __i = __u.begin();
1022        while (__u.size() != 0)
1023            __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
1024    }
1025    else
1026        std::__debug_db_swap(this, std::addressof(__u));
1027}
1028
1029template <class _Value, class _Hash, class _Pred, class _Alloc>
1030unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1031        initializer_list<value_type> __il)
1032{
1033    _VSTD::__debug_db_insert_c(this);
1034    insert(__il.begin(), __il.end());
1035}
1036
1037template <class _Value, class _Hash, class _Pred, class _Alloc>
1038unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1039        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1040        const key_equal& __eql)
1041    : __table_(__hf, __eql)
1042{
1043    _VSTD::__debug_db_insert_c(this);
1044    __table_.rehash(__n);
1045    insert(__il.begin(), __il.end());
1046}
1047
1048template <class _Value, class _Hash, class _Pred, class _Alloc>
1049unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
1050        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1051        const key_equal& __eql, const allocator_type& __a)
1052    : __table_(__hf, __eql, __a)
1053{
1054    _VSTD::__debug_db_insert_c(this);
1055    __table_.rehash(__n);
1056    insert(__il.begin(), __il.end());
1057}
1058
1059template <class _Value, class _Hash, class _Pred, class _Alloc>
1060inline
1061unordered_set<_Value, _Hash, _Pred, _Alloc>&
1062unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)
1063    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
1064{
1065    __table_ = _VSTD::move(__u.__table_);
1066    return *this;
1067}
1068
1069template <class _Value, class _Hash, class _Pred, class _Alloc>
1070inline
1071unordered_set<_Value, _Hash, _Pred, _Alloc>&
1072unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(
1073        initializer_list<value_type> __il)
1074{
1075    __table_.__assign_unique(__il.begin(), __il.end());
1076    return *this;
1077}
1078
1079#endif // _LIBCPP_CXX03_LANG
1080
1081template <class _Value, class _Hash, class _Pred, class _Alloc>
1082template <class _InputIterator>
1083inline
1084void
1085unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1086                                                    _InputIterator __last)
1087{
1088    for (; __first != __last; ++__first)
1089        __table_.__insert_unique(*__first);
1090}
1091
1092template <class _Value, class _Hash, class _Pred, class _Alloc>
1093inline _LIBCPP_INLINE_VISIBILITY
1094void
1095swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1096     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1097    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1098{
1099    __x.swap(__y);
1100}
1101
1102#if _LIBCPP_STD_VER > 17
1103template <class _Value, class _Hash, class _Pred, class _Alloc,
1104          class _Predicate>
1105inline _LIBCPP_INLINE_VISIBILITY
1106    typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type
1107    erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c,
1108             _Predicate __pred) {
1109  return _VSTD::__libcpp_erase_if_container(__c, __pred);
1110}
1111#endif
1112
1113template <class _Value, class _Hash, class _Pred, class _Alloc>
1114bool
1115operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1116           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1117{
1118    if (__x.size() != __y.size())
1119        return false;
1120    typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
1121                                                                 const_iterator;
1122    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
1123            __i != __ex; ++__i)
1124    {
1125        const_iterator __j = __y.find(*__i);
1126        if (__j == __ey || !(*__i == *__j))
1127            return false;
1128    }
1129    return true;
1130}
1131
1132template <class _Value, class _Hash, class _Pred, class _Alloc>
1133inline _LIBCPP_INLINE_VISIBILITY
1134bool
1135operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1136           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1137{
1138    return !(__x == __y);
1139}
1140
1141template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
1142          class _Alloc = allocator<_Value> >
1143class _LIBCPP_TEMPLATE_VIS unordered_multiset
1144{
1145public:
1146    // types
1147    typedef _Value                                                     key_type;
1148    typedef key_type                                                   value_type;
1149    typedef __type_identity_t<_Hash>                                   hasher;
1150    typedef __type_identity_t<_Pred>                                   key_equal;
1151    typedef __type_identity_t<_Alloc>                                  allocator_type;
1152    typedef value_type&                                                reference;
1153    typedef const value_type&                                          const_reference;
1154    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
1155                  "Invalid allocator::value_type");
1156
1157private:
1158    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
1159
1160    __table __table_;
1161
1162public:
1163    typedef typename __table::pointer         pointer;
1164    typedef typename __table::const_pointer   const_pointer;
1165    typedef typename __table::size_type       size_type;
1166    typedef typename __table::difference_type difference_type;
1167
1168    typedef typename __table::const_iterator       iterator;
1169    typedef typename __table::const_iterator       const_iterator;
1170    typedef typename __table::const_local_iterator local_iterator;
1171    typedef typename __table::const_local_iterator const_local_iterator;
1172
1173#if _LIBCPP_STD_VER > 14
1174    typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
1175#endif
1176
1177    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
1178        friend class _LIBCPP_TEMPLATE_VIS unordered_set;
1179    template <class _Value2, class _Hash2, class _Pred2, class _Alloc2>
1180        friend class _LIBCPP_TEMPLATE_VIS unordered_multiset;
1181
1182    _LIBCPP_INLINE_VISIBILITY
1183    unordered_multiset()
1184        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
1185    {
1186        _VSTD::__debug_db_insert_c(this);
1187    }
1188    explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
1189                                const key_equal& __eql = key_equal());
1190    unordered_multiset(size_type __n, const hasher& __hf,
1191                       const key_equal& __eql, const allocator_type& __a);
1192#if _LIBCPP_STD_VER > 11
1193    inline _LIBCPP_INLINE_VISIBILITY
1194    unordered_multiset(size_type __n, const allocator_type& __a)
1195        : unordered_multiset(__n, hasher(), key_equal(), __a) {}
1196    inline _LIBCPP_INLINE_VISIBILITY
1197    unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a)
1198        : unordered_multiset(__n, __hf, key_equal(), __a) {}
1199#endif
1200    template <class _InputIterator>
1201        unordered_multiset(_InputIterator __first, _InputIterator __last);
1202    template <class _InputIterator>
1203        unordered_multiset(_InputIterator __first, _InputIterator __last,
1204                      size_type __n, const hasher& __hf = hasher(),
1205                      const key_equal& __eql = key_equal());
1206    template <class _InputIterator>
1207        unordered_multiset(_InputIterator __first, _InputIterator __last,
1208                      size_type __n , const hasher& __hf,
1209                      const key_equal& __eql, const allocator_type& __a);
1210#if _LIBCPP_STD_VER > 11
1211    template <class _InputIterator>
1212    inline _LIBCPP_INLINE_VISIBILITY
1213    unordered_multiset(_InputIterator __first, _InputIterator __last,
1214                       size_type __n, const allocator_type& __a)
1215        : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {}
1216    template <class _InputIterator>
1217    inline _LIBCPP_INLINE_VISIBILITY
1218    unordered_multiset(_InputIterator __first, _InputIterator __last,
1219                       size_type __n, const hasher& __hf, const allocator_type& __a)
1220        : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
1221#endif
1222    _LIBCPP_INLINE_VISIBILITY
1223    explicit unordered_multiset(const allocator_type& __a);
1224    unordered_multiset(const unordered_multiset& __u);
1225    unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
1226#ifndef _LIBCPP_CXX03_LANG
1227    _LIBCPP_INLINE_VISIBILITY
1228    unordered_multiset(unordered_multiset&& __u)
1229        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
1230    unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
1231    unordered_multiset(initializer_list<value_type> __il);
1232    unordered_multiset(initializer_list<value_type> __il, size_type __n,
1233                       const hasher& __hf = hasher(),
1234                       const key_equal& __eql = key_equal());
1235    unordered_multiset(initializer_list<value_type> __il, size_type __n,
1236                       const hasher& __hf, const key_equal& __eql,
1237                       const allocator_type& __a);
1238#if _LIBCPP_STD_VER > 11
1239    inline _LIBCPP_INLINE_VISIBILITY
1240    unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
1241      : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
1242    inline _LIBCPP_INLINE_VISIBILITY
1243    unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)
1244      : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}
1245#endif
1246#endif // _LIBCPP_CXX03_LANG
1247    _LIBCPP_INLINE_VISIBILITY
1248    ~unordered_multiset() {
1249        static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), "");
1250    }
1251
1252    _LIBCPP_INLINE_VISIBILITY
1253    unordered_multiset& operator=(const unordered_multiset& __u)
1254    {
1255        __table_ = __u.__table_;
1256        return *this;
1257    }
1258#ifndef _LIBCPP_CXX03_LANG
1259    _LIBCPP_INLINE_VISIBILITY
1260    unordered_multiset& operator=(unordered_multiset&& __u)
1261        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
1262    unordered_multiset& operator=(initializer_list<value_type> __il);
1263#endif // _LIBCPP_CXX03_LANG
1264
1265    _LIBCPP_INLINE_VISIBILITY
1266    allocator_type get_allocator() const _NOEXCEPT
1267        {return allocator_type(__table_.__node_alloc());}
1268
1269    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1270    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
1271    _LIBCPP_INLINE_VISIBILITY
1272    size_type size() const _NOEXCEPT  {return __table_.size();}
1273    _LIBCPP_INLINE_VISIBILITY
1274    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
1275
1276    _LIBCPP_INLINE_VISIBILITY
1277    iterator       begin() _NOEXCEPT        {return __table_.begin();}
1278    _LIBCPP_INLINE_VISIBILITY
1279    iterator       end() _NOEXCEPT          {return __table_.end();}
1280    _LIBCPP_INLINE_VISIBILITY
1281    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
1282    _LIBCPP_INLINE_VISIBILITY
1283    const_iterator end()    const _NOEXCEPT {return __table_.end();}
1284    _LIBCPP_INLINE_VISIBILITY
1285    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
1286    _LIBCPP_INLINE_VISIBILITY
1287    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
1288
1289#ifndef _LIBCPP_CXX03_LANG
1290    template <class... _Args>
1291        _LIBCPP_INLINE_VISIBILITY
1292        iterator emplace(_Args&&... __args)
1293            {return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}
1294    template <class... _Args>
1295        _LIBCPP_INLINE_VISIBILITY
1296        iterator emplace_hint(const_iterator __p, _Args&&... __args)
1297            {return __table_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
1298
1299    _LIBCPP_INLINE_VISIBILITY
1300    iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}
1301    _LIBCPP_INLINE_VISIBILITY
1302    iterator insert(const_iterator __p, value_type&& __x)
1303        {return __table_.__insert_multi(__p, _VSTD::move(__x));}
1304    _LIBCPP_INLINE_VISIBILITY
1305    void insert(initializer_list<value_type> __il)
1306        {insert(__il.begin(), __il.end());}
1307#endif // _LIBCPP_CXX03_LANG
1308
1309    _LIBCPP_INLINE_VISIBILITY
1310    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
1311
1312    _LIBCPP_INLINE_VISIBILITY
1313    iterator insert(const_iterator __p, const value_type& __x)
1314        {return __table_.__insert_multi(__p, __x);}
1315
1316    template <class _InputIterator>
1317        _LIBCPP_INLINE_VISIBILITY
1318        void insert(_InputIterator __first, _InputIterator __last);
1319
1320#if _LIBCPP_STD_VER > 14
1321    _LIBCPP_INLINE_VISIBILITY
1322    iterator insert(node_type&& __nh)
1323    {
1324        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1325            "node_type with incompatible allocator passed to unordered_multiset::insert()");
1326        return __table_.template __node_handle_insert_multi<node_type>(
1327            _VSTD::move(__nh));
1328    }
1329    _LIBCPP_INLINE_VISIBILITY
1330    iterator insert(const_iterator __hint, node_type&& __nh)
1331    {
1332        _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
1333            "node_type with incompatible allocator passed to unordered_multiset::insert()");
1334        return __table_.template __node_handle_insert_multi<node_type>(
1335            __hint, _VSTD::move(__nh));
1336    }
1337    _LIBCPP_INLINE_VISIBILITY
1338    node_type extract(const_iterator __position)
1339    {
1340        return __table_.template __node_handle_extract<node_type>(
1341            __position);
1342    }
1343    _LIBCPP_INLINE_VISIBILITY
1344    node_type extract(key_type const& __key)
1345    {
1346        return __table_.template __node_handle_extract<node_type>(__key);
1347    }
1348
1349    template <class _H2, class _P2>
1350    _LIBCPP_INLINE_VISIBILITY
1351    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source)
1352    {
1353        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1354                       "merging container with incompatible allocator");
1355        return __table_.__node_handle_merge_multi(__source.__table_);
1356    }
1357    template <class _H2, class _P2>
1358    _LIBCPP_INLINE_VISIBILITY
1359    void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source)
1360    {
1361        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1362                       "merging container with incompatible allocator");
1363        return __table_.__node_handle_merge_multi(__source.__table_);
1364    }
1365    template <class _H2, class _P2>
1366    _LIBCPP_INLINE_VISIBILITY
1367    void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source)
1368    {
1369        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1370                       "merging container with incompatible allocator");
1371        return __table_.__node_handle_merge_multi(__source.__table_);
1372    }
1373    template <class _H2, class _P2>
1374    _LIBCPP_INLINE_VISIBILITY
1375    void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source)
1376    {
1377        _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(),
1378                       "merging container with incompatible allocator");
1379        return __table_.__node_handle_merge_multi(__source.__table_);
1380    }
1381#endif
1382
1383    _LIBCPP_INLINE_VISIBILITY
1384    iterator erase(const_iterator __p) {return __table_.erase(__p);}
1385    _LIBCPP_INLINE_VISIBILITY
1386    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
1387    _LIBCPP_INLINE_VISIBILITY
1388    iterator erase(const_iterator __first, const_iterator __last)
1389        {return __table_.erase(__first, __last);}
1390    _LIBCPP_INLINE_VISIBILITY
1391    void clear() _NOEXCEPT {__table_.clear();}
1392
1393    _LIBCPP_INLINE_VISIBILITY
1394    void swap(unordered_multiset& __u)
1395        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
1396        {__table_.swap(__u.__table_);}
1397
1398    _LIBCPP_INLINE_VISIBILITY
1399    hasher hash_function() const {return __table_.hash_function();}
1400    _LIBCPP_INLINE_VISIBILITY
1401    key_equal key_eq() const {return __table_.key_eq();}
1402
1403    _LIBCPP_INLINE_VISIBILITY
1404    iterator       find(const key_type& __k)       {return __table_.find(__k);}
1405    _LIBCPP_INLINE_VISIBILITY
1406    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
1407#if _LIBCPP_STD_VER > 17
1408    template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
1409    _LIBCPP_INLINE_VISIBILITY
1410    iterator       find(const _K2& __k)            {return __table_.find(__k);}
1411    template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
1412    _LIBCPP_INLINE_VISIBILITY
1413    const_iterator find(const _K2& __k) const      {return __table_.find(__k);}
1414#endif // _LIBCPP_STD_VER > 17
1415
1416    _LIBCPP_INLINE_VISIBILITY
1417    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
1418#if _LIBCPP_STD_VER > 17
1419    template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
1420    _LIBCPP_INLINE_VISIBILITY
1421    size_type count(const _K2& __k) const      {return __table_.__count_multi(__k);}
1422#endif // _LIBCPP_STD_VER > 17
1423
1424#if _LIBCPP_STD_VER > 17
1425    _LIBCPP_INLINE_VISIBILITY
1426    bool contains(const key_type& __k) const {return find(__k) != end();}
1427
1428    template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
1429    _LIBCPP_INLINE_VISIBILITY
1430    bool contains(const _K2& __k) const      {return find(__k) != end();}
1431#endif // _LIBCPP_STD_VER > 17
1432
1433    _LIBCPP_INLINE_VISIBILITY
1434    pair<iterator, iterator>             equal_range(const key_type& __k)
1435        {return __table_.__equal_range_multi(__k);}
1436    _LIBCPP_INLINE_VISIBILITY
1437    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
1438        {return __table_.__equal_range_multi(__k);}
1439#if _LIBCPP_STD_VER > 17
1440    template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr>
1441    _LIBCPP_INLINE_VISIBILITY
1442    pair<iterator, iterator>             equal_range(const _K2& __k)
1443        {return __table_.__equal_range_multi(__k);}
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<const_iterator, const_iterator> equal_range(const _K2& __k) const
1447        {return __table_.__equal_range_multi(__k);}
1448#endif // _LIBCPP_STD_VER > 17
1449
1450    _LIBCPP_INLINE_VISIBILITY
1451    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
1452    _LIBCPP_INLINE_VISIBILITY
1453    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
1454
1455    _LIBCPP_INLINE_VISIBILITY
1456    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
1457    _LIBCPP_INLINE_VISIBILITY
1458    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
1459
1460    _LIBCPP_INLINE_VISIBILITY
1461    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
1462    _LIBCPP_INLINE_VISIBILITY
1463    local_iterator       end(size_type __n)          {return __table_.end(__n);}
1464    _LIBCPP_INLINE_VISIBILITY
1465    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
1466    _LIBCPP_INLINE_VISIBILITY
1467    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
1468    _LIBCPP_INLINE_VISIBILITY
1469    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
1470    _LIBCPP_INLINE_VISIBILITY
1471    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
1472
1473    _LIBCPP_INLINE_VISIBILITY
1474    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
1475    _LIBCPP_INLINE_VISIBILITY
1476    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
1477    _LIBCPP_INLINE_VISIBILITY
1478    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
1479    _LIBCPP_INLINE_VISIBILITY
1480    void rehash(size_type __n) {__table_.rehash(__n);}
1481    _LIBCPP_INLINE_VISIBILITY
1482    void reserve(size_type __n) {__table_.reserve(__n);}
1483
1484#ifdef _LIBCPP_ENABLE_DEBUG_MODE
1485
1486    bool __dereferenceable(const const_iterator* __i) const
1487        {return __table_.__dereferenceable(__i);}
1488    bool __decrementable(const const_iterator* __i) const
1489        {return __table_.__decrementable(__i);}
1490    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
1491        {return __table_.__addable(__i, __n);}
1492    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
1493        {return __table_.__addable(__i, __n);}
1494
1495#endif // _LIBCPP_ENABLE_DEBUG_MODE
1496
1497};
1498
1499#if _LIBCPP_STD_VER >= 17
1500template<class _InputIterator,
1501         class _Hash = hash<__iter_value_type<_InputIterator>>,
1502         class _Pred = equal_to<__iter_value_type<_InputIterator>>,
1503         class _Allocator = allocator<__iter_value_type<_InputIterator>>,
1504         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1505         class = enable_if_t<!__is_allocator<_Hash>::value>,
1506         class = enable_if_t<!is_integral<_Hash>::value>,
1507         class = enable_if_t<!__is_allocator<_Pred>::value>,
1508         class = enable_if_t<__is_allocator<_Allocator>::value>>
1509unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0,
1510              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1511  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>;
1512
1513template<class _Tp, class _Hash = hash<_Tp>,
1514         class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>,
1515         class = enable_if_t<!__is_allocator<_Hash>::value>,
1516         class = enable_if_t<!is_integral<_Hash>::value>,
1517         class = enable_if_t<!__is_allocator<_Pred>::value>,
1518         class = enable_if_t<__is_allocator<_Allocator>::value>>
1519unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type = 0,
1520              _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1521  -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1522
1523template<class _InputIterator, class _Allocator,
1524         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1525         class = enable_if_t<__is_allocator<_Allocator>::value>>
1526unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator)
1527  -> unordered_multiset<__iter_value_type<_InputIterator>,
1528                   hash<__iter_value_type<_InputIterator>>,
1529                   equal_to<__iter_value_type<_InputIterator>>,
1530                   _Allocator>;
1531
1532template<class _InputIterator, class _Hash, class _Allocator,
1533         class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
1534         class = enable_if_t<!__is_allocator<_Hash>::value>,
1535         class = enable_if_t<!is_integral<_Hash>::value>,
1536         class = enable_if_t<__is_allocator<_Allocator>::value>>
1537unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type,
1538              _Hash, _Allocator)
1539  -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash,
1540                   equal_to<__iter_value_type<_InputIterator>>,
1541                   _Allocator>;
1542
1543template<class _Tp, class _Allocator,
1544         class = enable_if_t<__is_allocator<_Allocator>::value>>
1545unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator)
1546  -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1547
1548template<class _Tp, class _Hash, class _Allocator,
1549         class = enable_if_t<!__is_allocator<_Hash>::value>,
1550         class = enable_if_t<!is_integral<_Hash>::value>,
1551         class = enable_if_t<__is_allocator<_Allocator>::value>>
1552unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator)
1553  -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1554#endif
1555
1556template <class _Value, class _Hash, class _Pred, class _Alloc>
1557unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1558        size_type __n, const hasher& __hf, const key_equal& __eql)
1559    : __table_(__hf, __eql)
1560{
1561    _VSTD::__debug_db_insert_c(this);
1562    __table_.rehash(__n);
1563}
1564
1565template <class _Value, class _Hash, class _Pred, class _Alloc>
1566unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1567        size_type __n, const hasher& __hf, const key_equal& __eql,
1568        const allocator_type& __a)
1569    : __table_(__hf, __eql, __a)
1570{
1571    _VSTD::__debug_db_insert_c(this);
1572    __table_.rehash(__n);
1573}
1574
1575template <class _Value, class _Hash, class _Pred, class _Alloc>
1576template <class _InputIterator>
1577unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1578        _InputIterator __first, _InputIterator __last)
1579{
1580    _VSTD::__debug_db_insert_c(this);
1581    insert(__first, __last);
1582}
1583
1584template <class _Value, class _Hash, class _Pred, class _Alloc>
1585template <class _InputIterator>
1586unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1587        _InputIterator __first, _InputIterator __last, size_type __n,
1588        const hasher& __hf, const key_equal& __eql)
1589    : __table_(__hf, __eql)
1590{
1591    _VSTD::__debug_db_insert_c(this);
1592    __table_.rehash(__n);
1593    insert(__first, __last);
1594}
1595
1596template <class _Value, class _Hash, class _Pred, class _Alloc>
1597template <class _InputIterator>
1598unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1599        _InputIterator __first, _InputIterator __last, size_type __n,
1600        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
1601    : __table_(__hf, __eql, __a)
1602{
1603    _VSTD::__debug_db_insert_c(this);
1604    __table_.rehash(__n);
1605    insert(__first, __last);
1606}
1607
1608template <class _Value, class _Hash, class _Pred, class _Alloc>
1609inline
1610unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1611        const allocator_type& __a)
1612    : __table_(__a)
1613{
1614    _VSTD::__debug_db_insert_c(this);
1615}
1616
1617template <class _Value, class _Hash, class _Pred, class _Alloc>
1618unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1619        const unordered_multiset& __u)
1620    : __table_(__u.__table_)
1621{
1622    _VSTD::__debug_db_insert_c(this);
1623    __table_.rehash(__u.bucket_count());
1624    insert(__u.begin(), __u.end());
1625}
1626
1627template <class _Value, class _Hash, class _Pred, class _Alloc>
1628unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1629        const unordered_multiset& __u, const allocator_type& __a)
1630    : __table_(__u.__table_, __a)
1631{
1632    _VSTD::__debug_db_insert_c(this);
1633    __table_.rehash(__u.bucket_count());
1634    insert(__u.begin(), __u.end());
1635}
1636
1637#ifndef _LIBCPP_CXX03_LANG
1638
1639template <class _Value, class _Hash, class _Pred, class _Alloc>
1640inline
1641unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1642        unordered_multiset&& __u)
1643    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
1644    : __table_(_VSTD::move(__u.__table_))
1645{
1646    _VSTD::__debug_db_insert_c(this);
1647    std::__debug_db_swap(this, std::addressof(__u));
1648}
1649
1650template <class _Value, class _Hash, class _Pred, class _Alloc>
1651unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1652        unordered_multiset&& __u, const allocator_type& __a)
1653    : __table_(_VSTD::move(__u.__table_), __a)
1654{
1655    _VSTD::__debug_db_insert_c(this);
1656    if (__a != __u.get_allocator())
1657    {
1658        iterator __i = __u.begin();
1659        while (__u.size() != 0)
1660            __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
1661    }
1662    else
1663        std::__debug_db_swap(this, std::addressof(__u));
1664}
1665
1666template <class _Value, class _Hash, class _Pred, class _Alloc>
1667unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1668        initializer_list<value_type> __il)
1669{
1670    _VSTD::__debug_db_insert_c(this);
1671    insert(__il.begin(), __il.end());
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, size_type __n, const hasher& __hf,
1677        const key_equal& __eql)
1678    : __table_(__hf, __eql)
1679{
1680    _VSTD::__debug_db_insert_c(this);
1681    __table_.rehash(__n);
1682    insert(__il.begin(), __il.end());
1683}
1684
1685template <class _Value, class _Hash, class _Pred, class _Alloc>
1686unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
1687        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
1688        const key_equal& __eql, const allocator_type& __a)
1689    : __table_(__hf, __eql, __a)
1690{
1691    _VSTD::__debug_db_insert_c(this);
1692    __table_.rehash(__n);
1693    insert(__il.begin(), __il.end());
1694}
1695
1696template <class _Value, class _Hash, class _Pred, class _Alloc>
1697inline
1698unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
1699unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
1700        unordered_multiset&& __u)
1701    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
1702{
1703    __table_ = _VSTD::move(__u.__table_);
1704    return *this;
1705}
1706
1707template <class _Value, class _Hash, class _Pred, class _Alloc>
1708inline
1709unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
1710unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
1711        initializer_list<value_type> __il)
1712{
1713    __table_.__assign_multi(__il.begin(), __il.end());
1714    return *this;
1715}
1716
1717#endif // _LIBCPP_CXX03_LANG
1718
1719template <class _Value, class _Hash, class _Pred, class _Alloc>
1720template <class _InputIterator>
1721inline
1722void
1723unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
1724                                                         _InputIterator __last)
1725{
1726    for (; __first != __last; ++__first)
1727        __table_.__insert_multi(*__first);
1728}
1729
1730template <class _Value, class _Hash, class _Pred, class _Alloc>
1731inline _LIBCPP_INLINE_VISIBILITY
1732void
1733swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1734     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1735    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
1736{
1737    __x.swap(__y);
1738}
1739
1740#if _LIBCPP_STD_VER > 17
1741template <class _Value, class _Hash, class _Pred, class _Alloc,
1742          class _Predicate>
1743inline _LIBCPP_INLINE_VISIBILITY
1744    typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type
1745    erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c,
1746             _Predicate __pred) {
1747  return _VSTD::__libcpp_erase_if_container(__c, __pred);
1748}
1749#endif
1750
1751template <class _Value, class _Hash, class _Pred, class _Alloc>
1752bool
1753operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1754           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1755{
1756    if (__x.size() != __y.size())
1757        return false;
1758    typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
1759                                                                 const_iterator;
1760    typedef pair<const_iterator, const_iterator> _EqRng;
1761    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
1762    {
1763        _EqRng __xeq = __x.equal_range(*__i);
1764        _EqRng __yeq = __y.equal_range(*__i);
1765        if (_VSTD::distance(__xeq.first, __xeq.second) !=
1766            _VSTD::distance(__yeq.first, __yeq.second) ||
1767                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
1768            return false;
1769        __i = __xeq.second;
1770    }
1771    return true;
1772}
1773
1774template <class _Value, class _Hash, class _Pred, class _Alloc>
1775inline _LIBCPP_INLINE_VISIBILITY
1776bool
1777operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1778           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1779{
1780    return !(__x == __y);
1781}
1782
1783_LIBCPP_END_NAMESPACE_STD
1784
1785#endif // _LIBCPP_UNORDERED_SET
1786