From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1720) id 09EE93858411; Sat, 20 Nov 2021 15:14:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 09EE93858411 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: =?utf-8?b?RnJhbuCkpeCkiG9pcyBEdW1vbnQ=?= To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-5431] libstdc++: [_GLIBCXX_DEBUG] Reduce performance impact on std::erase_if X-Act-Checkin: gcc X-Git-Author: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Git-Refname: refs/heads/master X-Git-Oldrev: 74faa9834a9ad208e34f67b08c854c20b0fcfe92 X-Git-Newrev: 5f40d34b6dd30ed076f9beb9a88e7ec264c1a55a Message-Id: <20211120151416.09EE93858411@sourceware.org> Date: Sat, 20 Nov 2021 15:14:16 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Nov 2021 15:14:16 -0000 https://gcc.gnu.org/g:5f40d34b6dd30ed076f9beb9a88e7ec264c1a55a commit r12-5431-g5f40d34b6dd30ed076f9beb9a88e7ec264c1a55a Author: François Dumont Date: Tue Nov 16 21:51:11 2021 +0100 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. Diff: --- libstdc++-v3/include/bits/erase_if.h | 8 +++-- libstdc++-v3/include/debug/macros.h | 42 +++++++++++++++---------- libstdc++-v3/include/debug/map.h | 11 +++++-- libstdc++-v3/include/debug/multimap.h | 11 +++++-- libstdc++-v3/include/debug/multiset.h | 11 +++++-- libstdc++-v3/include/debug/set.h | 11 +++++-- libstdc++-v3/include/debug/unordered_map | 14 +++++++++ libstdc++-v3/include/debug/unordered_set | 14 +++++++++ libstdc++-v3/include/experimental/map | 12 +++++-- libstdc++-v3/include/experimental/set | 10 ++++-- libstdc++-v3/include/experimental/unordered_map | 12 +++++-- libstdc++-v3/include/experimental/unordered_set | 12 +++++-- libstdc++-v3/include/std/map | 12 +++++-- libstdc++-v3/include/std/set | 10 ++++-- libstdc++-v3/include/std/unordered_map | 12 +++++-- libstdc++-v3/include/std/unordered_set | 12 +++++-- 16 files changed, 170 insertions(+), 44 deletions(-) diff --git a/libstdc++-v3/include/bits/erase_if.h b/libstdc++-v3/include/bits/erase_if.h index 8d1d23168fa..61f88e3cca3 100644 --- a/libstdc++-v3/include/bits/erase_if.h +++ b/libstdc++-v3/include/bits/erase_if.h @@ -46,12 +46,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { - template + template 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)) diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h index 9e1288cf4d9..0183d2a8223 100644 --- a/libstdc++-v3/include/debug/macros.h +++ b/libstdc++-v3/include/debug/macros.h @@ -211,14 +211,22 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\ */ #define __glibcxx_check_erase(_Position) \ _GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ - _M_message(__gnu_debug::__msg_erase_bad) \ - ._M_sequence(*this, "this") \ + _M_message(__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)); \ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ _M_message(__gnu_debug::__msg_erase_different) \ ._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. @@ -241,7 +249,7 @@ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ __glibcxx_check_valid_range(_First,_Last); \ _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ _M_message(__gnu_debug::__msg_erase_different) \ - ._M_sequence(*this, "this") \ + ._M_sequence(*this, "this") \ ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last)) @@ -284,7 +292,7 @@ _GLIBCXX_DEBUG_VERIFY(!_Last._M_is_before_begin(), \ #define __glibcxx_check_subscript(_N) \ _GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ _M_message(__gnu_debug::__msg_subscript_oob) \ - ._M_sequence(*this, "this") \ + ._M_sequence(*this, "this") \ ._M_integer(_N, #_N) \ ._M_integer(this->size(), "size")) @@ -292,15 +300,15 @@ _GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ #define __glibcxx_check_bucket_index(_N) \ _GLIBCXX_DEBUG_VERIFY(_N < this->bucket_count(), \ _M_message(__gnu_debug::__msg_bucket_index_oob) \ - ._M_sequence(*this, "this") \ + ._M_sequence(*this, "this") \ ._M_integer(_N, #_N) \ ._M_integer(this->bucket_count(), "size")) // Verify that the container is nonempty #define __glibcxx_check_nonempty() \ _GLIBCXX_DEBUG_VERIFY(! this->empty(), \ - _M_message(__gnu_debug::__msg_empty) \ - ._M_sequence(*this, "this")) + _M_message(__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) // Verify that a predicate is irreflexive #define __glibcxx_check_irreflexive(_First,_Last) \ @@ -342,8 +350,8 @@ __glibcxx_check_irreflexive(_First,_Last); \ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted( \ __gnu_debug::__base(_First), \ __gnu_debug::__base(_Last)), \ - _M_message(__gnu_debug::__msg_unsorted) \ - ._M_iterator(_First, #_First) \ + _M_message(__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last)) /** Verify that the iterator range [_First, _Last) is sorted by the @@ -355,14 +363,14 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted( \ __gnu_debug::__base(_First), \ __gnu_debug::__base(_Last), _Pred), \ _M_message(__gnu_debug::__msg_unsorted_pred) \ - ._M_iterator(_First, #_First) \ + ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last) \ ._M_string(#_Pred)) // Special variant for std::merge, std::includes, std::set_* #define __glibcxx_check_sorted_set(_First1,_Last1,_First2) \ __glibcxx_check_valid_range(_First1,_Last1); \ -_GLIBCXX_DEBUG_VERIFY( \ +_GLIBCXX_DEBUG_VERIFY( \ __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1), \ __gnu_debug::__base(_Last1), _First2),\ _M_message(__gnu_debug::__msg_unsorted) \ @@ -371,7 +379,7 @@ _GLIBCXX_DEBUG_VERIFY( \ // Likewise with a _Pred. #define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred) \ -__glibcxx_check_valid_range(_First1,_Last1); \ +__glibcxx_check_valid_range(_First1,_Last1); \ _GLIBCXX_DEBUG_VERIFY( \ __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1), \ __gnu_debug::__base(_Last1), \ @@ -414,7 +422,7 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower( \ ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last) \ ._M_string(#_Pred) \ - ._M_string(#_Value)) + ._M_string(#_Value)) /** Verify that the iterator range [_First, _Last) is partitioned w.r.t. the value _Value and predicate _Pred. */ @@ -427,13 +435,13 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper( \ ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last) \ ._M_string(#_Pred) \ - ._M_string(#_Value)) + ._M_string(#_Value)) // Verify that the iterator range [_First, _Last) is a heap #define __glibcxx_check_heap(_First,_Last) \ _GLIBCXX_DEBUG_VERIFY(std::__is_heap(__gnu_debug::__base(_First), \ __gnu_debug::__base(_Last)), \ - _M_message(__gnu_debug::__msg_not_heap) \ + _M_message(__gnu_debug::__msg_not_heap) \ ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last)) @@ -444,7 +452,7 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper( \ __gnu_debug::__base(_Last), \ _Pred), \ _M_message(__gnu_debug::__msg_not_heap_pred) \ - ._M_iterator(_First, #_First) \ + ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last) \ ._M_string(#_Pred)) @@ -452,7 +460,7 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper( \ #define __glibcxx_check_max_load_factor(_F) \ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \ _M_message(__gnu_debug::__msg_valid_load_factor) \ - ._M_sequence(*this, "this")) + ._M_sequence(*this, "this")) #define __glibcxx_check_equal_allocs(_This, _Other) \ _GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(), \ diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h index c62f0b574e6..f13a25d4701 100644 --- a/libstdc++-v3/include/debug/map.h +++ b/libstdc++-v3/include/debug/map.h @@ -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 diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h index 5f0f1faa33e..b7c2388082b 100644 --- a/libstdc++-v3/include/debug/multimap.h +++ b/libstdc++-v3/include/debug/multimap.h @@ -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 diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h index 7729fc19689..30e93e4f038 100644 --- a/libstdc++-v3/include/debug/multiset.h +++ b/libstdc++-v3/include/debug/multiset.h @@ -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 diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h index 39142aef60b..0eaabf47d34 100644 --- a/libstdc++-v3/include/debug/set.h +++ b/libstdc++-v3/include/debug/set.h @@ -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 diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 64cc8bacabd..8ccb60c17db 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -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) { diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index 3516af4dc4e..716635fc20c 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -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) { diff --git a/libstdc++-v3/include/experimental/map b/libstdc++-v3/include/experimental/map index 0c0f42222f5..13304320232 100644 --- a/libstdc++-v3/include/experimental/map +++ b/libstdc++-v3/include/experimental/map @@ -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 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> diff --git a/libstdc++-v3/include/experimental/set b/libstdc++-v3/include/experimental/set index c3f5433e995..2a56ede5cf1 100644 --- a/libstdc++-v3/include/experimental/set +++ b/libstdc++-v3/include/experimental/set @@ -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 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> diff --git a/libstdc++-v3/include/experimental/unordered_map b/libstdc++-v3/include/experimental/unordered_map index 0b915ab13e5..69f209d83e7 100644 --- a/libstdc++-v3/include/experimental/unordered_map +++ b/libstdc++-v3/include/experimental/unordered_map @@ -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 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, diff --git a/libstdc++-v3/include/experimental/unordered_set b/libstdc++-v3/include/experimental/unordered_set index 87db4464401..fbab7e7ddb5 100644 --- a/libstdc++-v3/include/experimental/unordered_set +++ b/libstdc++-v3/include/experimental/unordered_set @@ -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 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, diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map index 44bd44b5922..9278a1b18ce 100644 --- a/libstdc++-v3/include/std/map +++ b/libstdc++-v3/include/std/map @@ -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 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 diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set index f1e1864937a..10178b65785 100644 --- a/libstdc++-v3/include/std/set +++ b/libstdc++-v3/include/std/set @@ -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 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 diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map index e6715069362..0c8b076a1eb 100644 --- a/libstdc++-v3/include/std/unordered_map +++ b/libstdc++-v3/include/std/unordered_map @@ -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 @@ -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 diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set index 1ad93d0031b..3a33f573499 100644 --- a/libstdc++-v3/include/std/unordered_set +++ b/libstdc++-v3/include/std/unordered_set @@ -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 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