aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-03-06 21:18:21 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2025-03-07 20:36:34 +0000
commite6e7b477bbdbfb3fee6b44087a59f94fd1e2c7a3 (patch)
tree90a0d01ebc70514d6648ca247ec5e97e6758b360
parent4b180459626df64dac758da8760d868c2604ddf2 (diff)
downloadgcc-e6e7b477bbdbfb3fee6b44087a59f94fd1e2c7a3.zip
gcc-e6e7b477bbdbfb3fee6b44087a59f94fd1e2c7a3.tar.gz
gcc-e6e7b477bbdbfb3fee6b44087a59f94fd1e2c7a3.tar.bz2
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>
-rw-r--r--libstdc++-v3/include/std/forward_list5
-rw-r--r--libstdc++-v3/include/std/list5
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc22
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/erasure.cc22
4 files changed, 50 insertions, 4 deletions
diff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list
index 6c5ad11..166fdb0 100644
--- a/libstdc++-v3/include/std/forward_list
+++ b/libstdc++-v3/include/std/forward_list
@@ -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;
});
}
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index 51f1bc0..170499d 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -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;
});
}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
index 37e5020..1ec11de 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc
@@ -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()
{
diff --git a/libstdc++-v3/testsuite/23_containers/list/erasure.cc b/libstdc++-v3/testsuite/23_containers/list/erasure.cc
index 1a33eca..9f4f853 100644
--- a/libstdc++-v3/testsuite/23_containers/list/erasure.cc
+++ b/libstdc++-v3/testsuite/23_containers/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::list<Int> l;
+ std::erase(l, Int{});
+}
+
int
main()
{