On Thu, May 29, 2025 at 4:01 AM Patrick Palka <ppa...@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 <jwak...@redhat.com>
> ---
>
LGTM.

>  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
>
>

Reply via email to