1 // unordered_set implementation -*- C++ -*-
3 // Copyright (C) 2010-2025 Free Software Foundation, Inc.
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)
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.
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.
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/>.
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}
30 #ifndef _UNORDERED_SET_H
31 #define _UNORDERED_SET_H
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.
41 namespace std
_GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
46 /// Base types for unordered_set.
48 using __uset_traits
= __detail::_Hashtable_traits
<_Cache
, true, true>;
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
>;
61 /// Base types for unordered_multiset.
63 using __umset_traits
= __detail::_Hashtable_traits
<_Cache
, true, false>;
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
,
73 __detail::_Mod_range_hashing
,
74 __detail::_Default_ranged_hash
,
75 __detail::_Prime_rehash_policy
, _Tr
>;
77 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
78 class unordered_multiset
;
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.
85 * @ingroup unordered_associative_containers
86 * @headerfile unordered_set
89 * @tparam _Value Type of key objects.
90 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
92 * @tparam _Pred Predicate function object type, defaults to
95 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
97 * Meets the requirements of a <a href="tables.html#65">container</a>, and
98 * <a href="tables.html#xx">unordered associative container</a>
100 * Base is _Hashtable, dispatched at compile time via template
101 * alias __uset_hashtable.
103 template<typename _Value
,
104 typename _Hash
= hash
<_Value
>,
105 typename _Pred
= equal_to
<_Value
>,
106 typename _Alloc
= allocator
<_Value
>>
109 typedef __uset_hashtable
<_Value
, _Hash
, _Pred
, _Alloc
> _Hashtable
;
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
;
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
;
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
;
142 // construct/destroy/copy
144 /// Default constructor.
145 unordered_set() = default;
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.
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
)
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.
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)).
175 template<typename _InputIterator
>
176 unordered_set(_InputIterator __first
, _InputIterator __last
,
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
)
184 /// Copy constructor.
185 unordered_set(const unordered_set
&) = default;
187 /// Move constructor.
188 unordered_set(unordered_set
&&) = default;
191 * @brief Creates an %unordered_set with no elements.
192 * @param __a An allocator object.
195 unordered_set(const allocator_type
& __a
)
200 * @brief Copy constructor with allocator argument.
201 * @param __uset Input %unordered_set to copy.
202 * @param __a An allocator object.
204 unordered_set(const unordered_set
& __uset
,
205 const allocator_type
& __a
)
206 : _M_h(__uset
._M_h
, __a
)
210 * @brief Move constructor with allocator argument.
211 * @param __uset Input %unordered_set to move.
212 * @param __a An allocator object.
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
)
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.
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()).
231 unordered_set(initializer_list
<value_type
> __l
,
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
)
239 unordered_set(size_type __n
, const allocator_type
& __a
)
240 : unordered_set(__n
, hasher(), key_equal(), __a
)
243 unordered_set(size_type __n
, const hasher
& __hf
,
244 const allocator_type
& __a
)
245 : unordered_set(__n
, __hf
, key_equal(), __a
)
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
)
256 template<typename _InputIterator
>
257 unordered_set(_InputIterator __first
, _InputIterator __last
,
259 const allocator_type
& __a
)
260 : unordered_set(__first
, __last
, __n
, hasher(), key_equal(), __a
)
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
)
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
)
278 unordered_set(initializer_list
<value_type
> __l
,
280 const allocator_type
& __a
)
281 : unordered_set(__l
, __n
, hasher(), key_equal(), __a
)
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
)
290 #if __glibcxx_containers_ranges // C++ >= 23
292 * @brief Builds an %unordered_set from a range.
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.
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)`).
304 template<__detail::__container_compatible_range
<_Value
> _Rg
>
305 unordered_set(from_range_t
, _Rg
&& __rg
,
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
)); }
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
)); }
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
)); }
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
)); }
333 /// Copy assignment operator.
335 operator=(const unordered_set
&) = default;
337 /// Move assignment operator.
339 operator=(unordered_set
&&) = default;
342 * @brief %Unordered_set list assignment operator.
343 * @param __l An initializer_list.
345 * This function fills an %unordered_set with copies of the elements in
346 * the initializer list @a __l.
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.
353 operator=(initializer_list
<value_type
> __l
)
359 /// Returns the allocator object used by the %unordered_set.
361 get_allocator() const noexcept
362 { return _M_h
.get_allocator(); }
364 // size and capacity:
366 /// Returns true if the %unordered_set is empty.
367 _GLIBCXX_NODISCARD
bool
368 empty() const noexcept
369 { return _M_h
.empty(); }
371 /// Returns the size of the %unordered_set.
373 size() const noexcept
374 { return _M_h
.size(); }
376 /// Returns the maximum size of the %unordered_set.
378 max_size() const noexcept
379 { return _M_h
.max_size(); }
385 * Returns a read-only (constant) iterator that points to the first
386 * element in the %unordered_set.
390 { return _M_h
.begin(); }
393 begin() const noexcept
394 { return _M_h
.begin(); }
399 * Returns a read-only (constant) iterator that points one past the last
400 * element in the %unordered_set.
404 { return _M_h
.end(); }
408 { return _M_h
.end(); }
412 * Returns a read-only (constant) iterator that points to the first
413 * element in the %unordered_set.
416 cbegin() const noexcept
417 { return _M_h
.begin(); }
420 * Returns a read-only (constant) iterator that points one past the last
421 * element in the %unordered_set.
424 cend() const noexcept
425 { return _M_h
.end(); }
430 * @brief Attempts to build and insert an element into the
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.
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
442 * Insertion requires amortized constant time.
444 template<typename
... _Args
>
445 std::pair
<iterator
, bool>
446 emplace(_Args
&&... __args
)
447 { return _M_h
.emplace(std::forward
<_Args
>(__args
)...); }
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
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
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.
465 * For more on @a hinting, see:
466 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
468 * Insertion requires amortized constant time.
470 template<typename
... _Args
>
472 emplace_hint(const_iterator __pos
, _Args
&&... __args
)
473 { return _M_h
.emplace_hint(__pos
, std::forward
<_Args
>(__args
)...); }
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.
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.
487 * Insertion requires amortized constant time.
489 std::pair
<iterator
, bool>
490 insert(const value_type
& __x
)
491 { return _M_h
.insert(__x
); }
493 std::pair
<iterator
, bool>
494 insert(value_type
&& __x
)
495 { return _M_h
.insert(std::move(__x
)); }
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).
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.
513 * For more on @a hinting, see:
514 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
516 * Insertion requires amortized constant.
519 insert(const_iterator __hint
, const value_type
& __x
)
520 { return _M_h
.insert(__hint
, __x
); }
523 insert(const_iterator __hint
, value_type
&& __x
)
524 { return _M_h
.insert(__hint
, std::move(__x
)); }
528 * @brief A template function that attempts to insert a range of
530 * @param __first Iterator pointing to the start of the range to be
532 * @param __last Iterator pointing to the end of the range.
534 * Complexity similar to that of the range constructor.
536 template<typename _InputIterator
>
538 insert(_InputIterator __first
, _InputIterator __last
)
539 { _M_h
.insert(__first
, __last
); }
542 * @brief Attempts to insert a list of elements into the %unordered_set.
543 * @param __l A std::initializer_list<value_type> of elements
546 * Complexity similar to that of the range constructor.
549 insert(initializer_list
<value_type
> __l
)
550 { _M_h
.insert(__l
); }
552 #if __glibcxx_containers_ranges // C++ >= 23
554 * @brief Inserts a range of elements.
556 * @param __rg An input range of elements that can be converted to
557 * the set's value type.
559 template<__detail::__container_compatible_range
<_Value
> _Rg
>
561 insert_range(_Rg
&& __rg
)
563 auto __first
= ranges::begin(__rg
);
564 const auto __last
= ranges::end(__rg
);
565 for (; __first
!= __last
; ++__first
)
566 _M_h
.emplace(*__first
);
570 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
573 extract(const_iterator __pos
)
575 __glibcxx_assert(__pos
!= end());
576 return _M_h
.extract(__pos
);
581 extract(const key_type
& __key
)
582 { return _M_h
.extract(__key
); }
584 /// Re-insert an extracted node.
586 insert(node_type
&& __nh
)
587 { return _M_h
._M_reinsert_node(std::move(__nh
)); }
589 /// Re-insert an extracted node.
591 insert(const_iterator
, node_type
&& __nh
)
592 { return _M_h
._M_reinsert_node(std::move(__nh
)).position
; }
593 #endif // node_extract
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.
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
610 erase(const_iterator __position
)
611 { return _M_h
.erase(__position
); }
615 erase(iterator __position
)
616 { return _M_h
.erase(__position
); }
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.
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.
632 erase(const key_type
& __x
)
633 { return _M_h
.erase(__x
); }
636 * @brief Erases a [__first,__last) range of elements from an
638 * @param __first Iterator pointing to the start of the range to be
640 * @param __last Iterator pointing to the end of the range to
642 * @return The iterator @a __last.
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.
650 erase(const_iterator __first
, const_iterator __last
)
651 { return _M_h
.erase(__first
, __last
); }
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.
664 * @brief Swaps data with another %unordered_set.
665 * @param __x An %unordered_set of the same element and allocator
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.
673 swap(unordered_set
& __x
)
674 noexcept( noexcept(_M_h
.swap(__x
._M_h
)) )
675 { _M_h
.swap(__x
._M_h
); }
677 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
678 template<typename
, typename
, typename
>
679 friend class std::_Hash_merge_helper
;
681 template<typename _H2
, typename _P2
>
683 merge(unordered_set
<_Value
, _H2
, _P2
, _Alloc
>& __source
)
685 if constexpr (is_same_v
<_H2
, _Hash
> && is_same_v
<_P2
, _Pred
>)
686 if (std::__addressof(__source
) == this) [[__unlikely__
]]
689 using _Merge_helper
= _Hash_merge_helper
<unordered_set
, _H2
, _P2
>;
690 _M_h
._M_merge_unique(_Merge_helper::_S_get_table(__source
));
693 template<typename _H2
, typename _P2
>
695 merge(unordered_set
<_Value
, _H2
, _P2
, _Alloc
>&& __source
)
697 using _Merge_helper
= _Hash_merge_helper
<unordered_set
, _H2
, _P2
>;
698 _M_h
._M_merge_unique(_Merge_helper::_S_get_table(__source
));
701 template<typename _H2
, typename _P2
>
703 merge(unordered_multiset
<_Value
, _H2
, _P2
, _Alloc
>& __source
)
705 using _Merge_helper
= _Hash_merge_helper
<unordered_set
, _H2
, _P2
>;
706 _M_h
._M_merge_unique(_Merge_helper::_S_get_table(__source
));
709 template<typename _H2
, typename _P2
>
711 merge(unordered_multiset
<_Value
, _H2
, _P2
, _Alloc
>&& __source
)
713 #endif // node_extract
717 /// Returns the hash functor object with which the %unordered_set was
720 hash_function() const
721 { return _M_h
.hash_function(); }
723 /// Returns the key comparison object with which the %unordered_set was
727 { return _M_h
.key_eq(); }
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
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.
744 find(const key_type
& __x
)
745 { return _M_h
.find(__x
); }
747 #if __cplusplus > 201703L
748 template<typename _Kt
>
751 -> decltype(_M_h
._M_find_tr(__k
))
752 { return _M_h
._M_find_tr(__k
); }
756 find(const key_type
& __x
) const
757 { return _M_h
.find(__x
); }
759 #if __cplusplus > 201703L
760 template<typename _Kt
>
762 find(const _Kt
& __k
) const
763 -> decltype(_M_h
._M_find_tr(__k
))
764 { return _M_h
._M_find_tr(__k
); }
770 * @brief Finds the number of elements.
771 * @param __x Element to located.
772 * @return Number of elements with specified key.
774 * This function only makes sense for unordered_multisets; for
775 * unordered_set the result will either be 0 (not present) or 1
779 count(const key_type
& __x
) const
780 { return _M_h
.count(__x
); }
782 #if __cplusplus > 201703L
783 template<typename _Kt
>
785 count(const _Kt
& __k
) const
786 -> decltype(_M_h
._M_count_tr(__k
))
787 { return _M_h
._M_count_tr(__k
); }
791 #if __cplusplus > 201703L
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.
799 contains(const key_type
& __x
) const
800 { return _M_h
.find(__x
) != _M_h
.end(); }
802 template<typename _Kt
>
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(); }
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.
817 * This function probably only makes sense for multisets.
819 std::pair
<iterator
, iterator
>
820 equal_range(const key_type
& __x
)
821 { return _M_h
.equal_range(__x
); }
823 #if __cplusplus > 201703L
824 template<typename _Kt
>
826 equal_range(const _Kt
& __k
)
827 -> decltype(_M_h
._M_equal_range_tr(__k
))
828 { return _M_h
._M_equal_range_tr(__k
); }
831 std::pair
<const_iterator
, const_iterator
>
832 equal_range(const key_type
& __x
) const
833 { return _M_h
.equal_range(__x
); }
835 #if __cplusplus > 201703L
836 template<typename _Kt
>
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
); }
846 /// Returns the number of buckets of the %unordered_set.
848 bucket_count() const noexcept
849 { return _M_h
.bucket_count(); }
851 /// Returns the maximum number of buckets of the %unordered_set.
853 max_bucket_count() const noexcept
854 { return _M_h
.max_bucket_count(); }
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.
862 bucket_size(size_type __n
) const
863 { return _M_h
.bucket_size(__n
); }
866 * @brief Returns the bucket index of a given element.
867 * @param __key A key instance.
868 * @return The key bucket index.
871 bucket(const key_type
& __key
) const
872 { return _M_h
.bucket(__key
); }
876 * @brief Returns a read-only (constant) iterator pointing to the first
878 * @param __n The bucket index.
879 * @return A read-only local iterator.
883 { return _M_h
.begin(__n
); }
886 begin(size_type __n
) const
887 { return _M_h
.begin(__n
); }
890 cbegin(size_type __n
) const
891 { return _M_h
.cbegin(__n
); }
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.
903 { return _M_h
.end(__n
); }
906 end(size_type __n
) const
907 { return _M_h
.end(__n
); }
910 cend(size_type __n
) const
911 { return _M_h
.cend(__n
); }
916 /// Returns the average number of elements per bucket.
918 load_factor() const noexcept
919 { return _M_h
.load_factor(); }
921 /// Returns a positive number that the %unordered_set tries to keep the
922 /// load factor less than or equal to.
924 max_load_factor() const noexcept
925 { return _M_h
.max_load_factor(); }
928 * @brief Change the %unordered_set maximum load factor.
929 * @param __z The new maximum load factor.
932 max_load_factor(float __z
)
933 { _M_h
.max_load_factor(__z
); }
936 * @brief May rehash the %unordered_set.
937 * @param __n The new number of buckets.
939 * Rehash will occur only if the new number of buckets respect the
940 * %unordered_set maximum load factor.
943 rehash(size_type __n
)
944 { _M_h
.rehash(__n
); }
947 * @brief Prepare the %unordered_set for a specified number of
949 * @param __n Number of elements required.
951 * Same as rehash(ceil(n / max_load_factor())).
954 reserve(size_type __n
)
955 { _M_h
.reserve(__n
); }
957 template<typename _Value1
, typename _Hash1
, typename _Pred1
,
960 operator==(const unordered_set
<_Value1
, _Hash1
, _Pred1
, _Alloc1
>&,
961 const unordered_set
<_Value1
, _Hash1
, _Pred1
, _Alloc1
>&);
964 #if __cpp_deduction_guides >= 201606
966 template<typename _InputIterator
,
968 hash
<typename iterator_traits
<_InputIterator
>::value_type
>,
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
>;
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
>;
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
,
1001 typename iterator_traits
<_InputIterator
>::value_type
>,
1003 typename iterator_traits
<_InputIterator
>::value_type
>,
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
,
1014 typename iterator_traits
<_InputIterator
>::value_type
>,
1016 typename iterator_traits
<_InputIterator
>::value_type
>,
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
,
1026 -> unordered_set
<typename iterator_traits
<_InputIterator
>::value_type
,
1029 typename iterator_traits
<_InputIterator
>::value_type
>,
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
>;
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
>;
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
>;
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
>;
1061 template<ranges::input_range _Rg
,
1062 __allocator_like _Allocator
>
1063 unordered_set(from_range_t
, _Rg
&&, unordered_set
<int>::size_type
,
1065 -> unordered_set
<ranges::range_value_t
<_Rg
>,
1066 hash
<ranges::range_value_t
<_Rg
>>,
1067 equal_to
<ranges::range_value_t
<_Rg
>>,
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
>>,
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
,
1083 -> unordered_set
<ranges::range_value_t
<_Rg
>, _Hash
,
1084 equal_to
<ranges::range_value_t
<_Rg
>>,
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.
1094 * @ingroup unordered_associative_containers
1095 * @headerfile unordered_set
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>.
1104 * Meets the requirements of a <a href="tables.html#65">container</a>, and
1105 * <a href="tables.html#xx">unordered associative container</a>
1107 * Base is _Hashtable, dispatched at compile time via template
1108 * alias __umset_hashtable.
1110 template<typename _Value
,
1111 typename _Hash
= hash
<_Value
>,
1112 typename _Pred
= equal_to
<_Value
>,
1113 typename _Alloc
= allocator
<_Value
>>
1114 class unordered_multiset
1116 typedef __umset_hashtable
<_Value
, _Hash
, _Pred
, _Alloc
> _Hashtable
;
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
;
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
;
1144 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1145 using node_type
= typename
_Hashtable::node_type
;
1148 // construct/destroy/copy
1150 /// Default constructor.
1151 unordered_multiset() = default;
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.
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
)
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.
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)).
1181 template<typename _InputIterator
>
1182 unordered_multiset(_InputIterator __first
, _InputIterator __last
,
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
)
1190 /// Copy constructor.
1191 unordered_multiset(const unordered_multiset
&) = default;
1193 /// Move constructor.
1194 unordered_multiset(unordered_multiset
&&) = default;
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.
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()).
1207 unordered_multiset(initializer_list
<value_type
> __l
,
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
)
1215 /// Copy assignment operator.
1217 operator=(const unordered_multiset
&) = default;
1219 /// Move assignment operator.
1221 operator=(unordered_multiset
&&) = default;
1224 * @brief Creates an %unordered_multiset with no elements.
1225 * @param __a An allocator object.
1228 unordered_multiset(const allocator_type
& __a
)
1233 * @brief Copy constructor with allocator argument.
1234 * @param __uset Input %unordered_multiset to copy.
1235 * @param __a An allocator object.
1237 unordered_multiset(const unordered_multiset
& __umset
,
1238 const allocator_type
& __a
)
1239 : _M_h(__umset
._M_h
, __a
)
1243 * @brief Move constructor with allocator argument.
1244 * @param __umset Input %unordered_multiset to move.
1245 * @param __a An allocator object.
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
)
1253 unordered_multiset(size_type __n
, const allocator_type
& __a
)
1254 : unordered_multiset(__n
, hasher(), key_equal(), __a
)
1257 unordered_multiset(size_type __n
, const hasher
& __hf
,
1258 const allocator_type
& __a
)
1259 : unordered_multiset(__n
, __hf
, key_equal(), __a
)
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
)
1270 template<typename _InputIterator
>
1271 unordered_multiset(_InputIterator __first
, _InputIterator __last
,
1273 const allocator_type
& __a
)
1274 : unordered_multiset(__first
, __last
, __n
, hasher(), key_equal(), __a
)
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
)
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
)
1291 unordered_multiset(initializer_list
<value_type
> __l
,
1293 const allocator_type
& __a
)
1294 : unordered_multiset(__l
, __n
, hasher(), key_equal(), __a
)
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
)
1303 #if __glibcxx_containers_ranges // C++ >= 23
1305 * @brief Builds an %unordered_multiset from a range.
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.
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)`).
1317 template<__detail::__container_compatible_range
<_Value
> _Rg
>
1318 unordered_multiset(from_range_t
, _Rg
&& __rg
,
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
)); }
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
)); }
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
)); }
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
)); }
1349 * @brief %Unordered_multiset list assignment operator.
1350 * @param __l An initializer_list.
1352 * This function fills an %unordered_multiset with copies of the elements
1353 * in the initializer list @a __l.
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.
1360 operator=(initializer_list
<value_type
> __l
)
1366 /// Returns the allocator object used by the %unordered_multiset.
1368 get_allocator() const noexcept
1369 { return _M_h
.get_allocator(); }
1371 // size and capacity:
1373 /// Returns true if the %unordered_multiset is empty.
1374 _GLIBCXX_NODISCARD
bool
1375 empty() const noexcept
1376 { return _M_h
.empty(); }
1378 /// Returns the size of the %unordered_multiset.
1380 size() const noexcept
1381 { return _M_h
.size(); }
1383 /// Returns the maximum size of the %unordered_multiset.
1385 max_size() const noexcept
1386 { return _M_h
.max_size(); }
1392 * Returns a read-only (constant) iterator that points to the first
1393 * element in the %unordered_multiset.
1397 { return _M_h
.begin(); }
1400 begin() const noexcept
1401 { return _M_h
.begin(); }
1406 * Returns a read-only (constant) iterator that points one past the last
1407 * element in the %unordered_multiset.
1411 { return _M_h
.end(); }
1414 end() const noexcept
1415 { return _M_h
.end(); }
1419 * Returns a read-only (constant) iterator that points to the first
1420 * element in the %unordered_multiset.
1423 cbegin() const noexcept
1424 { return _M_h
.begin(); }
1427 * Returns a read-only (constant) iterator that points one past the last
1428 * element in the %unordered_multiset.
1431 cend() const noexcept
1432 { return _M_h
.end(); }
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.
1441 * Insertion requires amortized constant time.
1443 template<typename
... _Args
>
1445 emplace(_Args
&&... __args
)
1446 { return _M_h
.emplace(std::forward
<_Args
>(__args
)...); }
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
1454 * @return An iterator that points to the inserted element.
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.
1460 * For more on @a hinting, see:
1461 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1463 * Insertion requires amortized constant time.
1465 template<typename
... _Args
>
1467 emplace_hint(const_iterator __pos
, _Args
&&... __args
)
1468 { return _M_h
.emplace_hint(__pos
, std::forward
<_Args
>(__args
)...); }
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.
1476 * Insertion requires amortized constant time.
1479 insert(const value_type
& __x
)
1480 { return _M_h
.insert(__x
); }
1483 insert(value_type
&& __x
)
1484 { return _M_h
.insert(std::move(__x
)); }
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.
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.
1499 * For more on @a hinting, see:
1500 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
1502 * Insertion requires amortized constant.
1505 insert(const_iterator __hint
, const value_type
& __x
)
1506 { return _M_h
.insert(__hint
, __x
); }
1509 insert(const_iterator __hint
, value_type
&& __x
)
1510 { return _M_h
.insert(__hint
, std::move(__x
)); }
1514 * @brief A template function that inserts a range of elements.
1515 * @param __first Iterator pointing to the start of the range to be
1517 * @param __last Iterator pointing to the end of the range.
1519 * Complexity similar to that of the range constructor.
1521 template<typename _InputIterator
>
1523 insert(_InputIterator __first
, _InputIterator __last
)
1524 { _M_h
.insert(__first
, __last
); }
1527 * @brief Inserts a list of elements into the %unordered_multiset.
1528 * @param __l A std::initializer_list<value_type> of elements to be
1531 * Complexity similar to that of the range constructor.
1534 insert(initializer_list
<value_type
> __l
)
1535 { _M_h
.insert(__l
); }
1537 #if __glibcxx_containers_ranges // C++ >= 23
1539 * @brief Inserts a range of elements.
1541 * @param __rg An input range of elements that can be converted to
1542 * the set's value type.
1544 template<__detail::__container_compatible_range
<_Value
> _Rg
>
1546 insert_range(_Rg
&& __rg
)
1548 auto __first
= ranges::begin(__rg
);
1549 const auto __last
= ranges::end(__rg
);
1550 if (__first
== __last
)
1553 if constexpr (ranges::forward_range
<_Rg
> || ranges::sized_range
<_Rg
>)
1554 _M_h
._M_rehash_insert(size_type(ranges::distance(__rg
)));
1556 _M_h
._M_rehash_insert(1);
1558 for (; __first
!= __last
; ++__first
)
1559 _M_h
.emplace(*__first
);
1563 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1566 extract(const_iterator __pos
)
1568 __glibcxx_assert(__pos
!= end());
1569 return _M_h
.extract(__pos
);
1574 extract(const key_type
& __key
)
1575 { return _M_h
.extract(__key
); }
1577 /// Re-insert an extracted node.
1579 insert(node_type
&& __nh
)
1580 { return _M_h
._M_reinsert_node_multi(cend(), std::move(__nh
)); }
1582 /// Re-insert an extracted node.
1584 insert(const_iterator __hint
, node_type
&& __nh
)
1585 { return _M_h
._M_reinsert_node_multi(__hint
, std::move(__nh
)); }
1586 #endif // node_extract
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.
1596 * This function erases an element, pointed to by the given iterator,
1597 * from an %unordered_multiset.
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.
1604 erase(const_iterator __position
)
1605 { return _M_h
.erase(__position
); }
1609 erase(iterator __position
)
1610 { return _M_h
.erase(__position
); }
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.
1619 * This function erases all the elements located by the given key from
1620 * an %unordered_multiset.
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.
1627 erase(const key_type
& __x
)
1628 { return _M_h
.erase(__x
); }
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
1635 * @param __last Iterator pointing to the end of the range to
1637 * @return The iterator @a __last.
1639 * This function erases a sequence of elements from an
1640 * %unordered_multiset.
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.
1647 erase(const_iterator __first
, const_iterator __last
)
1648 { return _M_h
.erase(__first
, __last
); }
1651 * Erases all elements in an %unordered_multiset.
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.
1662 * @brief Swaps data with another %unordered_multiset.
1663 * @param __x An %unordered_multiset of the same element and allocator
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.
1671 swap(unordered_multiset
& __x
)
1672 noexcept( noexcept(_M_h
.swap(__x
._M_h
)) )
1673 { _M_h
.swap(__x
._M_h
); }
1675 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
1676 template<typename
, typename
, typename
>
1677 friend class std::_Hash_merge_helper
;
1679 template<typename _H2
, typename _P2
>
1681 merge(unordered_multiset
<_Value
, _H2
, _P2
, _Alloc
>& __source
)
1683 if constexpr (is_same_v
<_H2
, _Hash
> && is_same_v
<_P2
, _Pred
>)
1684 if (std::__addressof(__source
) == this) [[__unlikely__
]]
1688 = _Hash_merge_helper
<unordered_multiset
, _H2
, _P2
>;
1689 _M_h
._M_merge_multi(_Merge_helper::_S_get_table(__source
));
1692 template<typename _H2
, typename _P2
>
1694 merge(unordered_multiset
<_Value
, _H2
, _P2
, _Alloc
>&& __source
)
1697 = _Hash_merge_helper
<unordered_multiset
, _H2
, _P2
>;
1698 _M_h
._M_merge_multi(_Merge_helper::_S_get_table(__source
));
1701 template<typename _H2
, typename _P2
>
1703 merge(unordered_set
<_Value
, _H2
, _P2
, _Alloc
>& __source
)
1706 = _Hash_merge_helper
<unordered_multiset
, _H2
, _P2
>;
1707 _M_h
._M_merge_multi(_Merge_helper::_S_get_table(__source
));
1710 template<typename _H2
, typename _P2
>
1712 merge(unordered_set
<_Value
, _H2
, _P2
, _Alloc
>&& __source
)
1713 { merge(__source
); }
1714 #endif // node_extract
1718 /// Returns the hash functor object with which the %unordered_multiset
1719 /// was constructed.
1721 hash_function() const
1722 { return _M_h
.hash_function(); }
1724 /// Returns the key comparison object with which the %unordered_multiset
1725 /// was constructed.
1728 { return _M_h
.key_eq(); }
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
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.
1745 find(const key_type
& __x
)
1746 { return _M_h
.find(__x
); }
1748 #if __cplusplus > 201703L
1749 template<typename _Kt
>
1751 find(const _Kt
& __x
)
1752 -> decltype(_M_h
._M_find_tr(__x
))
1753 { return _M_h
._M_find_tr(__x
); }
1757 find(const key_type
& __x
) const
1758 { return _M_h
.find(__x
); }
1760 #if __cplusplus > 201703L
1761 template<typename _Kt
>
1763 find(const _Kt
& __x
) const
1764 -> decltype(_M_h
._M_find_tr(__x
))
1765 { return _M_h
._M_find_tr(__x
); }
1771 * @brief Finds the number of elements.
1772 * @param __x Element to located.
1773 * @return Number of elements with specified key.
1776 count(const key_type
& __x
) const
1777 { return _M_h
.count(__x
); }
1779 #if __cplusplus > 201703L
1780 template<typename _Kt
>
1782 count(const _Kt
& __x
) const -> decltype(_M_h
._M_count_tr(__x
))
1783 { return _M_h
._M_count_tr(__x
); }
1787 #if __cplusplus > 201703L
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.
1795 contains(const key_type
& __x
) const
1796 { return _M_h
.find(__x
) != _M_h
.end(); }
1798 template<typename _Kt
>
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(); }
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.
1813 std::pair
<iterator
, iterator
>
1814 equal_range(const key_type
& __x
)
1815 { return _M_h
.equal_range(__x
); }
1817 #if __cplusplus > 201703L
1818 template<typename _Kt
>
1820 equal_range(const _Kt
& __x
)
1821 -> decltype(_M_h
._M_equal_range_tr(__x
))
1822 { return _M_h
._M_equal_range_tr(__x
); }
1825 std::pair
<const_iterator
, const_iterator
>
1826 equal_range(const key_type
& __x
) const
1827 { return _M_h
.equal_range(__x
); }
1829 #if __cplusplus > 201703L
1830 template<typename _Kt
>
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
); }
1838 // bucket interface.
1840 /// Returns the number of buckets of the %unordered_multiset.
1842 bucket_count() const noexcept
1843 { return _M_h
.bucket_count(); }
1845 /// Returns the maximum number of buckets of the %unordered_multiset.
1847 max_bucket_count() const noexcept
1848 { return _M_h
.max_bucket_count(); }
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.
1856 bucket_size(size_type __n
) const
1857 { return _M_h
.bucket_size(__n
); }
1860 * @brief Returns the bucket index of a given element.
1861 * @param __key A key instance.
1862 * @return The key bucket index.
1865 bucket(const key_type
& __key
) const
1866 { return _M_h
.bucket(__key
); }
1870 * @brief Returns a read-only (constant) iterator pointing to the first
1872 * @param __n The bucket index.
1873 * @return A read-only local iterator.
1876 begin(size_type __n
)
1877 { return _M_h
.begin(__n
); }
1879 const_local_iterator
1880 begin(size_type __n
) const
1881 { return _M_h
.begin(__n
); }
1883 const_local_iterator
1884 cbegin(size_type __n
) const
1885 { return _M_h
.cbegin(__n
); }
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.
1897 { return _M_h
.end(__n
); }
1899 const_local_iterator
1900 end(size_type __n
) const
1901 { return _M_h
.end(__n
); }
1903 const_local_iterator
1904 cend(size_type __n
) const
1905 { return _M_h
.cend(__n
); }
1910 /// Returns the average number of elements per bucket.
1912 load_factor() const noexcept
1913 { return _M_h
.load_factor(); }
1915 /// Returns a positive number that the %unordered_multiset tries to keep the
1916 /// load factor less than or equal to.
1918 max_load_factor() const noexcept
1919 { return _M_h
.max_load_factor(); }
1922 * @brief Change the %unordered_multiset maximum load factor.
1923 * @param __z The new maximum load factor.
1926 max_load_factor(float __z
)
1927 { _M_h
.max_load_factor(__z
); }
1930 * @brief May rehash the %unordered_multiset.
1931 * @param __n The new number of buckets.
1933 * Rehash will occur only if the new number of buckets respect the
1934 * %unordered_multiset maximum load factor.
1937 rehash(size_type __n
)
1938 { _M_h
.rehash(__n
); }
1941 * @brief Prepare the %unordered_multiset for a specified number of
1943 * @param __n Number of elements required.
1945 * Same as rehash(ceil(n / max_load_factor())).
1948 reserve(size_type __n
)
1949 { _M_h
.reserve(__n
); }
1951 template<typename _Value1
, typename _Hash1
, typename _Pred1
,
1954 operator==(const unordered_multiset
<_Value1
, _Hash1
, _Pred1
, _Alloc1
>&,
1955 const unordered_multiset
<_Value1
, _Hash1
, _Pred1
, _Alloc1
>&);
1959 #if __cpp_deduction_guides >= 201606
1961 template<typename _InputIterator
,
1963 hash
<typename iterator_traits
<_InputIterator
>::value_type
>,
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
>;
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
>;
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
,
1998 iterator_traits
<_InputIterator
>::value_type
>,
2000 iterator_traits
<_InputIterator
>::value_type
>,
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
,
2011 iterator_traits
<_InputIterator
>::value_type
>,
2013 iterator_traits
<_InputIterator
>::value_type
>,
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
,
2023 -> unordered_multiset
<typename
2024 iterator_traits
<_InputIterator
>::value_type
,
2028 iterator_traits
<_InputIterator
>::value_type
>,
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
>;
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
>;
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
>;
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
>;
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
>>,
2070 template<ranges::input_range _Rg
,
2071 __allocator_like _Allocator
>
2072 unordered_multiset(from_range_t
, _Rg
&&, unordered_multiset
<int>::size_type
,
2074 -> unordered_multiset
<ranges::range_value_t
<_Rg
>,
2075 hash
<ranges::range_value_t
<_Rg
>>,
2076 equal_to
<ranges::range_value_t
<_Rg
>>,
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
,
2085 -> unordered_multiset
<ranges::range_value_t
<_Rg
>, _Hash
,
2086 equal_to
<ranges::range_value_t
<_Rg
>>,
2091 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
2093 swap(unordered_set
<_Value
, _Hash
, _Pred
, _Alloc
>& __x
,
2094 unordered_set
<_Value
, _Hash
, _Pred
, _Alloc
>& __y
)
2095 noexcept(noexcept(__x
.swap(__y
)))
2098 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
2100 swap(unordered_multiset
<_Value
, _Hash
, _Pred
, _Alloc
>& __x
,
2101 unordered_multiset
<_Value
, _Hash
, _Pred
, _Alloc
>& __y
)
2102 noexcept(noexcept(__x
.swap(__y
)))
2105 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
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
); }
2111 #if __cpp_impl_three_way_comparison < 201907L
2112 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
2114 operator!=(const unordered_set
<_Value
, _Hash
, _Pred
, _Alloc
>& __x
,
2115 const unordered_set
<_Value
, _Hash
, _Pred
, _Alloc
>& __y
)
2116 { return !(__x
== __y
); }
2119 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
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
); }
2125 #if __cpp_impl_three_way_comparison < 201907L
2126 template<class _Value
, class _Hash
, class _Pred
, class _Alloc
>
2128 operator!=(const unordered_multiset
<_Value
, _Hash
, _Pred
, _Alloc
>& __x
,
2129 const unordered_multiset
<_Value
, _Hash
, _Pred
, _Alloc
>& __y
)
2130 { return !(__x
== __y
); }
2133 _GLIBCXX_END_NAMESPACE_CONTAINER
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
>
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
...>;
2148 friend unordered_set
<_Val
, _Hash1
, _Eq1
, _Alloc
>;
2151 _S_get_table(unordered_set
<_Val
, _Hash2
, _Eq2
, _Alloc
>& __set
)
2152 { return __set
._M_h
; }
2155 _S_get_table(unordered_multiset
<_Val
, _Hash2
, _Eq2
, _Alloc
>& __set
)
2156 { return __set
._M_h
; }
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
>,
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
...>;
2172 friend unordered_multiset
<_Val
, _Hash1
, _Eq1
, _Alloc
>;
2175 _S_get_table(unordered_set
<_Val
, _Hash2
, _Eq2
, _Alloc
>& __set
)
2176 { return __set
._M_h
; }
2179 _S_get_table(unordered_multiset
<_Val
, _Hash2
, _Eq2
, _Alloc
>& __set
)
2180 { return __set
._M_h
; }
2182 #endif // node_extract
2184 _GLIBCXX_END_NAMESPACE_VERSION
2187 #endif /* _UNORDERED_SET_H */