libstdc++
unordered_set.h
Go to the documentation of this file.
1// unordered_set implementation -*- C++ -*-
2
3// Copyright (C) 2010-2026 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>,
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>,
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>
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>>
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
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.
189
190 /**
191 * @brief Creates an %unordered_set with no elements.
192 * @param __a An allocator object.
193 */
194 explicit
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 */
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.
335 operator=(const unordered_set&) = default;
336
337 /// Move assignment operator.
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 */
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.
373 size() const noexcept
374 { return _M_h.size(); }
375
376 /// Returns the maximum size of the %unordered_set.
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 */
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 */
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>
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>
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 */
490 insert(const value_type& __x)
491 { return _M_h.insert(__x); }
492
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 */
519 insert(const_iterator __hint, const value_type& __x)
520 { return _M_h.insert(__hint, __x); }
521
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
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#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
585 template <__heterogeneous_hash_key<unordered_set> _Kt>
586 node_type
587 extract(_Kt&& __key)
588 { return _M_h._M_extract_tr(__key); }
589#endif
590
591 /// Re-insert an extracted node.
592 insert_return_type
593 insert(node_type&& __nh)
594 { return _M_h._M_reinsert_node(std::move(__nh)); }
595
596 /// Re-insert an extracted node.
598 insert(const_iterator, node_type&& __nh)
599 { return _M_h._M_reinsert_node(std::move(__nh)).position; }
600#endif // node_extract
601
602 ///@{
603 /**
604 * @brief Erases an element from an %unordered_set.
605 * @param __position An iterator pointing to the element to be erased.
606 * @return An iterator pointing to the element immediately following
607 * @a __position prior to the element being erased. If no such
608 * element exists, end() is returned.
609 *
610 * This function erases an element, pointed to by the given iterator,
611 * from an %unordered_set. Note that this function only erases the
612 * element, and that if the element is itself a pointer, the pointed-to
613 * memory is not touched in any way. Managing the pointer is the user's
614 * responsibility.
615 */
618 { return _M_h.erase(__position); }
619
620 // LWG 2059.
622 erase(iterator __position)
623 { return _M_h.erase(__position); }
624 ///@}
625
626 /**
627 * @brief Erases elements according to the provided key.
628 * @param __x Key of element to be erased.
629 * @return The number of elements erased.
630 *
631 * This function erases all the elements located by the given key from
632 * an %unordered_set. For an %unordered_set the result of this function
633 * can only be 0 (not present) or 1 (present).
634 * Note that this function only erases the element, and that if
635 * the element is itself a pointer, the pointed-to memory is not touched
636 * in any way. Managing the pointer is the user's responsibility.
637 */
639 erase(const key_type& __x)
640 { return _M_h.erase(__x); }
641
642#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
643 template <__heterogeneous_hash_key<unordered_set> _Kt>
645 erase(_Kt&& __key)
646 { return _M_h._M_erase_tr(__key); }
647#endif
648
649 /**
650 * @brief Erases a [__first,__last) range of elements from an
651 * %unordered_set.
652 * @param __first Iterator pointing to the start of the range to be
653 * erased.
654 * @param __last Iterator pointing to the end of the range to
655 * be erased.
656 * @return The iterator @a __last.
657 *
658 * This function erases a sequence of elements from an %unordered_set.
659 * Note that this function only erases the element, and that if
660 * the element is itself a pointer, the pointed-to memory is not touched
661 * in any way. Managing the pointer is the user's responsibility.
662 */
663 iterator
665 { return _M_h.erase(__first, __last); }
666
667 /**
668 * Erases all elements in an %unordered_set. Note that this function only
669 * erases the elements, and that if the elements themselves are pointers,
670 * the pointed-to memory is not touched in any way. Managing the pointer
671 * is the user's responsibility.
672 */
673 void
674 clear() noexcept
675 { _M_h.clear(); }
676
677 /**
678 * @brief Swaps data with another %unordered_set.
679 * @param __x An %unordered_set of the same element and allocator
680 * types.
681 *
682 * This exchanges the elements between two sets in constant time.
683 * Note that the global std::swap() function is specialized such that
684 * std::swap(s1,s2) will feed to this function.
685 */
686 void
688 noexcept( noexcept(_M_h.swap(__x._M_h)) )
689 { _M_h.swap(__x._M_h); }
690
691#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
692 template<typename, typename, typename>
693 friend class std::_Hash_merge_helper;
694
695 template<typename _H2, typename _P2>
696 void
698 {
699 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
700 if (std::__addressof(__source) == this) [[__unlikely__]]
701 return;
702
703 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
704 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
705 }
706
707 template<typename _H2, typename _P2>
708 void
709 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
710 {
711 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
712 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
713 }
714
715 template<typename _H2, typename _P2>
716 void
717 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
718 {
719 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
720 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
721 }
722
723 template<typename _H2, typename _P2>
724 void
725 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
726 { merge(__source); }
727#endif // node_extract
728
729 // observers.
730
731 /// Returns the hash functor object with which the %unordered_set was
732 /// constructed.
733 hasher
735 { return _M_h.hash_function(); }
736
737 /// Returns the key comparison object with which the %unordered_set was
738 /// constructed.
740 key_eq() const
741 { return _M_h.key_eq(); }
742
743 // lookup.
744
745 ///@{
746 /**
747 * @brief Tries to locate an element in an %unordered_set.
748 * @param __x Element to be located.
749 * @return Iterator pointing to sought-after element, or end() if not
750 * found.
751 *
752 * This function takes a key and tries to locate the element with which
753 * the key matches. If successful the function returns an iterator
754 * pointing to the sought after element. If unsuccessful it returns the
755 * past-the-end ( @c end() ) iterator.
756 */
758 find(const key_type& __x)
759 { return _M_h.find(__x); }
760
761#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
762 template<typename _Kt>
763 auto
764 find(const _Kt& __k)
765 -> decltype(_M_h._M_find_tr(__k))
766 { return _M_h._M_find_tr(__k); }
767#endif
768
769 const_iterator
770 find(const key_type& __x) const
771 { return _M_h.find(__x); }
772
773#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
774 template<typename _Kt>
775 auto
776 find(const _Kt& __k) const
777 -> decltype(_M_h._M_find_tr(__k))
778 { return _M_h._M_find_tr(__k); }
779#endif
780 ///@}
781
782 ///@{
783 /**
784 * @brief Finds the number of elements.
785 * @param __x Element to located.
786 * @return Number of elements with specified key.
787 *
788 * This function only makes sense for unordered_multisets; for
789 * unordered_set the result will either be 0 (not present) or 1
790 * (present).
791 */
792 size_type
793 count(const key_type& __x) const
794 { return _M_h.count(__x); }
795
796#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
797 template<typename _Kt>
798 auto
799 count(const _Kt& __k) const
800 -> decltype(_M_h._M_count_tr(__k))
801 { return _M_h._M_count_tr(__k); }
802#endif
803 ///@}
804
805#if __cplusplus > 201703L
806 ///@{
807 /**
808 * @brief Finds whether an element with the given key exists.
809 * @param __x Key of elements to be located.
810 * @return True if there is any element with the specified key.
811 */
812 bool
813 contains(const key_type& __x) const
814 { return _M_h.find(__x) != _M_h.end(); }
815
816 template<typename _Kt>
817 auto
818 contains(const _Kt& __k) const
819 -> decltype(_M_h._M_find_tr(__k), void(), true)
820 { return _M_h._M_find_tr(__k) != _M_h.end(); }
821 ///@}
822#endif
823
824 ///@{
825 /**
826 * @brief Finds a subsequence matching given key.
827 * @param __x Key to be located.
828 * @return Pair of iterators that possibly points to the subsequence
829 * matching given key.
830 *
831 * This function probably only makes sense for multisets.
832 */
835 { return _M_h.equal_range(__x); }
836
837#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
838 template<typename _Kt>
839 auto
840 equal_range(const _Kt& __k)
841 -> decltype(_M_h._M_equal_range_tr(__k))
842 { return _M_h._M_equal_range_tr(__k); }
843#endif
844
846 equal_range(const key_type& __x) const
847 { return _M_h.equal_range(__x); }
848
849#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
850 template<typename _Kt>
851 auto
852 equal_range(const _Kt& __k) const
853 -> decltype(_M_h._M_equal_range_tr(__k))
854 { return _M_h._M_equal_range_tr(__k); }
855#endif
856 ///@}
857
858 // bucket interface.
859
860 /// Returns the number of buckets of the %unordered_set.
861 size_type
862 bucket_count() const noexcept
863 { return _M_h.bucket_count(); }
864
865 /// Returns the maximum number of buckets of the %unordered_set.
867 max_bucket_count() const noexcept
868 { return _M_h.max_bucket_count(); }
869
870 /*
871 * @brief Returns the number of elements in a given bucket.
872 * @param __n A bucket index.
873 * @return The number of elements in the bucket.
874 */
876 bucket_size(size_type __n) const
877 { return _M_h.bucket_size(__n); }
878
879 /*
880 * @brief Returns the bucket index of a given element.
881 * @param __key A key instance.
882 * @return The key bucket index.
883 */
884 size_type
885 bucket(const key_type& __key) const
886 { return _M_h.bucket(__key); }
887
888 ///@{
889 /**
890 * @brief Returns a read-only (constant) iterator pointing to the first
891 * bucket element.
892 * @param __n The bucket index.
893 * @return A read-only local iterator.
894 */
897 { return _M_h.begin(__n); }
898
900 begin(size_type __n) const
901 { return _M_h.begin(__n); }
902
904 cbegin(size_type __n) const
905 { return _M_h.cbegin(__n); }
906 ///@}
907
908 ///@{
909 /**
910 * @brief Returns a read-only (constant) iterator pointing to one past
911 * the last bucket elements.
912 * @param __n The bucket index.
913 * @return A read-only local iterator.
914 */
917 { return _M_h.end(__n); }
918
920 end(size_type __n) const
921 { return _M_h.end(__n); }
922
924 cend(size_type __n) const
925 { return _M_h.cend(__n); }
926 ///@}
927
928 // hash policy.
929
930 /// Returns the average number of elements per bucket.
931 float
932 load_factor() const noexcept
933 { return _M_h.load_factor(); }
934
935 /// Returns a positive number that the %unordered_set tries to keep the
936 /// load factor less than or equal to.
937 float
938 max_load_factor() const noexcept
939 { return _M_h.max_load_factor(); }
940
941 /**
942 * @brief Change the %unordered_set maximum load factor.
943 * @param __z The new maximum load factor.
944 */
945 void
947 { _M_h.max_load_factor(__z); }
948
949 /**
950 * @brief May rehash the %unordered_set.
951 * @param __n The new number of buckets.
952 *
953 * Rehash will occur only if the new number of buckets respect the
954 * %unordered_set maximum load factor.
955 */
956 void
958 { _M_h.rehash(__n); }
959
960 /**
961 * @brief Prepare the %unordered_set for a specified number of
962 * elements.
963 * @param __n Number of elements required.
964 *
965 * Same as rehash(ceil(n / max_load_factor())).
966 */
967 void
969 { _M_h.reserve(__n); }
970
971 template<typename _Value1, typename _Hash1, typename _Pred1,
972 typename _Alloc1>
973 friend bool
976 };
977
978#if __cpp_deduction_guides >= 201606
979
980 template<typename _InputIterator,
981 typename _Hash =
982 hash<typename iterator_traits<_InputIterator>::value_type>,
983 typename _Pred =
984 equal_to<typename iterator_traits<_InputIterator>::value_type>,
985 typename _Allocator =
986 allocator<typename iterator_traits<_InputIterator>::value_type>,
987 typename = _RequireInputIter<_InputIterator>,
988 typename = _RequireNotAllocatorOrIntegral<_Hash>,
989 typename = _RequireNotAllocator<_Pred>,
990 typename = _RequireAllocator<_Allocator>>
991 unordered_set(_InputIterator, _InputIterator,
992 unordered_set<int>::size_type = {},
993 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
995 _Hash, _Pred, _Allocator>;
996
997 template<typename _Tp, typename _Hash = hash<_Tp>,
998 typename _Pred = equal_to<_Tp>,
999 typename _Allocator = allocator<_Tp>,
1000 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1001 typename = _RequireNotAllocator<_Pred>,
1002 typename = _RequireAllocator<_Allocator>>
1005 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1007
1008 template<typename _InputIterator, typename _Allocator,
1009 typename = _RequireInputIter<_InputIterator>,
1010 typename = _RequireAllocator<_Allocator>>
1011 unordered_set(_InputIterator, _InputIterator,
1014 hash<
1016 equal_to<
1018 _Allocator>;
1019
1020 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1021 // 2713. More missing allocator-extended constructors for unordered container
1022 template<typename _InputIterator, typename _Allocator,
1023 typename = _RequireInputIter<_InputIterator>,
1024 typename = _RequireAllocator<_Allocator>>
1025 unordered_set(_InputIterator, _InputIterator, _Allocator)
1027 hash<
1029 equal_to<
1031 _Allocator>;
1032
1033 template<typename _InputIterator, typename _Hash, typename _Allocator,
1034 typename = _RequireInputIter<_InputIterator>,
1035 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1036 typename = _RequireAllocator<_Allocator>>
1037 unordered_set(_InputIterator, _InputIterator,
1039 _Hash, _Allocator)
1041 _Hash,
1042 equal_to<
1044 _Allocator>;
1045
1046 template<typename _Tp, typename _Allocator,
1047 typename = _RequireAllocator<_Allocator>>
1051
1052 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1053 // 2713. More missing allocator-extended constructors for unordered container
1054 template<typename _Tp, typename _Allocator,
1055 typename = _RequireAllocator<_Allocator>>
1058
1059 template<typename _Tp, typename _Hash, typename _Allocator,
1060 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1061 typename = _RequireAllocator<_Allocator>>
1063 unordered_set<int>::size_type, _Hash, _Allocator)
1065
1066#if __glibcxx_containers_ranges // C++ >= 23
1067 template<ranges::input_range _Rg,
1068 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
1069 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
1070 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
1071 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type = {},
1072 _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator())
1073 -> unordered_set<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
1074
1075 template<ranges::input_range _Rg,
1076 __allocator_like _Allocator>
1077 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1078 _Allocator)
1082 _Allocator>;
1083
1084 template<ranges::input_range _Rg,
1085 __allocator_like _Allocator>
1086 unordered_set(from_range_t, _Rg&&, _Allocator)
1090 _Allocator>;
1091
1092 template<ranges::input_range _Rg,
1093 __not_allocator_like _Hash,
1094 __allocator_like _Allocator>
1095 unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type,
1096 _Hash, _Allocator)
1099 _Allocator>;
1100#endif
1101#endif
1102
1103 /**
1104 * @brief A standard container composed of equivalent keys
1105 * (possibly containing multiple of each key value) in which the
1106 * elements' keys are the elements themselves.
1107 *
1108 * @ingroup unordered_associative_containers
1109 * @headerfile unordered_set
1110 * @since C++11
1111 *
1112 * @tparam _Value Type of key objects.
1113 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
1114 * @tparam _Pred Predicate function object type, defaults
1115 * to equal_to<_Value>.
1116 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
1117 *
1118 * Meets the requirements of a <a href="tables.html#65">container</a>, and
1119 * <a href="tables.html#xx">unordered associative container</a>
1120 *
1121 * Base is _Hashtable, dispatched at compile time via template
1122 * alias __umset_hashtable.
1123 */
1124 template<typename _Value,
1125 typename _Hash = hash<_Value>,
1126 typename _Pred = equal_to<_Value>,
1127 typename _Alloc = allocator<_Value>>
1129 {
1130 typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
1131 _Hashtable _M_h;
1132
1133 public:
1134 // typedefs:
1135 ///@{
1136 /// Public typedefs.
1137 typedef typename _Hashtable::key_type key_type;
1138 typedef typename _Hashtable::value_type value_type;
1139 typedef typename _Hashtable::hasher hasher;
1140 typedef typename _Hashtable::key_equal key_equal;
1141 typedef typename _Hashtable::allocator_type allocator_type;
1142 ///@}
1143
1144 ///@{
1145 /// Iterator-related typedefs.
1146 typedef typename _Hashtable::pointer pointer;
1147 typedef typename _Hashtable::const_pointer const_pointer;
1148 typedef typename _Hashtable::reference reference;
1149 typedef typename _Hashtable::const_reference const_reference;
1150 typedef typename _Hashtable::iterator iterator;
1151 typedef typename _Hashtable::const_iterator const_iterator;
1152 typedef typename _Hashtable::local_iterator local_iterator;
1153 typedef typename _Hashtable::const_local_iterator const_local_iterator;
1154 typedef typename _Hashtable::size_type size_type;
1155 typedef typename _Hashtable::difference_type difference_type;
1156 ///@}
1157
1158#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1159 using node_type = typename _Hashtable::node_type;
1160#endif
1161
1162 // construct/destroy/copy
1163
1164 /// Default constructor.
1166
1167 /**
1168 * @brief Default constructor creates no elements.
1169 * @param __n Minimal initial number of buckets.
1170 * @param __hf A hash functor.
1171 * @param __eql A key equality functor.
1172 * @param __a An allocator object.
1173 */
1174 explicit
1176 const hasher& __hf = hasher(),
1177 const key_equal& __eql = key_equal(),
1178 const allocator_type& __a = allocator_type())
1179 : _M_h(__n, __hf, __eql, __a)
1180 { }
1181
1182 /**
1183 * @brief Builds an %unordered_multiset from a range.
1184 * @param __first An input iterator.
1185 * @param __last An input iterator.
1186 * @param __n Minimal initial number of buckets.
1187 * @param __hf A hash functor.
1188 * @param __eql A key equality functor.
1189 * @param __a An allocator object.
1190 *
1191 * Create an %unordered_multiset consisting of copies of the elements
1192 * from [__first,__last). This is linear in N (where N is
1193 * distance(__first,__last)).
1194 */
1195 template<typename _InputIterator>
1196 unordered_multiset(_InputIterator __first, _InputIterator __last,
1197 size_type __n = 0,
1198 const hasher& __hf = hasher(),
1199 const key_equal& __eql = key_equal(),
1200 const allocator_type& __a = allocator_type())
1201 : _M_h(__first, __last, __n, __hf, __eql, __a)
1202 { }
1203
1204 /// Copy constructor.
1206
1207 /// Move constructor.
1209
1210 /**
1211 * @brief Builds an %unordered_multiset from an initializer_list.
1212 * @param __l An initializer_list.
1213 * @param __n Minimal initial number of buckets.
1214 * @param __hf A hash functor.
1215 * @param __eql A key equality functor.
1216 * @param __a An allocator object.
1217 *
1218 * Create an %unordered_multiset consisting of copies of the elements in
1219 * the list. This is linear in N (where N is @a __l.size()).
1220 */
1222 size_type __n = 0,
1223 const hasher& __hf = hasher(),
1224 const key_equal& __eql = key_equal(),
1225 const allocator_type& __a = allocator_type())
1226 : _M_h(__l, __n, __hf, __eql, __a)
1227 { }
1228
1229 /// Copy assignment operator.
1232
1233 /// Move assignment operator.
1236
1237 /**
1238 * @brief Creates an %unordered_multiset with no elements.
1239 * @param __a An allocator object.
1240 */
1241 explicit
1243 : _M_h(__a)
1244 { }
1245
1246 /*
1247 * @brief Copy constructor with allocator argument.
1248 * @param __uset Input %unordered_multiset to copy.
1249 * @param __a An allocator object.
1250 */
1252 const allocator_type& __a)
1253 : _M_h(__umset._M_h, __a)
1254 { }
1255
1256 /*
1257 * @brief Move constructor with allocator argument.
1258 * @param __umset Input %unordered_multiset to move.
1259 * @param __a An allocator object.
1260 */
1261 unordered_multiset(unordered_multiset&& __umset,
1262 const allocator_type& __a)
1263 noexcept( noexcept(_Hashtable(std::move(__umset._M_h), __a)) )
1264 : _M_h(std::move(__umset._M_h), __a)
1265 { }
1266
1268 : unordered_multiset(__n, hasher(), key_equal(), __a)
1269 { }
1270
1271 unordered_multiset(size_type __n, const hasher& __hf,
1272 const allocator_type& __a)
1273 : unordered_multiset(__n, __hf, key_equal(), __a)
1274 { }
1275
1276 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1277 // 2713. More missing allocator-extended constructors for unordered container
1278 template<typename _InputIterator>
1279 unordered_multiset(_InputIterator __first, _InputIterator __last,
1280 const allocator_type& __a)
1281 : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a)
1282 { }
1283
1284 template<typename _InputIterator>
1285 unordered_multiset(_InputIterator __first, _InputIterator __last,
1286 size_type __n,
1287 const allocator_type& __a)
1288 : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
1289 { }
1290
1291 template<typename _InputIterator>
1292 unordered_multiset(_InputIterator __first, _InputIterator __last,
1293 size_type __n, const hasher& __hf,
1294 const allocator_type& __a)
1295 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
1296 { }
1297
1298 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1299 // 2713. More missing allocator-extended constructors for unordered container
1300 unordered_multiset(initializer_list<value_type> __l,
1301 const allocator_type& __a)
1302 : unordered_multiset(__l, 0, hasher(), key_equal(), __a)
1303 { }
1304
1305 unordered_multiset(initializer_list<value_type> __l,
1306 size_type __n,
1307 const allocator_type& __a)
1308 : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
1309 { }
1310
1311 unordered_multiset(initializer_list<value_type> __l,
1312 size_type __n, const hasher& __hf,
1313 const allocator_type& __a)
1314 : unordered_multiset(__l, __n, __hf, key_equal(), __a)
1315 { }
1316
1317#if __glibcxx_containers_ranges // C++ >= 23
1318 /**
1319 * @brief Builds an %unordered_multiset from a range.
1320 * @since C++23
1321 * @param __rg An input range of elements that can be converted to
1322 * the set's value type.
1323 * @param __n Minimal initial number of buckets.
1324 * @param __hf A hash functor.
1325 * @param __eql A key equality functor.
1326 * @param __a An allocator object.
1327 *
1328 * Create an %unordered_multiset consisting of copies of the elements in the
1329 * range. This is linear in N (where N is `std::ranges::size(__rg)`).
1330 */
1331 template<__detail::__container_compatible_range<_Value> _Rg>
1332 unordered_multiset(from_range_t, _Rg&& __rg,
1333 size_type __n = 0,
1334 const hasher& __hf = hasher(),
1335 const key_equal& __eql = key_equal(),
1336 const allocator_type& __a = allocator_type())
1337 : _M_h(__n, __hf, __eql, __a)
1338 { insert_range(std::forward<_Rg>(__rg)); }
1339
1340
1341 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1342 // 2713. More missing allocator-extended constructors for unordered container
1343 template<__detail::__container_compatible_range<_Value> _Rg>
1344 unordered_multiset(from_range_t, _Rg&& __rg, const allocator_type& __a)
1345 : _M_h(0, hasher(), key_equal(), __a)
1346 { insert_range(std::forward<_Rg>(__rg)); }
1347
1348 template<__detail::__container_compatible_range<_Value> _Rg>
1349 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1350 const allocator_type& __a)
1351 : _M_h(__n, hasher(), key_equal(), __a)
1352 { insert_range(std::forward<_Rg>(__rg)); }
1353
1354 template<__detail::__container_compatible_range<_Value> _Rg>
1355 unordered_multiset(from_range_t, _Rg&& __rg, size_type __n,
1356 const hasher& __hf, const allocator_type& __a)
1357 : _M_h(__n, __hf, key_equal(), __a)
1358 { insert_range(std::forward<_Rg>(__rg)); }
1359#endif
1360
1361
1362 /**
1363 * @brief %Unordered_multiset list assignment operator.
1364 * @param __l An initializer_list.
1365 *
1366 * This function fills an %unordered_multiset with copies of the elements
1367 * in the initializer list @a __l.
1368 *
1369 * Note that the assignment completely changes the %unordered_multiset
1370 * and that the resulting %unordered_multiset's size is the same as the
1371 * number of elements assigned.
1372 */
1375 {
1376 _M_h = __l;
1377 return *this;
1378 }
1379
1380 /// Returns the allocator object used by the %unordered_multiset.
1381 allocator_type
1382 get_allocator() const noexcept
1383 { return _M_h.get_allocator(); }
1384
1385 // size and capacity:
1386
1387 /// Returns true if the %unordered_multiset is empty.
1388 _GLIBCXX_NODISCARD bool
1389 empty() const noexcept
1390 { return _M_h.empty(); }
1391
1392 /// Returns the size of the %unordered_multiset.
1393 size_type
1394 size() const noexcept
1395 { return _M_h.size(); }
1396
1397 /// Returns the maximum size of the %unordered_multiset.
1398 size_type
1399 max_size() const noexcept
1400 { return _M_h.max_size(); }
1401
1402 // iterators.
1403
1404 ///@{
1405 /**
1406 * Returns a read-only (constant) iterator that points to the first
1407 * element in the %unordered_multiset.
1408 */
1409 iterator
1410 begin() noexcept
1411 { return _M_h.begin(); }
1412
1413 const_iterator
1414 begin() const noexcept
1415 { return _M_h.begin(); }
1416 ///@}
1417
1418 ///@{
1419 /**
1420 * Returns a read-only (constant) iterator that points one past the last
1421 * element in the %unordered_multiset.
1422 */
1423 iterator
1424 end() noexcept
1425 { return _M_h.end(); }
1426
1427 const_iterator
1428 end() const noexcept
1429 { return _M_h.end(); }
1430 ///@}
1431
1432 /**
1433 * Returns a read-only (constant) iterator that points to the first
1434 * element in the %unordered_multiset.
1435 */
1436 const_iterator
1437 cbegin() const noexcept
1438 { return _M_h.begin(); }
1439
1440 /**
1441 * Returns a read-only (constant) iterator that points one past the last
1442 * element in the %unordered_multiset.
1443 */
1444 const_iterator
1445 cend() const noexcept
1446 { return _M_h.end(); }
1447
1448 // modifiers.
1449
1450 /**
1451 * @brief Builds and insert an element into the %unordered_multiset.
1452 * @param __args Arguments used to generate an element.
1453 * @return An iterator that points to the inserted element.
1454 *
1455 * Insertion requires amortized constant time.
1456 */
1457 template<typename... _Args>
1458 iterator
1459 emplace(_Args&&... __args)
1460 { return _M_h.emplace(std::forward<_Args>(__args)...); }
1461
1462 /**
1463 * @brief Inserts an element into the %unordered_multiset.
1464 * @param __pos An iterator that serves as a hint as to where the
1465 * element should be inserted.
1466 * @param __args Arguments used to generate the element to be
1467 * inserted.
1468 * @return An iterator that points to the inserted element.
1469 *
1470 * Note that the first parameter is only a hint and can potentially
1471 * improve the performance of the insertion process. A bad hint would
1472 * cause no gains in efficiency.
1473 *
1474 * For more on @a hinting, see:
1475 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1476 *
1477 * Insertion requires amortized constant time.
1478 */
1479 template<typename... _Args>
1480 iterator
1481 emplace_hint(const_iterator __pos, _Args&&... __args)
1482 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1483
1484 ///@{
1485 /**
1486 * @brief Inserts an element into the %unordered_multiset.
1487 * @param __x Element to be inserted.
1488 * @return An iterator that points to the inserted element.
1489 *
1490 * Insertion requires amortized constant time.
1491 */
1492 iterator
1493 insert(const value_type& __x)
1494 { return _M_h.insert(__x); }
1495
1496 iterator
1498 { return _M_h.insert(std::move(__x)); }
1499 ///@}
1500
1501 ///@{
1502 /**
1503 * @brief Inserts an element into the %unordered_multiset.
1504 * @param __hint An iterator that serves as a hint as to where the
1505 * element should be inserted.
1506 * @param __x Element to be inserted.
1507 * @return An iterator that points to the inserted element.
1508 *
1509 * Note that the first parameter is only a hint and can potentially
1510 * improve the performance of the insertion process. A bad hint would
1511 * cause no gains in efficiency.
1512 *
1513 * For more on @a hinting, see:
1514 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1515 *
1516 * Insertion requires amortized constant.
1517 */
1518 iterator
1520 { return _M_h.insert(__hint, __x); }
1521
1522 iterator
1524 { return _M_h.insert(__hint, std::move(__x)); }
1525 ///@}
1526
1527 /**
1528 * @brief A template function that inserts a range of elements.
1529 * @param __first Iterator pointing to the start of the range to be
1530 * inserted.
1531 * @param __last Iterator pointing to the end of the range.
1532 *
1533 * Complexity similar to that of the range constructor.
1534 */
1535 template<typename _InputIterator>
1536 void
1537 insert(_InputIterator __first, _InputIterator __last)
1538 { _M_h.insert(__first, __last); }
1539
1540 /**
1541 * @brief Inserts a list of elements into the %unordered_multiset.
1542 * @param __l A std::initializer_list<value_type> of elements to be
1543 * inserted.
1544 *
1545 * Complexity similar to that of the range constructor.
1546 */
1547 void
1549 { _M_h.insert(__l); }
1550
1551#if __glibcxx_containers_ranges // C++ >= 23
1552 /**
1553 * @brief Inserts a range of elements.
1554 * @since C++23
1555 * @param __rg An input range of elements that can be converted to
1556 * the set's value type.
1557 */
1558 template<__detail::__container_compatible_range<_Value> _Rg>
1559 void
1560 insert_range(_Rg&& __rg)
1561 {
1562 auto __first = ranges::begin(__rg);
1563 const auto __last = ranges::end(__rg);
1564 if (__first == __last)
1565 return;
1566
1568 _M_h._M_rehash_insert(size_type(ranges::distance(__rg)));
1569 else
1570 _M_h._M_rehash_insert(1);
1571
1572 for (; __first != __last; ++__first)
1573 _M_h.emplace(*__first);
1574 }
1575#endif
1576
1577#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1578 /// Extract a node.
1579 node_type
1580 extract(const_iterator __pos)
1581 {
1582 __glibcxx_assert(__pos != end());
1583 return _M_h.extract(__pos);
1584 }
1585
1586 /// Extract a node.
1587 node_type
1588 extract(const key_type& __key)
1589 { return _M_h.extract(__key); }
1590
1591#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
1592 template <__heterogeneous_hash_key<unordered_multiset> _Kt>
1593 node_type
1594 extract(_Kt&& __key)
1595 { return _M_h._M_extract_tr(__key); }
1596#endif
1597
1598 /// Re-insert an extracted node.
1599 iterator
1600 insert(node_type&& __nh)
1601 { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1602
1603 /// Re-insert an extracted node.
1604 iterator
1605 insert(const_iterator __hint, node_type&& __nh)
1606 { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1607#endif // node_extract
1608
1609 ///@{
1610 /**
1611 * @brief Erases an element from an %unordered_multiset.
1612 * @param __position An iterator pointing to the element to be erased.
1613 * @return An iterator pointing to the element immediately following
1614 * @a __position prior to the element being erased. If no such
1615 * element exists, end() is returned.
1616 *
1617 * This function erases an element, pointed to by the given iterator,
1618 * from an %unordered_multiset.
1619 *
1620 * Note that this function only erases the element, and that if the
1621 * element is itself a pointer, the pointed-to memory is not touched in
1622 * any way. Managing the pointer is the user's responsibility.
1623 */
1624 iterator
1626 { return _M_h.erase(__position); }
1627
1628 // LWG 2059.
1629 iterator
1630 erase(iterator __position)
1631 { return _M_h.erase(__position); }
1632 ///@}
1633
1634
1635 /**
1636 * @brief Erases elements according to the provided key.
1637 * @param __x Key of element to be erased.
1638 * @return The number of elements erased.
1639 *
1640 * This function erases all the elements located by the given key from
1641 * an %unordered_multiset.
1642 *
1643 * Note that this function only erases the element, and that if the
1644 * element is itself a pointer, the pointed-to memory is not touched in
1645 * any way. Managing the pointer is the user's responsibility.
1646 */
1647 size_type
1648 erase(const key_type& __x)
1649 { return _M_h.erase(__x); }
1650
1651#ifdef __glibcxx_associative_heterogeneous_erasure // C++23
1652 template <__heterogeneous_hash_key<unordered_multiset> _Kt>
1653 size_type
1654 erase(_Kt&& __key)
1655 { return _M_h._M_erase_tr(__key); }
1656#endif
1657
1658 /**
1659 * @brief Erases a [__first,__last) range of elements from an
1660 * %unordered_multiset.
1661 * @param __first Iterator pointing to the start of the range to be
1662 * erased.
1663 * @param __last Iterator pointing to the end of the range to
1664 * be erased.
1665 * @return The iterator @a __last.
1666 *
1667 * This function erases a sequence of elements from an
1668 * %unordered_multiset.
1669 *
1670 * Note that this function only erases the element, and that if
1671 * the element is itself a pointer, the pointed-to memory is not touched
1672 * in any way. Managing the pointer is the user's responsibility.
1673 */
1674 iterator
1676 { return _M_h.erase(__first, __last); }
1677
1678 /**
1679 * Erases all elements in an %unordered_multiset.
1680 *
1681 * Note that this function only erases the elements, and that if the
1682 * elements themselves are pointers, the pointed-to memory is not touched
1683 * in any way. Managing the pointer is the user's responsibility.
1684 */
1685 void
1686 clear() noexcept
1687 { _M_h.clear(); }
1688
1689 /**
1690 * @brief Swaps data with another %unordered_multiset.
1691 * @param __x An %unordered_multiset of the same element and allocator
1692 * types.
1693 *
1694 * This exchanges the elements between two sets in constant time.
1695 * Note that the global std::swap() function is specialized such that
1696 * std::swap(s1,s2) will feed to this function.
1697 */
1698 void
1700 noexcept( noexcept(_M_h.swap(__x._M_h)) )
1701 { _M_h.swap(__x._M_h); }
1702
1703#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1704 template<typename, typename, typename>
1705 friend class std::_Hash_merge_helper;
1706
1707 template<typename _H2, typename _P2>
1708 void
1710 {
1711 if constexpr (is_same_v<_H2, _Hash> && is_same_v<_P2, _Pred>)
1712 if (std::__addressof(__source) == this) [[__unlikely__]]
1713 return;
1714
1715 using _Merge_helper
1716 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1717 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1718 }
1719
1720 template<typename _H2, typename _P2>
1721 void
1722 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1723 {
1724 using _Merge_helper
1725 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1726 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1727 }
1728
1729 template<typename _H2, typename _P2>
1730 void
1731 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1732 {
1733 using _Merge_helper
1734 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1735 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1736 }
1737
1738 template<typename _H2, typename _P2>
1739 void
1740 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1741 { merge(__source); }
1742#endif // node_extract
1743
1744 // observers.
1745
1746 /// Returns the hash functor object with which the %unordered_multiset
1747 /// was constructed.
1748 hasher
1750 { return _M_h.hash_function(); }
1751
1752 /// Returns the key comparison object with which the %unordered_multiset
1753 /// was constructed.
1754 key_equal
1755 key_eq() const
1756 { return _M_h.key_eq(); }
1757
1758 // lookup.
1759
1760 ///@{
1761 /**
1762 * @brief Tries to locate an element in an %unordered_multiset.
1763 * @param __x Element to be located.
1764 * @return Iterator pointing to sought-after element, or end() if not
1765 * found.
1766 *
1767 * This function takes a key and tries to locate the element with which
1768 * the key matches. If successful the function returns an iterator
1769 * pointing to the sought after element. If unsuccessful it returns the
1770 * past-the-end ( @c end() ) iterator.
1771 */
1772 iterator
1773 find(const key_type& __x)
1774 { return _M_h.find(__x); }
1775
1776#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1777 template<typename _Kt>
1778 auto
1779 find(const _Kt& __x)
1780 -> decltype(_M_h._M_find_tr(__x))
1781 { return _M_h._M_find_tr(__x); }
1782#endif
1783
1784 const_iterator
1785 find(const key_type& __x) const
1786 { return _M_h.find(__x); }
1787
1788#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1789 template<typename _Kt>
1790 auto
1791 find(const _Kt& __x) const
1792 -> decltype(_M_h._M_find_tr(__x))
1793 { return _M_h._M_find_tr(__x); }
1794#endif
1795 ///@}
1796
1797 ///@{
1798 /**
1799 * @brief Finds the number of elements.
1800 * @param __x Element to located.
1801 * @return Number of elements with specified key.
1802 */
1803 size_type
1804 count(const key_type& __x) const
1805 { return _M_h.count(__x); }
1806
1807#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1808 template<typename _Kt>
1809 auto
1810 count(const _Kt& __x) const -> decltype(_M_h._M_count_tr(__x))
1811 { return _M_h._M_count_tr(__x); }
1812#endif
1813 ///@}
1814
1815#if __cplusplus > 201703L
1816 ///@{
1817 /**
1818 * @brief Finds whether an element with the given key exists.
1819 * @param __x Key of elements to be located.
1820 * @return True if there is any element with the specified key.
1821 */
1822 bool
1823 contains(const key_type& __x) const
1824 { return _M_h.find(__x) != _M_h.end(); }
1825
1826 template<typename _Kt>
1827 auto
1828 contains(const _Kt& __x) const
1829 -> decltype(_M_h._M_find_tr(__x), void(), true)
1830 { return _M_h._M_find_tr(__x) != _M_h.end(); }
1831 ///@}
1832#endif
1833
1834 ///@{
1835 /**
1836 * @brief Finds a subsequence matching given key.
1837 * @param __x Key to be located.
1838 * @return Pair of iterators that possibly points to the subsequence
1839 * matching given key.
1840 */
1843 { return _M_h.equal_range(__x); }
1844
1845#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1846 template<typename _Kt>
1847 auto
1848 equal_range(const _Kt& __x)
1849 -> decltype(_M_h._M_equal_range_tr(__x))
1850 { return _M_h._M_equal_range_tr(__x); }
1851#endif
1852
1854 equal_range(const key_type& __x) const
1855 { return _M_h.equal_range(__x); }
1856
1857#ifdef __glibcxx_generic_unordered_lookup // C++ >= 20 && HOSTED
1858 template<typename _Kt>
1859 auto
1860 equal_range(const _Kt& __x) const
1861 -> decltype(_M_h._M_equal_range_tr(__x))
1862 { return _M_h._M_equal_range_tr(__x); }
1863#endif
1864 ///@}
1865
1866 // bucket interface.
1867
1868 /// Returns the number of buckets of the %unordered_multiset.
1869 size_type
1870 bucket_count() const noexcept
1871 { return _M_h.bucket_count(); }
1872
1873 /// Returns the maximum number of buckets of the %unordered_multiset.
1874 size_type
1875 max_bucket_count() const noexcept
1876 { return _M_h.max_bucket_count(); }
1877
1878 /*
1879 * @brief Returns the number of elements in a given bucket.
1880 * @param __n A bucket index.
1881 * @return The number of elements in the bucket.
1882 */
1883 size_type
1884 bucket_size(size_type __n) const
1885 { return _M_h.bucket_size(__n); }
1886
1887 /*
1888 * @brief Returns the bucket index of a given element.
1889 * @param __key A key instance.
1890 * @return The key bucket index.
1891 */
1892 size_type
1893 bucket(const key_type& __key) const
1894 { return _M_h.bucket(__key); }
1895
1896 ///@{
1897 /**
1898 * @brief Returns a read-only (constant) iterator pointing to the first
1899 * bucket element.
1900 * @param __n The bucket index.
1901 * @return A read-only local iterator.
1902 */
1905 { return _M_h.begin(__n); }
1906
1908 begin(size_type __n) const
1909 { return _M_h.begin(__n); }
1910
1913 { return _M_h.cbegin(__n); }
1914 ///@}
1915
1916 ///@{
1917 /**
1918 * @brief Returns a read-only (constant) iterator pointing to one past
1919 * the last bucket elements.
1920 * @param __n The bucket index.
1921 * @return A read-only local iterator.
1922 */
1925 { return _M_h.end(__n); }
1926
1928 end(size_type __n) const
1929 { return _M_h.end(__n); }
1930
1932 cend(size_type __n) const
1933 { return _M_h.cend(__n); }
1934 ///@}
1935
1936 // hash policy.
1937
1938 /// Returns the average number of elements per bucket.
1939 float
1940 load_factor() const noexcept
1941 { return _M_h.load_factor(); }
1942
1943 /// Returns a positive number that the %unordered_multiset tries to keep the
1944 /// load factor less than or equal to.
1945 float
1946 max_load_factor() const noexcept
1947 { return _M_h.max_load_factor(); }
1948
1949 /**
1950 * @brief Change the %unordered_multiset maximum load factor.
1951 * @param __z The new maximum load factor.
1952 */
1953 void
1955 { _M_h.max_load_factor(__z); }
1956
1957 /**
1958 * @brief May rehash the %unordered_multiset.
1959 * @param __n The new number of buckets.
1960 *
1961 * Rehash will occur only if the new number of buckets respect the
1962 * %unordered_multiset maximum load factor.
1963 */
1964 void
1966 { _M_h.rehash(__n); }
1967
1968 /**
1969 * @brief Prepare the %unordered_multiset for a specified number of
1970 * elements.
1971 * @param __n Number of elements required.
1972 *
1973 * Same as rehash(ceil(n / max_load_factor())).
1974 */
1975 void
1977 { _M_h.reserve(__n); }
1978
1979 template<typename _Value1, typename _Hash1, typename _Pred1,
1980 typename _Alloc1>
1981 friend bool
1984 };
1985
1986
1987#if __cpp_deduction_guides >= 201606
1988
1989 template<typename _InputIterator,
1990 typename _Hash =
1991 hash<typename iterator_traits<_InputIterator>::value_type>,
1992 typename _Pred =
1993 equal_to<typename iterator_traits<_InputIterator>::value_type>,
1994 typename _Allocator =
1995 allocator<typename iterator_traits<_InputIterator>::value_type>,
1996 typename = _RequireInputIter<_InputIterator>,
1997 typename = _RequireNotAllocatorOrIntegral<_Hash>,
1998 typename = _RequireNotAllocator<_Pred>,
1999 typename = _RequireAllocator<_Allocator>>
2000 unordered_multiset(_InputIterator, _InputIterator,
2001 unordered_multiset<int>::size_type = {},
2002 _Hash = _Hash(), _Pred = _Pred(),
2003 _Allocator = _Allocator())
2005 _Hash, _Pred, _Allocator>;
2006
2007 template<typename _Tp, typename _Hash = hash<_Tp>,
2008 typename _Pred = equal_to<_Tp>,
2009 typename _Allocator = allocator<_Tp>,
2010 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2011 typename = _RequireNotAllocator<_Pred>,
2012 typename = _RequireAllocator<_Allocator>>
2015 _Hash = _Hash(), _Pred = _Pred(),
2016 _Allocator = _Allocator())
2018
2019 template<typename _InputIterator, typename _Allocator,
2020 typename = _RequireInputIter<_InputIterator>,
2021 typename = _RequireAllocator<_Allocator>>
2022 unordered_multiset(_InputIterator, _InputIterator,
2025 hash<typename
2027 equal_to<typename
2029 _Allocator>;
2030
2031 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2032 // 2713. More missing allocator-extended constructors for unordered container
2033 template<typename _InputIterator, typename _Allocator,
2034 typename = _RequireInputIter<_InputIterator>,
2035 typename = _RequireAllocator<_Allocator>>
2036 unordered_multiset(_InputIterator, _InputIterator, _Allocator)
2038 hash<typename
2040 equal_to<typename
2042 _Allocator>;
2043
2044 template<typename _InputIterator, typename _Hash, typename _Allocator,
2045 typename = _RequireInputIter<_InputIterator>,
2046 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2047 typename = _RequireAllocator<_Allocator>>
2048 unordered_multiset(_InputIterator, _InputIterator,
2050 _Hash, _Allocator)
2051 -> unordered_multiset<typename
2053 _Hash,
2054 equal_to<
2055 typename
2057 _Allocator>;
2058
2059 template<typename _Tp, typename _Allocator,
2060 typename = _RequireAllocator<_Allocator>>
2064
2065 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2066 // 2713. More missing allocator-extended constructors for unordered container
2067 template<typename _Tp, typename _Allocator,
2068 typename = _RequireAllocator<_Allocator>>
2071
2072 template<typename _Tp, typename _Hash, typename _Allocator,
2073 typename = _RequireNotAllocatorOrIntegral<_Hash>,
2074 typename = _RequireAllocator<_Allocator>>
2076 unordered_multiset<int>::size_type, _Hash, _Allocator)
2078
2079#if __glibcxx_containers_ranges // C++ >= 23
2080 template<ranges::input_range _Rg,
2081 __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>,
2082 __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>,
2083 __allocator_like _Allocator = allocator<ranges::range_value_t<_Rg>>>
2084 unordered_multiset(from_range_t, _Rg&&,
2086 _Hash = _Hash(), _Pred = _Pred(),
2087 _Allocator = _Allocator())
2088 -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>;
2089
2090 template<ranges::input_range _Rg,
2091 __allocator_like _Allocator>
2092 unordered_multiset(from_range_t, _Rg&&, _Allocator)
2096 _Allocator>;
2097
2098 template<ranges::input_range _Rg,
2099 __allocator_like _Allocator>
2101 _Allocator)
2105 _Allocator>;
2106
2107 template<ranges::input_range _Rg,
2108 __not_allocator_like _Hash,
2109 __allocator_like _Allocator>
2110 unordered_multiset(from_range_t, _Rg&&,
2112 _Hash, _Allocator)
2115 _Allocator>;
2116#endif
2117#endif
2118
2119 template<class _Value, class _Hash, class _Pred, class _Alloc>
2120 inline void
2123 noexcept(noexcept(__x.swap(__y)))
2124 { __x.swap(__y); }
2125
2126 template<class _Value, class _Hash, class _Pred, class _Alloc>
2127 inline void
2130 noexcept(noexcept(__x.swap(__y)))
2131 { __x.swap(__y); }
2132
2133 template<class _Value, class _Hash, class _Pred, class _Alloc>
2134 inline bool
2135 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
2137 { return __x._M_h._M_equal(__y._M_h); }
2138
2139#if __cpp_impl_three_way_comparison < 201907L
2140 template<class _Value, class _Hash, class _Pred, class _Alloc>
2141 inline bool
2142 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
2144 { return !(__x == __y); }
2145#endif
2146
2147 template<class _Value, class _Hash, class _Pred, class _Alloc>
2148 inline bool
2151 { return __x._M_h._M_equal(__y._M_h); }
2152
2153#if __cpp_impl_three_way_comparison < 201907L
2154 template<class _Value, class _Hash, class _Pred, class _Alloc>
2155 inline bool
2158 { return !(__x == __y); }
2159#endif
2160
2161_GLIBCXX_END_NAMESPACE_CONTAINER
2162
2163#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
2164 // Allow std::unordered_set access to internals of compatible sets.
2165 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
2166 typename _Hash2, typename _Eq2>
2167 struct _Hash_merge_helper<
2168 _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2>
2169 {
2170 private:
2171 template<typename... _Tp>
2172 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
2173 template<typename... _Tp>
2174 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
2175
2176 friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>;
2177
2178 static auto&
2179 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
2180 { return __set._M_h; }
2181
2182 static auto&
2183 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
2184 { return __set._M_h; }
2185 };
2186
2187 // Allow std::unordered_multiset access to internals of compatible sets.
2188 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
2189 typename _Hash2, typename _Eq2>
2190 struct _Hash_merge_helper<
2191 _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>,
2192 _Hash2, _Eq2>
2193 {
2194 private:
2195 template<typename... _Tp>
2196 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
2197 template<typename... _Tp>
2198 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
2199
2200 friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>;
2201
2202 static auto&
2203 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
2204 { return __set._M_h; }
2205
2206 static auto&
2207 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
2208 { return __set._M_h; }
2209 };
2210#endif // node_extract
2211
2212_GLIBCXX_END_NAMESPACE_VERSION
2213} // namespace std
2214
2215#endif /* _UNORDERED_SET_H */
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.
__detail::_Hashtable_traits< _Cache, true, false > __umset_traits
Base types for unordered_multiset.
__detail::_Hashtable_traits< _Cache, true, true > __uset_traits
Base types for unordered_set.
initializer_list
Primary class template hash.
The standard allocator, as per C++03 [20.4.1].
Definition allocator.h:134
Traits class for iterators.
One of the comparison functors.
Struct holding two objects of arbitrary type.
Definition stl_pair.h:304
Common iterator class.
A standard container composed of equivalent keys (possibly containing multiple of each key value) in ...
iterator begin() noexcept
iterator insert(const_iterator __hint, const value_type &__x)
Inserts an element into the unordered_multiset.
void insert(initializer_list< value_type > __l)
Inserts a list of elements into the unordered_multiset.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
void rehash(size_type __n)
May rehash the unordered_multiset.
local_iterator begin(size_type __n)
Returns a read-only (constant) iterator pointing to the first bucket element.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_multiset.
float max_load_factor() const noexcept
Returns a positive number that the unordered_multiset tries to keep the load factor less than or equa...
bool empty() const noexcept
Returns true if the unordered_multiset is empty.
const_iterator cend() const noexcept
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
iterator emplace(_Args &&... __args)
Builds and insert an element into the unordered_multiset.
unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_multiset from a range.
unordered_multiset(const allocator_type &__a)
Creates an unordered_multiset with no elements.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
iterator find(const key_type &__x)
Tries to locate an element in an unordered_multiset.
unordered_multiset & operator=(unordered_multiset &&)=default
Move assignment operator.
float load_factor() const noexcept
Returns the average number of elements per bucket.
unordered_multiset()=default
Default constructor.
unordered_multiset & operator=(const unordered_multiset &)=default
Copy assignment operator.
hasher hash_function() const
Returns the hash functor object with which the unordered_multiset was constructed.
unordered_multiset(initializer_list< value_type > __l, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_multiset from an initializer_list.
auto contains(const _Kt &__x) const -> decltype(_M_h._M_find_tr(__x), void(), true)
Finds whether an element with the given key exists.
size_type count(const key_type &__x) const
Finds the number of elements.
iterator erase(const_iterator __position)
Erases an element from an unordered_multiset.
unordered_multiset(unordered_multiset &&)=default
Move constructor.
iterator end() noexcept
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Inserts an element into the unordered_multiset.
void swap(unordered_multiset &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_multiset.
const_iterator begin() const noexcept
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_multiset.
const_iterator cbegin() const noexcept
void insert(_InputIterator __first, _InputIterator __last)
A template function that inserts a range of elements.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
key_equal key_eq() const
Returns the key comparison object with which the unordered_multiset was constructed.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
iterator insert(value_type &&__x)
Inserts an element into the unordered_multiset.
iterator insert(const value_type &__x)
Inserts an element into the unordered_multiset.
const_iterator end() const noexcept
void reserve(size_type __n)
Prepare the unordered_multiset for a specified number of elements.
iterator insert(const_iterator __hint, value_type &&__x)
Inserts an element into the unordered_multiset.
iterator erase(iterator __position)
Erases an element from an unordered_multiset.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_multiset.
unordered_multiset(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
unordered_multiset & operator=(initializer_list< value_type > __l)
Unordered_multiset list assignment operator.
size_type size() const noexcept
Returns the size of the unordered_multiset.
local_iterator end(size_type __n)
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
size_type max_size() const noexcept
Returns the maximum size of the unordered_multiset.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_multiset(const unordered_multiset &)=default
Copy constructor.
size_type erase(const key_type &__x)
Erases elements according to the provided key.
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_multiset.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_multiset.
void max_load_factor(float __z)
Change the unordered_multiset maximum load factor.
A standard container composed of unique keys (containing at most one of each key value) in which the ...
std::pair< iterator, bool > insert(const value_type &__x)
Attempts to insert an element into the unordered_set.
unordered_set(initializer_list< value_type > __l, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_set from an initializer_list.
void max_load_factor(float __z)
Change the unordered_set maximum load factor.
const_local_iterator end(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
const_iterator cend() const noexcept
const_iterator find(const key_type &__x) const
Tries to locate an element in an unordered_set.
size_type count(const key_type &__x) const
Finds the number of elements.
const_local_iterator begin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
const_local_iterator cbegin(size_type __n) const
Returns a read-only (constant) iterator pointing to the first bucket element.
const_iterator begin() const noexcept
const_iterator cbegin() const noexcept
bool empty() const noexcept
Returns true if the unordered_set is empty.
unordered_set & operator=(initializer_list< value_type > __l)
Unordered_set list assignment operator.
iterator erase(iterator __position)
Erases an element from an unordered_set.
unordered_set(unordered_set &&)=default
Move constructor.
unordered_set(const allocator_type &__a)
Creates an unordered_set with no elements.
const_local_iterator cend(size_type __n) const
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
auto contains(const _Kt &__k) const -> decltype(_M_h._M_find_tr(__k), void(), true)
Finds whether an element with the given key exists.
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Finds a subsequence matching given key.
void swap(unordered_set &__x) noexcept(noexcept(_M_h.swap(__x._M_h)))
Swaps data with another unordered_set.
iterator insert(const_iterator __hint, const value_type &__x)
Attempts to insert an element into the unordered_set.
std::pair< iterator, bool > insert(value_type &&__x)
Attempts to insert an element into the unordered_set.
float load_factor() const noexcept
Returns the average number of elements per bucket.
void rehash(size_type __n)
May rehash the unordered_set.
local_iterator end(size_type __n)
Returns a read-only (constant) iterator pointing to one past the last bucket elements.
size_type size() const noexcept
Returns the size of the unordered_set.
hasher hash_function() const
Returns the hash functor object with which the unordered_set was constructed.
unordered_set(const unordered_set &)=default
Copy constructor.
std::pair< iterator, iterator > equal_range(const key_type &__x)
Finds a subsequence matching given key.
iterator emplace_hint(const_iterator __pos, _Args &&... __args)
Attempts to insert an element into the unordered_set.
key_equal key_eq() const
Returns the key comparison object with which the unordered_set was constructed.
iterator insert(const_iterator __hint, value_type &&__x)
Attempts to insert an element into the unordered_set.
const_iterator end() const noexcept
iterator end() noexcept
local_iterator begin(size_type __n)
Returns a read-only (constant) iterator pointing to the first bucket element.
unordered_set()=default
Default constructor.
unordered_set & operator=(unordered_set &&)=default
Move assignment operator.
void insert(_InputIterator __first, _InputIterator __last)
A template function that attempts to insert a range of elements.
float max_load_factor() const noexcept
Returns a positive number that the unordered_set tries to keep the load factor less than or equal to.
bool contains(const key_type &__x) const
Finds whether an element with the given key exists.
std::pair< iterator, bool > emplace(_Args &&... __args)
Attempts to build and insert an element into the unordered_set.
unordered_set & operator=(const unordered_set &)=default
Copy assignment operator.
size_type erase(const key_type &__x)
Erases elements according to the provided key.
unordered_set(size_type __n, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Default constructor creates no elements.
iterator erase(const_iterator __first, const_iterator __last)
Erases a [__first,__last) range of elements from an unordered_set.
iterator erase(const_iterator __position)
Erases an element from an unordered_set.
allocator_type get_allocator() const noexcept
Returns the allocator object used by the unordered_set.
void clear() noexcept
void insert(initializer_list< value_type > __l)
Attempts to insert a list of elements into the unordered_set.
unordered_set(_InputIterator __first, _InputIterator __last, size_type __n=0, const hasher &__hf=hasher(), const key_equal &__eql=key_equal(), const allocator_type &__a=allocator_type())
Builds an unordered_set from a range.
size_type bucket_count() const noexcept
Returns the number of buckets of the unordered_set.
void reserve(size_type __n)
Prepare the unordered_set for a specified number of elements.
iterator begin() noexcept
iterator find(const key_type &__x)
Tries to locate an element in an unordered_set.
size_type max_size() const noexcept
Returns the maximum size of the unordered_set.
size_type max_bucket_count() const noexcept
Returns the maximum number of buckets of the unordered_set.
[range.sized] The sized_range concept.
A range for which ranges::begin returns an input iterator.
A range for which ranges::begin returns a forward iterator.