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