mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-19 00:55:13 +08:00
libstdc++: [_GLIBCXX_DEBUG] Reduce performance impact on std::erase_if
Bypass the _GLIBCXX_DEBUG additional checks in std::__detail::__erase_node_if used by all implementations of std::erase_if for node based containers. libstdc++-v3/ChangeLog: * include/bits/erase_if.h (__erase_nodes_if): Add _UnsafeContainer template parameter. Use it to get iterators to work with. * include/debug/macros.h (__glibcxx_check_erase2): New. * include/debug/map.h (map<>::erase(_Base_const_iterator)): New. (map<>::erase(const_iterator)): Use latter. * include/debug/multimap.h (multimap<>::erase(_Base_const_iterator)): New. (multimap<>::erase(const_iterator)): Use latter. * include/debug/multiset.h (multiset<>::erase(_Base_const_iterator)): New. (multiset<>::erase(const_iterator)): Use latter. * include/debug/set.h (set<>::erase(_Base_const_iterator)): New. (set<>::erase(const_iterator)): Use latter. * include/debug/unordered_map (unordered_map<>::erase(_Base_const_iterator)): New. (unordered_multimap<>::erase(const_iterator)): New. * include/debug/unordered_set (unordered_set<>::erase(_Base_const_iterator)): New. (unordered_multiset<>::erase(const_iterator)): New. * include/experimental/map (erase_if): Adapt. * include/experimental/set (erase_if): Adapt. * include/experimental/unordered_map (erase_if): Adapt. * include/experimental/unordered_set (erase_if): Adapt. * include/std/map (erase_if): Adapt. * include/std/set (erase_if): Adapt. * include/std/unordered_map (erase_if): Adapt. * include/std/unordered_set (erase_if): Adapt.
This commit is contained in:
parent
74faa9834a
commit
5f40d34b6d
@ -46,12 +46,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
template<typename _Container, typename _Predicate>
|
||||
template<typename _Container, typename _UnsafeContainer,
|
||||
typename _Predicate>
|
||||
typename _Container::size_type
|
||||
__erase_nodes_if(_Container& __cont, _Predicate __pred)
|
||||
__erase_nodes_if(_Container& __cont, const _UnsafeContainer& __ucont,
|
||||
_Predicate __pred)
|
||||
{
|
||||
typename _Container::size_type __num = 0;
|
||||
for (auto __iter = __cont.begin(), __last = __cont.end();
|
||||
for (auto __iter = __ucont.begin(), __last = __ucont.end();
|
||||
__iter != __last;)
|
||||
{
|
||||
if (__pred(*__iter))
|
||||
|
@ -219,6 +219,14 @@ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_Position, #_Position))
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define __glibcxx_check_erase2(_CPosition) \
|
||||
_GLIBCXX_DEBUG_VERIFY(_CPosition != _M_base().cend(), \
|
||||
_M_message(__gnu_debug::__msg_erase_bad) \
|
||||
._M_sequence(*this, "this") \
|
||||
._M_iterator(_CPosition, #_CPosition));
|
||||
#endif
|
||||
|
||||
/** Verify that we can erase the element after the iterator
|
||||
* _Position. We can erase the element if the _Position iterator is
|
||||
* before a dereferenceable one and references this sequence.
|
||||
|
@ -480,8 +480,15 @@ namespace __debug
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return { _Base::erase(__position.base()), this };
|
||||
return { erase(__position.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase2(__position);
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
return _Base::erase(__position);
|
||||
}
|
||||
|
||||
_GLIBCXX_ABI_TAG_CXX11
|
||||
|
@ -360,8 +360,15 @@ namespace __debug
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return { _Base::erase(__position.base()), this };
|
||||
return { erase(__position.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase2(__position);
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
return _Base::erase(__position);
|
||||
}
|
||||
|
||||
_GLIBCXX_ABI_TAG_CXX11
|
||||
|
@ -332,8 +332,15 @@ namespace __debug
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return { _Base::erase(__position.base()), this };
|
||||
return { erase(__position.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase2(__position);
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
return _Base::erase(__position);
|
||||
}
|
||||
#else
|
||||
void
|
||||
|
@ -345,8 +345,15 @@ namespace __debug
|
||||
erase(const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase(__position);
|
||||
this->_M_invalidate_if(_Equal(__position.base()));
|
||||
return { _Base::erase(__position.base()), this };
|
||||
return { erase(__position.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __position)
|
||||
{
|
||||
__glibcxx_check_erase2(__position);
|
||||
this->_M_invalidate_if(_Equal(__position));
|
||||
return _Base::erase(__position);
|
||||
}
|
||||
#else
|
||||
void
|
||||
|
@ -679,6 +679,13 @@ namespace __debug
|
||||
return { _M_erase(__it.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase2(__it);
|
||||
return _M_erase(__it);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{
|
||||
@ -1389,6 +1396,13 @@ namespace __debug
|
||||
return { _M_erase(__it.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase2(__it);
|
||||
return _M_erase(__it);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{
|
||||
|
@ -564,6 +564,13 @@ namespace __debug
|
||||
return { _M_erase(__it.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase2(__it);
|
||||
return _M_erase(__it);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{
|
||||
@ -1234,6 +1241,13 @@ namespace __debug
|
||||
return { _M_erase(__it.base()), this };
|
||||
}
|
||||
|
||||
_Base_iterator
|
||||
erase(_Base_const_iterator __it)
|
||||
{
|
||||
__glibcxx_check_erase2(__it);
|
||||
return _M_erase(__it);
|
||||
}
|
||||
|
||||
iterator
|
||||
erase(iterator __it)
|
||||
{
|
||||
|
@ -50,13 +50,21 @@ inline namespace fundamentals_v2
|
||||
typename _Predicate>
|
||||
inline void
|
||||
erase_if(map<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline void
|
||||
erase_if(multimap<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
namespace pmr {
|
||||
template<typename _Key, typename _Tp, typename _Compare = less<_Key>>
|
||||
|
@ -50,13 +50,19 @@ inline namespace fundamentals_v2
|
||||
typename _Predicate>
|
||||
inline void
|
||||
erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline void
|
||||
erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
namespace pmr {
|
||||
template<typename _Key, typename _Compare = less<_Key>>
|
||||
|
@ -51,14 +51,22 @@ inline namespace fundamentals_v2
|
||||
inline void
|
||||
erase_if(unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash, typename _CPred,
|
||||
typename _Alloc, typename _Predicate>
|
||||
inline void
|
||||
erase_if(unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
namespace pmr {
|
||||
template<typename _Key, typename _Tp, typename _Hash = hash<_Key>,
|
||||
|
@ -51,14 +51,22 @@ inline namespace fundamentals_v2
|
||||
inline void
|
||||
erase_if(unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline void
|
||||
erase_if(unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ std::__detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
std::__detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
namespace pmr {
|
||||
template<typename _Key, typename _Hash = hash<_Key>,
|
||||
|
@ -95,13 +95,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
typename _Predicate>
|
||||
inline typename map<_Key, _Tp, _Compare, _Alloc>::size_type
|
||||
erase_if(map<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline typename multimap<_Key, _Tp, _Compare, _Alloc>::size_type
|
||||
erase_if(multimap<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // C++20
|
||||
|
@ -91,13 +91,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
typename _Predicate>
|
||||
inline typename set<_Key, _Compare, _Alloc>::size_type
|
||||
erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Compare, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline typename multiset<_Key, _Compare, _Alloc>::size_type
|
||||
erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // C++20
|
||||
|
@ -83,7 +83,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline typename unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>::size_type
|
||||
erase_if(unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Tp, typename _Hash, typename _CPred,
|
||||
typename _Alloc, typename _Predicate>
|
||||
@ -91,7 +95,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
size_type
|
||||
erase_if(unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // C++20
|
||||
|
@ -83,14 +83,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline typename unordered_set<_Key, _Hash, _CPred, _Alloc>::size_type
|
||||
erase_if(unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Hash, typename _CPred, typename _Alloc,
|
||||
typename _Predicate>
|
||||
inline typename unordered_multiset<_Key, _Hash, _CPred, _Alloc>::size_type
|
||||
erase_if(unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont,
|
||||
_Predicate __pred)
|
||||
{ return __detail::__erase_nodes_if(__cont, __pred); }
|
||||
{
|
||||
const _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>&
|
||||
__ucont = __cont;
|
||||
return __detail::__erase_nodes_if(__cont, __ucont, __pred);
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // C++20
|
||||
|
Loading…
Reference in New Issue
Block a user