[libcxx-commits] [libcxx] [libcxx] Add LWG4135: The helper lambda of std::erase for list should specify return type as bool (PR #128358)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 25 10:56:10 PST 2025


https://github.com/elhewaty updated https://github.com/llvm/llvm-project/pull/128358

>From ed34b2febb63a4570eb973b8cfaea7ca02f671fb Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Fri, 21 Feb 2025 21:17:25 +0200
Subject: [PATCH] [libcxx] Add LWG4135: The helper lambda of std::erase for
 list should specify return type as bool

---
 libcxx/docs/Status/Cxx2cIssues.csv            |  2 +-
 libcxx/include/forward_list                   |  2 +-
 libcxx/include/list                           |  2 +-
 .../forwardlist/bool-conversion.pass.cpp      | 37 +++++++++++++++++++
 .../list.modifiers/bool-conversion.pass.cpp   | 37 +++++++++++++++++++
 5 files changed, 77 insertions(+), 3 deletions(-)
 create mode 100644 libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp
 create mode 100644 libcxx/test/libcxx/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp

diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 1ec23dfabd5ea..228d95dead807 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -97,7 +97,7 @@
 "`LWG4124 <https://wg21.link/LWG4124>`__","Cannot format ``zoned_time`` with resolution coarser than ``seconds``","2024-11 (Wrocław)","","",""
 "`LWG4126 <https://wg21.link/LWG4126>`__","Some feature-test macros for fully freestanding features are not yet marked freestanding","2024-11 (Wrocław)","","",""
 "`LWG4134 <https://wg21.link/LWG4134>`__","Issue with Philox algorithm specification","2024-11 (Wrocław)","","",""
-"`LWG4135 <https://wg21.link/LWG4135>`__","The helper lambda of ``std::erase`` for list should specify return type as ``bool``","2024-11 (Wrocław)","","",""
+"`LWG4135 <https://wg21.link/LWG4135>`__","The helper lambda of ``std::erase`` for list should specify return type as ``bool``","2024-11 (Wrocław)","|Complete|","21",""
 "`LWG4140 <https://wg21.link/LWG4140>`__","Useless default constructors for bit reference types","2024-11 (Wrocław)","","",""
 "`LWG4141 <https://wg21.link/LWG4141>`__","Improve prohibitions on ""additional storage""","2024-11 (Wrocław)","","",""
 "`LWG4142 <https://wg21.link/LWG4142>`__","``format_parse_context::check_dynamic_spec`` should require at least one type","2024-11 (Wrocław)","","",""
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 4b6ca8ea8587c..8c688611d5ee2 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -1557,7 +1557,7 @@ erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
 template <class _Tp, class _Allocator, class _Up>
 inline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
 erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
-  return std::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
+  return std::erase_if(__c, [&](const auto& __elem) -> bool { return __elem == __v; });
 }
 #  endif
 
diff --git a/libcxx/include/list b/libcxx/include/list
index 3fcf796ebc03d..1285174f1c384 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -1703,7 +1703,7 @@ erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) {
 template <class _Tp, class _Allocator, class _Up>
 inline _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Allocator>::size_type
 erase(list<_Tp, _Allocator>& __c, const _Up& __v) {
-  return std::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
+  return std::erase_if(__c, [&](const auto& __elem) -> bool { return __elem == __v; });
 }
 
 template <>
diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp
new file mode 100644
index 0000000000000..237b0f155c7be
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// <forward_list>
+
+// This test shows the effect of implementing `LWG4135`, before it this code
+// was ill-formed, as the predicate is not bool. `LWG4135` suggests that
+// std::erase explicitly specifying the lambda's return type as bool.
+
+#include <forward_list>
+
+struct Bool {
+  Bool()            = default;
+  Bool(const Bool&) = delete;
+  operator bool() const { return true; }
+};
+
+struct Int {
+  Bool& operator==(Int) const {
+    static Bool b;
+    return b;
+  }
+};
+
+int main(int, char**) {
+  std::forward_list<Int> l;
+  std::erase(l, Int{});
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp
new file mode 100644
index 0000000000000..59083b8f45924
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// <list>
+
+// This test shows the effect of implementing `LWG4135`, before it this code
+// was ill-formed, as the predicate is not bool. `LWG4135` suggests that
+// std::erase explicitly specifying the lambda's return type as bool.
+
+#include <list>
+
+struct Bool {
+  Bool()            = default;
+  Bool(const Bool&) = delete;
+  operator bool() const { return true; }
+};
+
+struct Int {
+  Bool& operator==(Int) const {
+    static Bool b;
+    return b;
+  }
+};
+
+int main(int, char**) {
+  std::list<Int> l;
+  std::erase(l, Int{});
+
+  return 0;
+}



More information about the libcxx-commits mailing list