]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Make std::erase for linked lists convert to bool
authorJonathan Wakely <jwakely@redhat.com>
Thu, 6 Mar 2025 21:18:21 +0000 (21:18 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 7 Mar 2025 20:36:34 +0000 (20:36 +0000)
LWG 4135 (approved in Wrocław, November 2024) fixes the lambda
expressions used by std::erase for std::list and std::forward_list.
Previously they attempted to copy something that isn't required to be
copyable. Instead they should convert it to bool right away.

The issue resolution also changes the lambda's parameter to be const, so
that it can't modify the elements while comparing them.

libstdc++-v3/ChangeLog:

* include/std/forward_list (erase): Change lambda to have
explicit return type and const parameter type.
* include/std/list (erase): Likewise.
* testsuite/23_containers/forward_list/erasure.cc: Check lambda
is correct.
* testsuite/23_containers/list/erasure.cc: Likewise.

Reviewed-by: Patrick Palka <ppalka@redhat.com>
libstdc++-v3/include/std/forward_list
libstdc++-v3/include/std/list
libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
libstdc++-v3/testsuite/23_containers/list/erasure.cc

index 6c5ad1195db9bab2af841e89f5726855512877d4..166fdb04242ae5781cc0aa3ae9455d715cc9c398 100644 (file)
@@ -83,8 +83,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline typename forward_list<_Tp, _Alloc>::size_type
     erase(forward_list<_Tp, _Alloc>& __cont, const _Up& __value)
     {
-      using __elem_type = typename forward_list<_Tp, _Alloc>::value_type;
-      return std::erase_if(__cont, [&](__elem_type& __elem) {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 4135. helper lambda of std::erase for list should specify return type
+      return std::erase_if(__cont, [&](const auto& __elem) -> bool {
          return __elem == __value;
       });
     }
index 51f1bc079cc2aa61b691dbf99320f546795b874a..170499d65f718a13cd61b0dd0c10f8ef42e30dea 100644 (file)
@@ -107,8 +107,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline typename list<_Tp, _Alloc>::size_type
     erase(list<_Tp, _Alloc>& __cont, const _Up& __value)
     {
-      using __elem_type = typename list<_Tp, _Alloc>::value_type;
-      return std::erase_if(__cont, [&](__elem_type& __elem) {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 4135. helper lambda of std::erase for list should specify return type
+      return std::erase_if(__cont, [&](const auto& __elem) -> bool {
          return __elem == __value;
       });
     }
index 37e5020395991ec82a44e4cd72c56dc280e97759..1ec11de6e36ca8b6e8b76d4bcbc2e61c52e2ff9c 100644 (file)
@@ -53,6 +53,28 @@ test02()
   VERIFY( num == 0 );
 }
 
+// LWG 4135.
+// The helper lambda of std::erase for list should specify return type as bool
+void
+test_lwg4135()
+{
+  struct Bool {
+    Bool() = default;
+    Bool(const Bool&) = delete;
+    operator bool() const { return false; }
+  };
+
+  static Bool b;
+
+  struct Int {
+    Bool& operator==(Int) const { return b; }
+    void operator==(Int) = delete;
+  };
+
+  std::forward_list<Int> l;
+  std::erase(l, Int{});
+}
+
 int
 main()
 {
index 1a33eca77c26ce02f5a99e9e4d2d5a0b6cd494d6..9f4f8536fe6481dd61508be887c222bdf2ae018b 100644 (file)
@@ -52,6 +52,28 @@ test02()
   VERIFY( num == 0 );
 }
 
+// LWG 4135.
+// The helper lambda of std::erase for list should specify return type as bool
+void
+test_lwg4135()
+{
+  struct Bool {
+    Bool() = default;
+    Bool(const Bool&) = delete;
+    operator bool() const { return false; }
+  };
+
+  static Bool b;
+
+  struct Int {
+    Bool& operator==(Int) const { return b; }
+    void operator==(Int) = delete;
+  };
+
+  std::list<Int> l;
+  std::erase(l, Int{});
+}
+
 int
 main()
 {