29 #ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
30 #define _GLIBCXX_DEBUG_UNORDERED_MAP 1
32 #if __cplusplus < 201103L
41 namespace std _GLIBCXX_VISIBILITY(default)
46 template<
typename _Key,
typename _Tp,
51 :
public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
53 _Hash, _Pred, _Alloc> >
55 typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
58 typedef typename _Base::const_iterator _Base_const_iterator;
59 typedef typename _Base::iterator _Base_iterator;
60 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
61 typedef typename _Base::local_iterator _Base_local_iterator;
67 typedef typename _Base::size_type size_type;
68 typedef typename _Base::hasher hasher;
69 typedef typename _Base::key_equal key_equal;
70 typedef typename _Base::allocator_type allocator_type;
72 typedef typename _Base::key_type key_type;
73 typedef typename _Base::value_type value_type;
86 const hasher& __hf = hasher(),
87 const key_equal& __eql = key_equal(),
88 const allocator_type& __a = allocator_type())
89 :
_Base(__n, __hf, __eql, __a) { }
91 template<
typename _InputIterator>
94 const hasher& __hf = hasher(),
95 const key_equal& __eql = key_equal(),
96 const allocator_type& __a = allocator_type())
100 __hf, __eql, __a) { }
115 const allocator_type& __a)
116 :
_Base(__umap._M_base(), __a)
120 const allocator_type& __a)
121 :
_Base(std::move(__umap._M_base()), __a)
126 const hasher& __hf = hasher(),
127 const key_equal& __eql = key_equal(),
128 const allocator_type& __a = allocator_type())
129 :
_Base(__l, __n, __hf, __eql, __a) { }
136 _M_base() = __x._M_base();
137 this->_M_invalidate_all();
143 noexcept(_Alloc_traits::_S_nothrow_move())
145 __glibcxx_check_self_move_assign(__x);
146 bool xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
147 || __x.get_allocator() == this->get_allocator();
148 _M_base() = std::move(__x._M_base());
152 this->_M_invalidate_all();
153 __x._M_invalidate_all();
161 this->_M_invalidate_all();
167 noexcept(_Alloc_traits::_S_nothrow_swap())
169 if (!_Alloc_traits::_S_propagate_on_swap())
170 __glibcxx_check_equal_allocs(__x);
179 this->_M_invalidate_all();
184 {
return iterator(_Base::begin(),
this); }
187 begin()
const noexcept
192 {
return iterator(_Base::end(),
this); }
199 cbegin()
const noexcept
203 cend()
const noexcept
210 __glibcxx_check_bucket_index(__b);
217 __glibcxx_check_bucket_index(__b);
222 begin(size_type __b)
const
224 __glibcxx_check_bucket_index(__b);
229 end(size_type __b)
const
231 __glibcxx_check_bucket_index(__b);
236 cbegin(size_type __b)
const
238 __glibcxx_check_bucket_index(__b);
243 cend(size_type __b)
const
245 __glibcxx_check_bucket_index(__b);
250 bucket_size(size_type __b)
const
252 __glibcxx_check_bucket_index(__b);
253 return _Base::bucket_size(__b);
257 max_load_factor()
const noexcept
258 {
return _Base::max_load_factor(); }
261 max_load_factor(
float __f)
263 __glibcxx_check_max_load_factor(__f);
264 _Base::max_load_factor(__f);
267 template<
typename... _Args>
269 emplace(_Args&&... __args)
271 size_type __bucket_count = this->bucket_count();
273 = _Base::emplace(std::forward<_Args>(__args)...);
274 _M_check_rehashed(__bucket_count);
278 template<
typename... _Args>
283 size_type __bucket_count = this->bucket_count();
284 _Base_iterator __it = _Base::emplace_hint(__hint.
base(),
285 std::forward<_Args>(__args)...);
286 _M_check_rehashed(__bucket_count);
291 insert(
const value_type& __obj)
293 size_type __bucket_count = this->bucket_count();
295 _M_check_rehashed(__bucket_count);
303 size_type __bucket_count = this->bucket_count();
304 _Base_iterator __it = _Base::insert(__hint.
base(), __obj);
305 _M_check_rehashed(__bucket_count);
309 template<
typename _Pair,
typename =
typename
310 std::enable_if<std::is_constructible<value_type,
311 _Pair&&>::value>::type>
313 insert(_Pair&& __obj)
315 size_type __bucket_count = this->bucket_count();
317 _Base::insert(std::forward<_Pair>(__obj));
318 _M_check_rehashed(__bucket_count);
322 template<
typename _Pair,
typename =
typename
323 std::enable_if<std::is_constructible<value_type,
324 _Pair&&>::value>::type>
329 size_type __bucket_count = this->bucket_count();
330 _Base_iterator __it =
331 _Base::insert(__hint.
base(), std::forward<_Pair>(__obj));
332 _M_check_rehashed(__bucket_count);
339 size_type __bucket_count = this->bucket_count();
341 _M_check_rehashed(__bucket_count);
344 template<
typename _InputIterator>
346 insert(_InputIterator __first, _InputIterator __last)
348 __glibcxx_check_valid_range(__first, __last);
349 size_type __bucket_count = this->bucket_count();
352 _M_check_rehashed(__bucket_count);
356 find(
const key_type& __key)
357 {
return iterator(_Base::find(__key),
this); }
360 find(
const key_type& __key)
const
364 equal_range(
const key_type& __key)
367 _Base::equal_range(__key);
373 equal_range(
const key_type& __key)
const
376 _Base::equal_range(__key);
382 erase(
const key_type& __key)
385 _Base_iterator __victim(_Base::find(__key));
386 if (__victim != _Base::end())
389 {
return __it == __victim; });
391 [__victim](_Base_const_local_iterator __it)
392 {
return __it._M_cur == __victim._M_cur; });
393 size_type __bucket_count = this->bucket_count();
394 _Base::erase(__victim);
395 _M_check_rehashed(__bucket_count);
405 _Base_const_iterator __victim = __it.
base();
407 {
return __it == __victim; });
409 [__victim](_Base_const_local_iterator __it)
410 {
return __it._M_cur == __victim._M_cur; });
411 size_type __bucket_count = this->bucket_count();
412 _Base_iterator __next = _Base::erase(__it.base());
413 _M_check_rehashed(__bucket_count);
425 for (_Base_const_iterator __tmp = __first.
base();
426 __tmp != __last.
base(); ++__tmp)
428 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
429 _M_message(__gnu_debug::__msg_valid_range)
430 ._M_iterator(__first,
"first")
431 ._M_iterator(__last,
"last"));
433 {
return __it == __tmp; });
435 [__tmp](_Base_const_local_iterator __it)
436 {
return __it._M_cur == __tmp._M_cur; });
438 size_type __bucket_count = this->bucket_count();
439 _Base_iterator __next = _Base::erase(__first.
base(), __last.
base());
440 _M_check_rehashed(__bucket_count);
445 _M_base() noexcept {
return *
this; }
448 _M_base()
const noexcept {
return *
this; }
452 _M_invalidate_locals()
454 _Base_local_iterator __local_end = _Base::end(0);
456 [__local_end](_Base_const_local_iterator __it)
457 {
return __it != __local_end; });
463 _Base_iterator __end = _Base::end();
465 {
return __it != __end; });
466 _M_invalidate_locals();
470 _M_check_rehashed(size_type __prev_count)
472 if (__prev_count != this->bucket_count())
473 _M_invalidate_locals();
477 template<
typename _Key,
typename _Tp,
typename _Hash,
478 typename _Pred,
typename _Alloc>
484 template<
typename _Key,
typename _Tp,
typename _Hash,
485 typename _Pred,
typename _Alloc>
489 {
return __x._M_base() == __y._M_base(); }
491 template<
typename _Key,
typename _Tp,
typename _Hash,
492 typename _Pred,
typename _Alloc>
494 operator!=(
const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
495 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
496 {
return !(__x == __y); }
500 template<
typename _Key,
typename _Tp,
505 :
public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
508 _Tp, _Hash, _Pred, _Alloc> >
510 typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
511 _Pred, _Alloc>
_Base;
514 typedef typename _Base::const_iterator _Base_const_iterator;
515 typedef typename _Base::iterator _Base_iterator;
516 typedef typename _Base::const_local_iterator _Base_const_local_iterator;
517 typedef typename _Base::local_iterator _Base_local_iterator;
523 typedef typename _Base::size_type size_type;
524 typedef typename _Base::hasher hasher;
525 typedef typename _Base::key_equal key_equal;
526 typedef typename _Base::allocator_type allocator_type;
528 typedef typename _Base::key_type key_type;
529 typedef typename _Base::value_type value_type;
542 const hasher& __hf = hasher(),
543 const key_equal& __eql = key_equal(),
544 const allocator_type& __a = allocator_type())
545 :
_Base(__n, __hf, __eql, __a) { }
547 template<
typename _InputIterator>
550 const hasher& __hf = hasher(),
551 const key_equal& __eql = key_equal(),
552 const allocator_type& __a = allocator_type())
556 __hf, __eql, __a) { }
571 const allocator_type& __a)
572 :
_Base(__umap._M_base(), __a)
576 const allocator_type& __a)
577 :
_Base(std::move(__umap._M_base()), __a)
582 const hasher& __hf = hasher(),
583 const key_equal& __eql = key_equal(),
584 const allocator_type& __a = allocator_type())
585 :
_Base(__l, __n, __hf, __eql, __a) { }
592 _M_base() = __x._M_base();
593 this->_M_invalidate_all();
599 noexcept(_Alloc_traits::_S_nothrow_move())
601 __glibcxx_check_self_move_assign(__x);
602 bool xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
603 || __x.get_allocator() == this->get_allocator();
604 _M_base() = std::move(__x._M_base());
608 this->_M_invalidate_all();
609 __x._M_invalidate_all();
617 this->_M_invalidate_all();
623 noexcept(_Alloc_traits::_S_nothrow_swap())
625 if (!_Alloc_traits::_S_propagate_on_swap())
626 __glibcxx_check_equal_allocs(__x);
635 this->_M_invalidate_all();
640 {
return iterator(_Base::begin(),
this); }
643 begin()
const noexcept
648 {
return iterator(_Base::end(),
this); }
655 cbegin()
const noexcept
659 cend()
const noexcept
666 __glibcxx_check_bucket_index(__b);
673 __glibcxx_check_bucket_index(__b);
678 begin(size_type __b)
const
680 __glibcxx_check_bucket_index(__b);
685 end(size_type __b)
const
687 __glibcxx_check_bucket_index(__b);
692 cbegin(size_type __b)
const
694 __glibcxx_check_bucket_index(__b);
699 cend(size_type __b)
const
701 __glibcxx_check_bucket_index(__b);
706 bucket_size(size_type __b)
const
708 __glibcxx_check_bucket_index(__b);
709 return _Base::bucket_size(__b);
713 max_load_factor()
const noexcept
714 {
return _Base::max_load_factor(); }
717 max_load_factor(
float __f)
719 __glibcxx_check_max_load_factor(__f);
720 _Base::max_load_factor(__f);
723 template<
typename... _Args>
725 emplace(_Args&&... __args)
727 size_type __bucket_count = this->bucket_count();
729 = _Base::emplace(std::forward<_Args>(__args)...);
730 _M_check_rehashed(__bucket_count);
734 template<
typename... _Args>
739 size_type __bucket_count = this->bucket_count();
740 _Base_iterator __it = _Base::emplace_hint(__hint.
base(),
741 std::forward<_Args>(__args)...);
742 _M_check_rehashed(__bucket_count);
747 insert(
const value_type& __obj)
749 size_type __bucket_count = this->bucket_count();
750 _Base_iterator __it = _Base::insert(__obj);
751 _M_check_rehashed(__bucket_count);
759 size_type __bucket_count = this->bucket_count();
760 _Base_iterator __it = _Base::insert(__hint.
base(), __obj);
761 _M_check_rehashed(__bucket_count);
765 template<
typename _Pair,
typename =
typename
766 std::enable_if<std::is_constructible<value_type,
767 _Pair&&>::value>::type>
769 insert(_Pair&& __obj)
771 size_type __bucket_count = this->bucket_count();
772 _Base_iterator __it = _Base::insert(std::forward<_Pair>(__obj));
773 _M_check_rehashed(__bucket_count);
777 template<
typename _Pair,
typename =
typename
778 std::enable_if<std::is_constructible<value_type,
779 _Pair&&>::value>::type>
784 size_type __bucket_count = this->bucket_count();
785 _Base_iterator __it =
786 _Base::insert(__hint.
base(), std::forward<_Pair>(__obj));
787 _M_check_rehashed(__bucket_count);
793 { _Base::insert(__l); }
795 template<
typename _InputIterator>
797 insert(_InputIterator __first, _InputIterator __last)
799 __glibcxx_check_valid_range(__first, __last);
800 size_type __bucket_count = this->bucket_count();
803 _M_check_rehashed(__bucket_count);
807 find(
const key_type& __key)
808 {
return iterator(_Base::find(__key),
this); }
811 find(
const key_type& __key)
const
815 equal_range(
const key_type& __key)
818 _Base::equal_range(__key);
824 equal_range(
const key_type& __key)
const
827 _Base::equal_range(__key);
833 erase(
const key_type& __key)
836 size_type __bucket_count = this->bucket_count();
838 _Base::equal_range(__key);
839 for (_Base_iterator __victim = __pair.
first; __victim != __pair.
second;)
842 {
return __it == __victim; });
844 [__victim](_Base_const_local_iterator __it)
845 {
return __it._M_cur == __victim._M_cur; });
846 _Base::erase(__victim++);
849 _M_check_rehashed(__bucket_count);
857 _Base_const_iterator __victim = __it.
base();
859 {
return __it == __victim; });
861 [__victim](_Base_const_local_iterator __it)
862 {
return __it._M_cur == __victim._M_cur; });
863 size_type __bucket_count = this->bucket_count();
864 _Base_iterator __next = _Base::erase(__it.base());
865 _M_check_rehashed(__bucket_count);
877 for (_Base_const_iterator __tmp = __first.
base();
878 __tmp != __last.
base(); ++__tmp)
880 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
881 _M_message(__gnu_debug::__msg_valid_range)
882 ._M_iterator(__first,
"first")
883 ._M_iterator(__last,
"last"));
885 {
return __it == __tmp; });
887 [__tmp](_Base_const_local_iterator __it)
888 {
return __it._M_cur == __tmp._M_cur; });
890 size_type __bucket_count = this->bucket_count();
891 _Base_iterator __next = _Base::erase(__first.
base(), __last.
base());
892 _M_check_rehashed(__bucket_count);
897 _M_base() noexcept {
return *
this; }
900 _M_base()
const noexcept {
return *
this; }
904 _M_invalidate_locals()
906 _Base_local_iterator __local_end = _Base::end(0);
908 [__local_end](_Base_const_local_iterator __it)
909 {
return __it != __local_end; });
915 _Base_iterator __end = _Base::end();
917 {
return __it != __end; });
918 _M_invalidate_locals();
922 _M_check_rehashed(size_type __prev_count)
924 if (__prev_count != this->bucket_count())
925 _M_invalidate_locals();
929 template<
typename _Key,
typename _Tp,
typename _Hash,
930 typename _Pred,
typename _Alloc>
936 template<
typename _Key,
typename _Tp,
typename _Hash,
937 typename _Pred,
typename _Alloc>
941 {
return __x._M_base() == __y._M_base(); }
943 template<
typename _Key,
typename _Tp,
typename _Hash,
944 typename _Pred,
typename _Alloc>
946 operator!=(
const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
947 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
948 {
return !(__x == __y); }
Base class for constructing a safe unordered container type that tracks iterators that reference it...
_T2 second
first is a copy of the first object
void _M_invalidate_local_if(_Predicate __pred)
#define __glibcxx_check_insert(_Position)
Uniform interface to C++98 and C++0x allocators.
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.
A standard container composed of equivalent keys (possibly containing multiple of each key value) tha...
_T1 first
second_type is the second bound type
void _M_invalidate_if(_Predicate __pred)
Struct holding two objects of arbitrary type.
Class std::unordered_map with safety/checking/debug instrumentation.
void _M_swap(_Safe_unordered_container_base &__x)
Base class that supports tracking of iterators that reference a sequence.
A standard container composed of unique keys (containing at most one of each key value) that associat...
_Iterator base() const noexcept
Return the underlying iterator.
#define __glibcxx_check_erase(_Position)
The standard allocator, as per [20.4].
void swap(function< _Res(_Args...)> &__x, function< _Res(_Args...)> &__y)
Swap the targets of two polymorphic function object wrappers.
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
One of the comparison functors.
Primary class template hash.
Class std::unordered_multimap with safety/checking/debug instrumentation.
#define __glibcxx_check_erase_range(_First, _Last)