]> git.ipfire.org Git - thirdparty/gcc.git/blame_incremental - libstdc++-v3/include/bits/unordered_set.h
Fix overflow check in profile_count::operator* (const sreal &num).
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / unordered_set.h
... / ...
CommitLineData
1// unordered_set implementation -*- C++ -*-
2
3// Copyright (C) 2010-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unordered_set.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{unordered_set}
28 */
29
30#ifndef _UNORDERED_SET_H
31#define _UNORDERED_SET_H
32
33#include <bits/hashtable.h>
34#include <bits/allocator.h>
35#include <bits/functional_hash.h> // hash
36#include <bits/stl_function.h> // equal_to
37#if __glibcxx_containers_ranges // C++ >= 23
38# include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.
39#endif
40
41namespace std _GLIBCXX_VISIBILITY(default)
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
45
46 /// Base types for unordered_set.
47 template<bool _Cache>
48 using __uset_traits = __detail::_Hashtable_traits<_Cache, true, true>;
49
50 template<typename _Value,
51 typename _Hash = hash<_Value>,
52 typename _Pred = std::equal_to<_Value>,
53 typename _Alloc = std::allocator<_Value>,
54 typename _Tr = __uset_traits<__cache_default<_Value, _Hash>::value>>
55 using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc,
56 __detail::_Identity, _Pred, _Hash,
57 __detail::_Mod_range_hashing,
58 __detail::_Default_ranged_hash,
59 __detail::_Prime_rehash_policy, _Tr>;
60
61 /// Base types for unordered_multiset.
62 template<bool _Cache>
63 using __umset_traits = __detail::_Hashtable_traits<_Cache, true, false>;
64
65 template<typename _Value,
66 typename _Hash = hash<_Value>,
67 typename _Pred = std::equal_to<_Value>,
68 typename _Alloc = std::allocator<_Value>,
69 typename _Tr = __umset_traits<__cache_default<_Value, _Hash>::value>>
70 using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc,
71 __detail::_Identity,
72 _Pred, _Hash,
73 __detail::_Mod_range_hashing,
74 __detail::_Default_ranged_hash,
75 __detail::_Prime_rehash_policy, _Tr>;
76
77 template<class _Value, class _Hash, class _Pred, class _Alloc>
78 class unordered_multiset;
79
80 /**
81 * @brief A standard container composed of unique keys (containing
82 * at most one of each key value) in which the elements' keys are
83 * the elements themselves.
84 *
85 * @ingroup unordered_associative_containers
86 * @headerfile unordered_set
87 * @since C++11
88 *
89 * @tparam _Value Type of key objects.
90 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
91
92 * @tparam _Pred Predicate function object type, defaults to
93 * equal_to<_Value>.
94 *
95 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
96 *
97 * Meets the requirements of a <a href="tables.html#65">container</a>, and
98 * <a href="tables.html#xx">unordered associative container</a>
99 *
100 * Base is _Hashtable, dispatched at compile time via template
101 * alias __uset_hashtable.
102 */
103 template<typename _Value,
104 typename _Hash = hash<_Value>,
105 typename _Pred = equal_to<_Value>,
106 typename _Alloc = allocator<_Value>>
107 class unordered_set
108 {
109 typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
110 _Hashtable _M_h;
111
112 public:
113 // typedefs:
114 ///@{
115 /// Public typedefs.
116 typedef typename _Hashtable::key_type key_type;
117 typedef typename _Hashtable::value_type value_type;
118 typedef typename _Hashtable::hasher hasher;
119 typedef typename _Hashtable::key_equal key_equal;
120 typedef typename _Hashtable::allocator_type allocator_type;
121 ///@}
122
123 ///@{
124 /// Iterator-related typedefs.
125 typedef typename _Hashtable::pointer pointer;
126 typedef typename _Hashtable::const_pointer const_pointer;
127 typedef typename _Hashtable::reference reference;
128 typedef typename _Hashtable::const_reference const_reference;
129 typedef typename _Hashtable::iterator iterator;
130 typedef typename _Hashtable::const_iterator const_iterator;
131 typedef typename _Hashtable::local_iterator local_iterator;
132 typedef typename _Hashtable::const_local_iterator const_local_iterator;
133 typedef typename _Hashtable::size_type size_type;
134 typedef typename _Hashtable::difference_type difference_type;
135 ///@}
136
137#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
138 using node_type = typename _Hashtable::node_type;
139 using insert_return_type = typename _Hashtable::insert_return_type;
140#endif
141
142 // construct/destroy/copy
143
144 /// Default constructor.
145 unordered_set() = default;
146
147 /**
148 * @brief Default constructor creates no elements.
149 * @param __n Minimal initial number of buckets.
150 * @param __hf A hash functor.
151 * @param __eql A key equality functor.
152 * @param __a An allocator object.
153 */
154 explicit
155 unordered_set(size_type __n,
156 const hasher& __hf = hasher(),
157 const key_equal& __eql = key_equal(),
158 const allocator_type& __a = allocator_type())
159 : _M_h(__n, __hf, __eql, __a)
160 { }
161
162 /**
163 * @brief Builds an %unordered_set from a range.
164 * @param __first An input iterator.
165 * @param __last An input iterator.
166 * @param __n Minimal initial number of buckets.
167 * @param __hf A hash functor.
168 * @param __eql A key equality functor.
169 * @param __a An allocator object.
170 *
171 * Create an %unordered_set consisting of copies of the elements from
172 * [__first,__last). This is linear in N (where N is
173 * distance(__first,__last)).
174 */
175 template<typename _InputIterator>
176 unordered_set(_InputIterator __first, _InputIterator __last,
177 size_type __n = 0,
178 const hasher& __hf = hasher(),
179 const key_equal& __eql = key_equal(),
180 const allocator_type& __a = allocator_type())
181 : _M_h(__first, __last, __n, __hf, __eql, __a)
182 { }
183
184 /// Copy constructor.
185 unordered_set(const unordered_set&) = default;
186
187 /// Move constructor.
188 unordered_set(unordered_set&&) = default;
189
190 /**
191 * @brief Creates an %unordered_set with no elements.
192 * @param __a An allocator object.
193 */
194 explicit
195 unordered_set(const allocator_type& __a)
196 : _M_h(__a)
197 { }
198
199 /*
200 * @brief Copy constructor with allocator argument.
201 * @param __uset Input %unordered_set to copy.
202 * @param __a An allocator object.
203 */
204 unordered_set(const unordered_set& __uset,
205 const allocator_type& __a)
206 : _M_h(__uset._M_h, __a)
207 { }
208
209 /*
210 * @brief Move constructor with allocator argument.
211 * @param __uset Input %unordered_set to move.
212 * @param __a An allocator object.
213 */
214 unordered_set(unordered_set&& __uset,
215 const allocator_type& __a)
216 noexcept( noexcept(_Hashtable(std::move(__uset._M_h), __a)) )
217 : _M_h(std::move(__uset._M_h), __a)
218 { }
219
220 /**
221 * @brief Builds an %unordered_set from an initializer_list.
222 * @param __l An initializer_list.
223 * @param __n Minimal initial number of buckets.
224 * @param __hf A hash functor.
225 * @param __eql A key equality functor.
226 * @param __a An allocator object.
227 *
228 * Create an %unordered_set consisting of copies of the elements in the
229 * list. This is linear in N (where N is @a __l.size()).
230 */
231 unordered_set(initializer_list<value_type> __l,
232 size_type __n = 0,
233 const hasher& __hf = hasher(),
234 const key_equal& __eql = key_equal(),
235 const allocator_type& __a = allocator_type())
236 : _M_h(__l, __n, __hf, __eql, __a)
237 { }
238
239 unordered_set(size_type __n, const allocator_type& __a)
240 : unordered_set(__n, hasher(), key_equal(), __a)
241 { }
242
243 unordered_set(size_type __n, const hasher& __hf,
244 const allocator_type& __a)
245 : unordered_set(__n, __hf, key_equal(), __a)
246 { }
247
248 // _GLIBCXX_RESOLVE_LIB_DEFECTS
249 // 2713. More missing allocator-extended constructors for unordered container
250 template<typename _InputIterator>
251 unordered_set(_InputIterator __first, _InputIterator __last,
252 const allocator_type& __a)
253 : unordered_set(__first, __last, 0, hasher(), key_equal(), __a)
254 { }
255
256 template<typename _InputIterator>
257 unordered_set(_InputIterator __first, _InputIterator __last,
258 size_type __n,
259 const allocator_type& __a)
260 : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
261 { }
262
263 template<typename _InputIterator>
264 unordered_set(_InputIterator __first, _InputIterator __last,
265 size_type __n, const hasher& __hf,
266 const allocator_type& __a)
267 : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
268 { }
269
270
271 // _GLIBCXX_RESOLVE_LIB_DEFECTS
272 // 2713. More missing allocator-extended constructors for unordered container
273 unordered_set(initializer_list<value_type> __l,
274 const allocator_type& __a)
275 : unordered_set(__l, 0, hasher(), key_equal(), __a)
276 { }
277
278 unordered_set(initializer_list<value_type> __l,
279 size_type __n,
280 const allocator_type& __a)
281 : unordered_set(__l, __n, hasher(), key_equal(), __a)
282 { }
283
284 unordered_set(initializer_list<value_type> __l,
285 size_type __n, const hasher& __hf,
286 const allocator_type& __a)
287 : unordered_set(__l, __n, __hf, key_equal(), __a)
288 { }
289
290#if __glibcxx_containers_ranges // C++ >= 23
291 /**
292 * @brief Builds an %unordered_set from a range.
293 * @since C++23
294 * @param __rg An input range of elements that can be converted to
295 * the set's value type.
296 * @param __n Minimal initial number of buckets.
297 * @param __hf A hash functor.
298 * @param __eql A key equality functor.
299 * @param __a An allocator object.
300 *
301 * Create an %unordered_set consisting of copies of the elements in the
302 * range. This is linear in N (where N is `std::ranges::size(__rg)`).
303 */
304 template<__detail::__container_compatible_range<_Value> _Rg>
305 unordered_set(from_range_t, _Rg&& __rg,
306 size_type __n = 0,
307 const hasher& __hf = hasher(),
308 const key_equal& __eql = key_equal(),
309 const allocator_type& __a = allocator_type())
310 : _M_h(__n, __hf, __eql, __a)
311 { insert_range(std::forward<_Rg>(__rg)); }
312
313 // _GLIBCXX_RESOLVE_LIB_DEFECTS
314 // 2713. More missing allocator-extended constructors for unordered container
315 template<__detail::__container_compatible_range<_Value> _Rg>
316 unordered_set(from_range_t, _Rg&& __rg, const allocator_type& __a)
317 : _M_h(0, hasher(), key_equal(), __a)
318 { insert_range(std::forward<_Rg>(__rg)); }
319
320 template<__detail::__container_compatible_range<_Value> _Rg>
321 unordered_set(from_range_t, _Rg&& __rg, size_type __n,
322 const allocator_type& __a)
323 : _M_h(__n, hasher(), key_equal(), __a)
324 { insert_range(std::forward<_Rg>(__rg)); }
325
326 template<__detail::__container_compatible_range<_Value> _Rg>
327 unordered_set(from_range_t, _Rg&& __rg, size_type __n,
328 const hasher& __hf, const allocator_type& __a)
329 : _M_h(__n, __hf, key_equal(), __a)
330 { insert_range(std::forward<_Rg>(__rg)); }
331#endif
332
333 /// Copy assignment operator.
334 unordered_set&
335 operator=(const unordered_set&) = default;
336
337 /// Move assignment operator.
338 unordered_set&
339 operator=(unordered_set&&) = default;
340
341 /**
342 * @brief %Unordered_set list assignment operator.
343 * @param __l An initializer_list.
344 *
345 * This function fills an %unordered_set with copies of the elements in
346 * the initializer list @a __l.
347 *
348 * Note that the assignment completely changes the %unordered_set and
349 * that the resulting %unordered_set's size is the same as the number
350 * of elements assigned.
351 */
352 unordered_set&
353 operator=(initializer_list<value_type> __l)
354 {
355 _M_h = __l;
356 return *this;
357 }
358
359 /// Returns the allocator object used by the %unordered_set.
360 allocator_type
361 get_allocator() const noexcept
362 { return _M_h.get_allocator(); }
363
364 // size and capacity:
365
366 /// Returns true if the %unordered_set is empty.
367 _GLIBCXX_NODISCARD bool
368 empty() const noexcept
369 { return _M_h.empty(); }
370
371 /// Returns the size of the %unordered_set.
372 size_type
373 size() const noexcept
374 { return _M_h.size(); }
375
376 /// Returns the maximum size of the %unordered_set.
377 size_type
378 max_size() const noexcept
379 { return _M_h.max_size(); }
380
381 // iterators.
382
383 ///@{
384 /**
385 * Returns a read-only (constant) iterator that points to the first
386 * element in the %unordered_set.
387 */
388 iterator
389 begin() noexcept
390 { return _M_h.begin(); }
391
392 const_iterator
393 begin() const noexcept
394 { return _M_h.begin(); }
395 ///@}
396
397 ///@{
398 /**
399 * Returns a read-only (constant) iterator that points one past the last
400 * element in the %unordered_set.
401 */
402 iterator
403 end() noexcept
404 { return _M_h.end(); }
405
406 const_iterator
407 end() const noexcept
408 { return _M_h.end(); }
409 ///@}
410
411 /**
412 * Returns a read-only (constant) iterator that points to the first
413 * element in the %unordered_set.
414 */
415 const_iterator
416 cbegin() const noexcept
417 { return _M_h.begin(); }
418
419 /**
420 * Returns a read-only (constant) iterator that points one past the last
421 * element in the %unordered_set.
422 */
423 const_iterator
424 cend() const noexcept
425 { return _M_h.end(); }
426
427 // modifiers.
428
429 /**
430 * @brief Attempts to build and insert an element into the
431 * %unordered_set.
432 * @param __args Arguments used to generate an element.
433 * @return A pair, of which the first element is an iterator that points
434 * to the possibly inserted element, and the second is a bool
435 * that is true if the element was actually inserted.
436 *
437 * This function attempts to build and insert an element into the
438 * %unordered_set. An %unordered_set relies on unique keys and thus an
439 * element is only inserted if it is not already present in the
440 * %unordered_set.
441 *
442 * Insertion requires amortized constant time.
443 */
444 template<typename... _Args>
445 std::pair<iterator, bool>
446 emplace(_Args&&... __args)
447 { return _M_h.emplace(std::forward<_Args>(__args)...); }
448
449 /**
450 * @brief Attempts to insert an element into the %unordered_set.
451 * @param __pos An iterator that serves as a hint as to where the
452 * element should be inserted.
453 * @param __args Arguments used to generate the element to be
454 * inserted.
455 * @return An iterator that points to the element with key equivalent to
456 * the one generated from @a __args (may or may not be the
457 * element itself).
458 *
459 * This function is not concerned about whether the insertion took place,
460 * and thus does not return a boolean like the single-argument emplace()
461 * does. Note that the first parameter is only a hint and can
462 * potentially improve the performance of the insertion process. A bad
463 * hint would cause no gains in efficiency.
464 *
465 * For more on @a hinting, see:
466 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
467 *
468 * Insertion requires amortized constant time.
469 */
470 template<typename... _Args>
471 iterator
472 emplace_hint(const_iterator __pos, _Args&&... __args)
473 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
474
475 ///@{
476 /**
477 * @brief Attempts to insert an element into the %unordered_set.
478 * @param __x Element to be inserted.
479 * @return A pair, of which the first element is an iterator that points
480 * to the possibly inserted element, and the second is a bool
481 * that is true if the element was actually inserted.
482 *
483 * This function attempts to insert an element into the %unordered_set.
484 * An %unordered_set relies on unique keys and thus an element is only
485 * inserted if it is not already present in the %unordered_set.
486 *
487 * Insertion requires amortized constant time.
488 */
489 std::pair<iterator, bool>
490 insert(const value_type& __x)
491 { return _M_h.insert(__x); }
492
493 std::pair<iterator, bool>
494 insert(value_type&& __x)
495 { return _M_h.insert(std::move(__x)); }
496 ///@}
497
498 ///@{
499 /**
500 * @brief Attempts to insert an element into the %unordered_set.
501 * @param __hint An iterator that serves as a hint as to where the
502 * element should be inserted.
503 * @param __x Element to be inserted.
504 * @return An iterator that points to the element with key of
505 * @a __x (may or may not be the element passed in).
506 *
507 * This function is not concerned about whether the insertion took place,
508 * and thus does not return a boolean like the single-argument insert()
509 * does. Note that the first parameter is only a hint and can
510 * potentially improve the performance of the insertion process. A bad
511 * hint would cause no gains in efficiency.
512 *
513 * For more on @a hinting, see:
514 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
515 *
516 * Insertion requires amortized constant.
517 */
518 iterator
519 insert(const_iterator __hint, const value_type& __x)
520 { return _M_h.insert(__hint, __x); }
521
522 iterator
523 insert(const_iterator __hint, value_type&& __x)
524 { return _M_h.insert(__hint, std::move(__x)); }
525 ///@}
526
527 /**
528 * @brief A template function that attempts to insert a range of
529 * elements.
530 * @param __first Iterator pointing to the start of the range to be
531 * inserted.
532 * @param __last Iterator pointing to the end of the range.
533 *
534 * Complexity similar to that of the range constructor.
535 */
536 template<typename _InputIterator>
537 void
538 insert(_InputIterator __first, _InputIterator __last)
539 { _M_h.insert(__first, __last); }
540
541 /**
542 * @brief Attempts to insert a list of elements into the %unordered_set.
543 * @param __l A std::initializer_list<value_type> of elements
544 * to be inserted.
545 *
546 * Complexity similar to that of the range constructor.
547 */
548 void
549 insert(initializer_list<value_type> __l)
550 { _M_h.insert(__l); }
551
552#if __glibcxx_containers_ranges // C++ >= 23
553 /**
554 * @brief Inserts a range of elements.
555 * @since C++23
556 * @param __rg An input range of elements that can be converted to
557 * the set's value type.
558 */
559 template<__detail::__container_compatible_range<_Value> _Rg>
560 void
561 insert_range(_Rg&& __rg)
562 {
563 auto __first = ranges::begin(__rg);
564 const auto __last = ranges::end(__rg);
565 for (; __first != __last; ++__first)
566 _M_h.emplace(*__first);
567 }
568#endif
569
570#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
571 /// Extract a node.
572 node_type
573 extract(const_iterator __pos)
574 {
575 __glibcxx_assert(__pos != end());
576 return _M_h.extract(__pos);
577 }
578
579 /// Extract a node.
580 node_type
581 extract(const key_type& __key)
582 { return _M_h.extract(__key); }
583
584 /// Re-insert an extracted node.
585 insert_return_type
586 insert(node_type&& __nh)
587 { return _M_h._M_reinsert_node(std::move(__nh)); }
588
589 /// Re-insert an extracted node.
590 iterator
591 insert(const_iterator, node_type&& __nh)
592 { return _M_h._M_reinsert_node(std::move(__nh)).position; }
593#endif // node_extract
594
595 ///@{
596 /**
597 * @brief Erases an element from an %unordered_set.
598 * @param __position An iterator pointing to the element to be erased.
599 * @return An iterator pointing to the element immediately following
600 * @a __position prior to the element being erased. If no such
601 * element exists, end() is returned.
602 *
603 * This function erases an element, pointed to by the given iterator,
604 * from an %unordered_set. Note that this function only erases the
605 * element, and that if the element is itself a pointer, the pointed-to
606 * memory is not touched in any way. Managing the pointer is the user's
607 * responsibility.
608 */
609 iterator
610 erase(const_iterator __position)
611 { return _M_h.erase(__position); }
612
613 // LWG 2059.
614 iterator
615 erase(iterator __position)
616 { return _M_h.erase(__position); }
617 ///@}
618
619 /**
620 * @brief Erases elements according to the provided key.
621 * @param __x Key of element to be erased.
622 * @return The number of elements erased.
623 *
624 * This function erases all the elements located by the given key from
625 * an %unordered_set. For an %unordered_set the result of this function
626 * can only be 0 (not present) or 1 (present).
627 * Note that this function only erases the element, and that if
628 * the element is itself a pointer, the pointed-to memory is not touched
629 * in any way. Managing the pointer is the user's responsibility.
630 */
631 size_type
632 erase(const key_type& __x)
633 { return _M_h.erase(__x); }
634
635 /**
636 * @brief Erases a [__first,__last) range of elements from an
637 * %unordered_set.
638 * @param __first Iterator pointing to the start of the range to be
639 * erased.
640 * @param __last Iterator pointing to the end of the range to
641 * be erased.
642 * @return The iterator @a __last.
643 *
644 * This function erases a sequence of elements from an %unordered_set.
645 * Note that this function only erases the element, and that if
646 * the element is itself a pointer, the pointed-to memory is not touched
647 * in any way. Managing the pointer is the user's responsibility.
648 */
649 iterator
650 erase(const_iterator __first, const_iterator __last)
651 { return _M_h.erase(__first, __last); }
652
653 /**
654 * Erases all elements in an %unordered_set. Note that this function only
655 * erases the elements, and that if the elements themselves are pointers,
656 * the pointed-to memory is not touched in any way. Managing the pointer
657 * is the user's responsibility.
658 */
659 void
660 clear() noexcept
661 { _M_h.clear(); }
662
663 /**
664 * @brief Swaps data with another %unordered_set.
665 * @param __x An %unordered_set of the same element and allocator
666 * types.
667 *
668 * This exchanges the elements between two sets in constant time.
669 * Note that the global std::swap() function is specialized such that
670 * std::swap(s1,s2) will feed to this function.
671 */
672 void
673 swap(unordered_set& __x)
674 noexcept( noexcept(_M_h.swap(__x._M_h)) )
675 { _M_h.swap(__x._M_h); }
676
677#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
678 template<typename, typename, typename>
679 friend class std::_Hash_merge_helper;
680
681 template<typename _H2, typename _P2>
682 void
683 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
684 {
685 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
686 if (std::__addressof(__source) == this) [[__unlikely__]]
687 return;
688
689 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
690 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
691 }
692
693 template<typename _H2, typename _P2>
694 void
695 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
696 {
697 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
698 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
699 }
700
701 template<typename _H2, typename _P2>
702 void
703 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
704 {
705 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
706 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
707 }
708
709 template<typename _H2, typename _P2>
710 void
711 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
712 { merge(__source); }
713#endif // node_extract
714
715 // observers.
716
717 /// Returns the hash functor object with which the %unordered_set was
718 /// constructed.
719 hasher
720 hash_function() const
721 { return _M_h.hash_function(); }
722
723 /// Returns the key comparison object with which the %unordered_set was
724 /// constructed.
725 key_equal
726 key_eq() const
727 { return _M_h.key_eq(); }
728
729 // lookup.
730
731 ///@{
732 /**
733 * @brief Tries to locate an element in an %unordered_set.
734 * @param __x Element to be located.
735 * @return Iterator pointing to sought-after element, or end() if not
736 * found.
737 *
738 * This function takes a key and tries to locate the element with which
739 * the key matches. If successful the function returns an iterator
740 * pointing to the sought after element. If unsuccessful it returns the
741 * past-the-end ( @c end() ) iterator.
742 */
743 iterator
744 find(const key_type& __x)
745 { return _M_h.find(__x); }
746
747#if __cplusplus > 201703L
748 template<typename _Kt>
749 auto
750 find(const _Kt& __k)
751 -> decltype(_M_h._M_find_tr(__k))
752 { return _M_h._M_find_tr(__k); }
753#endif
754
755 const_iterator
756 find(const key_type& __x) const
757 { return _M_h.find(__x); }
758
759#if __cplusplus > 201703L
760 template<typename _Kt>
761 auto
762 find(const _Kt& __k) const
763 -> decltype(_M_h._M_find_tr(__k))
764 { return _M_h._M_find_tr(__k); }
765#endif
766 ///@}
767
768 ///@{
769 /**
770 * @brief Finds the number of elements.
771 * @param __x Element to located.
772 * @return Number of elements with specified key.
773 *
774 * This function only makes sense for unordered_multisets; for
775 * unordered_set the result will either be 0 (not present) or 1
776 * (present).
777 */
778 size_type
779 count(const key_type& __x) const
780 { return _M_h.count(__x); }
781
782#if __cplusplus > 201703L
783 template<typename _Kt>
784 auto
785 count(const _Kt& __k) const
786 -> decltype(_M_h._M_count_tr(__k))
787 { return _M_h._M_count_tr(__k); }
788#endif
789 ///@}
790
791#if __cplusplus > 201703L
792 ///@{
793 /**
794 * @brief Finds whether an element with the given key exists.
795 * @param __x Key of elements to be located.
796 * @return True if there is any element with the specified key.
797 */
798 bool
799 contains(const key_type& __x) const
800 { return _M_h.find(__x) != _M_h.end(); }
801
802 template<typename _Kt>
803 auto
804 contains(const _Kt& __k) const
805 -> decltype(_M_h._M_find_tr(__k), void(), true)
806 { return _M_h._M_find_tr(__k) != _M_h.end(); }
807 ///@}
808#endif
809
810 ///@{
811 /**
812 * @brief Finds a subsequence matching given key.
813 * @param __x Key to be located.
814 * @return Pair of iterators that possibly points to the subsequence
815 * matching given key.
816 *
817 * This function probably only makes sense for multisets.
818 */
819 std::pair<iterator, iterator>
820 equal_range(const key_type& __x)
821 { return _M_h.equal_range(__x); }
822
823#if __cplusplus > 201703L
824 template<typename _Kt>
825 auto
826 equal_range(const _Kt& __k)
827 -> decltype(_M_h._M_equal_range_tr(__k))
828 { return _M_h._M_equal_range_tr(__k); }
829#endif
830
831 std::pair<const_iterator, const_iterator>
832 equal_range(const key_type& __x) const
833 { return _M_h.equal_range(__x); }
834
835#if __cplusplus > 201703L
836 template<typename _Kt>
837 auto
838 equal_range(const _Kt& __k) const
839 -> decltype(_M_h._M_equal_range_tr(__k))
840 { return _M_h._M_equal_range_tr(__k); }
841#endif
842 ///@}
843
844 // bucket interface.
845
846 /// Returns the number of buckets of the %unordered_set.
847 size_type
848 bucket_count() const noexcept
849 { return _M_h.bucket_count(); }
850
851 /// Returns the maximum number of buckets of the %unordered_set.
852 size_type
853 max_bucket_count() const noexcept
854 { return _M_h.max_bucket_count(); }
855
856 /*
857 * @brief Returns the number of elements in a given bucket.
858 * @param __n A bucket index.
859 * @return The number of elements in the bucket.
860 */
861 size_type
862 bucket_size(size_type __n) const
863 { return _M_h.bucket_size(__n); }
864
865 /*
866 * @brief Returns the bucket index of a given element.
867 * @param __key A key instance.
868 * @return The key bucket index.
869 */
870 size_type
871 bucket(const key_type& __key) const
872 { return _M_h.bucket(__key); }
873
874 ///@{
875 /**
876 * @brief Returns a read-only (constant) iterator pointing to the first
877 * bucket element.
878 * @param __n The bucket index.
879 * @return A read-only local iterator.
880 */
881 local_iterator
882 begin(size_type __n)
883 { return _M_h.begin(__n); }
884
885 const_local_iterator
886 begin(size_type __n) const
887 { return _M_h.begin(__n); }
888
889 const_local_iterator
890 cbegin(size_type __n) const
891 { return _M_h.cbegin(__n); }
892 ///@}
893
894 ///@{
895 /**
896 * @brief Returns a read-only (constant) iterator pointing to one past
897 * the last bucket elements.
898 * @param __n The bucket index.
899 * @return A read-only local iterator.
900 */
901 local_iterator
902 end(size_type __n)
903 { return _M_h.end(__n); }
904
905 const_local_iterator
906 end(size_type __n) const
907 { return _M_h.end(__n); }
908
909 const_local_iterator
910 cend(size_type __n) const
911 { return _M_h.cend(__n); }
912 ///@}
913
914 // hash policy.
915
916 /// Returns the average number of elements per bucket.
917 float
918 load_factor() const noexcept
919 { return _M_h.load_factor(); }
920
921 /// Returns a positive number that the %unordered_set tries to keep the
922 /// load factor less than or equal to.
923 float
924 max_load_factor() const noexcept
925 { return _M_h.max_load_factor(); }
926
927 /**
928 * @brief Change the %unordered_set maximum load factor.
929 * @param __z The new maximum load factor.
930 */
931 void
932 max_load_factor(float __z)
933 { _M_h.max_load_factor(__z); }
934
935 /**
936 * @brief May rehash the %unordered_set.
937 * @param __n The new number of buckets.
938 *
939 * Rehash will occur only if the new number of buckets respect the
940 * %unordered_set maximum load factor.
941 */
942 void
943 rehash(size_type __n)
944 { _M_h.rehash(__n); }
945
946 /**
947 * @brief Prepare the %unordered_set for a specified number of
948 * elements.
949 * @param __n Number of elements required.
950 *
951 * Same as rehash(ceil(n / max_load_factor())).
952 */
953 void
954 reserve(size_type __n)
955 { _M_h.reserve(__n); }
956
957 template<typename _Value1, typename _Hash1, typename _Pred1,
958 typename _Alloc1>
959 friend bool
960 operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&,
961 const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&);
962 };
963
964#if __cpp_deduction_guides >= 201606
965
966 template<typename _InputIterator,
967 typename _Hash =
968 hash<typename iterator_traits<_InputIterator>::value_type>,
969 typename _Pred =
970 equal_to<typename iterator_traits<_InputIterator>::value_type>,
971 typename _Allocator =
972 allocator<typename iterator_traits<_InputIterator>::value_type>,
973 typename = _RequireInputIter<_InputIterator>,
974 typename = _RequireNotAllocatorOrIntegral<_Hash>,
975 typename = _RequireNotAllocator<_Pred>,
976 typename = _RequireAllocator<_Allocator>>
977 unordered_set(_InputIterator, _InputIterator,
978 unordered_set<int>::size_type = {},
979 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
980 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
981 _Hash, _Pred, _Allocator>;
982
983 template<typename _Tp, typename _Hash = hash<_Tp>,
984 typename _Pred = equal_to<_Tp>,
985 typename _Allocator = allocator<_Tp>,
986 typename = _RequireNotAllocatorOrIntegral<_Hash>,
987 typename = _RequireNotAllocator<_Pred>,
988 typename = _RequireAllocator<_Allocator>>
989 unordered_set(initializer_list<_Tp>,
990 unordered_set<int>::size_type = {},
991 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
992 -> unordered_set<_Tp, _Hash, _Pred, _Allocator>;
993
994 template<typename _InputIterator, typename _Allocator,
995 typename = _RequireInputIter<_InputIterator>,
996 typename = _RequireAllocator<_Allocator>>
997 unordered_set(_InputIterator, _InputIterator,
998 unordered_set<int>::size_type, _Allocator)
999 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
1000 hash<
1001 typename iterator_traits<_InputIterator>::value_type>,
1002 equal_to<
1003 typename iterator_traits<_InputIterator>::value_type>,
1004 _Allocator>;
1005
1006 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1007 // 2713. More missing allocator-extended constructors for unordered container
1008 template<typename _InputIterator, typename _Allocator,
1009 typename = _RequireInputIter<_InputIterator>,
1010 typename = _RequireAllocator<_Allocator>>
1011 unordered_set(_InputIterator, _InputIterator, _Allocator)
1012 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
1013 hash<
1014 typename iterator_traits<_InputIterator>::value_type>,
1015 equal_to<
1016 typename iterator_traits<_InputIterator>::value_type>,
1017 _Allocator>;
1018
1019 template<typename _InputIterator, typename _Hash, typename _Allocator,
1020 typename = _RequireInputIter<_InputIterator>,
1021 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1022 typename = _RequireAllocator<_Allocator>>
1023 unordered_set(_InputIterator, _InputIterator,
1024 unordered_set<int>::size_type,
1025 _Hash, _Allocator)
1026 -> unordered_set<typename iterator_traits<_InputIterator>::value_type,
1027 _Hash,
1028 equal_to<
1029 typename iterator_traits<_InputIterator>::value_type>,
1030 _Allocator>;
1031
1032 template<typename _Tp, typename _Allocator,
1033 typename = _RequireAllocator<_Allocator>>
1034 unordered_set(initializer_list<_Tp>,
1035 unordered_set<int>::size_type, _Allocator)
1036 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1037
1038 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1039 // 2713. More missing allocator-extended constructors for unordered container
1040 template<typename _Tp, typename _Allocator,
1041 typename = _RequireAllocator<_Allocator>>
1042 unordered_set(initializer_list<_Tp>, _Allocator)
1043 -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
1044
1045 template<typename _Tp, typename _Hash, typename _Allocator,
1046 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1047 typename = _RequireAllocator<_Allocator>>
1048 unordered_set(initializer_list<_Tp>,
1049 unordered_set<int>::size_type, _Hash, _Allocator)
1050 -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
1051
1052#if __glibcxx_containers_ranges // C++ >= 23
1053 template<ranges::input_range _Rg,
1054 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1055 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1056 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1057 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type = {},
1058 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1059 -> unordered_set<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1060
1061 template<ranges::input_range _Rg,
1062 __allocator_like _Allocator>
1063 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1064 _Allocator)
1065 -> unordered_set<ranges::range_value_t<_Rg>,
1066 hash<ranges::range_value_t<_Rg>>,
1067 equal_to<ranges::range_value_t<_Rg>>,
1068 _Allocator>;
1069
1070 template<ranges::input_range _Rg,
1071 __allocator_like _Allocator>
1072 unordered_set(from_range_t, _Rg&&, _Allocator)
1073 -> unordered_set<ranges::range_value_t<_Rg>,
1074 hash<ranges::range_value_t<_Rg>>,
1075 equal_to<ranges::range_value_t<_Rg>>,
1076 _Allocator>;
1077
1078 template<ranges::input_range _Rg,
1079 __not_allocator_like _Hash,
1080 __allocator_like _Allocator>
1081 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1082 _Hash, _Allocator)
1083 -> unordered_set<ranges::range_value_t<_Rg>, _Hash,
1084 equal_to<ranges::range_value_t<_Rg>>,
1085 _Allocator>;
1086#endif
1087#endif
1088
1089 /**
1090 * @brief A standard container composed of equivalent keys
1091 * (possibly containing multiple of each key value) in which the
1092 * elements' keys are the elements themselves.
1093 *
1094 * @ingroup unordered_associative_containers
1095 * @headerfile unordered_set
1096 * @since C++11
1097 *
1098 * @tparam _Value Type of key objects.
1099 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
1100 * @tparam _Pred Predicate function object type, defaults
1101 * to equal_to<_Value>.
1102 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
1103 *
1104 * Meets the requirements of a <a href="tables.html#65">container</a>, and
1105 * <a href="tables.html#xx">unordered associative container</a>
1106 *
1107 * Base is _Hashtable, dispatched at compile time via template
1108 * alias __umset_hashtable.
1109 */
1110 template<typename _Value,
1111 typename _Hash = hash<_Value>,
1112 typename _Pred = equal_to<_Value>,
1113 typename _Alloc = allocator<_Value>>
1114 class unordered_multiset
1115 {
1116 typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
1117 _Hashtable _M_h;
1118
1119 public:
1120 // typedefs:
1121 ///@{
1122 /// Public typedefs.
1123 typedef typename _Hashtable::key_type key_type;
1124 typedef typename _Hashtable::value_type value_type;
1125 typedef typename _Hashtable::hasher hasher;
1126 typedef typename _Hashtable::key_equal key_equal;
1127 typedef typename _Hashtable::allocator_type allocator_type;
1128 ///@}
1129
1130 ///@{
1131 /// Iterator-related typedefs.
1132 typedef typename _Hashtable::pointer pointer;
1133 typedef typename _Hashtable::const_pointer const_pointer;
1134 typedef typename _Hashtable::reference reference;
1135 typedef typename _Hashtable::const_reference const_reference;
1136 typedef typename _Hashtable::iterator iterator;
1137 typedef typename _Hashtable::const_iterator const_iterator;
1138 typedef typename _Hashtable::local_iterator local_iterator;
1139 typedef typename _Hashtable::const_local_iterator const_local_iterator;
1140 typedef typename _Hashtable::size_type size_type;
1141 typedef typename _Hashtable::difference_type difference_type;
1142 ///@}
1143
1144#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1145 using node_type = typename _Hashtable::node_type;
1146#endif
1147
1148 // construct/destroy/copy
1149
1150 /// Default constructor.
1151 unordered_multiset() = default;
1152
1153 /**
1154 * @brief Default constructor creates no elements.
1155 * @param __n Minimal initial number of buckets.
1156 * @param __hf A hash functor.
1157 * @param __eql A key equality functor.
1158 * @param __a An allocator object.
1159 */
1160 explicit
1161 unordered_multiset(size_type __n,
1162 const hasher& __hf = hasher(),
1163 const key_equal& __eql = key_equal(),
1164 const allocator_type& __a = allocator_type())
1165 : _M_h(__n, __hf, __eql, __a)
1166 { }
1167
1168 /**
1169 * @brief Builds an %unordered_multiset from a range.
1170 * @param __first An input iterator.
1171 * @param __last An input iterator.
1172 * @param __n Minimal initial number of buckets.
1173 * @param __hf A hash functor.
1174 * @param __eql A key equality functor.
1175 * @param __a An allocator object.
1176 *
1177 * Create an %unordered_multiset consisting of copies of the elements
1178 * from [__first,__last). This is linear in N (where N is
1179 * distance(__first,__last)).
1180 */
1181 template<typename _InputIterator>
1182 unordered_multiset(_InputIterator __first, _InputIterator __last,
1183 size_type __n = 0,
1184 const hasher& __hf = hasher(),
1185 const key_equal& __eql = key_equal(),
1186 const allocator_type& __a = allocator_type())
1187 : _M_h(__first, __last, __n, __hf, __eql, __a)
1188 { }
1189
1190 /// Copy constructor.
1191 unordered_multiset(const unordered_multiset&) = default;
1192
1193 /// Move constructor.
1194 unordered_multiset(unordered_multiset&&) = default;
1195
1196 /**
1197 * @brief Builds an %unordered_multiset from an initializer_list.
1198 * @param __l An initializer_list.
1199 * @param __n Minimal initial number of buckets.
1200 * @param __hf A hash functor.
1201 * @param __eql A key equality functor.
1202 * @param __a An allocator object.
1203 *
1204 * Create an %unordered_multiset consisting of copies of the elements in
1205 * the list. This is linear in N (where N is @a __l.size()).
1206 */
1207 unordered_multiset(initializer_list<value_type> __l,
1208 size_type __n = 0,
1209 const hasher& __hf = hasher(),
1210 const key_equal& __eql = key_equal(),
1211 const allocator_type& __a = allocator_type())
1212 : _M_h(__l, __n, __hf, __eql, __a)
1213 { }
1214
1215 /// Copy assignment operator.
1216 unordered_multiset&
1217 operator=(const unordered_multiset&) = default;
1218
1219 /// Move assignment operator.
1220 unordered_multiset&
1221 operator=(unordered_multiset&&) = default;
1222
1223 /**
1224 * @brief Creates an %unordered_multiset with no elements.
1225 * @param __a An allocator object.
1226 */
1227 explicit
1228 unordered_multiset(const allocator_type& __a)
1229 : _M_h(__a)
1230 { }
1231
1232 /*
1233 * @brief Copy constructor with allocator argument.
1234 * @param __uset Input %unordered_multiset to copy.
1235 * @param __a An allocator object.
1236 */
1237 unordered_multiset(const unordered_multiset& __umset,
1238 const allocator_type& __a)
1239 : _M_h(__umset._M_h, __a)
1240 { }
1241
1242 /*
1243 * @brief Move constructor with allocator argument.
1244 * @param __umset Input %unordered_multiset to move.
1245 * @param __a An allocator object.
1246 */
1247 unordered_multiset(unordered_multiset&& __umset,
1248 const allocator_type& __a)
1249 noexcept( noexcept(_Hashtable(std::move(__umset._M_h), __a)) )
1250 : _M_h(std::move(__umset._M_h), __a)
1251 { }
1252
1253 unordered_multiset(size_type __n, const allocator_type& __a)
1254 : unordered_multiset(__n, hasher(), key_equal(), __a)
1255 { }
1256
1257 unordered_multiset(size_type __n, const hasher& __hf,
1258 const allocator_type& __a)
1259 : unordered_multiset(__n, __hf, key_equal(), __a)
1260 { }
1261
1262 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1263 // 2713. More missing allocator-extended constructors for unordered container
1264 template<typename _InputIterator>
1265 unordered_multiset(_InputIterator __first, _InputIterator __last,
1266 const allocator_type& __a)
1267 : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a)
1268 { }
1269
1270 template<typename _InputIterator>
1271 unordered_multiset(_InputIterator __first, _InputIterator __last,
1272 size_type __n,
1273 const allocator_type& __a)
1274 : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
1275 { }
1276
1277 template<typename _InputIterator>
1278 unordered_multiset(_InputIterator __first, _InputIterator __last,
1279 size_type __n, const hasher& __hf,
1280 const allocator_type& __a)
1281 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
1282 { }
1283
1284 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1285 // 2713. More missing allocator-extended constructors for unordered container
1286 unordered_multiset(initializer_list<value_type> __l,
1287 const allocator_type& __a)
1288 : unordered_multiset(__l, 0, hasher(), key_equal(), __a)
1289 { }
1290
1291 unordered_multiset(initializer_list<value_type> __l,
1292 size_type __n,
1293 const allocator_type& __a)
1294 : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
1295 { }
1296
1297 unordered_multiset(initializer_list<value_type> __l,
1298 size_type __n, const hasher& __hf,
1299 const allocator_type& __a)
1300 : unordered_multiset(__l, __n, __hf, key_equal(), __a)
1301 { }
1302
1303#if __glibcxx_containers_ranges // C++ >= 23
1304 /**
1305 * @brief Builds an %unordered_multiset from a range.
1306 * @since C++23
1307 * @param __rg An input range of elements that can be converted to
1308 * the set's value type.
1309 * @param __n Minimal initial number of buckets.
1310 * @param __hf A hash functor.
1311 * @param __eql A key equality functor.
1312 * @param __a An allocator object.
1313 *
1314 * Create an %unordered_multiset consisting of copies of the elements in the
1315 * range. This is linear in N (where N is `std::ranges::size(__rg)`).
1316 */
1317 template<__detail::__container_compatible_range<_Value> _Rg>
1318 unordered_multiset(from_range_t, _Rg&& __rg,
1319 size_type __n = 0,
1320 const hasher& __hf = hasher(),
1321 const key_equal& __eql = key_equal(),
1322 const allocator_type& __a = allocator_type())
1323 : _M_h(__n, __hf, __eql, __a)
1324 { insert_range(std::forward<_Rg>(__rg)); }
1325
1326
1327 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1328 // 2713. More missing allocator-extended constructors for unordered container
1329 template<__detail::__container_compatible_range<_Value> _Rg>
1330 unordered_multiset(from_range_t, _Rg&& __rg, const allocator_type& __a)
1331 : _M_h(0, hasher(), key_equal(), __a)
1332 { insert_range(std::forward<_Rg>(__rg)); }
1333
1334 template<__detail::__container_compatible_range<_Value> _Rg>
1335 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1336 const allocator_type& __a)
1337 : _M_h(__n, hasher(), key_equal(), __a)
1338 { insert_range(std::forward<_Rg>(__rg)); }
1339
1340 template<__detail::__container_compatible_range<_Value> _Rg>
1341 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1342 const hasher& __hf, const allocator_type& __a)
1343 : _M_h(__n, __hf, key_equal(), __a)
1344 { insert_range(std::forward<_Rg>(__rg)); }
1345#endif
1346
1347
1348 /**
1349 * @brief %Unordered_multiset list assignment operator.
1350 * @param __l An initializer_list.
1351 *
1352 * This function fills an %unordered_multiset with copies of the elements
1353 * in the initializer list @a __l.
1354 *
1355 * Note that the assignment completely changes the %unordered_multiset
1356 * and that the resulting %unordered_multiset's size is the same as the
1357 * number of elements assigned.
1358 */
1359 unordered_multiset&
1360 operator=(initializer_list<value_type> __l)
1361 {
1362 _M_h = __l;
1363 return *this;
1364 }
1365
1366 /// Returns the allocator object used by the %unordered_multiset.
1367 allocator_type
1368 get_allocator() const noexcept
1369 { return _M_h.get_allocator(); }
1370
1371 // size and capacity:
1372
1373 /// Returns true if the %unordered_multiset is empty.
1374 _GLIBCXX_NODISCARD bool
1375 empty() const noexcept
1376 { return _M_h.empty(); }
1377
1378 /// Returns the size of the %unordered_multiset.
1379 size_type
1380 size() const noexcept
1381 { return _M_h.size(); }
1382
1383 /// Returns the maximum size of the %unordered_multiset.
1384 size_type
1385 max_size() const noexcept
1386 { return _M_h.max_size(); }
1387
1388 // iterators.
1389
1390 ///@{
1391 /**
1392 * Returns a read-only (constant) iterator that points to the first
1393 * element in the %unordered_multiset.
1394 */
1395 iterator
1396 begin() noexcept
1397 { return _M_h.begin(); }
1398
1399 const_iterator
1400 begin() const noexcept
1401 { return _M_h.begin(); }
1402 ///@}
1403
1404 ///@{
1405 /**
1406 * Returns a read-only (constant) iterator that points one past the last
1407 * element in the %unordered_multiset.
1408 */
1409 iterator
1410 end() noexcept
1411 { return _M_h.end(); }
1412
1413 const_iterator
1414 end() const noexcept
1415 { return _M_h.end(); }
1416 ///@}
1417
1418 /**
1419 * Returns a read-only (constant) iterator that points to the first
1420 * element in the %unordered_multiset.
1421 */
1422 const_iterator
1423 cbegin() const noexcept
1424 { return _M_h.begin(); }
1425
1426 /**
1427 * Returns a read-only (constant) iterator that points one past the last
1428 * element in the %unordered_multiset.
1429 */
1430 const_iterator
1431 cend() const noexcept
1432 { return _M_h.end(); }
1433
1434 // modifiers.
1435
1436 /**
1437 * @brief Builds and insert an element into the %unordered_multiset.
1438 * @param __args Arguments used to generate an element.
1439 * @return An iterator that points to the inserted element.
1440 *
1441 * Insertion requires amortized constant time.
1442 */
1443 template<typename... _Args>
1444 iterator
1445 emplace(_Args&&... __args)
1446 { return _M_h.emplace(std::forward<_Args>(__args)...); }
1447
1448 /**
1449 * @brief Inserts an element into the %unordered_multiset.
1450 * @param __pos An iterator that serves as a hint as to where the
1451 * element should be inserted.
1452 * @param __args Arguments used to generate the element to be
1453 * inserted.
1454 * @return An iterator that points to the inserted element.
1455 *
1456 * Note that the first parameter is only a hint and can potentially
1457 * improve the performance of the insertion process. A bad hint would
1458 * cause no gains in efficiency.
1459 *
1460 * For more on @a hinting, see:
1461 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1462 *
1463 * Insertion requires amortized constant time.
1464 */
1465 template<typename... _Args>
1466 iterator
1467 emplace_hint(const_iterator __pos, _Args&&... __args)
1468 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1469
1470 ///@{
1471 /**
1472 * @brief Inserts an element into the %unordered_multiset.
1473 * @param __x Element to be inserted.
1474 * @return An iterator that points to the inserted element.
1475 *
1476 * Insertion requires amortized constant time.
1477 */
1478 iterator
1479 insert(const value_type& __x)
1480 { return _M_h.insert(__x); }
1481
1482 iterator
1483 insert(value_type&& __x)
1484 { return _M_h.insert(std::move(__x)); }
1485 ///@}
1486
1487 ///@{
1488 /**
1489 * @brief Inserts an element into the %unordered_multiset.
1490 * @param __hint An iterator that serves as a hint as to where the
1491 * element should be inserted.
1492 * @param __x Element to be inserted.
1493 * @return An iterator that points to the inserted element.
1494 *
1495 * Note that the first parameter is only a hint and can potentially
1496 * improve the performance of the insertion process. A bad hint would
1497 * cause no gains in efficiency.
1498 *
1499 * For more on @a hinting, see:
1500 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1501 *
1502 * Insertion requires amortized constant.
1503 */
1504 iterator
1505 insert(const_iterator __hint, const value_type& __x)
1506 { return _M_h.insert(__hint, __x); }
1507
1508 iterator
1509 insert(const_iterator __hint, value_type&& __x)
1510 { return _M_h.insert(__hint, std::move(__x)); }
1511 ///@}
1512
1513 /**
1514 * @brief A template function that inserts a range of elements.
1515 * @param __first Iterator pointing to the start of the range to be
1516 * inserted.
1517 * @param __last Iterator pointing to the end of the range.
1518 *
1519 * Complexity similar to that of the range constructor.
1520 */
1521 template<typename _InputIterator>
1522 void
1523 insert(_InputIterator __first, _InputIterator __last)
1524 { _M_h.insert(__first, __last); }
1525
1526 /**
1527 * @brief Inserts a list of elements into the %unordered_multiset.
1528 * @param __l A std::initializer_list<value_type> of elements to be
1529 * inserted.
1530 *
1531 * Complexity similar to that of the range constructor.
1532 */
1533 void
1534 insert(initializer_list<value_type> __l)
1535 { _M_h.insert(__l); }
1536
1537#if __glibcxx_containers_ranges // C++ >= 23
1538 /**
1539 * @brief Inserts a range of elements.
1540 * @since C++23
1541 * @param __rg An input range of elements that can be converted to
1542 * the set's value type.
1543 */
1544 template<__detail::__container_compatible_range<_Value> _Rg>
1545 void
1546 insert_range(_Rg&& __rg)
1547 {
1548 auto __first = ranges::begin(__rg);
1549 const auto __last = ranges::end(__rg);
1550 if (__first == __last)
1551 return;
1552
1553 if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
1554 _M_h._M_rehash_insert(size_type(ranges::distance(__rg)));
1555 else
1556 _M_h._M_rehash_insert(1);
1557
1558 for (; __first != __last; ++__first)
1559 _M_h.emplace(*__first);
1560 }
1561#endif
1562
1563#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1564 /// Extract a node.
1565 node_type
1566 extract(const_iterator __pos)
1567 {
1568 __glibcxx_assert(__pos != end());
1569 return _M_h.extract(__pos);
1570 }
1571
1572 /// Extract a node.
1573 node_type
1574 extract(const key_type& __key)
1575 { return _M_h.extract(__key); }
1576
1577 /// Re-insert an extracted node.
1578 iterator
1579 insert(node_type&& __nh)
1580 { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1581
1582 /// Re-insert an extracted node.
1583 iterator
1584 insert(const_iterator __hint, node_type&& __nh)
1585 { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1586#endif // node_extract
1587
1588 ///@{
1589 /**
1590 * @brief Erases an element from an %unordered_multiset.
1591 * @param __position An iterator pointing to the element to be erased.
1592 * @return An iterator pointing to the element immediately following
1593 * @a __position prior to the element being erased. If no such
1594 * element exists, end() is returned.
1595 *
1596 * This function erases an element, pointed to by the given iterator,
1597 * from an %unordered_multiset.
1598 *
1599 * Note that this function only erases the element, and that if the
1600 * element is itself a pointer, the pointed-to memory is not touched in
1601 * any way. Managing the pointer is the user's responsibility.
1602 */
1603 iterator
1604 erase(const_iterator __position)
1605 { return _M_h.erase(__position); }
1606
1607 // LWG 2059.
1608 iterator
1609 erase(iterator __position)
1610 { return _M_h.erase(__position); }
1611 ///@}
1612
1613
1614 /**
1615 * @brief Erases elements according to the provided key.
1616 * @param __x Key of element to be erased.
1617 * @return The number of elements erased.
1618 *
1619 * This function erases all the elements located by the given key from
1620 * an %unordered_multiset.
1621 *
1622 * Note that this function only erases the element, and that if the
1623 * element is itself a pointer, the pointed-to memory is not touched in
1624 * any way. Managing the pointer is the user's responsibility.
1625 */
1626 size_type
1627 erase(const key_type& __x)
1628 { return _M_h.erase(__x); }
1629
1630 /**
1631 * @brief Erases a [__first,__last) range of elements from an
1632 * %unordered_multiset.
1633 * @param __first Iterator pointing to the start of the range to be
1634 * erased.
1635 * @param __last Iterator pointing to the end of the range to
1636 * be erased.
1637 * @return The iterator @a __last.
1638 *
1639 * This function erases a sequence of elements from an
1640 * %unordered_multiset.
1641 *
1642 * Note that this function only erases the element, and that if
1643 * the element is itself a pointer, the pointed-to memory is not touched
1644 * in any way. Managing the pointer is the user's responsibility.
1645 */
1646 iterator
1647 erase(const_iterator __first, const_iterator __last)
1648 { return _M_h.erase(__first, __last); }
1649
1650 /**
1651 * Erases all elements in an %unordered_multiset.
1652 *
1653 * Note that this function only erases the elements, and that if the
1654 * elements themselves are pointers, the pointed-to memory is not touched
1655 * in any way. Managing the pointer is the user's responsibility.
1656 */
1657 void
1658 clear() noexcept
1659 { _M_h.clear(); }
1660
1661 /**
1662 * @brief Swaps data with another %unordered_multiset.
1663 * @param __x An %unordered_multiset of the same element and allocator
1664 * types.
1665 *
1666 * This exchanges the elements between two sets in constant time.
1667 * Note that the global std::swap() function is specialized such that
1668 * std::swap(s1,s2) will feed to this function.
1669 */
1670 void
1671 swap(unordered_multiset& __x)
1672 noexcept( noexcept(_M_h.swap(__x._M_h)) )
1673 { _M_h.swap(__x._M_h); }
1674
1675#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1676 template<typename, typename, typename>
1677 friend class std::_Hash_merge_helper;
1678
1679 template<typename _H2, typename _P2>
1680 void
1681 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
1682 {
1683 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
1684 if (std::__addressof(__source) == this) [[__unlikely__]]
1685 return;
1686
1687 using _Merge_helper
1688 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1689 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1690 }
1691
1692 template<typename _H2, typename _P2>
1693 void
1694 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1695 {
1696 using _Merge_helper
1697 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1698 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1699 }
1700
1701 template<typename _H2, typename _P2>
1702 void
1703 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1704 {
1705 using _Merge_helper
1706 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1707 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1708 }
1709
1710 template<typename _H2, typename _P2>
1711 void
1712 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1713 { merge(__source); }
1714#endif // node_extract
1715
1716 // observers.
1717
1718 /// Returns the hash functor object with which the %unordered_multiset
1719 /// was constructed.
1720 hasher
1721 hash_function() const
1722 { return _M_h.hash_function(); }
1723
1724 /// Returns the key comparison object with which the %unordered_multiset
1725 /// was constructed.
1726 key_equal
1727 key_eq() const
1728 { return _M_h.key_eq(); }
1729
1730 // lookup.
1731
1732 ///@{
1733 /**
1734 * @brief Tries to locate an element in an %unordered_multiset.
1735 * @param __x Element to be located.
1736 * @return Iterator pointing to sought-after element, or end() if not
1737 * found.
1738 *
1739 * This function takes a key and tries to locate the element with which
1740 * the key matches. If successful the function returns an iterator
1741 * pointing to the sought after element. If unsuccessful it returns the
1742 * past-the-end ( @c end() ) iterator.
1743 */
1744 iterator
1745 find(const key_type& __x)
1746 { return _M_h.find(__x); }
1747
1748#if __cplusplus > 201703L
1749 template<typename _Kt>
1750 auto
1751 find(const _Kt& __x)
1752 -> decltype(_M_h._M_find_tr(__x))
1753 { return _M_h._M_find_tr(__x); }
1754#endif
1755
1756 const_iterator
1757 find(const key_type& __x) const
1758 { return _M_h.find(__x); }
1759
1760#if __cplusplus > 201703L
1761 template<typename _Kt>
1762 auto
1763 find(const _Kt& __x) const
1764 -> decltype(_M_h._M_find_tr(__x))
1765 { return _M_h._M_find_tr(__x); }
1766#endif
1767 ///@}
1768
1769 ///@{
1770 /**
1771 * @brief Finds the number of elements.
1772 * @param __x Element to located.
1773 * @return Number of elements with specified key.
1774 */
1775 size_type
1776 count(const key_type& __x) const
1777 { return _M_h.count(__x); }
1778
1779#if __cplusplus > 201703L
1780 template<typename _Kt>
1781 auto
1782 count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
1783 { return _M_h._M_count_tr(__x); }
1784#endif
1785 ///@}
1786
1787#if __cplusplus > 201703L
1788 ///@{
1789 /**
1790 * @brief Finds whether an element with the given key exists.
1791 * @param __x Key of elements to be located.
1792 * @return True if there is any element with the specified key.
1793 */
1794 bool
1795 contains(const key_type& __x) const
1796 { return _M_h.find(__x) != _M_h.end(); }
1797
1798 template<typename _Kt>
1799 auto
1800 contains(const _Kt& __x) const
1801 -> decltype(_M_h._M_find_tr(__x), void(), true)
1802 { return _M_h._M_find_tr(__x) != _M_h.end(); }
1803 ///@}
1804#endif
1805
1806 ///@{
1807 /**
1808 * @brief Finds a subsequence matching given key.
1809 * @param __x Key to be located.
1810 * @return Pair of iterators that possibly points to the subsequence
1811 * matching given key.
1812 */
1813 std::pair<iterator, iterator>
1814 equal_range(const key_type& __x)
1815 { return _M_h.equal_range(__x); }
1816
1817#if __cplusplus > 201703L
1818 template<typename _Kt>
1819 auto
1820 equal_range(const _Kt& __x)
1821 -> decltype(_M_h._M_equal_range_tr(__x))
1822 { return _M_h._M_equal_range_tr(__x); }
1823#endif
1824
1825 std::pair<const_iterator, const_iterator>
1826 equal_range(const key_type& __x) const
1827 { return _M_h.equal_range(__x); }
1828
1829#if __cplusplus > 201703L
1830 template<typename _Kt>
1831 auto
1832 equal_range(const _Kt& __x) const
1833 -> decltype(_M_h._M_equal_range_tr(__x))
1834 { return _M_h._M_equal_range_tr(__x); }
1835#endif
1836 ///@}
1837
1838 // bucket interface.
1839
1840 /// Returns the number of buckets of the %unordered_multiset.
1841 size_type
1842 bucket_count() const noexcept
1843 { return _M_h.bucket_count(); }
1844
1845 /// Returns the maximum number of buckets of the %unordered_multiset.
1846 size_type
1847 max_bucket_count() const noexcept
1848 { return _M_h.max_bucket_count(); }
1849
1850 /*
1851 * @brief Returns the number of elements in a given bucket.
1852 * @param __n A bucket index.
1853 * @return The number of elements in the bucket.
1854 */
1855 size_type
1856 bucket_size(size_type __n) const
1857 { return _M_h.bucket_size(__n); }
1858
1859 /*
1860 * @brief Returns the bucket index of a given element.
1861 * @param __key A key instance.
1862 * @return The key bucket index.
1863 */
1864 size_type
1865 bucket(const key_type& __key) const
1866 { return _M_h.bucket(__key); }
1867
1868 ///@{
1869 /**
1870 * @brief Returns a read-only (constant) iterator pointing to the first
1871 * bucket element.
1872 * @param __n The bucket index.
1873 * @return A read-only local iterator.
1874 */
1875 local_iterator
1876 begin(size_type __n)
1877 { return _M_h.begin(__n); }
1878
1879 const_local_iterator
1880 begin(size_type __n) const
1881 { return _M_h.begin(__n); }
1882
1883 const_local_iterator
1884 cbegin(size_type __n) const
1885 { return _M_h.cbegin(__n); }
1886 ///@}
1887
1888 ///@{
1889 /**
1890 * @brief Returns a read-only (constant) iterator pointing to one past
1891 * the last bucket elements.
1892 * @param __n The bucket index.
1893 * @return A read-only local iterator.
1894 */
1895 local_iterator
1896 end(size_type __n)
1897 { return _M_h.end(__n); }
1898
1899 const_local_iterator
1900 end(size_type __n) const
1901 { return _M_h.end(__n); }
1902
1903 const_local_iterator
1904 cend(size_type __n) const
1905 { return _M_h.cend(__n); }
1906 ///@}
1907
1908 // hash policy.
1909
1910 /// Returns the average number of elements per bucket.
1911 float
1912 load_factor() const noexcept
1913 { return _M_h.load_factor(); }
1914
1915 /// Returns a positive number that the %unordered_multiset tries to keep the
1916 /// load factor less than or equal to.
1917 float
1918 max_load_factor() const noexcept
1919 { return _M_h.max_load_factor(); }
1920
1921 /**
1922 * @brief Change the %unordered_multiset maximum load factor.
1923 * @param __z The new maximum load factor.
1924 */
1925 void
1926 max_load_factor(float __z)
1927 { _M_h.max_load_factor(__z); }
1928
1929 /**
1930 * @brief May rehash the %unordered_multiset.
1931 * @param __n The new number of buckets.
1932 *
1933 * Rehash will occur only if the new number of buckets respect the
1934 * %unordered_multiset maximum load factor.
1935 */
1936 void
1937 rehash(size_type __n)
1938 { _M_h.rehash(__n); }
1939
1940 /**
1941 * @brief Prepare the %unordered_multiset for a specified number of
1942 * elements.
1943 * @param __n Number of elements required.
1944 *
1945 * Same as rehash(ceil(n / max_load_factor())).
1946 */
1947 void
1948 reserve(size_type __n)
1949 { _M_h.reserve(__n); }
1950
1951 template<typename _Value1, typename _Hash1, typename _Pred1,
1952 typename _Alloc1>
1953 friend bool
1954 operator==(const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&,
1955 const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&);
1956 };
1957
1958
1959#if __cpp_deduction_guides >= 201606
1960
1961 template<typename _InputIterator,
1962 typename _Hash =
1963 hash<typename iterator_traits<_InputIterator>::value_type>,
1964 typename _Pred =
1965 equal_to<typename iterator_traits<_InputIterator>::value_type>,
1966 typename _Allocator =
1967 allocator<typename iterator_traits<_InputIterator>::value_type>,
1968 typename = _RequireInputIter<_InputIterator>,
1969 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1970 typename = _RequireNotAllocator<_Pred>,
1971 typename = _RequireAllocator<_Allocator>>
1972 unordered_multiset(_InputIterator, _InputIterator,
1973 unordered_multiset<int>::size_type = {},
1974 _Hash = _Hash(), _Pred = _Pred(),
1975 _Allocator = _Allocator())
1976 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1977 _Hash, _Pred, _Allocator>;
1978
1979 template<typename _Tp, typename _Hash = hash<_Tp>,
1980 typename _Pred = equal_to<_Tp>,
1981 typename _Allocator = allocator<_Tp>,
1982 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1983 typename = _RequireNotAllocator<_Pred>,
1984 typename = _RequireAllocator<_Allocator>>
1985 unordered_multiset(initializer_list<_Tp>,
1986 unordered_multiset<int>::size_type = {},
1987 _Hash = _Hash(), _Pred = _Pred(),
1988 _Allocator = _Allocator())
1989 -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>;
1990
1991 template<typename _InputIterator, typename _Allocator,
1992 typename = _RequireInputIter<_InputIterator>,
1993 typename = _RequireAllocator<_Allocator>>
1994 unordered_multiset(_InputIterator, _InputIterator,
1995 unordered_multiset<int>::size_type, _Allocator)
1996 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
1997 hash<typename
1998 iterator_traits<_InputIterator>::value_type>,
1999 equal_to<typename
2000 iterator_traits<_InputIterator>::value_type>,
2001 _Allocator>;
2002
2003 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2004 // 2713. More missing allocator-extended constructors for unordered container
2005 template<typename _InputIterator, typename _Allocator,
2006 typename = _RequireInputIter<_InputIterator>,
2007 typename = _RequireAllocator<_Allocator>>
2008 unordered_multiset(_InputIterator, _InputIterator, _Allocator)
2009 -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type,
2010 hash<typename
2011 iterator_traits<_InputIterator>::value_type>,
2012 equal_to<typename
2013 iterator_traits<_InputIterator>::value_type>,
2014 _Allocator>;
2015
2016 template<typename _InputIterator, typename _Hash, typename _Allocator,
2017 typename = _RequireInputIter<_InputIterator>,
2018 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2019 typename = _RequireAllocator<_Allocator>>
2020 unordered_multiset(_InputIterator, _InputIterator,
2021 unordered_multiset<int>::size_type,
2022 _Hash, _Allocator)
2023 -> unordered_multiset<typename
2024 iterator_traits<_InputIterator>::value_type,
2025 _Hash,
2026 equal_to<
2027 typename
2028 iterator_traits<_InputIterator>::value_type>,
2029 _Allocator>;
2030
2031 template<typename _Tp, typename _Allocator,
2032 typename = _RequireAllocator<_Allocator>>
2033 unordered_multiset(initializer_list<_Tp>,
2034 unordered_multiset<int>::size_type, _Allocator)
2035 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
2036
2037 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2038 // 2713. More missing allocator-extended constructors for unordered container
2039 template<typename _Tp, typename _Allocator,
2040 typename = _RequireAllocator<_Allocator>>
2041 unordered_multiset(initializer_list<_Tp>, _Allocator)
2042 -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>;
2043
2044 template<typename _Tp, typename _Hash, typename _Allocator,
2045 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2046 typename = _RequireAllocator<_Allocator>>
2047 unordered_multiset(initializer_list<_Tp>,
2048 unordered_multiset<int>::size_type, _Hash, _Allocator)
2049 -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>;
2050
2051#if __glibcxx_containers_ranges // C++ >= 23
2052 template<ranges::input_range _Rg,
2053 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
2054 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
2055 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
2056 unordered_multiset(from_range_t, _Rg&&,
2057 unordered_multiset<int>::size_type = {},
2058 _Hash = _Hash(), _Pred = _Pred(),
2059 _Allocator = _Allocator())
2060 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
2061
2062 template<ranges::input_range _Rg,
2063 __allocator_like _Allocator>
2064 unordered_multiset(from_range_t, _Rg&&, _Allocator)
2065 -> unordered_multiset<ranges::range_value_t<_Rg>,
2066 hash<ranges::range_value_t<_Rg>>,
2067 equal_to<ranges::range_value_t<_Rg>>,
2068 _Allocator>;
2069
2070 template<ranges::input_range _Rg,
2071 __allocator_like _Allocator>
2072 unordered_multiset(from_range_t, _Rg&&, unordered_multiset<int>::size_type,
2073 _Allocator)
2074 -> unordered_multiset<ranges::range_value_t<_Rg>,
2075 hash<ranges::range_value_t<_Rg>>,
2076 equal_to<ranges::range_value_t<_Rg>>,
2077 _Allocator>;
2078
2079 template<ranges::input_range _Rg,
2080 __not_allocator_like _Hash,
2081 __allocator_like _Allocator>
2082 unordered_multiset(from_range_t, _Rg&&,
2083 unordered_multiset<int>::size_type,
2084 _Hash, _Allocator)
2085 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash,
2086 equal_to<ranges::range_value_t<_Rg>>,
2087 _Allocator>;
2088#endif
2089#endif
2090
2091 template<class _Value, class _Hash, class _Pred, class _Alloc>
2092 inline void
2093 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
2094 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
2095 noexcept(noexcept(__x.swap(__y)))
2096 { __x.swap(__y); }
2097
2098 template<class _Value, class _Hash, class _Pred, class _Alloc>
2099 inline void
2100 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
2101 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
2102 noexcept(noexcept(__x.swap(__y)))
2103 { __x.swap(__y); }
2104
2105 template<class _Value, class _Hash, class _Pred, class _Alloc>
2106 inline bool
2107 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
2108 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
2109 { return __x._M_h._M_equal(__y._M_h); }
2110
2111#if __cpp_impl_three_way_comparison < 201907L
2112 template<class _Value, class _Hash, class _Pred, class _Alloc>
2113 inline bool
2114 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
2115 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
2116 { return !(__x == __y); }
2117#endif
2118
2119 template<class _Value, class _Hash, class _Pred, class _Alloc>
2120 inline bool
2121 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
2122 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
2123 { return __x._M_h._M_equal(__y._M_h); }
2124
2125#if __cpp_impl_three_way_comparison < 201907L
2126 template<class _Value, class _Hash, class _Pred, class _Alloc>
2127 inline bool
2128 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
2129 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
2130 { return !(__x == __y); }
2131#endif
2132
2133_GLIBCXX_END_NAMESPACE_CONTAINER
2134
2135#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
2136 // Allow std::unordered_set access to internals of compatible sets.
2137 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
2138 typename _Hash2, typename _Eq2>
2139 struct _Hash_merge_helper<
2140 _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2>
2141 {
2142 private:
2143 template<typename... _Tp>
2144 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
2145 template<typename... _Tp>
2146 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
2147
2148 friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>;
2149
2150 static auto&
2151 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
2152 { return __set._M_h; }
2153
2154 static auto&
2155 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
2156 { return __set._M_h; }
2157 };
2158
2159 // Allow std::unordered_multiset access to internals of compatible sets.
2160 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
2161 typename _Hash2, typename _Eq2>
2162 struct _Hash_merge_helper<
2163 _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>,
2164 _Hash2, _Eq2>
2165 {
2166 private:
2167 template<typename... _Tp>
2168 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
2169 template<typename... _Tp>
2170 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
2171
2172 friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>;
2173
2174 static auto&
2175 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
2176 { return __set._M_h; }
2177
2178 static auto&
2179 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
2180 { return __set._M_h; }
2181 };
2182#endif // node_extract
2183
2184_GLIBCXX_END_NAMESPACE_VERSION
2185} // namespace std
2186
2187#endif /* _UNORDERED_SET_H */