]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Simplify std::erase functions for sequence containers
authorJonathan Wakely <jwakely@redhat.com>
Fri, 19 Sep 2025 15:03:11 +0000 (16:03 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 26 Sep 2025 10:05:54 +0000 (11:05 +0100)
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 <tkaminsk@redhat.com>
libstdc++-v3/include/std/deque
libstdc++-v3/include/std/inplace_vector
libstdc++-v3/include/std/string
libstdc++-v3/include/std/vector

index 3b1a7dea2b1006a6e000007cda8b9d938aa400f6..c82f9dff2869ff871b96e3432f040d77658ad395 100644 (file)
@@ -66,7 +66,6 @@
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_deque.h>
-#include <bits/refwrap.h>
 #include <bits/range_access.h>
 #include <bits/deque.tcc>
 
@@ -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
index b32aa4f3708cbf01478d25fb08870ffb408f1014..91ceace08f5bb1a3db944707a178759c75080121 100644 (file)
@@ -42,7 +42,6 @@
 #include <bits/ranges_base.h> // borrowed_iterator_t, __detail::__container_compatible_range
 #include <bits/ranges_util.h> // subrange
 #include <bits/ranges_uninitialized.h>
-#include <bits/refwrap.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_algo.h> // 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<typename _Tp, size_t _Nm, typename _Up = _Tp>
     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
index 74e0c7f2be5855bdb89eb298b0375cd2c54ff414..4b84aeaa857b90327263ee800ad8113bd379d988 100644 (file)
@@ -51,7 +51,6 @@
 #include <bits/stl_function.h> // For less
 #include <ext/numeric_traits.h>
 #include <bits/stl_algobase.h>
-#include <bits/refwrap.h>
 #include <bits/range_access.h>
 #include <bits/basic_string.h>
 #include <bits/basic_string.tcc>
@@ -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
index 47105210bc0c64f21f566ce67b7f6e57d81389b6..cdc30cbff6deeba0daf7b2396a232c3f3e2ea3c5 100644 (file)
@@ -67,7 +67,6 @@
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_vector.h>
 #include <bits/stl_bvector.h>
-#include <bits/refwrap.h>
 #include <bits/range_access.h>
 
 #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