29 #ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H
30 #define _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H 1
39 template<
typename _Container>
42 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
43 template<
typename _ExtractKey,
typename _Source>
44 struct _UContInvalidatePred
46 template<
typename _Iterator>
48 operator()(_Iterator __it)
const
49 {
return _M_source._M_cont().count(_ExtractKey{}(*__it)) == 0; }
51 const _Safe_unordered_container<_Source>& _M_source;
54 template<
typename _ExtractKey,
typename _Source>
55 struct _UMContInvalidatePred
57 template<
typename _Iterator>
59 operator()(_Iterator __it)
const
62 _M_source._M_cont()._M_base().equal_range(_ExtractKey{}(*__it));
63 for (
auto __rit = __rng.first;
64 __rit != __rng.second; ++__rit)
73 const _Safe_unordered_container<_Source>& _M_source;
76 template<
typename _Source,
typename _Inval
idatePred>
77 struct _UContMergeGuard
79 _UContMergeGuard(_Safe_unordered_container<_Source>& __src) noexcept
80 : _M_source(__src), _M_size(__src._M_cont().size()), _M_pred { __src }
83 _UContMergeGuard(
const _UContMergeGuard&) =
delete;
87 const std::size_t __size = _M_source._M_cont().size();
88 if (__size == _M_size)
94 _M_source._M_invalidate_all();
96 _M_source._M_invalidate_all_if(_M_pred);
100 _M_source._M_invalidate_all();
104 _Safe_unordered_container<_Source>& _M_source;
105 const std::size_t _M_size;
106 _InvalidatePred _M_pred;
108 #endif // >= C++17 && HOSTED
128 template<
typename _Container>
129 class _Safe_unordered_container :
public _Safe_unordered_container_base
132 _M_cont() const noexcept
133 {
return *
static_cast<const _Container*
>(
this); }
135 const _Safe_unordered_container*
140 #ifdef __glibcxx_node_extract // >= C++17 && HOSTED
141 template<
typename _ExtractKey,
typename _Source>
142 friend struct ::__gnu_debug::_UContInvalidatePred;
144 template<
typename _ExtractKey,
typename _Source>
145 friend struct ::__gnu_debug::_UMContInvalidatePred;
147 template<
typename _Source,
typename _Inval
idatePred>
148 friend struct ::__gnu_debug::_UContMergeGuard;
150 template<
typename _ExtractKey,
typename _Source>
151 static _UContMergeGuard<_Source,
152 _UContInvalidatePred<_ExtractKey, _Source>>
153 _S_uc_guard(_ExtractKey, _Safe_unordered_container<_Source>& __src)
155 typedef _UContInvalidatePred<_ExtractKey, _Source> _InvalidatePred;
156 return _UContMergeGuard<_Source, _InvalidatePred>(__src);
159 template<
typename _ExtractKey,
typename _Source>
160 static _UContMergeGuard<_Source,
161 _UMContInvalidatePred<_ExtractKey, _Source>>
162 _S_umc_guard(_ExtractKey, _Safe_unordered_container<_Source>& __src)
164 typedef _UMContInvalidatePred<_ExtractKey, _Source> _InvalidatePred;
165 return _UContMergeGuard<_Source, _InvalidatePred>(__src);
167 #endif // >= C++17 && HOSTED
173 auto __end = _M_cont()._M_base().cend();
175 [__end](decltype(__end) __it)
176 {
return __it != __end; },
179 auto __local_end = _M_cont()._M_base().cend(0);
180 _M_invalidate_local_if(
181 [__local_end](decltype(__local_end) __it)
182 {
return __it != __local_end; },
186 template<
typename _Predicate>
188 _M_invalidate_all_if(_Predicate __pred)
191 _M_invalidate_if(__pred, sentry);
192 _M_invalidate_local_if(__pred, sentry);
195 template<
typename _VictimIt>
197 _M_invalidate(_VictimIt __victim)
200 _M_invalidate(__victim, sentry);
203 template<
typename _VictimIt>
207 auto __end = _M_cont()._M_base().cend();
209 [__victim](decltype(__end) __it)
210 {
return __it == __victim; },
213 auto __local_end = _M_cont()._M_base().cend(0);
214 _M_invalidate_local_if(
215 [__victim](decltype(__local_end) __it)
216 {
return __it == __victim; },
225 template<
typename _Predicate>
233 template<
typename _Predicate>
235 _M_invalidate_local_if(_Predicate __pred,