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>
This commit is contained in:
parent
4b18045962
commit
e6e7b477bb
4 changed files with 50 additions and 4 deletions
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue