Skip to content

Commit 7c2e60f

Browse files
pobrnjwakely
authored andcommitted
libstdc++: Optimize removal from unique assoc containers [PR112934]
Previously, calling erase(key) on both std::map and std::set would execute that same code that std::multi{map,set} would. However, doing that is unnecessary because std::{map,set} guarantee that all elements are unique. It is reasonable to expect that erase(key) is equivalent or better than: auto it = m.find(key); if (it != m.end()) m.erase(it); However, this was not the case. Fix that by adding a new function _Rb_tree<>::_M_erase_unique() that is essentially equivalent to the above snippet, and use this from both std::map and std::set. libstdc++-v3/ChangeLog: PR libstdc++/112934 * include/bits/stl_map.h (map::erase): Use _M_erase_unique. * include/bits/stl_set.h (set::erase): Likewise. * include/bits/stl_tree.h (_Rb_tree::_M_erase_unique): Add.
1 parent 102ecca commit 7c2e60f

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

libstdc++-v3/include/bits/stl_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
11561156
*/
11571157
size_type
11581158
erase(const key_type& __x)
1159-
{ return _M_t.erase(__x); }
1159+
{ return _M_t._M_erase_unique(__x); }
11601160

11611161
#if __cplusplus >= 201103L
11621162
// _GLIBCXX_RESOLVE_LIB_DEFECTS

libstdc++-v3/include/bits/stl_set.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
728728
*/
729729
size_type
730730
erase(const key_type& __x)
731-
{ return _M_t.erase(__x); }
731+
{ return _M_t._M_erase_unique(__x); }
732732

733733
#if __cplusplus >= 201103L
734734
// _GLIBCXX_RESOLVE_LIB_DEFECTS

libstdc++-v3/include/bits/stl_tree.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,9 @@ namespace __rb_tree
18501850
size_type
18511851
erase(const key_type& __x);
18521852

1853+
size_type
1854+
_M_erase_unique(const key_type& __x);
1855+
18531856
#if __cplusplus >= 201103L
18541857
// _GLIBCXX_RESOLVE_LIB_DEFECTS
18551858
// DR 130. Associative erase should return an iterator.
@@ -3139,6 +3142,20 @@ namespace __rb_tree
31393142
return __old_size - size();
31403143
}
31413144

3145+
template<typename _Key, typename _Val, typename _KeyOfValue,
3146+
typename _Compare, typename _Alloc>
3147+
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
3148+
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
3149+
_M_erase_unique(const _Key& __x)
3150+
{
3151+
iterator __it = find(__x);
3152+
if (__it == end())
3153+
return 0;
3154+
3155+
_M_erase_aux(__it);
3156+
return 1;
3157+
}
3158+
31423159
template<typename _Key, typename _Val, typename _KeyOfValue,
31433160
typename _Compare, typename _Alloc>
31443161
typename _Rb_tree<_Key, _Val, _KeyOfValue,

0 commit comments

Comments
 (0)