2015-09-19 Andrew Dixie <andrewd@gentrack.com>
[official-gcc.git] / libstdc++-v3 / include / debug / unordered_set
bloba45d3b54d387f8aa2e02d40e1dd386e0326a8951
1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
3 // Copyright (C) 2003-2015 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 #if __cplusplus < 201103L
33 # include <bits/c++0x_warning.h>
34 #else
35 # include <unordered_set>
37 #include <debug/safe_unordered_container.h>
38 #include <debug/safe_container.h>
39 #include <debug/safe_iterator.h>
40 #include <debug/safe_local_iterator.h>
42 namespace std _GLIBCXX_VISIBILITY(default)
44 namespace __debug
46   /// Class std::unordered_set with safety/checking/debug instrumentation.
47   template<typename _Value,
48            typename _Hash = std::hash<_Value>,
49            typename _Pred = std::equal_to<_Value>,
50            typename _Alloc = std::allocator<_Value> >
51     class unordered_set
52     : public __gnu_debug::_Safe_container<
53         unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
54         __gnu_debug::_Safe_unordered_container>,
55       public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
56     {
57       typedef _GLIBCXX_STD_C::unordered_set<
58         _Value, _Hash, _Pred, _Alloc>                                   _Base;
59       typedef __gnu_debug::_Safe_container<
60         unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container>  _Safe;
62       typedef typename _Base::const_iterator       _Base_const_iterator;
63       typedef typename _Base::iterator             _Base_iterator;
64       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
65       typedef typename _Base::local_iterator       _Base_local_iterator;
67     public:
68       typedef typename _Base::size_type                 size_type;
69       typedef typename _Base::hasher                    hasher;
70       typedef typename _Base::key_equal                 key_equal;
71       typedef typename _Base::allocator_type            allocator_type;
73       typedef typename _Base::key_type                  key_type;
74       typedef typename _Base::value_type                value_type;
76       typedef __gnu_debug::_Safe_iterator<
77         _Base_iterator, unordered_set>                  iterator;
78       typedef __gnu_debug::_Safe_iterator<
79         _Base_const_iterator, unordered_set>            const_iterator;
80       typedef __gnu_debug::_Safe_local_iterator<
81         _Base_local_iterator, unordered_set>            local_iterator;
82       typedef __gnu_debug::_Safe_local_iterator<
83         _Base_const_local_iterator, unordered_set>      const_local_iterator;
85       unordered_set() = default;
87       explicit
88       unordered_set(size_type __n,
89                     const hasher& __hf = hasher(),
90                     const key_equal& __eql = key_equal(),
91                     const allocator_type& __a = allocator_type())
92       : _Base(__n, __hf, __eql, __a) { }
94       template<typename _InputIterator>
95         unordered_set(_InputIterator __first, _InputIterator __last,
96                       size_type __n = 0,
97                       const hasher& __hf = hasher(),
98                       const key_equal& __eql = key_equal(),
99                       const allocator_type& __a = allocator_type())
100         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
101                                                                      __last)),
102                 __gnu_debug::__base(__last), __n,
103                 __hf, __eql, __a) { }
105       unordered_set(const unordered_set&) = default;
107       unordered_set(const _Base& __x)
108       : _Base(__x) { }
110       unordered_set(unordered_set&&) = default;
112       explicit
113       unordered_set(const allocator_type& __a)
114       : _Base(__a) { }
116       unordered_set(const unordered_set& __uset,
117                     const allocator_type& __a)
118       : _Base(__uset, __a) { }
120       unordered_set(unordered_set&& __uset,
121                     const allocator_type& __a)
122       : _Safe(std::move(__uset._M_safe()), __a),
123         _Base(std::move(__uset._M_base()), __a) { }
125       unordered_set(initializer_list<value_type> __l,
126                     size_type __n = 0,
127                     const hasher& __hf = hasher(),
128                     const key_equal& __eql = key_equal(),
129                     const allocator_type& __a = allocator_type())
130       : _Base(__l, __n, __hf, __eql, __a) { }
132       unordered_set(size_type __n, const allocator_type& __a)
133         : unordered_set(__n, hasher(), key_equal(), __a)
134       { }
136       unordered_set(size_type __n, const hasher& __hf,
137                     const allocator_type& __a)
138         : unordered_set(__n, __hf, key_equal(), __a)
139       { }
141       template<typename _InputIterator>
142         unordered_set(_InputIterator __first, _InputIterator __last,
143                       size_type __n,
144                       const allocator_type& __a)
145           : unordered_set(__first, __last, __n, hasher(), key_equal(), __a)
146         { }
148       template<typename _InputIterator>
149         unordered_set(_InputIterator __first, _InputIterator __last,
150                       size_type __n, const hasher& __hf,
151                       const allocator_type& __a)
152           : unordered_set(__first, __last, __n, __hf, key_equal(), __a)
153         { }
155       unordered_set(initializer_list<value_type> __l,
156                     size_type __n,
157                     const allocator_type& __a)
158         : unordered_set(__l, __n, hasher(), key_equal(), __a)
159       { }
161       unordered_set(initializer_list<value_type> __l,
162                     size_type __n, const hasher& __hf,
163                     const allocator_type& __a)
164         : unordered_set(__l, __n, __hf, key_equal(), __a)
165       { }
167       ~unordered_set() = default;
169       unordered_set&
170       operator=(const unordered_set&) = default;
172       unordered_set&
173       operator=(unordered_set&&) = default;
175       unordered_set&
176       operator=(initializer_list<value_type> __l)
177       {
178         _M_base() = __l;
179         this->_M_invalidate_all();
180         return *this;
181       }
183       void
184       swap(unordered_set& __x)
185         noexcept( noexcept(declval<_Base&>().swap(__x)) )
186       {
187         _Safe::_M_swap(__x);
188         _Base::swap(__x);
189       }
191       void
192       clear() noexcept
193       {
194         _Base::clear();
195         this->_M_invalidate_all();
196       }
198       iterator
199       begin() noexcept
200       { return iterator(_Base::begin(), this); }
202       const_iterator
203       begin() const noexcept
204       { return const_iterator(_Base::begin(), this); }
206       iterator
207       end() noexcept
208       { return iterator(_Base::end(), this); }
210       const_iterator
211       end() const noexcept
212       { return const_iterator(_Base::end(), this); }
214       const_iterator
215       cbegin() const noexcept
216       { return const_iterator(_Base::begin(), this); }
218       const_iterator
219       cend() const noexcept
220       { return const_iterator(_Base::end(), this); }
222       // local versions
223       local_iterator
224       begin(size_type __b)
225       {
226         __glibcxx_check_bucket_index(__b);
227         return local_iterator(_Base::begin(__b), this);
228       }
230       local_iterator
231       end(size_type __b)
232       {
233         __glibcxx_check_bucket_index(__b);
234         return local_iterator(_Base::end(__b), this);
235       }
237       const_local_iterator
238       begin(size_type __b) const
239       {
240         __glibcxx_check_bucket_index(__b);
241         return const_local_iterator(_Base::begin(__b), this);
242       }
244       const_local_iterator
245       end(size_type __b) const
246       {
247         __glibcxx_check_bucket_index(__b);
248         return const_local_iterator(_Base::end(__b), this);
249       }
251       const_local_iterator
252       cbegin(size_type __b) const
253       {
254         __glibcxx_check_bucket_index(__b);
255         return const_local_iterator(_Base::cbegin(__b), this);
256       }
258       const_local_iterator
259       cend(size_type __b) const
260       {
261         __glibcxx_check_bucket_index(__b);
262         return const_local_iterator(_Base::cend(__b), this);
263       }
265       size_type
266       bucket_size(size_type __b) const
267       {
268         __glibcxx_check_bucket_index(__b);
269         return _Base::bucket_size(__b);
270       }
272       float
273       max_load_factor() const noexcept
274       { return _Base::max_load_factor(); }
276       void
277       max_load_factor(float __f)
278       {
279         __glibcxx_check_max_load_factor(__f);
280         _Base::max_load_factor(__f);
281       }
283       template<typename... _Args>
284         std::pair<iterator, bool>
285         emplace(_Args&&... __args)
286         {
287           size_type __bucket_count = this->bucket_count();
288           std::pair<_Base_iterator, bool> __res
289             = _Base::emplace(std::forward<_Args>(__args)...);
290           _M_check_rehashed(__bucket_count);
291           return std::make_pair(iterator(__res.first, this), __res.second);
292         }
294       template<typename... _Args>
295         iterator
296         emplace_hint(const_iterator __hint, _Args&&... __args)
297         {
298           __glibcxx_check_insert(__hint);
299           size_type __bucket_count = this->bucket_count();
300           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
301                                         std::forward<_Args>(__args)...);
302           _M_check_rehashed(__bucket_count);
303           return iterator(__it, this);
304         }
306       std::pair<iterator, bool>
307       insert(const value_type& __obj)
308       {
309         size_type __bucket_count = this->bucket_count();
310         std::pair<_Base_iterator, bool> __res
311           = _Base::insert(__obj);
312         _M_check_rehashed(__bucket_count);
313         return std::make_pair(iterator(__res.first, this), __res.second);
314       }
316       iterator
317       insert(const_iterator __hint, const value_type& __obj)
318       {
319         __glibcxx_check_insert(__hint);
320         size_type __bucket_count = this->bucket_count();
321         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
322         _M_check_rehashed(__bucket_count);
323         return iterator(__it, this);
324       }
326       std::pair<iterator, bool>
327       insert(value_type&& __obj)
328       {
329         size_type __bucket_count = this->bucket_count();
330         std::pair<_Base_iterator, bool> __res
331           = _Base::insert(std::move(__obj));
332         _M_check_rehashed(__bucket_count);
333         return std::make_pair(iterator(__res.first, this), __res.second);
334       }
336       iterator
337       insert(const_iterator __hint, value_type&& __obj)
338       {
339         __glibcxx_check_insert(__hint);
340         size_type __bucket_count = this->bucket_count();
341         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
342         _M_check_rehashed(__bucket_count);
343         return iterator(__it, this);
344       }
346       void
347       insert(std::initializer_list<value_type> __l)
348       {
349         size_type __bucket_count = this->bucket_count();
350         _Base::insert(__l);
351         _M_check_rehashed(__bucket_count);
352       }
354       template<typename _InputIterator>
355         void
356         insert(_InputIterator __first, _InputIterator __last)
357         {
358           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
359           __glibcxx_check_valid_range2(__first, __last, __dist);
360           size_type __bucket_count = this->bucket_count();
362           if (__dist.second >= __gnu_debug::__dp_sign)
363             _Base::insert(__gnu_debug::__unsafe(__first),
364                           __gnu_debug::__unsafe(__last));
365           else
366             _Base::insert(__first, __last);
368           _M_check_rehashed(__bucket_count);
369         }
371       iterator
372       find(const key_type& __key)
373       { return iterator(_Base::find(__key), this); }
375       const_iterator
376       find(const key_type& __key) const
377       { return const_iterator(_Base::find(__key), this); }
379       std::pair<iterator, iterator>
380       equal_range(const key_type& __key)
381       {
382         std::pair<_Base_iterator, _Base_iterator> __res
383           = _Base::equal_range(__key);
384         return std::make_pair(iterator(__res.first, this),
385                               iterator(__res.second, this));
386       }
388       std::pair<const_iterator, const_iterator>
389       equal_range(const key_type& __key) const
390       {
391         std::pair<_Base_const_iterator, _Base_const_iterator>
392           __res = _Base::equal_range(__key);
393         return std::make_pair(const_iterator(__res.first, this),
394                               const_iterator(__res.second, this));
395       }
397       size_type
398       erase(const key_type& __key)
399       {
400         size_type __ret(0);
401         _Base_iterator __victim(_Base::find(__key));
402         if (__victim != _Base::end())
403           {
404             this->_M_invalidate_if(
405                             [__victim](_Base_const_iterator __it)
406                             { return __it == __victim; });
407             this->_M_invalidate_local_if(
408                             [__victim](_Base_const_local_iterator __it)
409                             { return __it._M_curr() == __victim._M_cur; });
410             size_type __bucket_count = this->bucket_count();
411             _Base::erase(__victim);
412             _M_check_rehashed(__bucket_count);
413             __ret = 1;
414           }
415         return __ret;
416       }
418       iterator
419       erase(const_iterator __it)
420       {
421         __glibcxx_check_erase(__it);
422         _Base_const_iterator __victim = __it.base();
423         this->_M_invalidate_if(
424                         [__victim](_Base_const_iterator __it)
425                         { return __it == __victim; });
426         this->_M_invalidate_local_if(
427                         [__victim](_Base_const_local_iterator __it)
428                         { return __it._M_curr() == __victim._M_cur; });
429         size_type __bucket_count = this->bucket_count();
430         _Base_iterator __next = _Base::erase(__it.base());
431         _M_check_rehashed(__bucket_count);
432         return iterator(__next, this);
433       }
435       iterator
436       erase(iterator __it)
437       { return erase(const_iterator(__it)); }
439       iterator
440       erase(const_iterator __first, const_iterator __last)
441       {
442         __glibcxx_check_erase_range(__first, __last);
443         for (_Base_const_iterator __tmp = __first.base();
444              __tmp != __last.base(); ++__tmp)
445           {
446             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
447                                   _M_message(__gnu_debug::__msg_valid_range)
448                                   ._M_iterator(__first, "first")
449                                   ._M_iterator(__last, "last"));
450             this->_M_invalidate_if(
451                             [__tmp](_Base_const_iterator __it)
452                             { return __it == __tmp; });
453             this->_M_invalidate_local_if(
454                             [__tmp](_Base_const_local_iterator __it)
455                             { return __it._M_curr() == __tmp._M_cur; });
456           }
457         size_type __bucket_count = this->bucket_count();
458         _Base_iterator __next = _Base::erase(__first.base(),
459                                              __last.base());
460         _M_check_rehashed(__bucket_count);
461         return iterator(__next, this);
462       }
464       _Base&
465       _M_base() noexcept { return *this; }
467       const _Base&
468       _M_base() const noexcept { return *this; }
470     private:
471       void
472       _M_check_rehashed(size_type __prev_count)
473       {
474         if (__prev_count != this->bucket_count())
475           this->_M_invalidate_locals();
476       }
477     };
479   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
480     inline void
481     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
482          unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
483     noexcept(noexcept(__x.swap(__y)))
484     { __x.swap(__y); }
486   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
487     inline bool
488     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
489                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
490     { return __x._M_base() == __y._M_base(); }
492   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
493     inline bool
494     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
495                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
496     { return !(__x == __y); }
499   /// Class std::unordered_multiset with safety/checking/debug instrumentation.
500   template<typename _Value,
501            typename _Hash = std::hash<_Value>,
502            typename _Pred = std::equal_to<_Value>,
503            typename _Alloc = std::allocator<_Value> >
504     class unordered_multiset
505     : public __gnu_debug::_Safe_container<
506         unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
507         __gnu_debug::_Safe_unordered_container>,
508       public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
509     {
510       typedef _GLIBCXX_STD_C::unordered_multiset<
511         _Value, _Hash, _Pred, _Alloc>                           _Base;
512       typedef __gnu_debug::_Safe_container<unordered_multiset,
513         _Alloc, __gnu_debug::_Safe_unordered_container>         _Safe;
514       typedef typename _Base::const_iterator    _Base_const_iterator;
515       typedef typename _Base::iterator          _Base_iterator;
516       typedef typename _Base::const_local_iterator
517                                                 _Base_const_local_iterator;
518       typedef typename _Base::local_iterator    _Base_local_iterator;
520     public:
521       typedef typename _Base::size_type                 size_type;
522       typedef typename _Base::hasher                    hasher;
523       typedef typename _Base::key_equal                 key_equal;
524       typedef typename _Base::allocator_type            allocator_type;
526       typedef typename _Base::key_type                  key_type;
527       typedef typename _Base::value_type                value_type;
529       typedef __gnu_debug::_Safe_iterator<
530         _Base_iterator, unordered_multiset>             iterator;
531       typedef __gnu_debug::_Safe_iterator<
532         _Base_const_iterator, unordered_multiset>       const_iterator;
533       typedef __gnu_debug::_Safe_local_iterator<
534         _Base_local_iterator, unordered_multiset>       local_iterator;
535       typedef __gnu_debug::_Safe_local_iterator<
536         _Base_const_local_iterator, unordered_multiset> const_local_iterator;
538       unordered_multiset() = default;
540       explicit
541       unordered_multiset(size_type __n,
542                          const hasher& __hf = hasher(),
543                          const key_equal& __eql = key_equal(),
544                          const allocator_type& __a = allocator_type())
545       : _Base(__n, __hf, __eql, __a) { }
547       template<typename _InputIterator>
548         unordered_multiset(_InputIterator __first, _InputIterator __last,
549                            size_type __n = 0,
550                            const hasher& __hf = hasher(),
551                            const key_equal& __eql = key_equal(),
552                            const allocator_type& __a = allocator_type())
553         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
554                                                                      __last)),
555                 __gnu_debug::__base(__last), __n,
556                 __hf, __eql, __a) { }
558       unordered_multiset(const unordered_multiset&) = default;
560       unordered_multiset(const _Base& __x)
561       : _Base(__x) { }
563       unordered_multiset(unordered_multiset&&) = default;
565       explicit
566       unordered_multiset(const allocator_type& __a)
567       : _Base(__a) { }
569       unordered_multiset(const unordered_multiset& __uset,
570                          const allocator_type& __a)
571       : _Base(__uset, __a) { }
573       unordered_multiset(unordered_multiset&& __uset,
574                          const allocator_type& __a)
575       : _Safe(std::move(__uset._M_safe()), __a),
576         _Base(std::move(__uset._M_base()), __a) { }
578       unordered_multiset(initializer_list<value_type> __l,
579                          size_type __n = 0,
580                          const hasher& __hf = hasher(),
581                          const key_equal& __eql = key_equal(),
582                          const allocator_type& __a = allocator_type())
583       : _Base(__l, __n, __hf, __eql, __a) { }
585       unordered_multiset(size_type __n, const allocator_type& __a)
586         : unordered_multiset(__n, hasher(), key_equal(), __a)
587       { }
589       unordered_multiset(size_type __n, const hasher& __hf,
590                          const allocator_type& __a)
591         : unordered_multiset(__n, __hf, key_equal(), __a)
592       { }
594       template<typename _InputIterator>
595         unordered_multiset(_InputIterator __first, _InputIterator __last,
596                            size_type __n,
597                            const allocator_type& __a)
598           : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a)
599         { }
601       template<typename _InputIterator>
602         unordered_multiset(_InputIterator __first, _InputIterator __last,
603                            size_type __n, const hasher& __hf,
604                            const allocator_type& __a)
605           : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a)
606         { }
608       unordered_multiset(initializer_list<value_type> __l,
609                          size_type __n,
610                          const allocator_type& __a)
611         : unordered_multiset(__l, __n, hasher(), key_equal(), __a)
612       { }
614       unordered_multiset(initializer_list<value_type> __l,
615                          size_type __n, const hasher& __hf,
616                          const allocator_type& __a)
617         : unordered_multiset(__l, __n, __hf, key_equal(), __a)
618       { }
620       ~unordered_multiset() = default;
622       unordered_multiset&
623       operator=(const unordered_multiset&) = default;
625       unordered_multiset&
626       operator=(unordered_multiset&&) = default;
628       unordered_multiset&
629       operator=(initializer_list<value_type> __l)
630       {
631         this->_M_base() = __l;
632         this->_M_invalidate_all();
633         return *this;
634       }
636       void
637       swap(unordered_multiset& __x)
638         noexcept( noexcept(declval<_Base&>().swap(__x)) )
639       {
640         _Safe::_M_swap(__x);
641         _Base::swap(__x);
642       }
644       void
645       clear() noexcept
646       {
647         _Base::clear();
648         this->_M_invalidate_all();
649       }
651       iterator
652       begin() noexcept
653       { return iterator(_Base::begin(), this); }
655       const_iterator
656       begin() const noexcept
657       { return const_iterator(_Base::begin(), this); }
659       iterator
660       end() noexcept
661       { return iterator(_Base::end(), this); }
663       const_iterator
664       end() const noexcept
665       { return const_iterator(_Base::end(), this); }
667       const_iterator
668       cbegin() const noexcept
669       { return const_iterator(_Base::begin(), this); }
671       const_iterator
672       cend() const noexcept
673       { return const_iterator(_Base::end(), this); }
675       // local versions
676       local_iterator
677       begin(size_type __b)
678       {
679         __glibcxx_check_bucket_index(__b);
680         return local_iterator(_Base::begin(__b), this);
681       }
683       local_iterator
684       end(size_type __b)
685       {
686         __glibcxx_check_bucket_index(__b);
687         return local_iterator(_Base::end(__b), this);
688       }
690       const_local_iterator
691       begin(size_type __b) const
692       {
693         __glibcxx_check_bucket_index(__b);
694         return const_local_iterator(_Base::begin(__b), this);
695       }
697       const_local_iterator
698       end(size_type __b) const
699       {
700         __glibcxx_check_bucket_index(__b);
701         return const_local_iterator(_Base::end(__b), this);
702       }
704       const_local_iterator
705       cbegin(size_type __b) const
706       {
707         __glibcxx_check_bucket_index(__b);
708         return const_local_iterator(_Base::cbegin(__b), this);
709       }
711       const_local_iterator
712       cend(size_type __b) const
713       {
714         __glibcxx_check_bucket_index(__b);
715         return const_local_iterator(_Base::cend(__b), this);
716       }
718       size_type
719       bucket_size(size_type __b) const
720       {
721         __glibcxx_check_bucket_index(__b);
722         return _Base::bucket_size(__b);
723       }
725       float
726       max_load_factor() const noexcept
727       { return _Base::max_load_factor(); }
729       void
730       max_load_factor(float __f)
731       {
732         __glibcxx_check_max_load_factor(__f);
733         _Base::max_load_factor(__f);
734       }
736       template<typename... _Args>
737         iterator
738         emplace(_Args&&... __args)
739         {
740           size_type __bucket_count = this->bucket_count();
741           _Base_iterator __it
742             = _Base::emplace(std::forward<_Args>(__args)...);
743           _M_check_rehashed(__bucket_count);
744           return iterator(__it, this);
745         }
747       template<typename... _Args>
748         iterator
749         emplace_hint(const_iterator __hint, _Args&&... __args)
750         {
751           __glibcxx_check_insert(__hint);
752           size_type __bucket_count = this->bucket_count();
753           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
754                                         std::forward<_Args>(__args)...);
755           _M_check_rehashed(__bucket_count);
756           return iterator(__it, this);
757         }
759       iterator
760       insert(const value_type& __obj)
761       {
762         size_type __bucket_count = this->bucket_count();
763         _Base_iterator __it = _Base::insert(__obj);
764         _M_check_rehashed(__bucket_count);
765         return iterator(__it, this);
766       }
768       iterator
769       insert(const_iterator __hint, const value_type& __obj)
770       {
771         __glibcxx_check_insert(__hint);
772         size_type __bucket_count = this->bucket_count();
773         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
774         _M_check_rehashed(__bucket_count);
775         return iterator(__it, this);
776       }
778       iterator
779       insert(value_type&& __obj)
780       {
781         size_type __bucket_count = this->bucket_count();
782         _Base_iterator __it = _Base::insert(std::move(__obj));
783         _M_check_rehashed(__bucket_count);
784         return iterator(__it, this);
785       }
787       iterator
788       insert(const_iterator __hint, value_type&& __obj)
789       {
790         __glibcxx_check_insert(__hint);
791         size_type __bucket_count = this->bucket_count();
792         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
793         _M_check_rehashed(__bucket_count);
794         return iterator(__it, this);
795       }
797       void
798       insert(std::initializer_list<value_type> __l)
799       {
800         size_type __bucket_count = this->bucket_count();
801         _Base::insert(__l);
802         _M_check_rehashed(__bucket_count);
803       }
805       template<typename _InputIterator>
806         void
807         insert(_InputIterator __first, _InputIterator __last)
808         {
809           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
810           __glibcxx_check_valid_range2(__first, __last, __dist);
811           size_type __bucket_count = this->bucket_count();
813           if (__dist.second >= __gnu_debug::__dp_sign)
814             _Base::insert(__gnu_debug::__unsafe(__first),
815                           __gnu_debug::__unsafe(__last));
816           else
817             _Base::insert(__first, __last);
819           _M_check_rehashed(__bucket_count);
820         }
822       iterator
823       find(const key_type& __key)
824       { return iterator(_Base::find(__key), this); }
826       const_iterator
827       find(const key_type& __key) const
828       { return const_iterator(_Base::find(__key), this); }
830       std::pair<iterator, iterator>
831       equal_range(const key_type& __key)
832       {
833         std::pair<_Base_iterator, _Base_iterator> __res
834           = _Base::equal_range(__key);
835         return std::make_pair(iterator(__res.first, this),
836                               iterator(__res.second, this));
837       }
839       std::pair<const_iterator, const_iterator>
840       equal_range(const key_type& __key) const
841       {
842         std::pair<_Base_const_iterator, _Base_const_iterator>
843           __res = _Base::equal_range(__key);
844         return std::make_pair(const_iterator(__res.first, this),
845                               const_iterator(__res.second, this));
846       }
848       size_type
849       erase(const key_type& __key)
850       {
851         size_type __ret(0);
852         std::pair<_Base_iterator, _Base_iterator> __pair =
853           _Base::equal_range(__key);
854         for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
855           {
856             this->_M_invalidate_if([__victim](_Base_const_iterator __it)
857                             { return __it == __victim; });
858             this->_M_invalidate_local_if(
859                             [__victim](_Base_const_local_iterator __it)
860                             { return __it._M_curr() == __victim._M_cur; });
861             _Base::erase(__victim++);
862             ++__ret;
863           }
864         return __ret;
865       }
867       iterator
868       erase(const_iterator __it)
869       {
870         __glibcxx_check_erase(__it);
871         _Base_const_iterator __victim = __it.base();
872         this->_M_invalidate_if([__victim](_Base_const_iterator __it)
873                         { return __it == __victim; });
874         this->_M_invalidate_local_if(
875                         [__victim](_Base_const_local_iterator __it)
876                         { return __it._M_curr() == __victim._M_cur; });
877         return iterator(_Base::erase(__it.base()), this);
878       }
880       iterator
881       erase(iterator __it)
882       { return erase(const_iterator(__it)); }
884       iterator
885       erase(const_iterator __first, const_iterator __last)
886       {
887         __glibcxx_check_erase_range(__first, __last);
888         for (_Base_const_iterator __tmp = __first.base();
889              __tmp != __last.base(); ++__tmp)
890           {
891             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
892                                   _M_message(__gnu_debug::__msg_valid_range)
893                                   ._M_iterator(__first, "first")
894                                   ._M_iterator(__last, "last"));
895             this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
896                             { return __it == __tmp; });
897             this->_M_invalidate_local_if(
898                             [__tmp](_Base_const_local_iterator __it)
899                             { return __it._M_curr() == __tmp._M_cur; });
900           }
901         return iterator(_Base::erase(__first.base(),
902                                      __last.base()), this);
903       }
905       _Base&
906       _M_base() noexcept        { return *this; }
908       const _Base&
909       _M_base() const noexcept  { return *this; }
911     private:
912       void
913       _M_check_rehashed(size_type __prev_count)
914       {
915         if (__prev_count != this->bucket_count())
916           this->_M_invalidate_locals();
917       }
918     };
920   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
921     inline void
922     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
923          unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
924     noexcept(noexcept(__x.swap(__y)))
925     { __x.swap(__y); }
927   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
928     inline bool
929     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
930                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
931     { return __x._M_base() == __y._M_base(); }
933   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
934     inline bool
935     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
936                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
937     { return !(__x == __y); }
939 } // namespace __debug
940 } // namespace std
942 #endif // C++11
944 #endif