From: Jonathan Wakely Date: Fri, 19 Sep 2025 15:03:11 +0000 (+0100) Subject: libstdc++: Simplify std::erase functions for sequence containers X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b83c2e52a21c1882a149e89e5ab152c09a73fb30;p=thirdparty%2Fgcc.git libstdc++: Simplify std::erase functions for sequence containers This removes the use of std::ref that meant that __remove_if used an indirection through the reference, which might be a pessimization. Users can always use std::ref to pass expensive predicates into erase_if, but we shouldn't do it unconditionally. We can std::move the predicate so that if it's not cheap to copy and the user didn't use std::ref, then we try to use a cheaper move instead of a copy. There's no reason that std::erase shouldn't just be implemented by forwarding to std::erase_if. I probably should have done that in r12-4083-gacf3a21cbc26b3 when std::erase started to call __remove_if directly. libstdc++-v3/ChangeLog: * include/std/deque (erase_if): Move predicate instead of wrapping with std::ref. (erase): Forward to erase_if. * include/std/inplace_vector (erase_if, erase): Likewise. * include/std/string (erase_if, erase): Likewise. * include/std/vector (erase_if, erase): Likewise. Reviewed-by: Tomasz KamiƄski --- diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque index 3b1a7dea2b1..c82f9dff286 100644 --- a/libstdc++-v3/include/std/deque +++ b/libstdc++-v3/include/std/deque @@ -66,7 +66,6 @@ #include #include #include -#include #include #include @@ -109,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const auto __osz = __cont.size(); const auto __end = __ucont.end(); auto __removed = std::__remove_if(__ucont.begin(), __end, - std::ref(__pred)); + std::move(__pred)); if (__removed != __end) { __cont.erase(__niter_wrap(__cont.begin(), __removed), @@ -124,22 +123,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)> inline typename deque<_Tp, _Alloc>::size_type erase(deque<_Tp, _Alloc>& __cont, const _Up& __value) - { - using namespace __gnu_cxx; - _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __ucont = __cont; - const auto __osz = __cont.size(); - const auto __end = __ucont.end(); - auto __removed = std::__remove_if(__ucont.begin(), __end, - __ops::__equal_to(__value)); - if (__removed != __end) - { - __cont.erase(__niter_wrap(__cont.begin(), __removed), - __cont.end()); - return __osz - __cont.size(); - } + { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } - return 0; - } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_erase_if diff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector index b32aa4f3708..91ceace08f5 100644 --- a/libstdc++-v3/include/std/inplace_vector +++ b/libstdc++-v3/include/std/inplace_vector @@ -42,7 +42,6 @@ #include // borrowed_iterator_t, __detail::__container_compatible_range #include // subrange #include -#include #include #include #include // rotate @@ -1343,7 +1342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const auto __osz = __cont.size(); const auto __end = __cont.end(); auto __removed = std::__remove_if(__cont.begin(), __end, - std::ref(__pred)); + std::move(__pred)); if (__removed != __end) { __cont.erase(__niter_wrap(__cont.begin(), __removed), @@ -1357,20 +1356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr size_t erase(inplace_vector<_Tp, _Nm>& __cont, const _Up& __value) - { - using namespace __gnu_cxx; - const auto __osz = __cont.size(); - const auto __end = __cont.end(); - auto __removed = std::__remove_if(__cont.begin(), __end, - __ops::__equal_to(__value)); - if (__removed != __end) - { - __cont.erase(__niter_wrap(__cont.begin(), __removed), - __cont.end()); - return __osz - __cont.size(); - } - return 0; - } + { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string index 74e0c7f2be5..4b84aeaa857 100644 --- a/libstdc++-v3/include/std/string +++ b/libstdc++-v3/include/std/string @@ -51,7 +51,6 @@ #include // For less #include #include -#include #include #include #include @@ -104,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const auto __osz = __cont.size(); const auto __end = __cont.end(); auto __removed = std::__remove_if(__cont.begin(), __end, - std::ref(__pred)); + std::move(__pred)); __cont.erase(__removed, __end); return __osz - __cont.size(); } @@ -114,15 +113,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename basic_string<_CharT, _Traits, _Alloc>::size_type erase(basic_string<_CharT, _Traits, _Alloc>& __cont, const _Up& __value) - { - using namespace __gnu_cxx; - const auto __osz = __cont.size(); - const auto __end = __cont.end(); - auto __removed = std::__remove_if(__cont.begin(), __end, - __ops::__equal_to(__value)); - __cont.erase(__removed, __end); - return __osz - __cont.size(); - } + { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_erase_if diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector index 47105210bc0..cdc30cbff6d 100644 --- a/libstdc++-v3/include/std/vector +++ b/libstdc++-v3/include/std/vector @@ -67,7 +67,6 @@ #include #include #include -#include #include #ifndef _GLIBCXX_EXPORT_TEMPLATE @@ -122,7 +121,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const auto __osz = __cont.size(); const auto __end = __ucont.end(); auto __removed = std::__remove_if(__ucont.begin(), __end, - std::ref(__pred)); + std::move(__pred)); if (__removed != __end) { __cont.erase(__niter_wrap(__cont.begin(), __removed), @@ -138,22 +137,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename vector<_Tp, _Alloc>::size_type erase(vector<_Tp, _Alloc>& __cont, const _Up& __value) - { - using namespace __gnu_cxx; - _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __ucont = __cont; - const auto __osz = __cont.size(); - const auto __end = __ucont.end(); - auto __removed = std::__remove_if(__ucont.begin(), __end, - __ops::__equal_to(__value)); - if (__removed != __end) - { - __cont.erase(__niter_wrap(__cont.begin(), __removed), - __cont.end()); - return __osz - __cont.size(); - } + { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } - return 0; - } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_erase_if