]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/debug/unordered_map
* many: Replace uses of __GXX_EXPERIMENTAL_CXX0X__ with __cplusplus.
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / unordered_map
CommitLineData
e63637ea
BK
1// Debugging unordered_map/unordered_multimap implementation -*- C++ -*-
2
739fd6a6 3// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
e63637ea
BK
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
748086b7 9// Free Software Foundation; either version 3, or (at your option)
e63637ea
BK
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
748086b7
JJ
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/>.
e63637ea
BK
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
734f5023 33#if __cplusplus < 201103L
ab65a4c7 34# include <bits/c++0x_warning.h>
c878d6ba
PC
35#else
36# include <unordered_map>
e63637ea 37
364c862b 38#include <debug/safe_unordered_container.h>
ced3cb9f 39#include <debug/safe_iterator.h>
77e0bf4e 40#include <debug/safe_local_iterator.h>
e63637ea 41
12ffa228 42namespace std _GLIBCXX_VISIBILITY(default)
e63637ea
BK
43{
44namespace __debug
45{
1ceb9e06 46 /// Class std::unordered_map with safety/checking/debug instrumentation.
e63637ea 47 template<typename _Key, typename _Tp,
ced3cb9f 48 typename _Hash = std::hash<_Key>,
e63637ea 49 typename _Pred = std::equal_to<_Key>,
ced3cb9f 50 typename _Alloc = std::allocator<_Key> >
e63637ea 51 class unordered_map
12ffa228 52 : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
364c862b 53 public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
77e0bf4e 54 _Hash, _Pred, _Alloc> >
e63637ea 55 {
12ffa228 56 typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
ced3cb9f 57 _Pred, _Alloc> _Base;
364c862b 58 typedef __gnu_debug::_Safe_unordered_container<unordered_map> _Safe_base;
afe96d41
FD
59 typedef typename _Base::const_iterator _Base_const_iterator;
60 typedef typename _Base::iterator _Base_iterator;
77e0bf4e
FD
61 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
62 typedef typename _Base::local_iterator _Base_local_iterator;
e63637ea
BK
63
64 public:
ced3cb9f
PC
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
afe96d41 73 typedef __gnu_debug::_Safe_iterator<_Base_iterator,
ced3cb9f 74 unordered_map> iterator;
afe96d41 75 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
ced3cb9f 76 unordered_map> const_iterator;
77e0bf4e
FD
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;
e63637ea
BK
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())
ced3cb9f 87 : _Base(__n, __hf, __eql, __a) { }
e63637ea
BK
88
89 template<typename _InputIterator>
77e0bf4e 90 unordered_map(_InputIterator __first, _InputIterator __last,
417e896e 91 size_type __n = 0,
e63637ea
BK
92 const hasher& __hf = hasher(),
93 const key_equal& __eql = key_equal(),
94 const allocator_type& __a = allocator_type())
1f5ca1a1
PC
95 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
96 __last)),
97 __gnu_debug::__base(__last), __n,
4c2d93db 98 __hf, __eql, __a) { }
e63637ea 99
ced3cb9f 100 unordered_map(const unordered_map& __x)
4c2d93db 101 : _Base(__x) { }
e63637ea 102
ced3cb9f 103 unordered_map(const _Base& __x)
4c2d93db 104 : _Base(__x) { }
ced3cb9f
PC
105
106 unordered_map(unordered_map&& __x)
4c2d93db 107 : _Base(std::move(__x)) { }
69b3331e 108
988499f4 109 unordered_map(initializer_list<value_type> __l,
417e896e 110 size_type __n = 0,
988499f4
JM
111 const hasher& __hf = hasher(),
112 const key_equal& __eql = key_equal(),
113 const allocator_type& __a = allocator_type())
4c2d93db 114 : _Base(__l, __n, __hf, __eql, __a) { }
ced3cb9f 115
6f59ea25
PC
116 ~unordered_map() noexcept { }
117
ced3cb9f
PC
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 }
988499f4 125
69b3331e
PC
126 unordered_map&
127 operator=(unordered_map&& __x)
128 {
0462fd5e
PC
129 // NB: DR 1204.
130 // NB: DR 675.
739fd6a6 131 __glibcxx_check_self_move_assign(__x);
0462fd5e
PC
132 clear();
133 swap(__x);
69b3331e
PC
134 return *this;
135 }
136
988499f4
JM
137 unordered_map&
138 operator=(initializer_list<value_type> __l)
139 {
140 this->clear();
141 this->insert(__l);
142 return *this;
143 }
144
e63637ea 145 void
ff74fd13 146 swap(unordered_map& __x)
e63637ea 147 {
ced3cb9f 148 _Base::swap(__x);
e63637ea
BK
149 _Safe_base::_M_swap(__x);
150 }
69b3331e
PC
151
152 void
d3677132 153 clear() noexcept
69b3331e
PC
154 {
155 _Base::clear();
156 this->_M_invalidate_all();
157 }
158
ced3cb9f 159 iterator
d3677132 160 begin() noexcept
ced3cb9f
PC
161 { return iterator(_Base::begin(), this); }
162
163 const_iterator
d3677132 164 begin() const noexcept
ced3cb9f
PC
165 { return const_iterator(_Base::begin(), this); }
166
167 iterator
d3677132 168 end() noexcept
ced3cb9f
PC
169 { return iterator(_Base::end(), this); }
170
171 const_iterator
d3677132 172 end() const noexcept
ced3cb9f
PC
173 { return const_iterator(_Base::end(), this); }
174
175 const_iterator
d3677132 176 cbegin() const noexcept
ced3cb9f
PC
177 { return const_iterator(_Base::begin(), this); }
178
179 const_iterator
d3677132 180 cend() const noexcept
ced3cb9f
PC
181 { return const_iterator(_Base::end(), this); }
182
183 // local versions
77e0bf4e
FD
184 local_iterator
185 begin(size_type __b)
7181e991
FD
186 {
187 __glibcxx_check_bucket_index(__b);
188 return local_iterator(_Base::begin(__b), __b, this);
189 }
77e0bf4e
FD
190
191 local_iterator
192 end(size_type __b)
7181e991
FD
193 {
194 __glibcxx_check_bucket_index(__b);
195 return local_iterator(_Base::end(__b), __b, this);
196 }
77e0bf4e
FD
197
198 const_local_iterator
199 begin(size_type __b) const
7181e991
FD
200 {
201 __glibcxx_check_bucket_index(__b);
202 return const_local_iterator(_Base::begin(__b), __b, this);
203 }
77e0bf4e
FD
204
205 const_local_iterator
206 end(size_type __b) const
7181e991
FD
207 {
208 __glibcxx_check_bucket_index(__b);
209 return const_local_iterator(_Base::end(__b), __b, this);
210 }
77e0bf4e
FD
211
212 const_local_iterator
213 cbegin(size_type __b) const
7181e991
FD
214 {
215 __glibcxx_check_bucket_index(__b);
216 return const_local_iterator(_Base::cbegin(__b), __b, this);
217 }
77e0bf4e
FD
218
219 const_local_iterator
220 cend(size_type __b) const
7181e991
FD
221 {
222 __glibcxx_check_bucket_index(__b);
223 return const_local_iterator(_Base::cend(__b), __b, this);
224 }
225
226 size_type
227 bucket_size(size_type __b) const
228 {
229 __glibcxx_check_bucket_index(__b);
230 return _Base::bucket_size(__b);
231 }
ced3cb9f 232
14cbb5d8
FD
233 float
234 max_load_factor() const noexcept
235 { return _Base::max_load_factor(); }
236
237 void
238 max_load_factor(float __f)
239 {
240 __glibcxx_check_max_load_factor(__f);
241 _Base::max_load_factor(__f);
242 }
243
9b81593b
FD
244 template<typename... _Args>
245 std::pair<iterator, bool>
246 emplace(_Args&&... __args)
247 {
248 size_type __bucket_count = this->bucket_count();
249 std::pair<_Base_iterator, bool> __res
250 = _Base::emplace(std::forward<_Args>(__args)...);
251 _M_check_rehashed(__bucket_count);
252 return std::make_pair(iterator(__res.first, this), __res.second);
253 }
254
255 template<typename... _Args>
256 iterator
257 emplace_hint(const_iterator __hint, _Args&&... __args)
258 {
259 __glibcxx_check_insert(__hint);
260 size_type __bucket_count = this->bucket_count();
261 _Base_iterator __it = _Base::emplace_hint(__hint.base(),
262 std::forward<_Args>(__args)...);
263 _M_check_rehashed(__bucket_count);
264 return iterator(__it, this);
265 }
266
ced3cb9f
PC
267 std::pair<iterator, bool>
268 insert(const value_type& __obj)
269 {
77e0bf4e 270 size_type __bucket_count = this->bucket_count();
afe96d41 271 std::pair<_Base_iterator, bool> __res = _Base::insert(__obj);
77e0bf4e 272 _M_check_rehashed(__bucket_count);
ced3cb9f
PC
273 return std::make_pair(iterator(__res.first, this), __res.second);
274 }
275
276 iterator
d66411ba 277 insert(const_iterator __hint, const value_type& __obj)
ced3cb9f 278 {
d66411ba 279 __glibcxx_check_insert(__hint);
77e0bf4e
FD
280 size_type __bucket_count = this->bucket_count();
281 _Base_iterator __it = _Base::insert(__hint.base(), __obj);
282 _M_check_rehashed(__bucket_count);
283 return iterator(__it, this);
ced3cb9f
PC
284 }
285
fb7342fd 286 template<typename _Pair, typename = typename
57cee56a
PC
287 std::enable_if<std::is_constructible<value_type,
288 _Pair&&>::value>::type>
77e0bf4e
FD
289 std::pair<iterator, bool>
290 insert(_Pair&& __obj)
291 {
292 size_type __bucket_count = this->bucket_count();
afe96d41
FD
293 std::pair<_Base_iterator, bool> __res =
294 _Base::insert(std::forward<_Pair>(__obj));
77e0bf4e 295 _M_check_rehashed(__bucket_count);
fb7342fd
PC
296 return std::make_pair(iterator(__res.first, this), __res.second);
297 }
298
299 template<typename _Pair, typename = typename
57cee56a
PC
300 std::enable_if<std::is_constructible<value_type,
301 _Pair&&>::value>::type>
77e0bf4e
FD
302 iterator
303 insert(const_iterator __hint, _Pair&& __obj)
304 {
d66411ba 305 __glibcxx_check_insert(__hint);
77e0bf4e
FD
306 size_type __bucket_count = this->bucket_count();
307 _Base_iterator __it =
308 _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
309 _M_check_rehashed(__bucket_count);
310 return iterator(__it, this);
fb7342fd
PC
311 }
312
ced3cb9f
PC
313 void
314 insert(std::initializer_list<value_type> __l)
77e0bf4e
FD
315 {
316 size_type __bucket_count = this->bucket_count();
317 _Base::insert(__l);
318 _M_check_rehashed(__bucket_count);
319 }
ced3cb9f
PC
320
321 template<typename _InputIterator>
77e0bf4e
FD
322 void
323 insert(_InputIterator __first, _InputIterator __last)
324 {
ced3cb9f 325 __glibcxx_check_valid_range(__first, __last);
77e0bf4e 326 size_type __bucket_count = this->bucket_count();
1f5ca1a1
PC
327 _Base::insert(__gnu_debug::__base(__first),
328 __gnu_debug::__base(__last));
77e0bf4e 329 _M_check_rehashed(__bucket_count);
ced3cb9f
PC
330 }
331
332 iterator
333 find(const key_type& __key)
334 { return iterator(_Base::find(__key), this); }
335
336 const_iterator
337 find(const key_type& __key) const
338 { return const_iterator(_Base::find(__key), this); }
339
340 std::pair<iterator, iterator>
341 equal_range(const key_type& __key)
342 {
afe96d41
FD
343 std::pair<_Base_iterator, _Base_iterator> __res =
344 _Base::equal_range(__key);
ced3cb9f
PC
345 return std::make_pair(iterator(__res.first, this),
346 iterator(__res.second, this));
347 }
348
349 std::pair<const_iterator, const_iterator>
350 equal_range(const key_type& __key) const
351 {
afe96d41
FD
352 std::pair<_Base_const_iterator, _Base_const_iterator> __res =
353 _Base::equal_range(__key);
ced3cb9f
PC
354 return std::make_pair(const_iterator(__res.first, this),
355 const_iterator(__res.second, this));
356 }
357
358 size_type
359 erase(const key_type& __key)
360 {
361 size_type __ret(0);
afe96d41
FD
362 _Base_iterator __victim(_Base::find(__key));
363 if (__victim != _Base::end())
ced3cb9f 364 {
77e0bf4e
FD
365 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
366 { return __it == __victim; });
367 _Base_local_iterator __local_victim = _S_to_local(__victim);
368 this->_M_invalidate_local_if(
369 [__local_victim](_Base_const_local_iterator __it)
370 { return __it == __local_victim; });
371 size_type __bucket_count = this->bucket_count();
afe96d41 372 _Base::erase(__victim);
77e0bf4e 373 _M_check_rehashed(__bucket_count);
ced3cb9f
PC
374 __ret = 1;
375 }
376 return __ret;
377 }
378
d723ced2 379 iterator
ced3cb9f
PC
380 erase(const_iterator __it)
381 {
382 __glibcxx_check_erase(__it);
77e0bf4e
FD
383 _Base_const_iterator __victim = __it.base();
384 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
385 { return __it == __victim; });
386 _Base_const_local_iterator __local_victim = _S_to_local(__victim);
387 this->_M_invalidate_local_if(
388 [__local_victim](_Base_const_local_iterator __it)
389 { return __it == __local_victim; });
390 size_type __bucket_count = this->bucket_count();
391 _Base_iterator __next = _Base::erase(__it.base());
392 _M_check_rehashed(__bucket_count);
393 return iterator(__next, this);
ced3cb9f
PC
394 }
395
6dc88283
PC
396 iterator
397 erase(iterator __it)
398 { return erase(const_iterator(__it)); }
399
d723ced2 400 iterator
ced3cb9f
PC
401 erase(const_iterator __first, const_iterator __last)
402 {
403 __glibcxx_check_erase_range(__first, __last);
afe96d41
FD
404 for (_Base_const_iterator __tmp = __first.base();
405 __tmp != __last.base(); ++__tmp)
406 {
407 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
408 _M_message(__gnu_debug::__msg_valid_range)
409 ._M_iterator(__first, "first")
410 ._M_iterator(__last, "last"));
77e0bf4e
FD
411 this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
412 { return __it == __tmp; });
413 _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
414 this->_M_invalidate_local_if(
415 [__local_tmp](_Base_const_local_iterator __it)
416 { return __it == __local_tmp; });
afe96d41 417 }
77e0bf4e
FD
418 size_type __bucket_count = this->bucket_count();
419 _Base_iterator __next = _Base::erase(__first.base(), __last.base());
420 _M_check_rehashed(__bucket_count);
421 return iterator(__next, this);
ced3cb9f
PC
422 }
423
424 _Base&
d3677132 425 _M_base() noexcept { return *this; }
ced3cb9f
PC
426
427 const _Base&
d3677132 428 _M_base() const noexcept { return *this; }
ced3cb9f 429
69b3331e 430 private:
77e0bf4e
FD
431 void
432 _M_invalidate_locals()
433 {
434 _Base_local_iterator __local_end = _Base::end(0);
435 this->_M_invalidate_local_if(
436 [__local_end](_Base_const_local_iterator __it)
437 { return __it != __local_end; });
438 }
439
69b3331e
PC
440 void
441 _M_invalidate_all()
442 {
77e0bf4e
FD
443 _Base_iterator __end = _Base::end();
444 this->_M_invalidate_if([__end](_Base_const_iterator __it)
445 { return __it != __end; });
446 _M_invalidate_locals();
69b3331e 447 }
77e0bf4e
FD
448
449 void
450 _M_check_rehashed(size_type __prev_count)
451 {
452 if (__prev_count != this->bucket_count())
453 _M_invalidate_locals();
454 }
455
456 static _Base_local_iterator
457 _S_to_local(_Base_iterator __it)
a188284c
FD
458 {
459 // The returned local iterator will not be incremented so we don't
460 // need to compute __it's node bucket
461 return _Base_local_iterator(__it._M_cur, 0, 0);
462 }
77e0bf4e
FD
463
464 static _Base_const_local_iterator
465 _S_to_local(_Base_const_iterator __it)
a188284c
FD
466 {
467 // The returned local iterator will not be incremented so we don't
468 // need to compute __it's node bucket
469 return _Base_const_local_iterator(__it._M_cur, 0, 0);
470 }
e63637ea
BK
471 };
472
473 template<typename _Key, typename _Tp, typename _Hash,
474 typename _Pred, typename _Alloc>
69b3331e
PC
475 inline void
476 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
477 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
478 { __x.swap(__y); }
e63637ea 479
5dc22714
PC
480 template<typename _Key, typename _Tp, typename _Hash,
481 typename _Pred, typename _Alloc>
482 inline bool
483 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
484 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
099e644e 485 { return __x._M_base() == __y._M_base(); }
5dc22714
PC
486
487 template<typename _Key, typename _Tp, typename _Hash,
488 typename _Pred, typename _Alloc>
489 inline bool
490 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
491 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
492 { return !(__x == __y); }
493
e63637ea 494
1ceb9e06 495 /// Class std::unordered_multimap with safety/checking/debug instrumentation.
e63637ea 496 template<typename _Key, typename _Tp,
ced3cb9f 497 typename _Hash = std::hash<_Key>,
e63637ea 498 typename _Pred = std::equal_to<_Key>,
ced3cb9f 499 typename _Alloc = std::allocator<_Key> >
e63637ea 500 class unordered_multimap
12ffa228 501 : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
ced3cb9f 502 _Pred, _Alloc>,
364c862b 503 public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
77e0bf4e 504 _Tp, _Hash, _Pred, _Alloc> >
e63637ea 505 {
12ffa228 506 typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
ced3cb9f 507 _Pred, _Alloc> _Base;
364c862b 508 typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
77e0bf4e 509 _Safe_base;
afe96d41
FD
510 typedef typename _Base::const_iterator _Base_const_iterator;
511 typedef typename _Base::iterator _Base_iterator;
77e0bf4e
FD
512 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
513 typedef typename _Base::local_iterator _Base_local_iterator;
e63637ea
BK
514
515 public:
ced3cb9f
PC
516 typedef typename _Base::size_type size_type;
517 typedef typename _Base::hasher hasher;
518 typedef typename _Base::key_equal key_equal;
519 typedef typename _Base::allocator_type allocator_type;
520
521 typedef typename _Base::key_type key_type;
522 typedef typename _Base::value_type value_type;
523
afe96d41 524 typedef __gnu_debug::_Safe_iterator<_Base_iterator,
ced3cb9f 525 unordered_multimap> iterator;
afe96d41 526 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
ced3cb9f 527 unordered_multimap> const_iterator;
77e0bf4e
FD
528 typedef __gnu_debug::_Safe_local_iterator<
529 _Base_local_iterator, unordered_multimap> local_iterator;
530 typedef __gnu_debug::_Safe_local_iterator<
531 _Base_const_local_iterator, unordered_multimap> const_local_iterator;
e63637ea
BK
532
533 explicit
534 unordered_multimap(size_type __n = 10,
ced3cb9f
PC
535 const hasher& __hf = hasher(),
536 const key_equal& __eql = key_equal(),
537 const allocator_type& __a = allocator_type())
538 : _Base(__n, __hf, __eql, __a) { }
e63637ea
BK
539
540 template<typename _InputIterator>
77e0bf4e 541 unordered_multimap(_InputIterator __first, _InputIterator __last,
417e896e 542 size_type __n = 0,
ced3cb9f
PC
543 const hasher& __hf = hasher(),
544 const key_equal& __eql = key_equal(),
545 const allocator_type& __a = allocator_type())
1f5ca1a1
PC
546 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
547 __last)),
548 __gnu_debug::__base(__last), __n,
4c2d93db 549 __hf, __eql, __a) { }
ced3cb9f
PC
550
551 unordered_multimap(const unordered_multimap& __x)
4c2d93db 552 : _Base(__x) { }
ced3cb9f
PC
553
554 unordered_multimap(const _Base& __x)
4c2d93db 555 : _Base(__x) { }
ced3cb9f 556
6f59ea25 557 unordered_multimap(unordered_multimap&& __x)
4c2d93db 558 : _Base(std::move(__x)) { }
e63637ea 559
988499f4 560 unordered_multimap(initializer_list<value_type> __l,
417e896e 561 size_type __n = 0,
988499f4
JM
562 const hasher& __hf = hasher(),
563 const key_equal& __eql = key_equal(),
564 const allocator_type& __a = allocator_type())
4c2d93db 565 : _Base(__l, __n, __hf, __eql, __a) { }
e63637ea 566
6f59ea25
PC
567 ~unordered_multimap() noexcept { }
568
ced3cb9f
PC
569 unordered_multimap&
570 operator=(const unordered_multimap& __x)
571 {
572 *static_cast<_Base*>(this) = __x;
573 this->_M_invalidate_all();
574 return *this;
575 }
69b3331e
PC
576
577 unordered_multimap&
578 operator=(unordered_multimap&& __x)
579 {
0462fd5e
PC
580 // NB: DR 1204.
581 // NB: DR 675.
739fd6a6 582 __glibcxx_check_self_move_assign(__x);
0462fd5e
PC
583 clear();
584 swap(__x);
69b3331e
PC
585 return *this;
586 }
587
988499f4
JM
588 unordered_multimap&
589 operator=(initializer_list<value_type> __l)
590 {
591 this->clear();
592 this->insert(__l);
593 return *this;
594 }
595
e63637ea 596 void
ff74fd13 597 swap(unordered_multimap& __x)
e63637ea 598 {
ced3cb9f 599 _Base::swap(__x);
e63637ea
BK
600 _Safe_base::_M_swap(__x);
601 }
69b3331e
PC
602
603 void
d3677132 604 clear() noexcept
69b3331e
PC
605 {
606 _Base::clear();
607 this->_M_invalidate_all();
608 }
609
ced3cb9f 610 iterator
d3677132 611 begin() noexcept
ced3cb9f
PC
612 { return iterator(_Base::begin(), this); }
613
614 const_iterator
d3677132 615 begin() const noexcept
ced3cb9f
PC
616 { return const_iterator(_Base::begin(), this); }
617
618 iterator
d3677132 619 end() noexcept
ced3cb9f
PC
620 { return iterator(_Base::end(), this); }
621
622 const_iterator
d3677132 623 end() const noexcept
ced3cb9f
PC
624 { return const_iterator(_Base::end(), this); }
625
626 const_iterator
d3677132 627 cbegin() const noexcept
ced3cb9f
PC
628 { return const_iterator(_Base::begin(), this); }
629
630 const_iterator
d3677132 631 cend() const noexcept
ced3cb9f
PC
632 { return const_iterator(_Base::end(), this); }
633
634 // local versions
77e0bf4e
FD
635 local_iterator
636 begin(size_type __b)
7181e991
FD
637 {
638 __glibcxx_check_bucket_index(__b);
639 return local_iterator(_Base::begin(__b), __b, this);
640 }
77e0bf4e
FD
641
642 local_iterator
643 end(size_type __b)
7181e991
FD
644 {
645 __glibcxx_check_bucket_index(__b);
646 return local_iterator(_Base::end(__b), __b, this);
647 }
77e0bf4e
FD
648
649 const_local_iterator
650 begin(size_type __b) const
7181e991
FD
651 {
652 __glibcxx_check_bucket_index(__b);
653 return const_local_iterator(_Base::begin(__b), __b, this);
654 }
77e0bf4e
FD
655
656 const_local_iterator
657 end(size_type __b) const
7181e991
FD
658 {
659 __glibcxx_check_bucket_index(__b);
660 return const_local_iterator(_Base::end(__b), __b, this);
661 }
77e0bf4e
FD
662
663 const_local_iterator
664 cbegin(size_type __b) const
7181e991
FD
665 {
666 __glibcxx_check_bucket_index(__b);
667 return const_local_iterator(_Base::cbegin(__b), __b, this);
668 }
77e0bf4e
FD
669
670 const_local_iterator
671 cend(size_type __b) const
7181e991
FD
672 {
673 __glibcxx_check_bucket_index(__b);
674 return const_local_iterator(_Base::cend(__b), __b, this);
675 }
676
677 size_type
678 bucket_size(size_type __b) const
679 {
680 __glibcxx_check_bucket_index(__b);
681 return _Base::bucket_size(__b);
682 }
ced3cb9f 683
14cbb5d8
FD
684 float
685 max_load_factor() const noexcept
686 { return _Base::max_load_factor(); }
687
688 void
689 max_load_factor(float __f)
690 {
691 __glibcxx_check_max_load_factor(__f);
692 _Base::max_load_factor(__f);
693 }
694
9b81593b
FD
695 template<typename... _Args>
696 iterator
697 emplace(_Args&&... __args)
698 {
699 size_type __bucket_count = this->bucket_count();
700 _Base_iterator __it
701 = _Base::emplace(std::forward<_Args>(__args)...);
702 _M_check_rehashed(__bucket_count);
703 return iterator(__it, this);
704 }
705
706 template<typename... _Args>
707 iterator
708 emplace_hint(const_iterator __hint, _Args&&... __args)
709 {
710 __glibcxx_check_insert(__hint);
711 size_type __bucket_count = this->bucket_count();
712 _Base_iterator __it = _Base::emplace_hint(__hint.base(),
713 std::forward<_Args>(__args)...);
714 _M_check_rehashed(__bucket_count);
715 return iterator(__it, this);
716 }
717
ced3cb9f
PC
718 iterator
719 insert(const value_type& __obj)
77e0bf4e
FD
720 {
721 size_type __bucket_count = this->bucket_count();
722 _Base_iterator __it = _Base::insert(__obj);
723 _M_check_rehashed(__bucket_count);
724 return iterator(__it, this);
725 }
ced3cb9f
PC
726
727 iterator
d66411ba
FD
728 insert(const_iterator __hint, const value_type& __obj)
729 {
730 __glibcxx_check_insert(__hint);
77e0bf4e
FD
731 size_type __bucket_count = this->bucket_count();
732 _Base_iterator __it = _Base::insert(__hint.base(), __obj);
733 _M_check_rehashed(__bucket_count);
734 return iterator(__it, this);
d66411ba 735 }
ced3cb9f 736
fb7342fd 737 template<typename _Pair, typename = typename
57cee56a
PC
738 std::enable_if<std::is_constructible<value_type,
739 _Pair&&>::value>::type>
77e0bf4e
FD
740 iterator
741 insert(_Pair&& __obj)
742 {
743 size_type __bucket_count = this->bucket_count();
744 _Base_iterator __it = _Base::insert(std::forward<_Pair>(__obj));
745 _M_check_rehashed(__bucket_count);
746 return iterator(__it, this);
747 }
fb7342fd
PC
748
749 template<typename _Pair, typename = typename
57cee56a
PC
750 std::enable_if<std::is_constructible<value_type,
751 _Pair&&>::value>::type>
afe96d41 752 iterator
d66411ba
FD
753 insert(const_iterator __hint, _Pair&& __obj)
754 {
755 __glibcxx_check_insert(__hint);
77e0bf4e
FD
756 size_type __bucket_count = this->bucket_count();
757 _Base_iterator __it =
758 _Base::insert(__hint.base(), std::forward<_Pair>(__obj));
759 _M_check_rehashed(__bucket_count);
760 return iterator(__it, this);
d66411ba 761 }
fb7342fd 762
ced3cb9f
PC
763 void
764 insert(std::initializer_list<value_type> __l)
765 { _Base::insert(__l); }
766
767 template<typename _InputIterator>
77e0bf4e
FD
768 void
769 insert(_InputIterator __first, _InputIterator __last)
770 {
ced3cb9f 771 __glibcxx_check_valid_range(__first, __last);
77e0bf4e 772 size_type __bucket_count = this->bucket_count();
1f5ca1a1
PC
773 _Base::insert(__gnu_debug::__base(__first),
774 __gnu_debug::__base(__last));
77e0bf4e 775 _M_check_rehashed(__bucket_count);
ced3cb9f
PC
776 }
777
778 iterator
779 find(const key_type& __key)
780 { return iterator(_Base::find(__key), this); }
781
782 const_iterator
783 find(const key_type& __key) const
784 { return const_iterator(_Base::find(__key), this); }
785
786 std::pair<iterator, iterator>
787 equal_range(const key_type& __key)
788 {
afe96d41
FD
789 std::pair<_Base_iterator, _Base_iterator> __res =
790 _Base::equal_range(__key);
ced3cb9f
PC
791 return std::make_pair(iterator(__res.first, this),
792 iterator(__res.second, this));
793 }
794
795 std::pair<const_iterator, const_iterator>
796 equal_range(const key_type& __key) const
797 {
afe96d41
FD
798 std::pair<_Base_const_iterator, _Base_const_iterator> __res =
799 _Base::equal_range(__key);
ced3cb9f
PC
800 return std::make_pair(const_iterator(__res.first, this),
801 const_iterator(__res.second, this));
802 }
803
804 size_type
805 erase(const key_type& __key)
806 {
807 size_type __ret(0);
77e0bf4e 808 size_type __bucket_count = this->bucket_count();
d3b8263e
FD
809 std::pair<_Base_iterator, _Base_iterator> __pair =
810 _Base::equal_range(__key);
811 for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
ced3cb9f 812 {
77e0bf4e
FD
813 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
814 { return __it == __victim; });
815 _Base_local_iterator __local_victim = _S_to_local(__victim);
816 this->_M_invalidate_local_if(
817 [__local_victim](_Base_const_local_iterator __it)
818 { return __it == __local_victim; });
d3b8263e
FD
819 _Base::erase(__victim++);
820 ++__ret;
ced3cb9f 821 }
77e0bf4e 822 _M_check_rehashed(__bucket_count);
ced3cb9f
PC
823 return __ret;
824 }
825
d723ced2 826 iterator
ced3cb9f
PC
827 erase(const_iterator __it)
828 {
829 __glibcxx_check_erase(__it);
77e0bf4e
FD
830 _Base_const_iterator __victim = __it.base();
831 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
832 { return __it == __victim; });
833 _Base_const_local_iterator __local_victim = _S_to_local(__victim);
834 this->_M_invalidate_local_if(
835 [__local_victim](_Base_const_local_iterator __it)
836 { return __it == __local_victim; });
837 size_type __bucket_count = this->bucket_count();
838 _Base_iterator __next = _Base::erase(__it.base());
839 _M_check_rehashed(__bucket_count);
840 return iterator(__next, this);
ced3cb9f
PC
841 }
842
6dc88283
PC
843 iterator
844 erase(iterator __it)
845 { return erase(const_iterator(__it)); }
846
d723ced2 847 iterator
ced3cb9f
PC
848 erase(const_iterator __first, const_iterator __last)
849 {
850 __glibcxx_check_erase_range(__first, __last);
afe96d41
FD
851 for (_Base_const_iterator __tmp = __first.base();
852 __tmp != __last.base(); ++__tmp)
853 {
854 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
855 _M_message(__gnu_debug::__msg_valid_range)
856 ._M_iterator(__first, "first")
857 ._M_iterator(__last, "last"));
77e0bf4e
FD
858 this->_M_invalidate_if([__tmp](_Base_const_iterator __it)
859 { return __it == __tmp; });
860 _Base_const_local_iterator __local_tmp = _S_to_local(__tmp);
861 this->_M_invalidate_local_if(
862 [__local_tmp](_Base_const_local_iterator __it)
863 { return __it == __local_tmp; });
afe96d41 864 }
77e0bf4e
FD
865 size_type __bucket_count = this->bucket_count();
866 _Base_iterator __next = _Base::erase(__first.base(), __last.base());
867 _M_check_rehashed(__bucket_count);
868 return iterator(__next, this);
ced3cb9f
PC
869 }
870
871 _Base&
d3677132 872 _M_base() noexcept { return *this; }
ced3cb9f
PC
873
874 const _Base&
d3677132 875 _M_base() const noexcept { return *this; }
ced3cb9f 876
69b3331e 877 private:
77e0bf4e
FD
878 void
879 _M_invalidate_locals()
880 {
881 _Base_local_iterator __local_end = _Base::end(0);
882 this->_M_invalidate_local_if(
883 [__local_end](_Base_const_local_iterator __it)
884 { return __it != __local_end; });
885 }
886
69b3331e
PC
887 void
888 _M_invalidate_all()
889 {
77e0bf4e
FD
890 _Base_iterator __end = _Base::end();
891 this->_M_invalidate_if([__end](_Base_const_iterator __it)
892 { return __it != __end; });
893 _M_invalidate_locals();
69b3331e 894 }
77e0bf4e
FD
895
896 void
897 _M_check_rehashed(size_type __prev_count)
898 {
899 if (__prev_count != this->bucket_count())
900 _M_invalidate_locals();
901 }
902
903 static _Base_local_iterator
904 _S_to_local(_Base_iterator __it)
a188284c
FD
905 {
906 // The returned local iterator will not be incremented so we don't
907 // need to compute __it's node bucket
908 return _Base_local_iterator(__it._M_cur, 0, 0);
909 }
77e0bf4e
FD
910
911 static _Base_const_local_iterator
912 _S_to_local(_Base_const_iterator __it)
a188284c
FD
913 {
914 // The returned local iterator will not be incremented so we don't
915 // need to compute __it's node bucket
916 return _Base_const_local_iterator(__it._M_cur, 0, 0);
917 }
e63637ea
BK
918 };
919
920 template<typename _Key, typename _Tp, typename _Hash,
921 typename _Pred, typename _Alloc>
69b3331e
PC
922 inline void
923 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
924 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
925 { __x.swap(__y); }
e63637ea 926
5dc22714
PC
927 template<typename _Key, typename _Tp, typename _Hash,
928 typename _Pred, typename _Alloc>
929 inline bool
930 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
931 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
099e644e 932 { return __x._M_base() == __y._M_base(); }
5dc22714
PC
933
934 template<typename _Key, typename _Tp, typename _Hash,
935 typename _Pred, typename _Alloc>
936 inline bool
937 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
938 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
939 { return !(__x == __y); }
940
e63637ea
BK
941} // namespace __debug
942} // namespace std
943
734f5023 944#endif // C++11
c878d6ba 945
e63637ea 946#endif