1861b860e4cc01c7ba297005abb94713b14d61d1
[platform/upstream/gcc48.git] / libstdc++-v3 / include / debug / unordered_map
1 // Debugging unordered_map/unordered_multimap implementation -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /** @file debug/unordered_map
27  *  This file is a GNU debug extension to the Standard C++ Library.
28  */
29
30 #ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
31 #define _GLIBCXX_DEBUG_UNORDERED_MAP 1
32
33 #ifndef __GXX_EXPERIMENTAL_CXX0X__
34 # include <bits/c++0x_warning.h>
35 #else
36 # include <unordered_map>
37
38 #include <debug/safe_unordered_container.h>
39 #include <debug/safe_iterator.h>
40 #include <debug/safe_local_iterator.h>
41
42 namespace std _GLIBCXX_VISIBILITY(default)
43 {
44 namespace __debug
45 {
46   /// Class std::unordered_map with safety/checking/debug instrumentation.
47   template<typename _Key, typename _Tp,
48            typename _Hash = std::hash<_Key>,
49            typename _Pred = std::equal_to<_Key>,
50            typename _Alloc = std::allocator<_Key> >
51     class unordered_map
52     : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
53       public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
54                                                         _Hash, _Pred, _Alloc> >
55     {
56       typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
57                                             _Pred, _Alloc> _Base;
58       typedef __gnu_debug::_Safe_unordered_container<unordered_map> _Safe_base;
59       typedef typename _Base::const_iterator _Base_const_iterator;
60       typedef typename _Base::iterator _Base_iterator;
61       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
62       typedef typename _Base::local_iterator _Base_local_iterator;
63
64     public:
65       typedef typename _Base::size_type       size_type;
66       typedef typename _Base::hasher          hasher;
67       typedef typename _Base::key_equal       key_equal;
68       typedef typename _Base::allocator_type  allocator_type;
69
70       typedef typename _Base::key_type        key_type;
71       typedef typename _Base::value_type      value_type;
72
73       typedef __gnu_debug::_Safe_iterator<_Base_iterator,
74                                           unordered_map> iterator;
75       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
76                                           unordered_map> const_iterator;
77       typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
78                                           unordered_map> local_iterator;
79       typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
80                                           unordered_map> const_local_iterator;
81
82       explicit
83       unordered_map(size_type __n = 10,
84                     const hasher& __hf = hasher(),
85                     const key_equal& __eql = key_equal(),
86                     const allocator_type& __a = allocator_type())
87       : _Base(__n, __hf, __eql, __a) { }
88
89       template<typename _InputIterator>
90         unordered_map(_InputIterator __first, _InputIterator __last, 
91                       size_type __n = 0,
92                       const hasher& __hf = hasher(), 
93                       const key_equal& __eql = key_equal(), 
94                       const allocator_type& __a = allocator_type())
95         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
96                                                                      __last)),
97                 __gnu_debug::__base(__last), __n,
98                 __hf, __eql, __a) { }
99
100       unordered_map(const unordered_map& __x) 
101       : _Base(__x) { }
102
103       unordered_map(const _Base& __x)
104       : _Base(__x) { }
105
106       unordered_map(unordered_map&& __x)
107       : _Base(std::move(__x)) { }
108
109       unordered_map(initializer_list<value_type> __l,
110                     size_type __n = 0,
111                     const hasher& __hf = hasher(),
112                     const key_equal& __eql = key_equal(),
113                     const allocator_type& __a = allocator_type())
114       : _Base(__l, __n, __hf, __eql, __a) { }
115
116       ~unordered_map() noexcept { }
117
118       unordered_map&
119       operator=(const unordered_map& __x)
120       {
121         *static_cast<_Base*>(this) = __x;
122         this->_M_invalidate_all();
123         return *this;
124       }
125
126       unordered_map&
127       operator=(unordered_map&& __x)
128       {
129         // NB: DR 1204.
130         // NB: DR 675.
131         clear();
132         swap(__x);
133         return *this;
134       }
135
136       unordered_map&
137       operator=(initializer_list<value_type> __l)
138       {
139         this->clear();
140         this->insert(__l);
141         return *this;
142       }
143
144       void
145       swap(unordered_map& __x)
146       {
147         _Base::swap(__x);
148         _Safe_base::_M_swap(__x);
149       }
150
151       void
152       clear() noexcept
153       {
154         _Base::clear();
155         this->_M_invalidate_all();
156       }
157
158       iterator 
159       begin() noexcept
160       { return iterator(_Base::begin(), this); }
161
162       const_iterator
163       begin() const noexcept
164       { return const_iterator(_Base::begin(), this); }
165
166       iterator
167       end() noexcept
168       { return iterator(_Base::end(), this); }
169
170       const_iterator
171       end() const noexcept
172       { return const_iterator(_Base::end(), this); }
173
174       const_iterator
175       cbegin() const noexcept
176       { return const_iterator(_Base::begin(), this); }
177
178       const_iterator
179       cend() const noexcept
180       { return const_iterator(_Base::end(), this); }
181
182       // local versions
183       local_iterator
184       begin(size_type __b)
185       { return local_iterator(_Base::begin(__b), __b, this); }
186
187       local_iterator
188       end(size_type __b)
189       { return local_iterator(_Base::end(__b), __b, this); }
190
191       const_local_iterator
192       begin(size_type __b) const
193       { return const_local_iterator(_Base::begin(__b), __b, this); }
194
195       const_local_iterator
196       end(size_type __b) const
197       { return const_local_iterator(_Base::end(__b), __b, this); }
198
199       const_local_iterator
200       cbegin(size_type __b) const
201       { return const_local_iterator(_Base::cbegin(__b), __b, this); }
202
203       const_local_iterator
204       cend(size_type __b) const
205       { return const_local_iterator(_Base::cend(__b), __b, this); }
206
207       template<typename... _Args>
208         std::pair<iterator, bool>
209         emplace(_Args&&... __args)
210         {
211           size_type __bucket_count = this->bucket_count();
212           std::pair<_Base_iterator, bool> __res
213             = _Base::emplace(std::forward<_Args>(__args)...);
214           _M_check_rehashed(__bucket_count);
215           return std::make_pair(iterator(__res.first, this), __res.second);
216         }
217
218       template<typename... _Args>
219         iterator
220         emplace_hint(const_iterator __hint, _Args&&... __args)
221         {
222           __glibcxx_check_insert(__hint);
223           size_type __bucket_count = this->bucket_count();
224           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
225                                         std::forward<_Args>(__args)...);
226           _M_check_rehashed(__bucket_count);
227           return iterator(__it, this);
228         }
229
230       std::pair<iterator, bool>
231       insert(const value_type& __obj)
232       {
233         size_type __bucket_count = this->bucket_count();
234         std::pair<_Base_iterator, bool> __res = _Base::insert(__obj);
235         _M_check_rehashed(__bucket_count);
236         return std::make_pair(iterator(__res.first, this), __res.second);
237       }
238
239       iterator
240       insert(const_iterator __hint, const value_type& __obj)
241       {
242         __glibcxx_check_insert(__hint);
243         size_type __bucket_count = this->bucket_count();
244         _Base_iterator __it = _Base::insert(__hint.base(), __obj); 
245         _M_check_rehashed(__bucket_count);
246         return iterator(__it, this);
247       }
248
249       template<typename _Pair, typename = typename
250                std::enable_if<std::is_constructible<value_type,
251                                                     _Pair&&>::value>::type>
252         std::pair<iterator, bool>
253         insert(_Pair&& __obj)
254         {
255           size_type __bucket_count = this->bucket_count();
256           std::pair<_Base_iterator, bool> __res =
257             _Base::insert(std::forward<_Pair>(__obj));
258           _M_check_rehashed(__bucket_count);
259           return std::make_pair(iterator(__res.first, this), __res.second);
260         }
261
262       template<typename _Pair, typename = typename
263                std::enable_if<std::is_constructible<value_type,
264                                                     _Pair&&>::value>::type>
265         iterator
266         insert(const_iterator __hint, _Pair&& __obj)
267         {
268           __glibcxx_check_insert(__hint);
269           size_type __bucket_count = this->bucket_count();
270           _Base_iterator __it =
271             _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
272           _M_check_rehashed(__bucket_count);
273           return iterator(__it, this);
274         }
275
276       void
277       insert(std::initializer_list<value_type> __l)
278       {
279         size_type __bucket_count = this->bucket_count();
280         _Base::insert(__l);
281         _M_check_rehashed(__bucket_count);
282       }
283
284       template<typename _InputIterator>
285         void
286         insert(_InputIterator __first, _InputIterator __last)
287         {
288           __glibcxx_check_valid_range(__first, __last);
289           size_type __bucket_count = this->bucket_count();
290           _Base::insert(__gnu_debug::__base(__first),
291                         __gnu_debug::__base(__last));
292           _M_check_rehashed(__bucket_count);
293         }
294
295       iterator
296       find(const key_type& __key)
297       { return iterator(_Base::find(__key), this); }
298
299       const_iterator
300       find(const key_type& __key) const
301       { return const_iterator(_Base::find(__key), this); }
302
303       std::pair<iterator, iterator>
304       equal_range(const key_type& __key)
305       {
306         std::pair<_Base_iterator, _Base_iterator> __res =
307           _Base::equal_range(__key);
308         return std::make_pair(iterator(__res.first, this),
309                               iterator(__res.second, this));
310       }
311
312       std::pair<const_iterator, const_iterator>
313       equal_range(const key_type& __key) const
314       {
315         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
316           _Base::equal_range(__key);
317         return std::make_pair(const_iterator(__res.first, this),
318                               const_iterator(__res.second, this));
319       }
320
321       size_type
322       erase(const key_type& __key)
323       {
324         size_type __ret(0);
325         _Base_iterator __victim(_Base::find(__key));
326         if (__victim != _Base::end())
327           {
328             this->_M_invalidate_if([__victim](_Base_const_iterator __it)
329                             { return __it == __victim; });
330             _Base_local_iterator __local_victim = _S_to_local(__victim);
331             this->_M_invalidate_local_if(
332                             [__local_victim](_Base_const_local_iterator __it)
333                             { return __it == __local_victim; });
334             size_type __bucket_count = this->bucket_count();
335             _Base::erase(__victim);
336             _M_check_rehashed(__bucket_count);
337             __ret = 1;
338           }
339         return __ret;
340       }
341
342       iterator
343       erase(const_iterator __it)
344       {
345         __glibcxx_check_erase(__it);
346         _Base_const_iterator __victim = __it.base();
347         this->_M_invalidate_if([__victim](_Base_const_iterator __it)
348                         { return __it == __victim; });
349         _Base_const_local_iterator __local_victim = _S_to_local(__victim);
350         this->_M_invalidate_local_if(
351                         [__local_victim](_Base_const_local_iterator __it)
352                         { return __it == __local_victim; });
353         size_type __bucket_count = this->bucket_count();
354         _Base_iterator __next = _Base::erase(__it.base()); 
355         _M_check_rehashed(__bucket_count);
356         return iterator(__next, this);
357       }
358
359       iterator
360       erase(iterator __it)
361       { return erase(const_iterator(__it)); }
362
363       iterator
364       erase(const_iterator __first, const_iterator __last)
365       {
366         __glibcxx_check_erase_range(__first, __last);
367         for (_Base_const_iterator __tmp = __first.base();
368              __tmp != __last.base(); ++__tmp)
369           {
370             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
371                                   _M_message(__gnu_debug::__msg_valid_range)
372                                   ._M_iterator(__first, "first")
373                                   ._M_iterator(__last, "last"));
374             this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
375                             { return __it == __tmp; });
376             _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
377             this->_M_invalidate_local_if(
378                             [__local_tmp](_Base_const_local_iterator __it)
379                             { return __it == __local_tmp; });
380           }
381         size_type __bucket_count = this->bucket_count();
382         _Base_iterator __next = _Base::erase(__first.base(), __last.base());
383         _M_check_rehashed(__bucket_count);
384         return iterator(__next, this);
385       }
386
387       _Base&
388       _M_base() noexcept       { return *this; }
389
390       const _Base&
391       _M_base() const noexcept { return *this; }
392
393     private:
394       void
395       _M_invalidate_locals()
396       {
397         _Base_local_iterator __local_end = _Base::end(0);
398         this->_M_invalidate_local_if(
399                         [__local_end](_Base_const_local_iterator __it)
400                         { return __it != __local_end; });
401       }
402
403       void
404       _M_invalidate_all()
405       {
406         _Base_iterator __end = _Base::end();
407         this->_M_invalidate_if([__end](_Base_const_iterator __it)
408                         { return __it != __end; });
409         _M_invalidate_locals();
410       }
411
412       void
413       _M_check_rehashed(size_type __prev_count)
414       {
415         if (__prev_count != this->bucket_count())
416           _M_invalidate_locals();
417       }
418
419       static _Base_local_iterator
420       _S_to_local(_Base_iterator __it)
421       {
422         // The returned local iterator will not be incremented so we don't
423         // need to compute __it's node bucket
424         return _Base_local_iterator(__it._M_cur, 0, 0);
425       }
426
427       static _Base_const_local_iterator
428       _S_to_local(_Base_const_iterator __it)
429       {
430         // The returned local iterator will not be incremented so we don't
431         // need to compute __it's node bucket
432         return _Base_const_local_iterator(__it._M_cur, 0, 0);
433       }
434     };
435
436   template<typename _Key, typename _Tp, typename _Hash,
437            typename _Pred, typename _Alloc>
438     inline void
439     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
440          unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
441     { __x.swap(__y); }
442
443   template<typename _Key, typename _Tp, typename _Hash,
444            typename _Pred, typename _Alloc>
445     inline bool
446     operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
447                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
448     { return __x._M_equal(__y); }
449
450   template<typename _Key, typename _Tp, typename _Hash,
451            typename _Pred, typename _Alloc>
452     inline bool
453     operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
454                const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
455     { return !(__x == __y); }
456
457
458   /// Class std::unordered_multimap with safety/checking/debug instrumentation.
459   template<typename _Key, typename _Tp,
460            typename _Hash = std::hash<_Key>,
461            typename _Pred = std::equal_to<_Key>,
462            typename _Alloc = std::allocator<_Key> >
463     class unordered_multimap
464     : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
465                                                 _Pred, _Alloc>,
466       public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
467                                                 _Tp, _Hash, _Pred, _Alloc> >
468     {
469       typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
470                                                  _Pred, _Alloc> _Base;
471       typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
472         _Safe_base;
473       typedef typename _Base::const_iterator _Base_const_iterator;
474       typedef typename _Base::iterator _Base_iterator;
475       typedef typename _Base::const_local_iterator _Base_const_local_iterator;
476       typedef typename _Base::local_iterator _Base_local_iterator;
477
478     public:
479       typedef typename _Base::size_type       size_type;
480       typedef typename _Base::hasher          hasher;
481       typedef typename _Base::key_equal       key_equal;
482       typedef typename _Base::allocator_type  allocator_type;
483
484       typedef typename _Base::key_type        key_type;
485       typedef typename _Base::value_type      value_type;
486
487       typedef __gnu_debug::_Safe_iterator<_Base_iterator,
488                                           unordered_multimap> iterator;
489       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
490                                           unordered_multimap> const_iterator;
491       typedef __gnu_debug::_Safe_local_iterator<
492         _Base_local_iterator, unordered_multimap> local_iterator;
493       typedef __gnu_debug::_Safe_local_iterator<
494         _Base_const_local_iterator, unordered_multimap> const_local_iterator;
495
496       explicit
497       unordered_multimap(size_type __n = 10,
498                          const hasher& __hf = hasher(),
499                          const key_equal& __eql = key_equal(),
500                          const allocator_type& __a = allocator_type())
501       : _Base(__n, __hf, __eql, __a) { }
502
503       template<typename _InputIterator>
504         unordered_multimap(_InputIterator __first, _InputIterator __last, 
505                            size_type __n = 0,
506                            const hasher& __hf = hasher(), 
507                            const key_equal& __eql = key_equal(), 
508                            const allocator_type& __a = allocator_type())
509         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
510                                                                      __last)),
511                 __gnu_debug::__base(__last), __n,
512                 __hf, __eql, __a) { }
513
514       unordered_multimap(const unordered_multimap& __x) 
515       : _Base(__x) { }
516
517       unordered_multimap(const _Base& __x) 
518       : _Base(__x) { }
519
520       unordered_multimap(unordered_multimap&& __x)
521       : _Base(std::move(__x)) { }
522
523       unordered_multimap(initializer_list<value_type> __l,
524                          size_type __n = 0,
525                          const hasher& __hf = hasher(),
526                          const key_equal& __eql = key_equal(),
527                          const allocator_type& __a = allocator_type())
528       : _Base(__l, __n, __hf, __eql, __a) { }
529
530       ~unordered_multimap() noexcept { }
531
532       unordered_multimap&
533       operator=(const unordered_multimap& __x)
534       {
535         *static_cast<_Base*>(this) = __x;
536         this->_M_invalidate_all();
537         return *this;
538       }
539
540       unordered_multimap&
541       operator=(unordered_multimap&& __x)
542       {
543         // NB: DR 1204.
544         // NB: DR 675.
545         clear();
546         swap(__x);
547         return *this;
548       }
549
550       unordered_multimap&
551       operator=(initializer_list<value_type> __l)
552       {
553         this->clear();
554         this->insert(__l);
555         return *this;
556       }
557
558       void
559       swap(unordered_multimap& __x)
560       {
561         _Base::swap(__x);
562         _Safe_base::_M_swap(__x);
563       }
564
565       void
566       clear() noexcept
567       {
568         _Base::clear();
569         this->_M_invalidate_all();
570       }
571
572       iterator 
573       begin() noexcept
574       { return iterator(_Base::begin(), this); }
575
576       const_iterator
577       begin() const noexcept
578       { return const_iterator(_Base::begin(), this); }
579
580       iterator
581       end() noexcept
582       { return iterator(_Base::end(), this); }
583
584       const_iterator
585       end() const noexcept
586       { return const_iterator(_Base::end(), this); }
587
588       const_iterator
589       cbegin() const noexcept
590       { return const_iterator(_Base::begin(), this); }
591
592       const_iterator
593       cend() const noexcept
594       { return const_iterator(_Base::end(), this); }
595
596       // local versions
597       local_iterator
598       begin(size_type __b)
599       { return local_iterator(_Base::begin(__b), __b, this); }
600
601       local_iterator
602       end(size_type __b)
603       { return local_iterator(_Base::end(__b), __b, this); }
604
605       const_local_iterator
606       begin(size_type __b) const
607       { return const_local_iterator(_Base::begin(__b), __b, this); }
608
609       const_local_iterator
610       end(size_type __b) const
611       { return const_local_iterator(_Base::end(__b), __b, this); }
612
613       const_local_iterator
614       cbegin(size_type __b) const
615       { return const_local_iterator(_Base::cbegin(__b), __b, this); }
616
617       const_local_iterator
618       cend(size_type __b) const
619       { return const_local_iterator(_Base::cend(__b), __b, this); }
620
621       template<typename... _Args>
622         iterator
623         emplace(_Args&&... __args)
624         {
625           size_type __bucket_count = this->bucket_count();
626           _Base_iterator __it
627             = _Base::emplace(std::forward<_Args>(__args)...);
628           _M_check_rehashed(__bucket_count);
629           return iterator(__it, this);
630         }
631
632       template<typename... _Args>
633         iterator
634         emplace_hint(const_iterator __hint, _Args&&... __args)
635         {
636           __glibcxx_check_insert(__hint);
637           size_type __bucket_count = this->bucket_count();
638           _Base_iterator __it = _Base::emplace_hint(__hint.base(),
639                                         std::forward<_Args>(__args)...);
640           _M_check_rehashed(__bucket_count);
641           return iterator(__it, this);
642         }
643
644       iterator
645       insert(const value_type& __obj)
646       {
647         size_type __bucket_count = this->bucket_count();
648         _Base_iterator __it = _Base::insert(__obj);
649         _M_check_rehashed(__bucket_count);
650         return iterator(__it, this);
651       }
652
653       iterator
654       insert(const_iterator __hint, const value_type& __obj)
655       {
656         __glibcxx_check_insert(__hint);
657         size_type __bucket_count = this->bucket_count();
658         _Base_iterator __it = _Base::insert(__hint.base(), __obj);
659         _M_check_rehashed(__bucket_count);
660         return iterator(__it, this);
661       }
662
663       template<typename _Pair, typename = typename
664                std::enable_if<std::is_constructible<value_type,
665                                                     _Pair&&>::value>::type>
666         iterator
667         insert(_Pair&& __obj)
668         {
669           size_type __bucket_count = this->bucket_count();
670           _Base_iterator __it = _Base::insert(std::forward<_Pair>(__obj));
671           _M_check_rehashed(__bucket_count);
672           return iterator(__it, this);
673         }
674
675       template<typename _Pair, typename = typename
676                std::enable_if<std::is_constructible<value_type,
677                                                     _Pair&&>::value>::type>
678         iterator
679         insert(const_iterator __hint, _Pair&& __obj)
680         {
681           __glibcxx_check_insert(__hint);
682           size_type __bucket_count = this->bucket_count();
683           _Base_iterator __it =
684             _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
685           _M_check_rehashed(__bucket_count);
686           return iterator(__it, this);
687         }
688
689       void
690       insert(std::initializer_list<value_type> __l)
691       { _Base::insert(__l); }
692
693       template<typename _InputIterator>
694         void
695         insert(_InputIterator __first, _InputIterator __last)
696         {
697           __glibcxx_check_valid_range(__first, __last);
698           size_type __bucket_count = this->bucket_count();
699           _Base::insert(__gnu_debug::__base(__first),
700                         __gnu_debug::__base(__last));
701           _M_check_rehashed(__bucket_count);
702         }
703
704       iterator
705       find(const key_type& __key)
706       { return iterator(_Base::find(__key), this); }
707
708       const_iterator
709       find(const key_type& __key) const
710       { return const_iterator(_Base::find(__key), this); }
711
712       std::pair<iterator, iterator>
713       equal_range(const key_type& __key)
714       {
715         std::pair<_Base_iterator, _Base_iterator> __res =
716           _Base::equal_range(__key);
717         return std::make_pair(iterator(__res.first, this),
718                               iterator(__res.second, this));
719       }
720
721       std::pair<const_iterator, const_iterator>
722       equal_range(const key_type& __key) const
723       {
724         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
725           _Base::equal_range(__key);
726         return std::make_pair(const_iterator(__res.first, this),
727                               const_iterator(__res.second, this));
728       }
729
730       size_type
731       erase(const key_type& __key)
732       {
733         size_type __ret(0);
734         size_type __bucket_count = this->bucket_count();
735         std::pair<_Base_iterator, _Base_iterator> __pair =
736           _Base::equal_range(__key);
737         for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
738           {
739             this->_M_invalidate_if([__victim](_Base_const_iterator __it)
740                             { return __it == __victim; });
741             _Base_local_iterator __local_victim = _S_to_local(__victim);
742             this->_M_invalidate_local_if(
743                             [__local_victim](_Base_const_local_iterator __it)
744                             { return __it == __local_victim; });
745             _Base::erase(__victim++);
746             ++__ret;
747           }
748         _M_check_rehashed(__bucket_count);
749         return __ret;
750       }
751
752       iterator
753       erase(const_iterator __it)
754       {
755         __glibcxx_check_erase(__it);
756         _Base_const_iterator __victim = __it.base();
757         this->_M_invalidate_if([__victim](_Base_const_iterator __it)
758                         { return __it == __victim; });
759         _Base_const_local_iterator __local_victim = _S_to_local(__victim);
760         this->_M_invalidate_local_if(
761                         [__local_victim](_Base_const_local_iterator __it)
762                         { return __it == __local_victim; });
763         size_type __bucket_count = this->bucket_count();
764         _Base_iterator __next = _Base::erase(__it.base());
765         _M_check_rehashed(__bucket_count);
766         return iterator(__next, this);
767       }
768
769       iterator
770       erase(iterator __it)
771       { return erase(const_iterator(__it)); }
772
773       iterator
774       erase(const_iterator __first, const_iterator __last)
775       {
776         __glibcxx_check_erase_range(__first, __last);
777         for (_Base_const_iterator __tmp = __first.base();
778              __tmp != __last.base(); ++__tmp)
779           {
780             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
781                                   _M_message(__gnu_debug::__msg_valid_range)
782                                   ._M_iterator(__first, "first")
783                                   ._M_iterator(__last, "last"));
784             this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
785                             { return __it == __tmp; });
786             _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
787             this->_M_invalidate_local_if(
788                             [__local_tmp](_Base_const_local_iterator __it)
789                             { return __it == __local_tmp; });
790           }
791         size_type __bucket_count = this->bucket_count();
792         _Base_iterator __next = _Base::erase(__first.base(), __last.base());
793         _M_check_rehashed(__bucket_count);
794         return iterator(__next, this);
795       }
796
797       _Base&
798       _M_base() noexcept       { return *this; }
799
800       const _Base&
801       _M_base() const noexcept { return *this; }
802
803     private:
804       void
805       _M_invalidate_locals()
806       {
807         _Base_local_iterator __local_end = _Base::end(0);
808         this->_M_invalidate_local_if(
809                         [__local_end](_Base_const_local_iterator __it)
810                         { return __it != __local_end; });
811       }
812
813       void
814       _M_invalidate_all()
815       {
816         _Base_iterator __end = _Base::end();
817         this->_M_invalidate_if([__end](_Base_const_iterator __it)
818                         { return __it != __end; });
819         _M_invalidate_locals();
820       }
821
822       void
823       _M_check_rehashed(size_type __prev_count)
824       {
825         if (__prev_count != this->bucket_count())
826           _M_invalidate_locals();
827       }
828
829       static _Base_local_iterator
830       _S_to_local(_Base_iterator __it)
831       {
832         // The returned local iterator will not be incremented so we don't
833         // need to compute __it's node bucket
834         return _Base_local_iterator(__it._M_cur, 0, 0);
835       }
836
837       static _Base_const_local_iterator
838       _S_to_local(_Base_const_iterator __it)
839       {
840         // The returned local iterator will not be incremented so we don't
841         // need to compute __it's node bucket
842         return _Base_const_local_iterator(__it._M_cur, 0, 0);
843       }
844     };
845
846   template<typename _Key, typename _Tp, typename _Hash,
847            typename _Pred, typename _Alloc>
848     inline void
849     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
850          unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
851     { __x.swap(__y); }
852
853   template<typename _Key, typename _Tp, typename _Hash,
854            typename _Pred, typename _Alloc>
855     inline bool
856     operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
857                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
858     { return __x._M_equal(__y); }
859
860   template<typename _Key, typename _Tp, typename _Hash,
861            typename _Pred, typename _Alloc>
862     inline bool
863     operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
864                const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
865     { return !(__x == __y); }
866
867 } // namespace __debug
868 } // namespace std
869
870 #endif // __GXX_EXPERIMENTAL_CXX0X__
871
872 #endif