[PATCH] libstdc++: Fix tuple/pair confusion with std::erase_if(flat_foo) [PR120465]
Jonathan Wakely
jwakely.gcc@gmail.com
Thu May 29 06:54:21 GMT 2025
On Thu, 29 May 2025, 03:00 Patrick Palka, <ppalka@redhat.com> wrote:
> std::erase_if for flat_map / flat_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. So use a projection to convert the tuple into the corresponding
> pair type.
>
> 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>
> ---
>
OK for trunk and 15, thanks
libstdc++-v3/include/std/flat_map | 5 ++++-
> libstdc++-v3/testsuite/23_containers/flat_map/1.cc | 3 ++-
> 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 5f9a2eda1939..c0716d12412a 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 2af516410279..01278d7dc33c 100644
> --- a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc
> +++ b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc
> @@ -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}}) );
> }
> diff --git a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc
> b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc
> index 1c5c9a88ab6b..d746614401de 100644
> --- a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc
> +++ b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc
> @@ -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}}) );
> }
> --
> 2.50.0.rc0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250529/f58e5683/attachment-0001.htm>
More information about the Libstdc++
mailing list