]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/unordered_set.h
re PR libstdc++/81064 (Inline namespace regression)
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / unordered_set.h
CommitLineData
3b2524b1
PC
1// unordered_set implementation -*- C++ -*-
2
cbe34bb5 3// Copyright (C) 2010-2017 Free Software Foundation, Inc.
3b2524b1
PC
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.
f910786b 27 * Do not attempt to use it directly. @headername{unordered_set}
3b2524b1
PC
28 */
29
30#ifndef _UNORDERED_SET_H
31#define _UNORDERED_SET_H
32
12ffa228
BK
33namespace std _GLIBCXX_VISIBILITY(default)
34{
4a15d842 35_GLIBCXX_BEGIN_NAMESPACE_VERSION
12ffa228 36_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
3b2524b1 37
4dad8b49
BK
38 /// Base types for unordered_set.
39 template<bool _Cache>
40 using __uset_traits = __detail::_Hashtable_traits<_Cache, true, true>;
41
42 template<typename _Value,
43 typename _Hash = hash<_Value>,
44 typename _Pred = std::equal_to<_Value>,
45 typename _Alloc = std::allocator<_Value>,
46 typename _Tr = __uset_traits<__cache_default<_Value, _Hash>::value>>
47 using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc,
5ac4e73a 48 __detail::_Identity, _Pred, _Hash,
4dad8b49
BK
49 __detail::_Mod_range_hashing,
50 __detail::_Default_ranged_hash,
51 __detail::_Prime_rehash_policy, _Tr>;
52
53 /// Base types for unordered_multiset.
54 template<bool _Cache>
55 using __umset_traits = __detail::_Hashtable_traits<_Cache, true, false>;
56
57 template<typename _Value,
58 typename _Hash = hash<_Value>,
59 typename _Pred = std::equal_to<_Value>,
60 typename _Alloc = std::allocator<_Value>,
61 typename _Tr = __umset_traits<__cache_default<_Value, _Hash>::value>>
62 using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc,
5ac4e73a 63 __detail::_Identity,
4dad8b49
BK
64 _Pred, _Hash,
65 __detail::_Mod_range_hashing,
66 __detail::_Default_ranged_hash,
67 __detail::_Prime_rehash_policy, _Tr>;
3b2524b1 68
2dbe56bd
JW
69 template<class _Value, class _Hash, class _Pred, class _Alloc>
70 class unordered_multiset;
71
3b2524b1
PC
72 /**
73 * @brief A standard container composed of unique keys (containing
74 * at most one of each key value) in which the elements' keys are
75 * the elements themselves.
76 *
77 * @ingroup unordered_associative_containers
78 *
4dad8b49
BK
79 * @tparam _Value Type of key objects.
80 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
81
82 * @tparam _Pred Predicate function object type, defaults to
83 * equal_to<_Value>.
84 *
85 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
86 *
d632488a
BK
87 * Meets the requirements of a <a href="tables.html#65">container</a>, and
88 * <a href="tables.html#xx">unordered associative container</a>
89 *
4dad8b49
BK
90 * Base is _Hashtable, dispatched at compile time via template
91 * alias __uset_hashtable.
3b2524b1
PC
92 */
93 template<class _Value,
94 class _Hash = hash<_Value>,
95 class _Pred = std::equal_to<_Value>,
96 class _Alloc = std::allocator<_Value> >
8ed13e27 97 class unordered_set
3b2524b1 98 {
637fd8b3
FD
99 typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
100 _Hashtable _M_h;
3b2524b1
PC
101
102 public:
637fd8b3
FD
103 // typedefs:
104 //@{
105 /// Public typedefs.
106 typedef typename _Hashtable::key_type key_type;
107 typedef typename _Hashtable::value_type value_type;
108 typedef typename _Hashtable::hasher hasher;
109 typedef typename _Hashtable::key_equal key_equal;
110 typedef typename _Hashtable::allocator_type allocator_type;
111 //@}
4dad8b49 112
637fd8b3
FD
113 //@{
114 /// Iterator-related typedefs.
0462b6aa
FD
115 typedef typename _Hashtable::pointer pointer;
116 typedef typename _Hashtable::const_pointer const_pointer;
117 typedef typename _Hashtable::reference reference;
118 typedef typename _Hashtable::const_reference const_reference;
637fd8b3
FD
119 typedef typename _Hashtable::iterator iterator;
120 typedef typename _Hashtable::const_iterator const_iterator;
121 typedef typename _Hashtable::local_iterator local_iterator;
122 typedef typename _Hashtable::const_local_iterator const_local_iterator;
123 typedef typename _Hashtable::size_type size_type;
124 typedef typename _Hashtable::difference_type difference_type;
125 //@}
126
2dbe56bd
JW
127#if __cplusplus > 201402L
128 using node_type = typename _Hashtable::node_type;
129 using insert_return_type = typename _Hashtable::insert_return_type;
130#endif
131
637fd8b3 132 // construct/destroy/copy
da27f556
FD
133
134 /// Default constructor.
135 unordered_set() = default;
136
637fd8b3
FD
137 /**
138 * @brief Default constructor creates no elements.
da27f556 139 * @param __n Minimal initial number of buckets.
637fd8b3
FD
140 * @param __hf A hash functor.
141 * @param __eql A key equality functor.
142 * @param __a An allocator object.
143 */
3b2524b1 144 explicit
da27f556 145 unordered_set(size_type __n,
3b2524b1
PC
146 const hasher& __hf = hasher(),
147 const key_equal& __eql = key_equal(),
148 const allocator_type& __a = allocator_type())
637fd8b3 149 : _M_h(__n, __hf, __eql, __a)
3b2524b1
PC
150 { }
151
637fd8b3
FD
152 /**
153 * @brief Builds an %unordered_set from a range.
154 * @param __first An input iterator.
155 * @param __last An input iterator.
156 * @param __n Minimal initial number of buckets.
157 * @param __hf A hash functor.
158 * @param __eql A key equality functor.
159 * @param __a An allocator object.
160 *
161 * Create an %unordered_set consisting of copies of the elements from
162 * [__first,__last). This is linear in N (where N is
163 * distance(__first,__last)).
164 */
3b2524b1 165 template<typename _InputIterator>
00541349 166 unordered_set(_InputIterator __first, _InputIterator __last,
417e896e 167 size_type __n = 0,
4dad8b49
BK
168 const hasher& __hf = hasher(),
169 const key_equal& __eql = key_equal(),
3b2524b1 170 const allocator_type& __a = allocator_type())
00541349 171 : _M_h(__first, __last, __n, __hf, __eql, __a)
4dad8b49 172 { }
3b2524b1 173
099e644e
FD
174 /// Copy constructor.
175 unordered_set(const unordered_set&) = default;
637fd8b3 176
099e644e
FD
177 /// Move constructor.
178 unordered_set(unordered_set&&) = default;
637fd8b3 179
0462b6aa
FD
180 /**
181 * @brief Creates an %unordered_set with no elements.
182 * @param __a An allocator object.
183 */
184 explicit
185 unordered_set(const allocator_type& __a)
e55b80f5 186 : _M_h(__a)
0462b6aa
FD
187 { }
188
189 /*
190 * @brief Copy constructor with allocator argument.
191 * @param __uset Input %unordered_set to copy.
192 * @param __a An allocator object.
193 */
194 unordered_set(const unordered_set& __uset,
195 const allocator_type& __a)
e55b80f5 196 : _M_h(__uset._M_h, __a)
0462b6aa
FD
197 { }
198
199 /*
200 * @brief Move constructor with allocator argument.
201 * @param __uset Input %unordered_set to move.
202 * @param __a An allocator object.
203 */
204 unordered_set(unordered_set&& __uset,
205 const allocator_type& __a)
e55b80f5 206 : _M_h(std::move(__uset._M_h), __a)
0462b6aa
FD
207 { }
208
637fd8b3
FD
209 /**
210 * @brief Builds an %unordered_set from an initializer_list.
211 * @param __l An initializer_list.
212 * @param __n Minimal initial number of buckets.
213 * @param __hf A hash functor.
214 * @param __eql A key equality functor.
215 * @param __a An allocator object.
216 *
217 * Create an %unordered_set consisting of copies of the elements in the
218 * list. This is linear in N (where N is @a __l.size()).
219 */
3b2524b1 220 unordered_set(initializer_list<value_type> __l,
417e896e 221 size_type __n = 0,
3b2524b1
PC
222 const hasher& __hf = hasher(),
223 const key_equal& __eql = key_equal(),
224 const allocator_type& __a = allocator_type())
e55b80f5
FD
225 : _M_h(__l, __n, __hf, __eql, __a)
226 { }
227
228 unordered_set(size_type __n, const allocator_type& __a)
229 : unordered_set(__n, hasher(), key_equal(), __a)
230 { }
231
232 unordered_set(size_type __n, const hasher& __hf,
233 const allocator_type& __a)
234 : unordered_set(__n, __hf, key_equal(), __a)
235 { }
236
237 template<typename _InputIterator>
238 unordered_set(_InputIterator __first, _InputIterator __last,
239 size_type __n,
240 const allocator_type& __a)
241 : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
242 { }
243
244 template<typename _InputIterator>
245 unordered_set(_InputIterator __first, _InputIterator __last,
246 size_type __n, const hasher& __hf,
247 const allocator_type& __a)
248 : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
249 { }
250
251 unordered_set(initializer_list<value_type> __l,
252 size_type __n,
253 const allocator_type& __a)
254 : unordered_set(__l, __n, hasher(), key_equal(), __a)
255 { }
256
257 unordered_set(initializer_list<value_type> __l,
258 size_type __n, const hasher& __hf,
259 const allocator_type& __a)
260 : unordered_set(__l, __n, __hf, key_equal(), __a)
3b2524b1 261 { }
637fd8b3 262
099e644e 263 /// Copy assignment operator.
637fd8b3 264 unordered_set&
099e644e 265 operator=(const unordered_set&) = default;
637fd8b3 266
099e644e 267 /// Move assignment operator.
637fd8b3 268 unordered_set&
099e644e 269 operator=(unordered_set&&) = default;
637fd8b3
FD
270
271 /**
272 * @brief %Unordered_set list assignment operator.
273 * @param __l An initializer_list.
274 *
275 * This function fills an %unordered_set with copies of the elements in
276 * the initializer list @a __l.
277 *
278 * Note that the assignment completely changes the %unordered_set and
279 * that the resulting %unordered_set's size is the same as the number
0a2bf188 280 * of elements assigned.
637fd8b3
FD
281 */
282 unordered_set&
283 operator=(initializer_list<value_type> __l)
284 {
285 _M_h = __l;
286 return *this;
287 }
288
0a2bf188 289 /// Returns the allocator object used by the %unordered_set.
637fd8b3
FD
290 allocator_type
291 get_allocator() const noexcept
292 { return _M_h.get_allocator(); }
293
294 // size and capacity:
295
296 /// Returns true if the %unordered_set is empty.
297 bool
298 empty() const noexcept
299 { return _M_h.empty(); }
300
301 /// Returns the size of the %unordered_set.
302 size_type
303 size() const noexcept
304 { return _M_h.size(); }
305
306 /// Returns the maximum size of the %unordered_set.
307 size_type
308 max_size() const noexcept
309 { return _M_h.max_size(); }
310
311 // iterators.
312
313 //@{
314 /**
315 * Returns a read-only (constant) iterator that points to the first
316 * element in the %unordered_set.
317 */
318 iterator
319 begin() noexcept
320 { return _M_h.begin(); }
321
322 const_iterator
323 begin() const noexcept
324 { return _M_h.begin(); }
325 //@}
326
327 //@{
328 /**
329 * Returns a read-only (constant) iterator that points one past the last
330 * element in the %unordered_set.
331 */
332 iterator
333 end() noexcept
334 { return _M_h.end(); }
335
336 const_iterator
337 end() const noexcept
338 { return _M_h.end(); }
339 //@}
340
341 /**
342 * Returns a read-only (constant) iterator that points to the first
343 * element in the %unordered_set.
344 */
345 const_iterator
346 cbegin() const noexcept
347 { return _M_h.begin(); }
348
349 /**
350 * Returns a read-only (constant) iterator that points one past the last
351 * element in the %unordered_set.
352 */
353 const_iterator
354 cend() const noexcept
355 { return _M_h.end(); }
356
357 // modifiers.
358
359 /**
360 * @brief Attempts to build and insert an element into the
361 * %unordered_set.
362 * @param __args Arguments used to generate an element.
363 * @return A pair, of which the first element is an iterator that points
364 * to the possibly inserted element, and the second is a bool
365 * that is true if the element was actually inserted.
366 *
367 * This function attempts to build and insert an element into the
368 * %unordered_set. An %unordered_set relies on unique keys and thus an
099e644e
FD
369 * element is only inserted if it is not already present in the
370 * %unordered_set.
637fd8b3
FD
371 *
372 * Insertion requires amortized constant time.
373 */
374 template<typename... _Args>
375 std::pair<iterator, bool>
376 emplace(_Args&&... __args)
377 { return _M_h.emplace(std::forward<_Args>(__args)...); }
378
379 /**
380 * @brief Attempts to insert an element into the %unordered_set.
381 * @param __pos An iterator that serves as a hint as to where the
382 * element should be inserted.
383 * @param __args Arguments used to generate the element to be
384 * inserted.
385 * @return An iterator that points to the element with key equivalent to
386 * the one generated from @a __args (may or may not be the
387 * element itself).
388 *
389 * This function is not concerned about whether the insertion took place,
390 * and thus does not return a boolean like the single-argument emplace()
391 * does. Note that the first parameter is only a hint and can
392 * potentially improve the performance of the insertion process. A bad
393 * hint would cause no gains in efficiency.
394 *
395 * For more on @a hinting, see:
10d43d2f 396 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
637fd8b3
FD
397 *
398 * Insertion requires amortized constant time.
399 */
400 template<typename... _Args>
401 iterator
402 emplace_hint(const_iterator __pos, _Args&&... __args)
403 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
404
405 //@{
406 /**
407 * @brief Attempts to insert an element into the %unordered_set.
408 * @param __x Element to be inserted.
409 * @return A pair, of which the first element is an iterator that points
410 * to the possibly inserted element, and the second is a bool
411 * that is true if the element was actually inserted.
412 *
413 * This function attempts to insert an element into the %unordered_set.
414 * An %unordered_set relies on unique keys and thus an element is only
415 * inserted if it is not already present in the %unordered_set.
416 *
417 * Insertion requires amortized constant time.
418 */
419 std::pair<iterator, bool>
420 insert(const value_type& __x)
421 { return _M_h.insert(__x); }
422
423 std::pair<iterator, bool>
424 insert(value_type&& __x)
425 { return _M_h.insert(std::move(__x)); }
426 //@}
427
428 //@{
429 /**
430 * @brief Attempts to insert an element into the %unordered_set.
431 * @param __hint An iterator that serves as a hint as to where the
432 * element should be inserted.
433 * @param __x Element to be inserted.
434 * @return An iterator that points to the element with key of
435 * @a __x (may or may not be the element passed in).
436 *
437 * This function is not concerned about whether the insertion took place,
438 * and thus does not return a boolean like the single-argument insert()
439 * does. Note that the first parameter is only a hint and can
440 * potentially improve the performance of the insertion process. A bad
441 * hint would cause no gains in efficiency.
442 *
443 * For more on @a hinting, see:
10d43d2f 444 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
637fd8b3
FD
445 *
446 * Insertion requires amortized constant.
447 */
448 iterator
449 insert(const_iterator __hint, const value_type& __x)
450 { return _M_h.insert(__hint, __x); }
451
452 iterator
453 insert(const_iterator __hint, value_type&& __x)
454 { return _M_h.insert(__hint, std::move(__x)); }
455 //@}
456
457 /**
458 * @brief A template function that attempts to insert a range of
459 * elements.
460 * @param __first Iterator pointing to the start of the range to be
461 * inserted.
462 * @param __last Iterator pointing to the end of the range.
463 *
464 * Complexity similar to that of the range constructor.
465 */
466 template<typename _InputIterator>
467 void
468 insert(_InputIterator __first, _InputIterator __last)
469 { _M_h.insert(__first, __last); }
470
471 /**
472 * @brief Attempts to insert a list of elements into the %unordered_set.
473 * @param __l A std::initializer_list<value_type> of elements
474 * to be inserted.
475 *
476 * Complexity similar to that of the range constructor.
477 */
478 void
479 insert(initializer_list<value_type> __l)
480 { _M_h.insert(__l); }
481
2dbe56bd
JW
482#if __cplusplus > 201402L
483 /// Extract a node.
484 node_type
485 extract(const_iterator __pos)
976160b9
JW
486 {
487 __glibcxx_assert(__pos != end());
488 return _M_h.extract(__pos);
489 }
2dbe56bd
JW
490
491 /// Extract a node.
492 node_type
493 extract(const key_type& __key)
494 { return _M_h.extract(__key); }
495
496 /// Re-insert an extracted node.
497 insert_return_type
498 insert(node_type&& __nh)
499 { return _M_h._M_reinsert_node(std::move(__nh)); }
500
501 /// Re-insert an extracted node.
502 iterator
503 insert(const_iterator, node_type&& __nh)
504 { return _M_h._M_reinsert_node(std::move(__nh)).position; }
505#endif // C++17
506
637fd8b3
FD
507 //@{
508 /**
509 * @brief Erases an element from an %unordered_set.
510 * @param __position An iterator pointing to the element to be erased.
511 * @return An iterator pointing to the element immediately following
512 * @a __position prior to the element being erased. If no such
513 * element exists, end() is returned.
514 *
515 * This function erases an element, pointed to by the given iterator,
516 * from an %unordered_set. Note that this function only erases the
517 * element, and that if the element is itself a pointer, the pointed-to
518 * memory is not touched in any way. Managing the pointer is the user's
519 * responsibility.
520 */
521 iterator
522 erase(const_iterator __position)
523 { return _M_h.erase(__position); }
524
525 // LWG 2059.
526 iterator
00541349
JW
527 erase(iterator __position)
528 { return _M_h.erase(__position); }
637fd8b3
FD
529 //@}
530
531 /**
532 * @brief Erases elements according to the provided key.
533 * @param __x Key of element to be erased.
534 * @return The number of elements erased.
535 *
536 * This function erases all the elements located by the given key from
537 * an %unordered_set. For an %unordered_set the result of this function
538 * can only be 0 (not present) or 1 (present).
539 * Note that this function only erases the element, and that if
540 * the element is itself a pointer, the pointed-to memory is not touched
541 * in any way. Managing the pointer is the user's responsibility.
542 */
543 size_type
544 erase(const key_type& __x)
545 { return _M_h.erase(__x); }
546
547 /**
548 * @brief Erases a [__first,__last) range of elements from an
549 * %unordered_set.
550 * @param __first Iterator pointing to the start of the range to be
551 * erased.
552 * @param __last Iterator pointing to the end of the range to
553 * be erased.
554 * @return The iterator @a __last.
555 *
556 * This function erases a sequence of elements from an %unordered_set.
557 * Note that this function only erases the element, and that if
558 * the element is itself a pointer, the pointed-to memory is not touched
559 * in any way. Managing the pointer is the user's responsibility.
560 */
561 iterator
562 erase(const_iterator __first, const_iterator __last)
563 { return _M_h.erase(__first, __last); }
564
565 /**
566 * Erases all elements in an %unordered_set. Note that this function only
567 * erases the elements, and that if the elements themselves are pointers,
568 * the pointed-to memory is not touched in any way. Managing the pointer
569 * is the user's responsibility.
570 */
571 void
572 clear() noexcept
573 { _M_h.clear(); }
574
575 /**
576 * @brief Swaps data with another %unordered_set.
577 * @param __x An %unordered_set of the same element and allocator
578 * types.
579 *
580 * This exchanges the elements between two sets in constant time.
581 * Note that the global std::swap() function is specialized such that
582 * std::swap(s1,s2) will feed to this function.
583 */
584 void
585 swap(unordered_set& __x)
0462b6aa 586 noexcept( noexcept(_M_h.swap(__x._M_h)) )
637fd8b3
FD
587 { _M_h.swap(__x._M_h); }
588
2dbe56bd
JW
589#if __cplusplus > 201402L
590 template<typename, typename, typename>
591 friend class _Hash_merge_helper;
592
593 template<typename _H2, typename _P2>
594 void
595 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
596 {
597 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
598 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
599 }
600
601 template<typename _H2, typename _P2>
602 void
603 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
604 { merge(__source); }
605
606 template<typename _H2, typename _P2>
607 void
608 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
609 {
610 using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>;
611 _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source));
612 }
613
614 template<typename _H2, typename _P2>
615 void
616 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
617 { merge(__source); }
618#endif // C++17
619
637fd8b3
FD
620 // observers.
621
622 /// Returns the hash functor object with which the %unordered_set was
623 /// constructed.
624 hasher
625 hash_function() const
626 { return _M_h.hash_function(); }
627
628 /// Returns the key comparison object with which the %unordered_set was
629 /// constructed.
630 key_equal
631 key_eq() const
632 { return _M_h.key_eq(); }
633
634 // lookup.
635
636 //@{
637 /**
638 * @brief Tries to locate an element in an %unordered_set.
639 * @param __x Element to be located.
640 * @return Iterator pointing to sought-after element, or end() if not
641 * found.
642 *
643 * This function takes a key and tries to locate the element with which
644 * the key matches. If successful the function returns an iterator
645 * pointing to the sought after element. If unsuccessful it returns the
646 * past-the-end ( @c end() ) iterator.
647 */
648 iterator
649 find(const key_type& __x)
650 { return _M_h.find(__x); }
651
652 const_iterator
653 find(const key_type& __x) const
654 { return _M_h.find(__x); }
655 //@}
656
657 /**
658 * @brief Finds the number of elements.
659 * @param __x Element to located.
660 * @return Number of elements with specified key.
661 *
662 * This function only makes sense for unordered_multisets; for
663 * unordered_set the result will either be 0 (not present) or 1
664 * (present).
665 */
666 size_type
667 count(const key_type& __x) const
668 { return _M_h.count(__x); }
669
670 //@{
671 /**
672 * @brief Finds a subsequence matching given key.
673 * @param __x Key to be located.
674 * @return Pair of iterators that possibly points to the subsequence
675 * matching given key.
676 *
677 * This function probably only makes sense for multisets.
678 */
679 std::pair<iterator, iterator>
680 equal_range(const key_type& __x)
681 { return _M_h.equal_range(__x); }
682
683 std::pair<const_iterator, const_iterator>
684 equal_range(const key_type& __x) const
685 { return _M_h.equal_range(__x); }
686 //@}
687
688 // bucket interface.
689
690 /// Returns the number of buckets of the %unordered_set.
691 size_type
692 bucket_count() const noexcept
693 { return _M_h.bucket_count(); }
694
695 /// Returns the maximum number of buckets of the %unordered_set.
696 size_type
697 max_bucket_count() const noexcept
698 { return _M_h.max_bucket_count(); }
699
700 /*
701 * @brief Returns the number of elements in a given bucket.
702 * @param __n A bucket index.
703 * @return The number of elements in the bucket.
704 */
705 size_type
706 bucket_size(size_type __n) const
707 { return _M_h.bucket_size(__n); }
708
709 /*
710 * @brief Returns the bucket index of a given element.
711 * @param __key A key instance.
712 * @return The key bucket index.
713 */
714 size_type
715 bucket(const key_type& __key) const
716 { return _M_h.bucket(__key); }
717
718 //@{
719 /**
720 * @brief Returns a read-only (constant) iterator pointing to the first
721 * bucket element.
722 * @param __n The bucket index.
723 * @return A read-only local iterator.
724 */
725 local_iterator
726 begin(size_type __n)
727 { return _M_h.begin(__n); }
728
729 const_local_iterator
730 begin(size_type __n) const
731 { return _M_h.begin(__n); }
732
733 const_local_iterator
734 cbegin(size_type __n) const
735 { return _M_h.cbegin(__n); }
736 //@}
737
738 //@{
739 /**
740 * @brief Returns a read-only (constant) iterator pointing to one past
741 * the last bucket elements.
742 * @param __n The bucket index.
743 * @return A read-only local iterator.
744 */
745 local_iterator
746 end(size_type __n)
747 { return _M_h.end(__n); }
748
749 const_local_iterator
750 end(size_type __n) const
751 { return _M_h.end(__n); }
752
753 const_local_iterator
754 cend(size_type __n) const
755 { return _M_h.cend(__n); }
756 //@}
757
758 // hash policy.
759
760 /// Returns the average number of elements per bucket.
761 float
762 load_factor() const noexcept
763 { return _M_h.load_factor(); }
764
765 /// Returns a positive number that the %unordered_set tries to keep the
766 /// load factor less than or equal to.
767 float
768 max_load_factor() const noexcept
769 { return _M_h.max_load_factor(); }
770
771 /**
772 * @brief Change the %unordered_set maximum load factor.
773 * @param __z The new maximum load factor.
774 */
775 void
776 max_load_factor(float __z)
777 { _M_h.max_load_factor(__z); }
778
779 /**
780 * @brief May rehash the %unordered_set.
781 * @param __n The new number of buckets.
782 *
783 * Rehash will occur only if the new number of buckets respect the
784 * %unordered_set maximum load factor.
785 */
786 void
787 rehash(size_type __n)
788 { _M_h.rehash(__n); }
789
790 /**
791 * @brief Prepare the %unordered_set for a specified number of
792 * elements.
793 * @param __n Number of elements required.
794 *
795 * Same as rehash(ceil(n / max_load_factor())).
796 */
797 void
798 reserve(size_type __n)
799 { _M_h.reserve(__n); }
800
801 template<typename _Value1, typename _Hash1, typename _Pred1,
802 typename _Alloc1>
803 friend bool
e55b80f5
FD
804 operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&,
805 const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&);
3b2524b1
PC
806 };
807
808 /**
809 * @brief A standard container composed of equivalent keys
810 * (possibly containing multiple of each key value) in which the
811 * elements' keys are the elements themselves.
812 *
813 * @ingroup unordered_associative_containers
814 *
4dad8b49
BK
815 * @tparam _Value Type of key objects.
816 * @tparam _Hash Hashing function object type, defaults to hash<_Value>.
817 * @tparam _Pred Predicate function object type, defaults
818 * to equal_to<_Value>.
819 * @tparam _Alloc Allocator type, defaults to allocator<_Key>.
820 *
d632488a
BK
821 * Meets the requirements of a <a href="tables.html#65">container</a>, and
822 * <a href="tables.html#xx">unordered associative container</a>
823 *
4dad8b49
BK
824 * Base is _Hashtable, dispatched at compile time via template
825 * alias __umset_hashtable.
3b2524b1
PC
826 */
827 template<class _Value,
828 class _Hash = hash<_Value>,
829 class _Pred = std::equal_to<_Value>,
830 class _Alloc = std::allocator<_Value> >
8ed13e27 831 class unordered_multiset
3b2524b1 832 {
637fd8b3
FD
833 typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
834 _Hashtable _M_h;
3b2524b1
PC
835
836 public:
637fd8b3
FD
837 // typedefs:
838 //@{
839 /// Public typedefs.
840 typedef typename _Hashtable::key_type key_type;
841 typedef typename _Hashtable::value_type value_type;
842 typedef typename _Hashtable::hasher hasher;
843 typedef typename _Hashtable::key_equal key_equal;
844 typedef typename _Hashtable::allocator_type allocator_type;
845 //@}
846
847 //@{
848 /// Iterator-related typedefs.
0462b6aa
FD
849 typedef typename _Hashtable::pointer pointer;
850 typedef typename _Hashtable::const_pointer const_pointer;
851 typedef typename _Hashtable::reference reference;
852 typedef typename _Hashtable::const_reference const_reference;
637fd8b3
FD
853 typedef typename _Hashtable::iterator iterator;
854 typedef typename _Hashtable::const_iterator const_iterator;
855 typedef typename _Hashtable::local_iterator local_iterator;
856 typedef typename _Hashtable::const_local_iterator const_local_iterator;
857 typedef typename _Hashtable::size_type size_type;
858 typedef typename _Hashtable::difference_type difference_type;
859 //@}
4dad8b49 860
2dbe56bd
JW
861#if __cplusplus > 201402L
862 using node_type = typename _Hashtable::node_type;
863#endif
864
637fd8b3 865 // construct/destroy/copy
da27f556
FD
866
867 /// Default constructor.
868 unordered_multiset() = default;
869
637fd8b3
FD
870 /**
871 * @brief Default constructor creates no elements.
da27f556 872 * @param __n Minimal initial number of buckets.
637fd8b3
FD
873 * @param __hf A hash functor.
874 * @param __eql A key equality functor.
875 * @param __a An allocator object.
876 */
3b2524b1 877 explicit
da27f556 878 unordered_multiset(size_type __n,
3b2524b1
PC
879 const hasher& __hf = hasher(),
880 const key_equal& __eql = key_equal(),
881 const allocator_type& __a = allocator_type())
637fd8b3 882 : _M_h(__n, __hf, __eql, __a)
3b2524b1
PC
883 { }
884
637fd8b3
FD
885 /**
886 * @brief Builds an %unordered_multiset from a range.
887 * @param __first An input iterator.
00541349
JW
888 * @param __last An input iterator.
889 * @param __n Minimal initial number of buckets.
890 * @param __hf A hash functor.
891 * @param __eql A key equality functor.
892 * @param __a An allocator object.
637fd8b3
FD
893 *
894 * Create an %unordered_multiset consisting of copies of the elements
895 * from [__first,__last). This is linear in N (where N is
896 * distance(__first,__last)).
897 */
3b2524b1 898 template<typename _InputIterator>
00541349 899 unordered_multiset(_InputIterator __first, _InputIterator __last,
417e896e 900 size_type __n = 0,
4dad8b49
BK
901 const hasher& __hf = hasher(),
902 const key_equal& __eql = key_equal(),
3b2524b1 903 const allocator_type& __a = allocator_type())
00541349 904 : _M_h(__first, __last, __n, __hf, __eql, __a)
4dad8b49 905 { }
3b2524b1 906
099e644e
FD
907 /// Copy constructor.
908 unordered_multiset(const unordered_multiset&) = default;
637fd8b3 909
099e644e
FD
910 /// Move constructor.
911 unordered_multiset(unordered_multiset&&) = default;
637fd8b3
FD
912
913 /**
914 * @brief Builds an %unordered_multiset from an initializer_list.
915 * @param __l An initializer_list.
916 * @param __n Minimal initial number of buckets.
917 * @param __hf A hash functor.
918 * @param __eql A key equality functor.
919 * @param __a An allocator object.
920 *
921 * Create an %unordered_multiset consisting of copies of the elements in
922 * the list. This is linear in N (where N is @a __l.size()).
923 */
3b2524b1 924 unordered_multiset(initializer_list<value_type> __l,
417e896e 925 size_type __n = 0,
3b2524b1
PC
926 const hasher& __hf = hasher(),
927 const key_equal& __eql = key_equal(),
928 const allocator_type& __a = allocator_type())
e55b80f5 929 : _M_h(__l, __n, __hf, __eql, __a)
3b2524b1 930 { }
637fd8b3 931
099e644e 932 /// Copy assignment operator.
637fd8b3 933 unordered_multiset&
099e644e 934 operator=(const unordered_multiset&) = default;
637fd8b3 935
099e644e 936 /// Move assignment operator.
637fd8b3 937 unordered_multiset&
0462b6aa
FD
938 operator=(unordered_multiset&&) = default;
939
940 /**
941 * @brief Creates an %unordered_multiset with no elements.
942 * @param __a An allocator object.
943 */
944 explicit
945 unordered_multiset(const allocator_type& __a)
e55b80f5 946 : _M_h(__a)
0462b6aa
FD
947 { }
948
949 /*
950 * @brief Copy constructor with allocator argument.
951 * @param __uset Input %unordered_multiset to copy.
952 * @param __a An allocator object.
953 */
954 unordered_multiset(const unordered_multiset& __umset,
955 const allocator_type& __a)
e55b80f5 956 : _M_h(__umset._M_h, __a)
0462b6aa
FD
957 { }
958
959 /*
960 * @brief Move constructor with allocator argument.
961 * @param __umset Input %unordered_multiset to move.
962 * @param __a An allocator object.
963 */
964 unordered_multiset(unordered_multiset&& __umset,
965 const allocator_type& __a)
e55b80f5
FD
966 : _M_h(std::move(__umset._M_h), __a)
967 { }
968
969 unordered_multiset(size_type __n, const allocator_type& __a)
970 : unordered_multiset(__n, hasher(), key_equal(), __a)
971 { }
972
973 unordered_multiset(size_type __n, const hasher& __hf,
974 const allocator_type& __a)
975 : unordered_multiset(__n, __hf, key_equal(), __a)
976 { }
977
978 template<typename _InputIterator>
979 unordered_multiset(_InputIterator __first, _InputIterator __last,
980 size_type __n,
981 const allocator_type& __a)
982 : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
983 { }
984
985 template<typename _InputIterator>
986 unordered_multiset(_InputIterator __first, _InputIterator __last,
987 size_type __n, const hasher& __hf,
988 const allocator_type& __a)
989 : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
990 { }
991
992 unordered_multiset(initializer_list<value_type> __l,
993 size_type __n,
994 const allocator_type& __a)
995 : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
996 { }
997
998 unordered_multiset(initializer_list<value_type> __l,
999 size_type __n, const hasher& __hf,
1000 const allocator_type& __a)
1001 : unordered_multiset(__l, __n, __hf, key_equal(), __a)
0462b6aa 1002 { }
637fd8b3
FD
1003
1004 /**
1005 * @brief %Unordered_multiset list assignment operator.
1006 * @param __l An initializer_list.
1007 *
1008 * This function fills an %unordered_multiset with copies of the elements
1009 * in the initializer list @a __l.
1010 *
1011 * Note that the assignment completely changes the %unordered_multiset
e55b80f5 1012 * and that the resulting %unordered_multiset's size is the same as the
0a2bf188 1013 * number of elements assigned.
637fd8b3
FD
1014 */
1015 unordered_multiset&
1016 operator=(initializer_list<value_type> __l)
1017 {
1018 _M_h = __l;
1019 return *this;
1020 }
1021
0a2bf188 1022 /// Returns the allocator object used by the %unordered_multiset.
637fd8b3
FD
1023 allocator_type
1024 get_allocator() const noexcept
1025 { return _M_h.get_allocator(); }
1026
1027 // size and capacity:
1028
1029 /// Returns true if the %unordered_multiset is empty.
1030 bool
1031 empty() const noexcept
1032 { return _M_h.empty(); }
1033
1034 /// Returns the size of the %unordered_multiset.
1035 size_type
1036 size() const noexcept
1037 { return _M_h.size(); }
1038
1039 /// Returns the maximum size of the %unordered_multiset.
1040 size_type
1041 max_size() const noexcept
1042 { return _M_h.max_size(); }
1043
1044 // iterators.
1045
1046 //@{
1047 /**
1048 * Returns a read-only (constant) iterator that points to the first
1049 * element in the %unordered_multiset.
1050 */
1051 iterator
1052 begin() noexcept
1053 { return _M_h.begin(); }
1054
1055 const_iterator
1056 begin() const noexcept
1057 { return _M_h.begin(); }
1058 //@}
1059
1060 //@{
1061 /**
1062 * Returns a read-only (constant) iterator that points one past the last
1063 * element in the %unordered_multiset.
1064 */
1065 iterator
1066 end() noexcept
1067 { return _M_h.end(); }
1068
1069 const_iterator
1070 end() const noexcept
1071 { return _M_h.end(); }
1072 //@}
1073
1074 /**
1075 * Returns a read-only (constant) iterator that points to the first
1076 * element in the %unordered_multiset.
1077 */
1078 const_iterator
1079 cbegin() const noexcept
1080 { return _M_h.begin(); }
1081
1082 /**
1083 * Returns a read-only (constant) iterator that points one past the last
1084 * element in the %unordered_multiset.
1085 */
1086 const_iterator
1087 cend() const noexcept
1088 { return _M_h.end(); }
1089
1090 // modifiers.
1091
1092 /**
1093 * @brief Builds and insert an element into the %unordered_multiset.
1094 * @param __args Arguments used to generate an element.
1095 * @return An iterator that points to the inserted element.
1096 *
1097 * Insertion requires amortized constant time.
1098 */
1099 template<typename... _Args>
1100 iterator
1101 emplace(_Args&&... __args)
1102 { return _M_h.emplace(std::forward<_Args>(__args)...); }
1103
1104 /**
1105 * @brief Inserts an element into the %unordered_multiset.
1106 * @param __pos An iterator that serves as a hint as to where the
1107 * element should be inserted.
1108 * @param __args Arguments used to generate the element to be
1109 * inserted.
1110 * @return An iterator that points to the inserted element.
1111 *
1112 * Note that the first parameter is only a hint and can potentially
1113 * improve the performance of the insertion process. A bad hint would
1114 * cause no gains in efficiency.
1115 *
1116 * For more on @a hinting, see:
10d43d2f 1117 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
637fd8b3
FD
1118 *
1119 * Insertion requires amortized constant time.
1120 */
1121 template<typename... _Args>
1122 iterator
1123 emplace_hint(const_iterator __pos, _Args&&... __args)
1124 { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
1125
1126 //@{
1127 /**
1128 * @brief Inserts an element into the %unordered_multiset.
1129 * @param __x Element to be inserted.
1130 * @return An iterator that points to the inserted element.
1131 *
1132 * Insertion requires amortized constant time.
1133 */
1134 iterator
1135 insert(const value_type& __x)
1136 { return _M_h.insert(__x); }
1137
1138 iterator
1139 insert(value_type&& __x)
1140 { return _M_h.insert(std::move(__x)); }
1141 //@}
1142
1143 //@{
1144 /**
1145 * @brief Inserts an element into the %unordered_multiset.
1146 * @param __hint An iterator that serves as a hint as to where the
1147 * element should be inserted.
1148 * @param __x Element to be inserted.
1149 * @return An iterator that points to the inserted element.
1150 *
1151 * Note that the first parameter is only a hint and can potentially
1152 * improve the performance of the insertion process. A bad hint would
1153 * cause no gains in efficiency.
1154 *
1155 * For more on @a hinting, see:
10d43d2f 1156 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
637fd8b3
FD
1157 *
1158 * Insertion requires amortized constant.
1159 */
1160 iterator
1161 insert(const_iterator __hint, const value_type& __x)
1162 { return _M_h.insert(__hint, __x); }
1163
1164 iterator
1165 insert(const_iterator __hint, value_type&& __x)
1166 { return _M_h.insert(__hint, std::move(__x)); }
1167 //@}
1168
1169 /**
1170 * @brief A template function that inserts a range of elements.
1171 * @param __first Iterator pointing to the start of the range to be
1172 * inserted.
1173 * @param __last Iterator pointing to the end of the range.
1174 *
1175 * Complexity similar to that of the range constructor.
1176 */
1177 template<typename _InputIterator>
1178 void
1179 insert(_InputIterator __first, _InputIterator __last)
1180 { _M_h.insert(__first, __last); }
1181
1182 /**
1183 * @brief Inserts a list of elements into the %unordered_multiset.
1184 * @param __l A std::initializer_list<value_type> of elements to be
1185 * inserted.
1186 *
1187 * Complexity similar to that of the range constructor.
1188 */
1189 void
1190 insert(initializer_list<value_type> __l)
1191 { _M_h.insert(__l); }
1192
2dbe56bd
JW
1193#if __cplusplus > 201402L
1194 /// Extract a node.
1195 node_type
1196 extract(const_iterator __pos)
976160b9
JW
1197 {
1198 __glibcxx_assert(__pos != end());
1199 return _M_h.extract(__pos);
1200 }
2dbe56bd
JW
1201
1202 /// Extract a node.
1203 node_type
1204 extract(const key_type& __key)
1205 { return _M_h.extract(__key); }
1206
1207 /// Re-insert an extracted node.
1208 iterator
1209 insert(node_type&& __nh)
1210 { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); }
1211
1212 /// Re-insert an extracted node.
1213 iterator
1214 insert(const_iterator __hint, node_type&& __nh)
1215 { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
1216#endif // C++17
1217
637fd8b3
FD
1218 //@{
1219 /**
1220 * @brief Erases an element from an %unordered_multiset.
1221 * @param __position An iterator pointing to the element to be erased.
1222 * @return An iterator pointing to the element immediately following
1223 * @a __position prior to the element being erased. If no such
1224 * element exists, end() is returned.
1225 *
1226 * This function erases an element, pointed to by the given iterator,
1227 * from an %unordered_multiset.
1228 *
1229 * Note that this function only erases the element, and that if the
1230 * element is itself a pointer, the pointed-to memory is not touched in
1231 * any way. Managing the pointer is the user's responsibility.
1232 */
1233 iterator
1234 erase(const_iterator __position)
1235 { return _M_h.erase(__position); }
1236
1237 // LWG 2059.
1238 iterator
00541349
JW
1239 erase(iterator __position)
1240 { return _M_h.erase(__position); }
637fd8b3
FD
1241 //@}
1242
1243
1244 /**
1245 * @brief Erases elements according to the provided key.
1246 * @param __x Key of element to be erased.
1247 * @return The number of elements erased.
1248 *
1249 * This function erases all the elements located by the given key from
1250 * an %unordered_multiset.
1251 *
1252 * Note that this function only erases the element, and that if the
1253 * element is itself a pointer, the pointed-to memory is not touched in
1254 * any way. Managing the pointer is the user's responsibility.
1255 */
1256 size_type
1257 erase(const key_type& __x)
1258 { return _M_h.erase(__x); }
1259
1260 /**
1261 * @brief Erases a [__first,__last) range of elements from an
1262 * %unordered_multiset.
1263 * @param __first Iterator pointing to the start of the range to be
1264 * erased.
1265 * @param __last Iterator pointing to the end of the range to
1266 * be erased.
1267 * @return The iterator @a __last.
1268 *
1269 * This function erases a sequence of elements from an
1270 * %unordered_multiset.
1271 *
1272 * Note that this function only erases the element, and that if
1273 * the element is itself a pointer, the pointed-to memory is not touched
1274 * in any way. Managing the pointer is the user's responsibility.
1275 */
1276 iterator
1277 erase(const_iterator __first, const_iterator __last)
1278 { return _M_h.erase(__first, __last); }
1279
1280 /**
1281 * Erases all elements in an %unordered_multiset.
1282 *
1283 * Note that this function only erases the elements, and that if the
1284 * elements themselves are pointers, the pointed-to memory is not touched
1285 * in any way. Managing the pointer is the user's responsibility.
1286 */
1287 void
1288 clear() noexcept
1289 { _M_h.clear(); }
1290
1291 /**
1292 * @brief Swaps data with another %unordered_multiset.
1293 * @param __x An %unordered_multiset of the same element and allocator
1294 * types.
1295 *
1296 * This exchanges the elements between two sets in constant time.
1297 * Note that the global std::swap() function is specialized such that
1298 * std::swap(s1,s2) will feed to this function.
1299 */
1300 void
1301 swap(unordered_multiset& __x)
0462b6aa 1302 noexcept( noexcept(_M_h.swap(__x._M_h)) )
637fd8b3
FD
1303 { _M_h.swap(__x._M_h); }
1304
2dbe56bd
JW
1305#if __cplusplus > 201402L
1306 template<typename, typename, typename>
1307 friend class _Hash_merge_helper;
1308
1309 template<typename _H2, typename _P2>
1310 void
1311 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source)
1312 {
1313 using _Merge_helper
1314 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1315 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1316 }
1317
1318 template<typename _H2, typename _P2>
1319 void
1320 merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source)
1321 { merge(__source); }
1322
1323 template<typename _H2, typename _P2>
1324 void
1325 merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source)
1326 {
1327 using _Merge_helper
1328 = _Hash_merge_helper<unordered_multiset, _H2, _P2>;
1329 _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source));
1330 }
1331
1332 template<typename _H2, typename _P2>
1333 void
1334 merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source)
1335 { merge(__source); }
1336#endif // C++17
1337
637fd8b3
FD
1338 // observers.
1339
1340 /// Returns the hash functor object with which the %unordered_multiset
1341 /// was constructed.
1342 hasher
1343 hash_function() const
1344 { return _M_h.hash_function(); }
1345
1346 /// Returns the key comparison object with which the %unordered_multiset
1347 /// was constructed.
1348 key_equal
1349 key_eq() const
1350 { return _M_h.key_eq(); }
1351
1352 // lookup.
1353
1354 //@{
1355 /**
1356 * @brief Tries to locate an element in an %unordered_multiset.
1357 * @param __x Element to be located.
1358 * @return Iterator pointing to sought-after element, or end() if not
1359 * found.
1360 *
1361 * This function takes a key and tries to locate the element with which
1362 * the key matches. If successful the function returns an iterator
1363 * pointing to the sought after element. If unsuccessful it returns the
1364 * past-the-end ( @c end() ) iterator.
1365 */
1366 iterator
1367 find(const key_type& __x)
1368 { return _M_h.find(__x); }
1369
1370 const_iterator
1371 find(const key_type& __x) const
1372 { return _M_h.find(__x); }
1373 //@}
1374
1375 /**
1376 * @brief Finds the number of elements.
1377 * @param __x Element to located.
1378 * @return Number of elements with specified key.
1379 */
1380 size_type
1381 count(const key_type& __x) const
1382 { return _M_h.count(__x); }
1383
1384 //@{
1385 /**
1386 * @brief Finds a subsequence matching given key.
1387 * @param __x Key to be located.
1388 * @return Pair of iterators that possibly points to the subsequence
1389 * matching given key.
1390 */
1391 std::pair<iterator, iterator>
1392 equal_range(const key_type& __x)
1393 { return _M_h.equal_range(__x); }
1394
1395 std::pair<const_iterator, const_iterator>
1396 equal_range(const key_type& __x) const
1397 { return _M_h.equal_range(__x); }
1398 //@}
1399
1400 // bucket interface.
1401
1402 /// Returns the number of buckets of the %unordered_multiset.
1403 size_type
1404 bucket_count() const noexcept
1405 { return _M_h.bucket_count(); }
1406
1407 /// Returns the maximum number of buckets of the %unordered_multiset.
1408 size_type
1409 max_bucket_count() const noexcept
1410 { return _M_h.max_bucket_count(); }
1411
1412 /*
1413 * @brief Returns the number of elements in a given bucket.
1414 * @param __n A bucket index.
1415 * @return The number of elements in the bucket.
1416 */
1417 size_type
1418 bucket_size(size_type __n) const
1419 { return _M_h.bucket_size(__n); }
1420
1421 /*
1422 * @brief Returns the bucket index of a given element.
1423 * @param __key A key instance.
1424 * @return The key bucket index.
1425 */
1426 size_type
1427 bucket(const key_type& __key) const
1428 { return _M_h.bucket(__key); }
1429
1430 //@{
1431 /**
1432 * @brief Returns a read-only (constant) iterator pointing to the first
1433 * bucket element.
1434 * @param __n The bucket index.
1435 * @return A read-only local iterator.
1436 */
1437 local_iterator
1438 begin(size_type __n)
1439 { return _M_h.begin(__n); }
1440
1441 const_local_iterator
1442 begin(size_type __n) const
1443 { return _M_h.begin(__n); }
1444
1445 const_local_iterator
1446 cbegin(size_type __n) const
1447 { return _M_h.cbegin(__n); }
1448 //@}
1449
1450 //@{
1451 /**
1452 * @brief Returns a read-only (constant) iterator pointing to one past
1453 * the last bucket elements.
1454 * @param __n The bucket index.
1455 * @return A read-only local iterator.
1456 */
1457 local_iterator
1458 end(size_type __n)
1459 { return _M_h.end(__n); }
1460
1461 const_local_iterator
1462 end(size_type __n) const
1463 { return _M_h.end(__n); }
1464
1465 const_local_iterator
1466 cend(size_type __n) const
1467 { return _M_h.cend(__n); }
1468 //@}
1469
1470 // hash policy.
1471
1472 /// Returns the average number of elements per bucket.
1473 float
1474 load_factor() const noexcept
1475 { return _M_h.load_factor(); }
1476
1477 /// Returns a positive number that the %unordered_multiset tries to keep the
1478 /// load factor less than or equal to.
1479 float
1480 max_load_factor() const noexcept
1481 { return _M_h.max_load_factor(); }
1482
1483 /**
1484 * @brief Change the %unordered_multiset maximum load factor.
1485 * @param __z The new maximum load factor.
1486 */
1487 void
1488 max_load_factor(float __z)
1489 { _M_h.max_load_factor(__z); }
1490
1491 /**
1492 * @brief May rehash the %unordered_multiset.
1493 * @param __n The new number of buckets.
1494 *
1495 * Rehash will occur only if the new number of buckets respect the
1496 * %unordered_multiset maximum load factor.
1497 */
1498 void
1499 rehash(size_type __n)
1500 { _M_h.rehash(__n); }
1501
1502 /**
1503 * @brief Prepare the %unordered_multiset for a specified number of
1504 * elements.
1505 * @param __n Number of elements required.
1506 *
1507 * Same as rehash(ceil(n / max_load_factor())).
1508 */
1509 void
1510 reserve(size_type __n)
1511 { _M_h.reserve(__n); }
1512
1513 template<typename _Value1, typename _Hash1, typename _Pred1,
1514 typename _Alloc1>
1515 friend bool
1516 operator==(const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&,
1517 const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&);
3b2524b1
PC
1518 };
1519
1520 template<class _Value, class _Hash, class _Pred, class _Alloc>
1521 inline void
1522 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1523 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
a2b5fdcb 1524 noexcept(noexcept(__x.swap(__y)))
3b2524b1
PC
1525 { __x.swap(__y); }
1526
1527 template<class _Value, class _Hash, class _Pred, class _Alloc>
1528 inline void
1529 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1530 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
a2b5fdcb 1531 noexcept(noexcept(__x.swap(__y)))
3b2524b1
PC
1532 { __x.swap(__y); }
1533
5dc22714
PC
1534 template<class _Value, class _Hash, class _Pred, class _Alloc>
1535 inline bool
1536 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1537 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
637fd8b3 1538 { return __x._M_h._M_equal(__y._M_h); }
5dc22714
PC
1539
1540 template<class _Value, class _Hash, class _Pred, class _Alloc>
1541 inline bool
1542 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
1543 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
1544 { return !(__x == __y); }
1545
1546 template<class _Value, class _Hash, class _Pred, class _Alloc>
1547 inline bool
1548 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1549 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
637fd8b3 1550 { return __x._M_h._M_equal(__y._M_h); }
5dc22714
PC
1551
1552 template<class _Value, class _Hash, class _Pred, class _Alloc>
1553 inline bool
1554 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1555 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1556 { return !(__x == __y); }
1557
12ffa228 1558_GLIBCXX_END_NAMESPACE_CONTAINER
2dbe56bd
JW
1559
1560#if __cplusplus > 201402L
2dbe56bd
JW
1561 // Allow std::unordered_set access to internals of compatible sets.
1562 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
1563 typename _Hash2, typename _Eq2>
1564 struct _Hash_merge_helper<
1565 _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2>
1566 {
1567 private:
1568 template<typename... _Tp>
1569 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
1570 template<typename... _Tp>
1571 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
1572
1573 friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>;
1574
1575 static auto&
1576 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
1577 { return __set._M_h; }
1578
1579 static auto&
1580 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
1581 { return __set._M_h; }
1582 };
1583
1584 // Allow std::unordered_multiset access to internals of compatible sets.
1585 template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc,
1586 typename _Hash2, typename _Eq2>
1587 struct _Hash_merge_helper<
1588 _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>,
1589 _Hash2, _Eq2>
1590 {
1591 private:
1592 template<typename... _Tp>
1593 using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>;
1594 template<typename... _Tp>
1595 using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>;
1596
1597 friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>;
1598
1599 static auto&
1600 _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set)
1601 { return __set._M_h; }
1602
1603 static auto&
1604 _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set)
1605 { return __set._M_h; }
1606 };
2dbe56bd
JW
1607#endif // C++17
1608
4a15d842 1609_GLIBCXX_END_NAMESPACE_VERSION
12ffa228 1610} // namespace std
3b2524b1
PC
1611
1612#endif /* _UNORDERED_SET_H */