[gcc r13-9479] libstdc++: Make std::erase for linked lists convert to bool
Jonathan Wakely
redi@gcc.gnu.org
Mon Mar 31 12:07:42 GMT 2025
https://gcc.gnu.org/g:8debc3440846a9840330835e61b5179616beaf63
commit r13-9479-g8debc3440846a9840330835e61b5179616beaf63
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Mar 6 21:18:21 2025 +0000
libstdc++: Make std::erase for linked lists convert to bool
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>
(cherry picked from commit e6e7b477bbdbfb3fee6b44087a59f94fd1e2c7a3)
Diff:
---
libstdc++-v3/include/std/forward_list | 5 +++--
libstdc++-v3/include/std/list | 5 +++--
.../23_containers/forward_list/erasure.cc | 22 ++++++++++++++++++++++
.../testsuite/23_containers/list/erasure.cc | 22 ++++++++++++++++++++++
4 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list
index 1c110df971b7..2e9379d388ea 100644
--- a/libstdc++-v3/include/std/forward_list
+++ b/libstdc++-v3/include/std/forward_list
@@ -75,8 +75,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;
});
}
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index 48861b9a3400..9eff5e9b0b04 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -99,8 +99,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;
});
}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
index 1454e8319774..ace04d4737f3 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
@@ -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::forward_list<Int> l;
+ std::erase(l, Int{});
+}
+
int
main()
{
diff --git a/libstdc++-v3/testsuite/23_containers/list/erasure.cc b/libstdc++-v3/testsuite/23_containers/list/erasure.cc
index de036dcd5bb4..3828df101ddf 100644
--- a/libstdc++-v3/testsuite/23_containers/list/erasure.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/erasure.cc
@@ -51,6 +51,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()
{
More information about the Gcc-cvs
mailing list