* testsuite/26_numerics/headers/cmath/hypot.cc: XFAIL on AIX.
[official-gcc.git] / libstdc++-v3 / include / debug / unordered_set
blobf8587c06bfc7bcb5f132327cc332c515aac77827
1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
3 // Copyright (C) 2003-2016 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
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 debug/unordered_set
26  *  This file is a GNU debug extension to the Standard C++ Library.
27  */
29 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
30 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
36 #else
37 # include <unordered_set>
39 #include <debug/safe_unordered_container.h>
40 #include <debug/safe_container.h>
41 #include <debug/safe_iterator.h>
42 #include <debug/safe_local_iterator.h>
44 namespace std _GLIBCXX_VISIBILITY(default)
46 namespace __debug
48   /// Class std::unordered_set with safety/checking/debug instrumentation.
49   template<typename _Value,
50            typename _Hash = std::hash<_Value>,
51            typename _Pred = std::equal_to<_Value>,
52            typename _Alloc = std::allocator<_Value> >
53     class unordered_set
54     : public __gnu_debug::_Safe_container<
55         unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
56         __gnu_debug::_Safe_unordered_container>,
57       public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
58     {
59       typedef _GLIBCXX_STD_C::unordered_set<
60         _Value, _Hash, _Pred, _Alloc>                                   _Base;
61       typedef __gnu_debug::_Safe_container<
62         unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container>  _Safe;
64       typedef typename _Base::const_iterator       _Base_const_iterator;
65       typedef typename _Base::iterator             _Base_iterator;
66       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
67       typedef typename _Base::local_iterator       _Base_local_iterator;
69     public:
70       typedef typename _Base::size_type                 size_type;
71       typedef typename _Base::hasher                    hasher;
72       typedef typename _Base::key_equal                 key_equal;
73       typedef typename _Base::allocator_type            allocator_type;
75       typedef typename _Base::key_type                  key_type;
76       typedef typename _Base::value_type                value_type;
78       typedef __gnu_debug::_Safe_iterator<
79         _Base_iterator, unordered_set>                  iterator;
80       typedef __gnu_debug::_Safe_iterator<
81         _Base_const_iterator, unordered_set>            const_iterator;
82       typedef __gnu_debug::_Safe_local_iterator<
83         _Base_local_iterator, unordered_set>            local_iterator;
84       typedef __gnu_debug::_Safe_local_iterator<
85         _Base_const_local_iterator, unordered_set>      const_local_iterator;
87       unordered_set() = default;
89       explicit
90       unordered_set(size_type __n,
91                     const hasher& __hf = hasher(),
92                     const key_equal& __eql = key_equal(),
93                     const allocator_type& __a = allocator_type())
94       : _Base(__n, __hf, __eql, __a) { }
96       template<typename _InputIterator>
97         unordered_set(_InputIterator __first, _InputIterator __last,
98                       size_type __n = 0,
99                       const hasher& __hf = hasher(),
100                       const key_equal& __eql = key_equal(),
101                       const allocator_type& __a = allocator_type())
102         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
103                                                                      __last)),
104                 __gnu_debug::__base(__last), __n,
105                 __hf, __eql, __a) { }
107       unordered_set(const unordered_set&) = default;
109       unordered_set(const _Base& __x)
110       : _Base(__x) { }
112       unordered_set(unordered_set&&) = default;
114       explicit
115       unordered_set(const allocator_type& __a)
116       : _Base(__a) { }
118       unordered_set(const unordered_set& __uset,
119                     const allocator_type& __a)
120       : _Base(__uset, __a) { }
122       unordered_set(unordered_set&& __uset,
123                     const allocator_type& __a)
124       : _Safe(std::move(__uset._M_safe()), __a),
125         _Base(std::move(__uset._M_base()), __a) { }
127       unordered_set(initializer_list<value_type> __l,
128                     size_type __n = 0,
129                     const hasher& __hf = hasher(),
130                     const key_equal& __eql = key_equal(),
131                     const allocator_type& __a = allocator_type())
132       : _Base(__l, __n, __hf, __eql, __a) { }
134       unordered_set(size_type __n, const allocator_type& __a)
135         : unordered_set(__n, hasher(), key_equal(), __a)
136       { }
138       unordered_set(size_type __n, const hasher& __hf,
139                     const allocator_type& __a)
140         : unordered_set(__n, __hf, key_equal(), __a)
141       { }
143       template<typename _InputIterator>
144         unordered_set(_InputIterator __first, _InputIterator __last,
145                       size_type __n,
146                       const allocator_type& __a)
147           : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
148         { }
150       template<typename _InputIterator>
151         unordered_set(_InputIterator __first, _InputIterator __last,
152                       size_type __n, const hasher& __hf,
153                       const allocator_type& __a)
154           : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
155         { }
157       unordered_set(initializer_list<value_type> __l,
158                     size_type __n,
159                     const allocator_type& __a)
160         : unordered_set(__l, __n, hasher(), key_equal(), __a)
161       { }
163       unordered_set(initializer_list<value_type> __l,
164                     size_type __n, const hasher& __hf,
165                     const allocator_type& __a)
166         : unordered_set(__l, __n, __hf, key_equal(), __a)
167       { }
169       ~unordered_set() = default;
171       unordered_set&
172       operator=(const unordered_set&) = default;
174       unordered_set&
175       operator=(unordered_set&&) = default;
177       unordered_set&
178       operator=(initializer_list<value_type> __l)
179       {
180         _M_base() = __l;
181         this->_M_invalidate_all();
182         return *this;
183       }
185       void
186       swap(unordered_set& __x)
187         noexcept( noexcept(declval<_Base&>().swap(__x)) )
188       {
189         _Safe::_M_swap(__x);
190         _Base::swap(__x);
191       }
193       void
194       clear() noexcept
195       {
196         _Base::clear();
197         this->_M_invalidate_all();
198       }
200       iterator
201       begin() noexcept
202       { return iterator(_Base::begin(), this); }
204       const_iterator
205       begin() const noexcept
206       { return const_iterator(_Base::begin(), this); }
208       iterator
209       end() noexcept
210       { return iterator(_Base::end(), this); }
212       const_iterator
213       end() const noexcept
214       { return const_iterator(_Base::end(), this); }
216       const_iterator
217       cbegin() const noexcept
218       { return const_iterator(_Base::begin(), this); }
220       const_iterator
221       cend() const noexcept
222       { return const_iterator(_Base::end(), this); }
224       // local versions
225       local_iterator
226       begin(size_type __b)
227       {
228         __glibcxx_check_bucket_index(__b);
229         return local_iterator(_Base::begin(__b), this);
230       }
232       local_iterator
233       end(size_type __b)
234       {
235         __glibcxx_check_bucket_index(__b);
236         return local_iterator(_Base::end(__b), this);
237       }
239       const_local_iterator
240       begin(size_type __b) const
241       {
242         __glibcxx_check_bucket_index(__b);
243         return const_local_iterator(_Base::begin(__b), this);
244       }
246       const_local_iterator
247       end(size_type __b) const
248       {
249         __glibcxx_check_bucket_index(__b);
250         return const_local_iterator(_Base::end(__b), this);
251       }
253       const_local_iterator
254       cbegin(size_type __b) const
255       {
256         __glibcxx_check_bucket_index(__b);
257         return const_local_iterator(_Base::cbegin(__b), this);
258       }
260       const_local_iterator
261       cend(size_type __b) const
262       {
263         __glibcxx_check_bucket_index(__b);
264         return const_local_iterator(_Base::cend(__b), this);
265       }
267       size_type
268       bucket_size(size_type __b) const
269       {
270         __glibcxx_check_bucket_index(__b);
271         return _Base::bucket_size(__b);
272       }
274       float
275       max_load_factor() const noexcept
276       { return _Base::max_load_factor(); }
278       void
279       max_load_factor(float __f)
280       {
281         __glibcxx_check_max_load_factor(__f);
282         _Base::max_load_factor(__f);
283       }
285       template<typename... _Args>
286         std::pair<iterator, bool>
287         emplace(_Args&&... __args)
288         {
289           size_type __bucket_count = this->bucket_count();
290           std::pair<_Base_iterator, bool> __res
291             = _Base::emplace(std::forward<_Args>(__args)...);
292           _M_check_rehashed(__bucket_count);
293           return std::make_pair(iterator(__res.first, this), __res.second);
294         }
296       template<typename... _Args>
297         iterator
298         emplace_hint(const_iterator __hint, _Args&&... __args)
299         {
300           __glibcxx_check_insert(__hint);
301           size_type __bucket_count = this->bucket_count();
302           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
303                                         std::forward<_Args>(__args)...);
304           _M_check_rehashed(__bucket_count);
305           return iterator(__it, this);
306         }
308       std::pair<iterator, bool>
309       insert(const value_type& __obj)
310       {
311         size_type __bucket_count = this->bucket_count();
312         std::pair<_Base_iterator, bool> __res
313           = _Base::insert(__obj);
314         _M_check_rehashed(__bucket_count);
315         return std::make_pair(iterator(__res.first, this), __res.second);
316       }
318       iterator
319       insert(const_iterator __hint, const value_type& __obj)
320       {
321         __glibcxx_check_insert(__hint);
322         size_type __bucket_count = this->bucket_count();
323         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
324         _M_check_rehashed(__bucket_count);
325         return iterator(__it, this);
326       }
328       std::pair<iterator, bool>
329       insert(value_type&& __obj)
330       {
331         size_type __bucket_count = this->bucket_count();
332         std::pair<_Base_iterator, bool> __res
333           = _Base::insert(std::move(__obj));
334         _M_check_rehashed(__bucket_count);
335         return std::make_pair(iterator(__res.first, this), __res.second);
336       }
338       iterator
339       insert(const_iterator __hint, value_type&& __obj)
340       {
341         __glibcxx_check_insert(__hint);
342         size_type __bucket_count = this->bucket_count();
343         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
344         _M_check_rehashed(__bucket_count);
345         return iterator(__it, this);
346       }
348       void
349       insert(std::initializer_list<value_type> __l)
350       {
351         size_type __bucket_count = this->bucket_count();
352         _Base::insert(__l);
353         _M_check_rehashed(__bucket_count);
354       }
356       template<typename _InputIterator>
357         void
358         insert(_InputIterator __first, _InputIterator __last)
359         {
360           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
361           __glibcxx_check_valid_range2(__first, __last, __dist);
362           size_type __bucket_count = this->bucket_count();
364           if (__dist.second >= __gnu_debug::__dp_sign)
365             _Base::insert(__gnu_debug::__unsafe(__first),
366                           __gnu_debug::__unsafe(__last));
367           else
368             _Base::insert(__first, __last);
370           _M_check_rehashed(__bucket_count);
371         }
373 #if __cplusplus > 201402L
374       using node_type = typename _Base::node_type;
376       struct insert_return_type
377       {
378         bool inserted;
379         iterator position;
380         node_type node;
381       };
383       node_type
384       extract(const_iterator __position)
385       {
386         __glibcxx_check_erase(__position);
387         _Base_const_iterator __victim = __position.base();
388         this->_M_invalidate_if(
389             [__victim](_Base_const_iterator __it) { return __it == __victim; }
390             );
391         this->_M_invalidate_local_if(
392             [__victim](_Base_const_local_iterator __it) {
393                 return __it._M_curr() == __victim._M_cur;
394             });
395         return _Base::extract(__position.base());
396       }
398       node_type
399       extract(const key_type& __key)
400       {
401         const auto __position = find(__key);
402         if (__position != end())
403           return extract(__position);
404         return {};
405       }
407       insert_return_type
408       insert(node_type&& __nh)
409       {
410         auto __ret = _Base::insert(std::move(__nh));
411         iterator __pos = iterator(__ret.position, this);
412         return { __ret.inserted, __pos, std::move(__ret.node) };
413       }
415       iterator
416       insert(const_iterator __hint, node_type&& __nh)
417       {
418         __glibcxx_check_insert(__hint);
419         return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
420       }
422       using _Base::merge;
423 #endif // C++17
425       iterator
426       find(const key_type& __key)
427       { return iterator(_Base::find(__key), this); }
429       const_iterator
430       find(const key_type& __key) const
431       { return const_iterator(_Base::find(__key), this); }
433       std::pair<iterator, iterator>
434       equal_range(const key_type& __key)
435       {
436         std::pair<_Base_iterator, _Base_iterator> __res
437           = _Base::equal_range(__key);
438         return std::make_pair(iterator(__res.first, this),
439                               iterator(__res.second, this));
440       }
442       std::pair<const_iterator, const_iterator>
443       equal_range(const key_type& __key) const
444       {
445         std::pair<_Base_const_iterator, _Base_const_iterator>
446           __res = _Base::equal_range(__key);
447         return std::make_pair(const_iterator(__res.first, this),
448                               const_iterator(__res.second, this));
449       }
451       size_type
452       erase(const key_type& __key)
453       {
454         size_type __ret(0);
455         _Base_iterator __victim(_Base::find(__key));
456         if (__victim != _Base::end())
457           {
458             this->_M_invalidate_if(
459                             [__victim](_Base_const_iterator __it)
460                             { return __it == __victim; });
461             this->_M_invalidate_local_if(
462                             [__victim](_Base_const_local_iterator __it)
463                             { return __it._M_curr() == __victim._M_cur; });
464             size_type __bucket_count = this->bucket_count();
465             _Base::erase(__victim);
466             _M_check_rehashed(__bucket_count);
467             __ret = 1;
468           }
469         return __ret;
470       }
472       iterator
473       erase(const_iterator __it)
474       {
475         __glibcxx_check_erase(__it);
476         _Base_const_iterator __victim = __it.base();
477         this->_M_invalidate_if(
478                         [__victim](_Base_const_iterator __it)
479                         { return __it == __victim; });
480         this->_M_invalidate_local_if(
481                         [__victim](_Base_const_local_iterator __it)
482                         { return __it._M_curr() == __victim._M_cur; });
483         size_type __bucket_count = this->bucket_count();
484         _Base_iterator __next = _Base::erase(__it.base());
485         _M_check_rehashed(__bucket_count);
486         return iterator(__next, this);
487       }
489       iterator
490       erase(iterator __it)
491       { return erase(const_iterator(__it)); }
493       iterator
494       erase(const_iterator __first, const_iterator __last)
495       {
496         __glibcxx_check_erase_range(__first, __last);
497         for (_Base_const_iterator __tmp = __first.base();
498              __tmp != __last.base(); ++__tmp)
499           {
500             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
501                                   _M_message(__gnu_debug::__msg_valid_range)
502                                   ._M_iterator(__first, "first")
503                                   ._M_iterator(__last, "last"));
504             this->_M_invalidate_if(
505                             [__tmp](_Base_const_iterator __it)
506                             { return __it == __tmp; });
507             this->_M_invalidate_local_if(
508                             [__tmp](_Base_const_local_iterator __it)
509                             { return __it._M_curr() == __tmp._M_cur; });
510           }
511         size_type __bucket_count = this->bucket_count();
512         _Base_iterator __next = _Base::erase(__first.base(),
513                                              __last.base());
514         _M_check_rehashed(__bucket_count);
515         return iterator(__next, this);
516       }
518       _Base&
519       _M_base() noexcept { return *this; }
521       const _Base&
522       _M_base() const noexcept { return *this; }
524     private:
525       void
526       _M_check_rehashed(size_type __prev_count)
527       {
528         if (__prev_count != this->bucket_count())
529           this->_M_invalidate_locals();
530       }
531     };
533   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
534     inline void
535     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
536          unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
537     noexcept(noexcept(__x.swap(__y)))
538     { __x.swap(__y); }
540   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
541     inline bool
542     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
543                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
544     { return __x._M_base() == __y._M_base(); }
546   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
547     inline bool
548     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
549                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
550     { return !(__x == __y); }
553   /// Class std::unordered_multiset with safety/checking/debug instrumentation.
554   template<typename _Value,
555            typename _Hash = std::hash<_Value>,
556            typename _Pred = std::equal_to<_Value>,
557            typename _Alloc = std::allocator<_Value> >
558     class unordered_multiset
559     : public __gnu_debug::_Safe_container<
560         unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
561         __gnu_debug::_Safe_unordered_container>,
562       public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
563     {
564       typedef _GLIBCXX_STD_C::unordered_multiset<
565         _Value, _Hash, _Pred, _Alloc>                           _Base;
566       typedef __gnu_debug::_Safe_container<unordered_multiset,
567         _Alloc, __gnu_debug::_Safe_unordered_container>         _Safe;
568       typedef typename _Base::const_iterator    _Base_const_iterator;
569       typedef typename _Base::iterator          _Base_iterator;
570       typedef typename _Base::const_local_iterator
571                                                 _Base_const_local_iterator;
572       typedef typename _Base::local_iterator    _Base_local_iterator;
574     public:
575       typedef typename _Base::size_type                 size_type;
576       typedef typename _Base::hasher                    hasher;
577       typedef typename _Base::key_equal                 key_equal;
578       typedef typename _Base::allocator_type            allocator_type;
580       typedef typename _Base::key_type                  key_type;
581       typedef typename _Base::value_type                value_type;
583       typedef __gnu_debug::_Safe_iterator<
584         _Base_iterator, unordered_multiset>             iterator;
585       typedef __gnu_debug::_Safe_iterator<
586         _Base_const_iterator, unordered_multiset>       const_iterator;
587       typedef __gnu_debug::_Safe_local_iterator<
588         _Base_local_iterator, unordered_multiset>       local_iterator;
589       typedef __gnu_debug::_Safe_local_iterator<
590         _Base_const_local_iterator, unordered_multiset> const_local_iterator;
592       unordered_multiset() = default;
594       explicit
595       unordered_multiset(size_type __n,
596                          const hasher& __hf = hasher(),
597                          const key_equal& __eql = key_equal(),
598                          const allocator_type& __a = allocator_type())
599       : _Base(__n, __hf, __eql, __a) { }
601       template<typename _InputIterator>
602         unordered_multiset(_InputIterator __first, _InputIterator __last,
603                            size_type __n = 0,
604                            const hasher& __hf = hasher(),
605                            const key_equal& __eql = key_equal(),
606                            const allocator_type& __a = allocator_type())
607         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
608                                                                      __last)),
609                 __gnu_debug::__base(__last), __n,
610                 __hf, __eql, __a) { }
612       unordered_multiset(const unordered_multiset&) = default;
614       unordered_multiset(const _Base& __x)
615       : _Base(__x) { }
617       unordered_multiset(unordered_multiset&&) = default;
619       explicit
620       unordered_multiset(const allocator_type& __a)
621       : _Base(__a) { }
623       unordered_multiset(const unordered_multiset& __uset,
624                          const allocator_type& __a)
625       : _Base(__uset, __a) { }
627       unordered_multiset(unordered_multiset&& __uset,
628                          const allocator_type& __a)
629       : _Safe(std::move(__uset._M_safe()), __a),
630         _Base(std::move(__uset._M_base()), __a) { }
632       unordered_multiset(initializer_list<value_type> __l,
633                          size_type __n = 0,
634                          const hasher& __hf = hasher(),
635                          const key_equal& __eql = key_equal(),
636                          const allocator_type& __a = allocator_type())
637       : _Base(__l, __n, __hf, __eql, __a) { }
639       unordered_multiset(size_type __n, const allocator_type& __a)
640         : unordered_multiset(__n, hasher(), key_equal(), __a)
641       { }
643       unordered_multiset(size_type __n, const hasher& __hf,
644                          const allocator_type& __a)
645         : unordered_multiset(__n, __hf, key_equal(), __a)
646       { }
648       template<typename _InputIterator>
649         unordered_multiset(_InputIterator __first, _InputIterator __last,
650                            size_type __n,
651                            const allocator_type& __a)
652           : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
653         { }
655       template<typename _InputIterator>
656         unordered_multiset(_InputIterator __first, _InputIterator __last,
657                            size_type __n, const hasher& __hf,
658                            const allocator_type& __a)
659           : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
660         { }
662       unordered_multiset(initializer_list<value_type> __l,
663                          size_type __n,
664                          const allocator_type& __a)
665         : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
666       { }
668       unordered_multiset(initializer_list<value_type> __l,
669                          size_type __n, const hasher& __hf,
670                          const allocator_type& __a)
671         : unordered_multiset(__l, __n, __hf, key_equal(), __a)
672       { }
674       ~unordered_multiset() = default;
676       unordered_multiset&
677       operator=(const unordered_multiset&) = default;
679       unordered_multiset&
680       operator=(unordered_multiset&&) = default;
682       unordered_multiset&
683       operator=(initializer_list<value_type> __l)
684       {
685         this->_M_base() = __l;
686         this->_M_invalidate_all();
687         return *this;
688       }
690       void
691       swap(unordered_multiset& __x)
692         noexcept( noexcept(declval<_Base&>().swap(__x)) )
693       {
694         _Safe::_M_swap(__x);
695         _Base::swap(__x);
696       }
698       void
699       clear() noexcept
700       {
701         _Base::clear();
702         this->_M_invalidate_all();
703       }
705       iterator
706       begin() noexcept
707       { return iterator(_Base::begin(), this); }
709       const_iterator
710       begin() const noexcept
711       { return const_iterator(_Base::begin(), this); }
713       iterator
714       end() noexcept
715       { return iterator(_Base::end(), this); }
717       const_iterator
718       end() const noexcept
719       { return const_iterator(_Base::end(), this); }
721       const_iterator
722       cbegin() const noexcept
723       { return const_iterator(_Base::begin(), this); }
725       const_iterator
726       cend() const noexcept
727       { return const_iterator(_Base::end(), this); }
729       // local versions
730       local_iterator
731       begin(size_type __b)
732       {
733         __glibcxx_check_bucket_index(__b);
734         return local_iterator(_Base::begin(__b), this);
735       }
737       local_iterator
738       end(size_type __b)
739       {
740         __glibcxx_check_bucket_index(__b);
741         return local_iterator(_Base::end(__b), this);
742       }
744       const_local_iterator
745       begin(size_type __b) const
746       {
747         __glibcxx_check_bucket_index(__b);
748         return const_local_iterator(_Base::begin(__b), this);
749       }
751       const_local_iterator
752       end(size_type __b) const
753       {
754         __glibcxx_check_bucket_index(__b);
755         return const_local_iterator(_Base::end(__b), this);
756       }
758       const_local_iterator
759       cbegin(size_type __b) const
760       {
761         __glibcxx_check_bucket_index(__b);
762         return const_local_iterator(_Base::cbegin(__b), this);
763       }
765       const_local_iterator
766       cend(size_type __b) const
767       {
768         __glibcxx_check_bucket_index(__b);
769         return const_local_iterator(_Base::cend(__b), this);
770       }
772       size_type
773       bucket_size(size_type __b) const
774       {
775         __glibcxx_check_bucket_index(__b);
776         return _Base::bucket_size(__b);
777       }
779       float
780       max_load_factor() const noexcept
781       { return _Base::max_load_factor(); }
783       void
784       max_load_factor(float __f)
785       {
786         __glibcxx_check_max_load_factor(__f);
787         _Base::max_load_factor(__f);
788       }
790       template<typename... _Args>
791         iterator
792         emplace(_Args&&... __args)
793         {
794           size_type __bucket_count = this->bucket_count();
795           _Base_iterator __it
796             = _Base::emplace(std::forward<_Args>(__args)...);
797           _M_check_rehashed(__bucket_count);
798           return iterator(__it, this);
799         }
801       template<typename... _Args>
802         iterator
803         emplace_hint(const_iterator __hint, _Args&&... __args)
804         {
805           __glibcxx_check_insert(__hint);
806           size_type __bucket_count = this->bucket_count();
807           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
808                                         std::forward<_Args>(__args)...);
809           _M_check_rehashed(__bucket_count);
810           return iterator(__it, this);
811         }
813       iterator
814       insert(const value_type& __obj)
815       {
816         size_type __bucket_count = this->bucket_count();
817         _Base_iterator __it = _Base::insert(__obj);
818         _M_check_rehashed(__bucket_count);
819         return iterator(__it, this);
820       }
822       iterator
823       insert(const_iterator __hint, const value_type& __obj)
824       {
825         __glibcxx_check_insert(__hint);
826         size_type __bucket_count = this->bucket_count();
827         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
828         _M_check_rehashed(__bucket_count);
829         return iterator(__it, this);
830       }
832       iterator
833       insert(value_type&& __obj)
834       {
835         size_type __bucket_count = this->bucket_count();
836         _Base_iterator __it = _Base::insert(std::move(__obj));
837         _M_check_rehashed(__bucket_count);
838         return iterator(__it, this);
839       }
841       iterator
842       insert(const_iterator __hint, value_type&& __obj)
843       {
844         __glibcxx_check_insert(__hint);
845         size_type __bucket_count = this->bucket_count();
846         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
847         _M_check_rehashed(__bucket_count);
848         return iterator(__it, this);
849       }
851       void
852       insert(std::initializer_list<value_type> __l)
853       {
854         size_type __bucket_count = this->bucket_count();
855         _Base::insert(__l);
856         _M_check_rehashed(__bucket_count);
857       }
859       template<typename _InputIterator>
860         void
861         insert(_InputIterator __first, _InputIterator __last)
862         {
863           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
864           __glibcxx_check_valid_range2(__first, __last, __dist);
865           size_type __bucket_count = this->bucket_count();
867           if (__dist.second >= __gnu_debug::__dp_sign)
868             _Base::insert(__gnu_debug::__unsafe(__first),
869                           __gnu_debug::__unsafe(__last));
870           else
871             _Base::insert(__first, __last);
873           _M_check_rehashed(__bucket_count);
874         }
876 #if __cplusplus > 201402L
877       using node_type = typename _Base::node_type;
879       node_type
880       extract(const_iterator __position)
881       {
882         __glibcxx_check_erase(__position);
883         _Base_const_iterator __victim = __position.base();
884         this->_M_invalidate_if(
885             [__victim](_Base_const_iterator __it) { return __it == __victim; }
886             );
887         this->_M_invalidate_local_if(
888             [__victim](_Base_const_local_iterator __it) {
889                 return __it._M_curr() == __victim._M_cur;
890             });
891         return _Base::extract(__position.base());
892       }
894       node_type
895       extract(const key_type& __key)
896       {
897         const auto __position = find(__key);
898         if (__position != end())
899           return extract(__position);
900         return {};
901       }
903       iterator
904       insert(node_type&& __nh)
905       { return iterator(_Base::insert(std::move(__nh)), this); }
907       iterator
908       insert(const_iterator __hint, node_type&& __nh)
909       {
910         __glibcxx_check_insert(__hint);
911         return iterator(_Base::insert(__hint.base(), std::move(__nh)), this);
912       }
914       using _Base::merge;
915 #endif // C++17
917       iterator
918       find(const key_type& __key)
919       { return iterator(_Base::find(__key), this); }
921       const_iterator
922       find(const key_type& __key) const
923       { return const_iterator(_Base::find(__key), this); }
925       std::pair<iterator, iterator>
926       equal_range(const key_type& __key)
927       {
928         std::pair<_Base_iterator, _Base_iterator> __res
929           = _Base::equal_range(__key);
930         return std::make_pair(iterator(__res.first, this),
931                               iterator(__res.second, this));
932       }
934       std::pair<const_iterator, const_iterator>
935       equal_range(const key_type& __key) const
936       {
937         std::pair<_Base_const_iterator, _Base_const_iterator>
938           __res = _Base::equal_range(__key);
939         return std::make_pair(const_iterator(__res.first, this),
940                               const_iterator(__res.second, this));
941       }
943       size_type
944       erase(const key_type& __key)
945       {
946         size_type __ret(0);
947         std::pair<_Base_iterator, _Base_iterator> __pair =
948           _Base::equal_range(__key);
949         for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
950           {
951             this->_M_invalidate_if([__victim](_Base_const_iterator __it)
952                             { return __it == __victim; });
953             this->_M_invalidate_local_if(
954                             [__victim](_Base_const_local_iterator __it)
955                             { return __it._M_curr() == __victim._M_cur; });
956             _Base::erase(__victim++);
957             ++__ret;
958           }
959         return __ret;
960       }
962       iterator
963       erase(const_iterator __it)
964       {
965         __glibcxx_check_erase(__it);
966         _Base_const_iterator __victim = __it.base();
967         this->_M_invalidate_if([__victim](_Base_const_iterator __it)
968                         { return __it == __victim; });
969         this->_M_invalidate_local_if(
970                         [__victim](_Base_const_local_iterator __it)
971                         { return __it._M_curr() == __victim._M_cur; });
972         return iterator(_Base::erase(__it.base()), this);
973       }
975       iterator
976       erase(iterator __it)
977       { return erase(const_iterator(__it)); }
979       iterator
980       erase(const_iterator __first, const_iterator __last)
981       {
982         __glibcxx_check_erase_range(__first, __last);
983         for (_Base_const_iterator __tmp = __first.base();
984              __tmp != __last.base(); ++__tmp)
985           {
986             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
987                                   _M_message(__gnu_debug::__msg_valid_range)
988                                   ._M_iterator(__first, "first")
989                                   ._M_iterator(__last, "last"));
990             this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
991                             { return __it == __tmp; });
992             this->_M_invalidate_local_if(
993                             [__tmp](_Base_const_local_iterator __it)
994                             { return __it._M_curr() == __tmp._M_cur; });
995           }
996         return iterator(_Base::erase(__first.base(),
997                                      __last.base()), this);
998       }
1000       _Base&
1001       _M_base() noexcept        { return *this; }
1003       const _Base&
1004       _M_base() const noexcept  { return *this; }
1006     private:
1007       void
1008       _M_check_rehashed(size_type __prev_count)
1009       {
1010         if (__prev_count != this->bucket_count())
1011           this->_M_invalidate_locals();
1012       }
1013     };
1015   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1016     inline void
1017     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1018          unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1019     noexcept(noexcept(__x.swap(__y)))
1020     { __x.swap(__y); }
1022   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1023     inline bool
1024     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1025                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1026     { return __x._M_base() == __y._M_base(); }
1028   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
1029     inline bool
1030     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
1031                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
1032     { return !(__x == __y); }
1034 } // namespace __debug
1035 } // namespace std
1037 #endif // C++11
1039 #endif