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

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 26 12:13:31 PST 2025


Author: elhewaty
Date: 2025-02-26T22:13:27+02:00
New Revision: 2c36411ed26e9ad0cc7e20bac11a34461682bccf

URL: https://github.com/llvm/llvm-project/commit/2c36411ed26e9ad0cc7e20bac11a34461682bccf
DIFF: https://github.com/llvm/llvm-project/commit/2c36411ed26e9ad0cc7e20bac11a34461682bccf.diff

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

Fixes https://github.com/llvm/llvm-project/issues/118355

Added: 
    libcxx/test/libcxx/containers/sequences/forwardlist/bool-conversion.pass.cpp
    libcxx/test/libcxx/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx2cIssues.csv
    libcxx/include/forward_list
    libcxx/include/list

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index d15688d064bb6..ef2da4df5d06c 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