diff options
author | Patrick Palka <ppalka@redhat.com> | 2025-05-29 10:11:57 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2025-06-01 10:41:20 -0400 |
commit | 48d6f5dbb0e412266ebb77def04ed378ca856029 (patch) | |
tree | 50a36679a1ccc615c39d3196f0985477cf116bbb | |
parent | 512a41fae40cec705ca45a47150524154af8ead2 (diff) | |
download | gcc-48d6f5dbb0e412266ebb77def04ed378ca856029.zip gcc-48d6f5dbb0e412266ebb77def04ed378ca856029.tar.gz gcc-48d6f5dbb0e412266ebb77def04ed378ca856029.tar.bz2 |
libstdc++: Fix tuple/pair confusion with std::erase_if(flat_map) [PR120465]
std::erase_if for flat_map/multimap is implemented via ranges::erase_if
over a zip_view of the keys and values, the value_type of which is a
tuple, but the given predicate needs to be called with a pair (flat_map's
value_type). So use a projection to convert the tuple into a suitable
pair.
PR libstdc++/120465
libstdc++-v3/ChangeLog:
* include/std/flat_map (_Flat_map_impl::_M_erase_if): Use a
projection with ranges::remove_if to pass a pair instead of
a tuple to the predicate.
* testsuite/23_containers/flat_map/1.cc (test07): Strengthen
to expect the argument passed to the predicate is a pair.
* testsuite/23_containers/flat_multimap/1.cc (test07): Likewise.
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz KamiĆski <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
(cherry picked from commit 589b27ec5769410e036df57645ff1eb7c765f692)
-rw-r--r-- | libstdc++-v3/include/std/flat_map | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/flat_map/1.cc | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc | 3 |
3 files changed, 8 insertions, 3 deletions
diff --git a/libstdc++-v3/include/std/flat_map b/libstdc++-v3/include/std/flat_map index 6593988..cec7f36 100644 --- a/libstdc++-v3/include/std/flat_map +++ b/libstdc++-v3/include/std/flat_map @@ -895,7 +895,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { auto __guard = _M_make_clear_guard(); auto __zv = views::zip(_M_cont.keys, _M_cont.values); - auto __sr = ranges::remove_if(__zv, __pred); + auto __sr = ranges::remove_if(__zv, __pred, + [](const auto& __e) { + return const_reference(__e); + }); auto __erased = __sr.size(); erase(end() - __erased, end()); __guard._M_disable(); diff --git a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc index 38fd449..9d99796 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc @@ -245,8 +245,9 @@ void test07() { // PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work + // PR libstdc++/120465 - erase_if for flat_map calls predicate with incorrect type std::flat_map<int, int> m = {std::pair{1, 2}, {3, 4}, {5, 6}}; - auto n = std::erase_if(m, [](auto x) { auto [k,v] = x; return k == 1 || v == 6; }); + auto n = std::erase_if(m, [](auto x) { return x.first == 1 || x.second == 6; }); VERIFY( n == 2 ); VERIFY( std::ranges::equal(m, (std::pair<int,int>[]){{3,4}}) ); } diff --git a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc index 79fbc1a..0010955 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc @@ -223,8 +223,9 @@ void test07() { // PR libstdc++/119427 - std::erase_if(std::flat_foo) does not work + // PR libstdc++/120465 - erase_if for flat_map calls predicate with incorrect type std::flat_multimap<int, int> m = {std::pair{1, 2}, {3, 4}, {3, 3}, {5, 6}, {6, 6}}; - auto n = std::erase_if(m, [](auto x) { auto [k,v] = x; return k == 1 || v == 6; }); + auto n = std::erase_if(m, [](auto x) { return x.first == 1 || x.second == 6; }); VERIFY( n == 3 ); VERIFY( std::ranges::equal(m, (std::pair<int,int>[]){{3,4},{3,3}}) ); } |