libstdc++

unordered_set

Go to the documentation of this file.
00001 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file debug/unordered_set
00026  *  This file is a GNU debug extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
00030 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
00031 
00032 #if __cplusplus < 201103L
00033 # include <bits/c++0x_warning.h>
00034 #else
00035 # include <unordered_set>
00036 
00037 #include <debug/safe_unordered_container.h>
00038 #include <debug/safe_container.h>
00039 #include <debug/safe_iterator.h>
00040 #include <debug/safe_local_iterator.h>
00041 
00042 namespace std _GLIBCXX_VISIBILITY(default)
00043 {
00044 namespace __debug
00045 {
00046   /// Class std::unordered_set with safety/checking/debug instrumentation.
00047   template<typename _Value,
00048            typename _Hash = std::hash<_Value>,
00049            typename _Pred = std::equal_to<_Value>,
00050            typename _Alloc = std::allocator<_Value> >
00051     class unordered_set
00052     : public __gnu_debug::_Safe_container<
00053         unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
00054         __gnu_debug::_Safe_unordered_container>,
00055       public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
00056     {
00057       typedef _GLIBCXX_STD_C::unordered_set<
00058         _Value, _Hash, _Pred, _Alloc>                                   _Base;
00059       typedef __gnu_debug::_Safe_container<
00060         unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container>  _Safe;
00061 
00062       typedef typename _Base::const_iterator       _Base_const_iterator;
00063       typedef typename _Base::iterator             _Base_iterator;
00064       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
00065       typedef typename _Base::local_iterator       _Base_local_iterator;
00066 
00067     public:
00068       typedef typename _Base::size_type                 size_type;
00069       typedef typename _Base::hasher                    hasher;
00070       typedef typename _Base::key_equal                 key_equal;
00071       typedef typename _Base::allocator_type            allocator_type;
00072 
00073       typedef typename _Base::key_type                  key_type;
00074       typedef typename _Base::value_type                value_type;
00075 
00076       typedef __gnu_debug::_Safe_iterator<
00077         _Base_iterator, unordered_set>                  iterator;
00078       typedef __gnu_debug::_Safe_iterator<
00079         _Base_const_iterator, unordered_set>            const_iterator;
00080       typedef __gnu_debug::_Safe_local_iterator<
00081         _Base_local_iterator, unordered_set>            local_iterator;
00082       typedef __gnu_debug::_Safe_local_iterator<
00083         _Base_const_local_iterator, unordered_set>      const_local_iterator;
00084 
00085       unordered_set() = default;
00086 
00087       explicit
00088       unordered_set(size_type __n,
00089                     const hasher& __hf = hasher(),
00090                     const key_equal& __eql = key_equal(),
00091                     const allocator_type& __a = allocator_type())
00092       : _Base(__n, __hf, __eql, __a) { }
00093 
00094       template<typename _InputIterator>
00095         unordered_set(_InputIterator __first, _InputIterator __last,
00096                       size_type __n = 0,
00097                       const hasher& __hf = hasher(),
00098                       const key_equal& __eql = key_equal(),
00099                       const allocator_type& __a = allocator_type())
00100         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00101                                                                      __last)),
00102                 __gnu_debug::__base(__last), __n,
00103                 __hf, __eql, __a) { }
00104 
00105       unordered_set(const unordered_set&) = default;
00106 
00107       unordered_set(const _Base& __x)
00108       : _Base(__x) { }
00109 
00110       unordered_set(unordered_set&&) = default;
00111 
00112       explicit
00113       unordered_set(const allocator_type& __a)
00114       : _Base(__a) { }
00115 
00116       unordered_set(const unordered_set& __uset,
00117                     const allocator_type& __a)
00118       : _Base(__uset, __a) { }
00119 
00120       unordered_set(unordered_set&& __uset,
00121                     const allocator_type& __a)
00122       : _Safe(std::move(__uset._M_safe()), __a),
00123         _Base(std::move(__uset._M_base()), __a) { }
00124 
00125       unordered_set(initializer_list<value_type> __l,
00126                     size_type __n = 0,
00127                     const hasher& __hf = hasher(),
00128                     const key_equal& __eql = key_equal(),
00129                     const allocator_type& __a = allocator_type())
00130       : _Base(__l, __n, __hf, __eql, __a) { }
00131 
00132       ~unordered_set() = default;
00133 
00134       unordered_set&
00135       operator=(const unordered_set&) = default;
00136 
00137       unordered_set&
00138       operator=(unordered_set&&) = default;
00139 
00140       unordered_set&
00141       operator=(initializer_list<value_type> __l)
00142       {
00143         _M_base() = __l;
00144         this->_M_invalidate_all();
00145         return *this;
00146       }
00147 
00148       void
00149       swap(unordered_set& __x)
00150         noexcept( noexcept(declval<_Base>().swap(__x)) )
00151       {
00152         _Safe::_M_swap(__x);
00153         _Base::swap(__x);
00154       }
00155 
00156       void
00157       clear() noexcept
00158       {
00159         _Base::clear();
00160         this->_M_invalidate_all();
00161       }
00162 
00163       iterator
00164       begin() noexcept
00165       { return iterator(_Base::begin(), this); }
00166 
00167       const_iterator
00168       begin() const noexcept
00169       { return const_iterator(_Base::begin(), this); }
00170 
00171       iterator
00172       end() noexcept
00173       { return iterator(_Base::end(), this); }
00174 
00175       const_iterator
00176       end() const noexcept
00177       { return const_iterator(_Base::end(), this); }
00178 
00179       const_iterator
00180       cbegin() const noexcept
00181       { return const_iterator(_Base::begin(), this); }
00182 
00183       const_iterator
00184       cend() const noexcept
00185       { return const_iterator(_Base::end(), this); }
00186 
00187       // local versions
00188       local_iterator
00189       begin(size_type __b)
00190       {
00191         __glibcxx_check_bucket_index(__b);
00192         return local_iterator(_Base::begin(__b), this);
00193       }
00194 
00195       local_iterator
00196       end(size_type __b)
00197       {
00198         __glibcxx_check_bucket_index(__b);
00199         return local_iterator(_Base::end(__b), this);
00200       }
00201 
00202       const_local_iterator
00203       begin(size_type __b) const
00204       {
00205         __glibcxx_check_bucket_index(__b);
00206         return const_local_iterator(_Base::begin(__b), this);
00207       }
00208 
00209       const_local_iterator
00210       end(size_type __b) const
00211       {
00212         __glibcxx_check_bucket_index(__b);
00213         return const_local_iterator(_Base::end(__b), this);
00214       }
00215 
00216       const_local_iterator
00217       cbegin(size_type __b) const
00218       {
00219         __glibcxx_check_bucket_index(__b);
00220         return const_local_iterator(_Base::cbegin(__b), this);
00221       }
00222 
00223       const_local_iterator
00224       cend(size_type __b) const
00225       {
00226         __glibcxx_check_bucket_index(__b);
00227         return const_local_iterator(_Base::cend(__b), this);
00228       }
00229 
00230       size_type
00231       bucket_size(size_type __b) const
00232       {
00233         __glibcxx_check_bucket_index(__b);
00234         return _Base::bucket_size(__b);
00235       }
00236 
00237       float
00238       max_load_factor() const noexcept
00239       { return _Base::max_load_factor(); }
00240 
00241       void
00242       max_load_factor(float __f)
00243       {
00244         __glibcxx_check_max_load_factor(__f);
00245         _Base::max_load_factor(__f);
00246       }
00247 
00248       template<typename... _Args>
00249         std::pair<iterator, bool>
00250         emplace(_Args&&... __args)
00251         {
00252           size_type __bucket_count = this->bucket_count();
00253           std::pair<_Base_iterator, bool> __res
00254             = _Base::emplace(std::forward<_Args>(__args)...);
00255           _M_check_rehashed(__bucket_count);
00256           return std::make_pair(iterator(__res.first, this), __res.second);
00257         }
00258 
00259       template<typename... _Args>
00260         iterator
00261         emplace_hint(const_iterator __hint, _Args&&... __args)
00262         {
00263           __glibcxx_check_insert(__hint);
00264           size_type __bucket_count = this->bucket_count();
00265           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
00266                                         std::forward<_Args>(__args)...);
00267           _M_check_rehashed(__bucket_count);
00268           return iterator(__it, this);
00269         }
00270 
00271       std::pair<iterator, bool>
00272       insert(const value_type& __obj)
00273       {
00274         size_type __bucket_count = this->bucket_count();
00275         std::pair<_Base_iterator, bool> __res
00276           = _Base::insert(__obj);
00277         _M_check_rehashed(__bucket_count);
00278         return std::make_pair(iterator(__res.first, this), __res.second);
00279       }
00280 
00281       iterator
00282       insert(const_iterator __hint, const value_type& __obj)
00283       {
00284         __glibcxx_check_insert(__hint);
00285         size_type __bucket_count = this->bucket_count();
00286         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
00287         _M_check_rehashed(__bucket_count);
00288         return iterator(__it, this);
00289       }
00290 
00291       std::pair<iterator, bool>
00292       insert(value_type&& __obj)
00293       {
00294         size_type __bucket_count = this->bucket_count();
00295         std::pair<_Base_iterator, bool> __res
00296           = _Base::insert(std::move(__obj));
00297         _M_check_rehashed(__bucket_count);
00298         return std::make_pair(iterator(__res.first, this), __res.second);
00299       }
00300 
00301       iterator
00302       insert(const_iterator __hint, value_type&& __obj)
00303       {
00304         __glibcxx_check_insert(__hint);
00305         size_type __bucket_count = this->bucket_count();
00306         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
00307         _M_check_rehashed(__bucket_count);
00308         return iterator(__it, this);
00309       }
00310 
00311       void
00312       insert(std::initializer_list<value_type> __l)
00313       {
00314         size_type __bucket_count = this->bucket_count();
00315         _Base::insert(__l);
00316         _M_check_rehashed(__bucket_count);
00317       }
00318 
00319       template<typename _InputIterator>
00320         void
00321         insert(_InputIterator __first, _InputIterator __last)
00322         {
00323           __glibcxx_check_valid_range(__first, __last);
00324           size_type __bucket_count = this->bucket_count();
00325           _Base::insert(__gnu_debug::__base(__first),
00326                         __gnu_debug::__base(__last));
00327           _M_check_rehashed(__bucket_count);
00328         }
00329 
00330       iterator
00331       find(const key_type& __key)
00332       { return iterator(_Base::find(__key), this); }
00333 
00334       const_iterator
00335       find(const key_type& __key) const
00336       { return const_iterator(_Base::find(__key), this); }
00337 
00338       std::pair<iterator, iterator>
00339       equal_range(const key_type& __key)
00340       {
00341         std::pair<_Base_iterator, _Base_iterator> __res
00342           = _Base::equal_range(__key);
00343         return std::make_pair(iterator(__res.first, this),
00344                               iterator(__res.second, this));
00345       }
00346 
00347       std::pair<const_iterator, const_iterator>
00348       equal_range(const key_type& __key) const
00349       {
00350         std::pair<_Base_const_iterator, _Base_const_iterator>
00351           __res = _Base::equal_range(__key);
00352         return std::make_pair(const_iterator(__res.first, this),
00353                               const_iterator(__res.second, this));
00354       }
00355 
00356       size_type
00357       erase(const key_type& __key)
00358       {
00359         size_type __ret(0);
00360         _Base_iterator __victim(_Base::find(__key));
00361         if (__victim != _Base::end())
00362           {
00363             this->_M_invalidate_if(
00364                             [__victim](_Base_const_iterator __it)
00365                             { return __it == __victim; });
00366             this->_M_invalidate_local_if(
00367                             [__victim](_Base_const_local_iterator __it)
00368                             { return __it._M_curr() == __victim._M_cur; });
00369             size_type __bucket_count = this->bucket_count();
00370             _Base::erase(__victim);
00371             _M_check_rehashed(__bucket_count);
00372             __ret = 1;
00373           }
00374         return __ret;
00375       }
00376 
00377       iterator
00378       erase(const_iterator __it)
00379       {
00380         __glibcxx_check_erase(__it);
00381         _Base_const_iterator __victim = __it.base();
00382         this->_M_invalidate_if(
00383                         [__victim](_Base_const_iterator __it)
00384                         { return __it == __victim; });
00385         this->_M_invalidate_local_if(
00386                         [__victim](_Base_const_local_iterator __it)
00387                         { return __it._M_curr() == __victim._M_cur; });
00388         size_type __bucket_count = this->bucket_count();
00389         _Base_iterator __next = _Base::erase(__it.base());
00390         _M_check_rehashed(__bucket_count);
00391         return iterator(__next, this);
00392       }
00393 
00394       iterator
00395       erase(iterator __it)
00396       { return erase(const_iterator(__it)); }
00397 
00398       iterator
00399       erase(const_iterator __first, const_iterator __last)
00400       {
00401         __glibcxx_check_erase_range(__first, __last);
00402         for (_Base_const_iterator __tmp = __first.base();
00403              __tmp != __last.base(); ++__tmp)
00404           {
00405             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
00406                                   _M_message(__gnu_debug::__msg_valid_range)
00407                                   ._M_iterator(__first, "first")
00408                                   ._M_iterator(__last, "last"));
00409             this->_M_invalidate_if(
00410                             [__tmp](_Base_const_iterator __it)
00411                             { return __it == __tmp; });
00412             this->_M_invalidate_local_if(
00413                             [__tmp](_Base_const_local_iterator __it)
00414                             { return __it._M_curr() == __tmp._M_cur; });
00415           }
00416         size_type __bucket_count = this->bucket_count();
00417         _Base_iterator __next = _Base::erase(__first.base(),
00418                                              __last.base());
00419         _M_check_rehashed(__bucket_count);
00420         return iterator(__next, this);
00421       }
00422 
00423       _Base&
00424       _M_base() noexcept { return *this; }
00425 
00426       const _Base&
00427       _M_base() const noexcept { return *this; }
00428 
00429     private:
00430       void
00431       _M_check_rehashed(size_type __prev_count)
00432       {
00433         if (__prev_count != this->bucket_count())
00434           this->_M_invalidate_locals();
00435       }
00436     };
00437 
00438   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00439     inline void
00440     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00441          unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00442     { __x.swap(__y); }
00443 
00444   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00445     inline bool
00446     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00447                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00448     { return __x._M_base() == __y._M_base(); }
00449 
00450   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00451     inline bool
00452     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00453                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00454     { return !(__x == __y); }
00455 
00456 
00457   /// Class std::unordered_multiset with safety/checking/debug instrumentation.
00458   template<typename _Value,
00459            typename _Hash = std::hash<_Value>,
00460            typename _Pred = std::equal_to<_Value>,
00461            typename _Alloc = std::allocator<_Value> >
00462     class unordered_multiset
00463     : public __gnu_debug::_Safe_container<
00464         unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
00465         __gnu_debug::_Safe_unordered_container>,
00466       public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00467     {
00468       typedef _GLIBCXX_STD_C::unordered_multiset<
00469         _Value, _Hash, _Pred, _Alloc>                           _Base;
00470       typedef __gnu_debug::_Safe_container<unordered_multiset,
00471         _Alloc, __gnu_debug::_Safe_unordered_container>         _Safe;
00472       typedef typename _Base::const_iterator    _Base_const_iterator;
00473       typedef typename _Base::iterator          _Base_iterator;
00474       typedef typename _Base::const_local_iterator
00475                                                 _Base_const_local_iterator;
00476       typedef typename _Base::local_iterator    _Base_local_iterator;
00477 
00478     public:
00479       typedef typename _Base::size_type                 size_type;
00480       typedef typename _Base::hasher                    hasher;
00481       typedef typename _Base::key_equal                 key_equal;
00482       typedef typename _Base::allocator_type            allocator_type;
00483 
00484       typedef typename _Base::key_type                  key_type;
00485       typedef typename _Base::value_type                value_type;
00486 
00487       typedef __gnu_debug::_Safe_iterator<
00488         _Base_iterator, unordered_multiset>             iterator;
00489       typedef __gnu_debug::_Safe_iterator<
00490         _Base_const_iterator, unordered_multiset>       const_iterator;
00491       typedef __gnu_debug::_Safe_local_iterator<
00492         _Base_local_iterator, unordered_multiset>       local_iterator;
00493       typedef __gnu_debug::_Safe_local_iterator<
00494         _Base_const_local_iterator, unordered_multiset> const_local_iterator;
00495 
00496       unordered_multiset() = default;
00497 
00498       explicit
00499       unordered_multiset(size_type __n,
00500                          const hasher& __hf = hasher(),
00501                          const key_equal& __eql = key_equal(),
00502                          const allocator_type& __a = allocator_type())
00503       : _Base(__n, __hf, __eql, __a) { }
00504 
00505       template<typename _InputIterator>
00506         unordered_multiset(_InputIterator __first, _InputIterator __last,
00507                            size_type __n = 0,
00508                            const hasher& __hf = hasher(),
00509                            const key_equal& __eql = key_equal(),
00510                            const allocator_type& __a = allocator_type())
00511         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00512                                                                      __last)),
00513                 __gnu_debug::__base(__last), __n,
00514                 __hf, __eql, __a) { }
00515 
00516       unordered_multiset(const unordered_multiset&) = default;
00517 
00518       unordered_multiset(const _Base& __x)
00519       : _Base(__x) { }
00520 
00521       unordered_multiset(unordered_multiset&&) = default;
00522 
00523       explicit
00524       unordered_multiset(const allocator_type& __a)
00525       : _Base(__a) { }
00526 
00527       unordered_multiset(const unordered_multiset& __uset,
00528                          const allocator_type& __a)
00529       : _Base(__uset, __a) { }
00530 
00531       unordered_multiset(unordered_multiset&& __uset,
00532                          const allocator_type& __a)
00533       : _Safe(std::move(__uset._M_safe()), __a),
00534         _Base(std::move(__uset._M_base()), __a) { }
00535 
00536       unordered_multiset(initializer_list<value_type> __l,
00537                          size_type __n = 0,
00538                          const hasher& __hf = hasher(),
00539                          const key_equal& __eql = key_equal(),
00540                          const allocator_type& __a = allocator_type())
00541       : _Base(__l, __n, __hf, __eql, __a) { }
00542 
00543       ~unordered_multiset() = default;
00544 
00545       unordered_multiset&
00546       operator=(const unordered_multiset&) = default;
00547 
00548       unordered_multiset&
00549       operator=(unordered_multiset&&) = default;
00550 
00551       unordered_multiset&
00552       operator=(initializer_list<value_type> __l)
00553       {
00554         this->_M_base() = __l;
00555         this->_M_invalidate_all();
00556         return *this;
00557       }
00558 
00559       void
00560       swap(unordered_multiset& __x)
00561         noexcept( noexcept(declval<_Base>().swap(__x)) )
00562       {
00563         _Safe::_M_swap(__x);
00564         _Base::swap(__x);
00565       }
00566 
00567       void
00568       clear() noexcept
00569       {
00570         _Base::clear();
00571         this->_M_invalidate_all();
00572       }
00573 
00574       iterator
00575       begin() noexcept
00576       { return iterator(_Base::begin(), this); }
00577 
00578       const_iterator
00579       begin() const noexcept
00580       { return const_iterator(_Base::begin(), this); }
00581 
00582       iterator
00583       end() noexcept
00584       { return iterator(_Base::end(), this); }
00585 
00586       const_iterator
00587       end() const noexcept
00588       { return const_iterator(_Base::end(), this); }
00589 
00590       const_iterator
00591       cbegin() const noexcept
00592       { return const_iterator(_Base::begin(), this); }
00593 
00594       const_iterator
00595       cend() const noexcept
00596       { return const_iterator(_Base::end(), this); }
00597 
00598       // local versions
00599       local_iterator
00600       begin(size_type __b)
00601       {
00602         __glibcxx_check_bucket_index(__b);
00603         return local_iterator(_Base::begin(__b), this);
00604       }
00605 
00606       local_iterator
00607       end(size_type __b)
00608       {
00609         __glibcxx_check_bucket_index(__b);
00610         return local_iterator(_Base::end(__b), this);
00611       }
00612 
00613       const_local_iterator
00614       begin(size_type __b) const
00615       {
00616         __glibcxx_check_bucket_index(__b);
00617         return const_local_iterator(_Base::begin(__b), this);
00618       }
00619 
00620       const_local_iterator
00621       end(size_type __b) const
00622       {
00623         __glibcxx_check_bucket_index(__b);
00624         return const_local_iterator(_Base::end(__b), this);
00625       }
00626 
00627       const_local_iterator
00628       cbegin(size_type __b) const
00629       {
00630         __glibcxx_check_bucket_index(__b);
00631         return const_local_iterator(_Base::cbegin(__b), this);
00632       }
00633 
00634       const_local_iterator
00635       cend(size_type __b) const
00636       {
00637         __glibcxx_check_bucket_index(__b);
00638         return const_local_iterator(_Base::cend(__b), this);
00639       }
00640 
00641       size_type
00642       bucket_size(size_type __b) const
00643       {
00644         __glibcxx_check_bucket_index(__b);
00645         return _Base::bucket_size(__b);
00646       }
00647 
00648       float
00649       max_load_factor() const noexcept
00650       { return _Base::max_load_factor(); }
00651 
00652       void
00653       max_load_factor(float __f)
00654       {
00655         __glibcxx_check_max_load_factor(__f);
00656         _Base::max_load_factor(__f);
00657       }
00658 
00659       template<typename... _Args>
00660         iterator
00661         emplace(_Args&&... __args)
00662         {
00663           size_type __bucket_count = this->bucket_count();
00664           _Base_iterator __it
00665             = _Base::emplace(std::forward<_Args>(__args)...);
00666           _M_check_rehashed(__bucket_count);
00667           return iterator(__it, this);
00668         }
00669 
00670       template<typename... _Args>
00671         iterator
00672         emplace_hint(const_iterator __hint, _Args&&... __args)
00673         {
00674           __glibcxx_check_insert(__hint);
00675           size_type __bucket_count = this->bucket_count();
00676           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
00677                                         std::forward<_Args>(__args)...);
00678           _M_check_rehashed(__bucket_count);
00679           return iterator(__it, this);
00680         }
00681 
00682       iterator
00683       insert(const value_type& __obj)
00684       {
00685         size_type __bucket_count = this->bucket_count();
00686         _Base_iterator __it = _Base::insert(__obj);
00687         _M_check_rehashed(__bucket_count);
00688         return iterator(__it, this);
00689       }
00690 
00691       iterator
00692       insert(const_iterator __hint, const value_type& __obj)
00693       {
00694         __glibcxx_check_insert(__hint);
00695         size_type __bucket_count = this->bucket_count();
00696         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
00697         _M_check_rehashed(__bucket_count);
00698         return iterator(__it, this);
00699       }
00700 
00701       iterator
00702       insert(value_type&& __obj)
00703       {
00704         size_type __bucket_count = this->bucket_count();
00705         _Base_iterator __it = _Base::insert(std::move(__obj));
00706         _M_check_rehashed(__bucket_count);
00707         return iterator(__it, this);
00708       }
00709 
00710       iterator
00711       insert(const_iterator __hint, value_type&& __obj)
00712       {
00713         __glibcxx_check_insert(__hint);
00714         size_type __bucket_count = this->bucket_count();
00715         _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
00716         _M_check_rehashed(__bucket_count);
00717         return iterator(__it, this);
00718       }
00719 
00720       void
00721       insert(std::initializer_list<value_type> __l)
00722       {
00723         size_type __bucket_count = this->bucket_count();
00724         _Base::insert(__l);
00725         _M_check_rehashed(__bucket_count);
00726       }
00727 
00728       template<typename _InputIterator>
00729         void
00730         insert(_InputIterator __first, _InputIterator __last)
00731         {
00732           __glibcxx_check_valid_range(__first, __last);
00733           size_type __bucket_count = this->bucket_count();
00734           _Base::insert(__gnu_debug::__base(__first),
00735                         __gnu_debug::__base(__last));
00736           _M_check_rehashed(__bucket_count);
00737         }
00738 
00739       iterator
00740       find(const key_type& __key)
00741       { return iterator(_Base::find(__key), this); }
00742 
00743       const_iterator
00744       find(const key_type& __key) const
00745       { return const_iterator(_Base::find(__key), this); }
00746 
00747       std::pair<iterator, iterator>
00748       equal_range(const key_type& __key)
00749       {
00750         std::pair<_Base_iterator, _Base_iterator> __res
00751           = _Base::equal_range(__key);
00752         return std::make_pair(iterator(__res.first, this),
00753                               iterator(__res.second, this));
00754       }
00755 
00756       std::pair<const_iterator, const_iterator>
00757       equal_range(const key_type& __key) const
00758       {
00759         std::pair<_Base_const_iterator, _Base_const_iterator>
00760           __res = _Base::equal_range(__key);
00761         return std::make_pair(const_iterator(__res.first, this),
00762                               const_iterator(__res.second, this));
00763       }
00764 
00765       size_type
00766       erase(const key_type& __key)
00767       {
00768         size_type __ret(0);
00769         std::pair<_Base_iterator, _Base_iterator> __pair =
00770           _Base::equal_range(__key);
00771         for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
00772           {
00773             this->_M_invalidate_if([__victim](_Base_const_iterator __it)
00774                             { return __it == __victim; });
00775             this->_M_invalidate_local_if(
00776                             [__victim](_Base_const_local_iterator __it)
00777                             { return __it._M_curr() == __victim._M_cur; });
00778             _Base::erase(__victim++);
00779             ++__ret;
00780           }
00781         return __ret;
00782       }
00783 
00784       iterator
00785       erase(const_iterator __it)
00786       {
00787         __glibcxx_check_erase(__it);
00788         _Base_const_iterator __victim = __it.base();
00789         this->_M_invalidate_if([__victim](_Base_const_iterator __it)
00790                         { return __it == __victim; });
00791         this->_M_invalidate_local_if(
00792                         [__victim](_Base_const_local_iterator __it)
00793                         { return __it._M_curr() == __victim._M_cur; });
00794         return iterator(_Base::erase(__it.base()), this);
00795       }
00796 
00797       iterator
00798       erase(iterator __it)
00799       { return erase(const_iterator(__it)); }
00800 
00801       iterator
00802       erase(const_iterator __first, const_iterator __last)
00803       {
00804         __glibcxx_check_erase_range(__first, __last);
00805         for (_Base_const_iterator __tmp = __first.base();
00806              __tmp != __last.base(); ++__tmp)
00807           {
00808             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
00809                                   _M_message(__gnu_debug::__msg_valid_range)
00810                                   ._M_iterator(__first, "first")
00811                                   ._M_iterator(__last, "last"));
00812             this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
00813                             { return __it == __tmp; });
00814             this->_M_invalidate_local_if(
00815                             [__tmp](_Base_const_local_iterator __it)
00816                             { return __it._M_curr() == __tmp._M_cur; });
00817           }
00818         return iterator(_Base::erase(__first.base(),
00819                                      __last.base()), this);
00820       }
00821 
00822       _Base&
00823       _M_base() noexcept        { return *this; }
00824 
00825       const _Base&
00826       _M_base() const noexcept  { return *this; }
00827 
00828     private:
00829       void
00830       _M_check_rehashed(size_type __prev_count)
00831       {
00832         if (__prev_count != this->bucket_count())
00833           this->_M_invalidate_locals();
00834       }
00835     };
00836 
00837   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00838     inline void
00839     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00840          unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00841     { __x.swap(__y); }
00842 
00843   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00844     inline bool
00845     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00846                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00847     { return __x._M_base() == __y._M_base(); }
00848 
00849   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
00850     inline bool
00851     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00852                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00853     { return !(__x == __y); }
00854 
00855 } // namespace __debug
00856 } // namespace std
00857 
00858 #endif // C++11
00859 
00860 #endif