]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix tuple/pair confusion with std::erase_if(flat_map) [PR120465]
authorPatrick Palka <ppalka@redhat.com>
Thu, 29 May 2025 14:11:57 +0000 (10:11 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 29 May 2025 14:11:57 +0000 (10:11 -0400)
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>
libstdc++-v3/include/std/flat_map
libstdc++-v3/testsuite/23_containers/flat_map/1.cc
libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc

index 6593988d213c8cc6fb607b6014536d9030b305f9..cec7f36cff9fe5f46d8eb101a20667c1a59e2970 100644 (file)
@@ -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();
index a9690208b09fd62782a3c0fdae309907e173a5de..1b593135f22542f3c5b99e55cf1fa6faf0e44e64 100644 (file)
@@ -247,8 +247,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}}) );
 }
index 1c5c9a88ab6b58c6a5d948d30967d6243305c139..d746614401dea73ce06aad2cabae833d3073457e 100644 (file)
@@ -225,8 +225,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}}) );
 }