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