On Mon, 20 Jan 2025, Jonathan Wakely wrote:

> 
> 
> On Monday, 20 January 2025, Patrick Palka <ppa...@redhat.com> wrote:
> > On Sun, 19 Jan 2025, Giuseppe D'Angelo wrote:
> >
> >> Hi,
> >>
> >> the attached patch fixes PR118185 (mentioned in the earlier thread about
> >> 118160). Tested on x86-64 Linux.
> >>
> >> Thanks,
> >> --
> >> Giuseppe D'Angelo
> >>
> >
> >> Subject: [PATCH] libstdc++: perfectly forward std::ranges::clamp arguments
> >>
> >> As reported in PR118185, std::ranges::clamp does not correctly forward
> >> the projected value to the comparator. Add the missing forward.
> >
> > LGTM!
> 
> Agreed, this is ok for trunk and any relevant branches. Could you please push 
> this one, Patrick?

Pushed to trunk so far.

> 
> 
> >
> >>
> >> libstdc++-v3/ChangeLog:
> >>
> >>       PR libstdc++/118185
> >>         PR libstdc++/100249

A leading tab was needed on this line in order to make the changelog/commit 
hook happy.

> >>       * include/bits/ranges_algo.h (__clamp_fn): Correctly forward the
> >>       projected value to the comparator.
> >>       * testsuite/25_algorithms/clamp/118185.cc: New test.
> >>
> >> Signed-off-by: Giuseppe D'Angelo <giuseppe.dang...@kdab.com>
> >> ---
> >>  libstdc++-v3/include/bits/ranges_algo.h       |  4 +-
> >>  .../testsuite/25_algorithms/clamp/118185.cc   | 42 +++++++++++++++++++
> >>  2 files changed, 44 insertions(+), 2 deletions(-)
> >>  create mode 100644 libstdc++-v3/testsuite/25_algorithms/clamp/118185.cc
> >>
> >> diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
> >> b/libstdc++-v3/include/bits/ranges_algo.h
> >> index e38a330d48c..bb6ab8b6b4b 100644
> >> --- a/libstdc++-v3/include/bits/ranges_algo.h
> >> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> >> @@ -2993,9 +2993,9 @@ namespace ranges
> >>                                        std::__invoke(__proj, __hi),
> >>                                        std::__invoke(__proj, __lo))));
> >>       auto&& __proj_val = std::__invoke(__proj, __val);
> >> -     if (std::__invoke(__comp, __proj_val, std::__invoke(__proj, __lo)))
> >> +     if (std::__invoke(__comp, 
> >> std::forward<decltype(__proj_val)>(__proj_val), std::__invoke(__proj, 
> >> __lo)))
> >>         return __lo;
> >> -     else if (std::__invoke(__comp, std::__invoke(__proj, __hi), 
> >> __proj_val))
> >> +     else if (std::__invoke(__comp, std::__invoke(__proj, __hi), 
> >> std::forward<decltype(__proj_val)>(__proj_val)))

I also made the trivial formatting change of splitting these lines up to
be more consistent with nearby code.

> >>         return __hi;
> >>       else
> >>         return __val;
> >> diff --git a/libstdc++-v3/testsuite/25_algorithms/clamp/118185.cc 
> >> b/libstdc++-v3/testsuite/25_algorithms/clamp/118185.cc
> >> new file mode 100644
> >> index 00000000000..908eb708c1e
> >> --- /dev/null
> >> +++ b/libstdc++-v3/testsuite/25_algorithms/clamp/118185.cc
> >> @@ -0,0 +1,42 @@
> >> +// { dg-do compile { target c++20 } }
> >> +
> >> +#include <algorithm>
> >> +#include <concepts>
> >> +
> >> +struct Comp
> >> +{
> >> +  constexpr bool operator()(const int&& x, const int&& y) { return x < y; 
> >> }
> >> +};
> >> +
> >> +struct Proj
> >> +{
> >> +  constexpr const int&& operator()(const int& x) const { return 
> >> std::move(x); }
> >> +};
> >> +
> >> +static_assert(std::indirect_strict_weak_order<Comp, std::projected<const 
> >> int*, Proj>>);
> >> +
> >> +static_assert(std::ranges::clamp(+1, 0, 2, Comp{}, Proj{}) == 1);
> >> +static_assert(std::ranges::clamp(-1, 0, 2, Comp{}, Proj{}) == 0);
> >> +static_assert(std::ranges::clamp(10, 0, 2, Comp{}, Proj{}) == 2);
> >> +
> >> +
> >> +// Testcase from PR118185
> >> +
> >> +struct Comp2
> >> +{
> >> +  constexpr bool operator()(const int&& x, const int&& y) const { return 
> >> x < y; }
> >> +  constexpr bool operator()(const int&& x, int& y) const { return x < y; }
> >> +  constexpr bool operator()(int& x, const int&& y) const { return x < y; }
> >> +  constexpr bool operator()(int& x, int& y) const { return x < y; }
> >> +  constexpr bool operator()(std::same_as<const int&> auto && x, 
> >> std::same_as<const int&> auto && y) const
> >> +  {
> >> +    return x < y;
> >> +  }
> >> +};
> >> +
> >> +static_assert(std::indirect_strict_weak_order<Comp2, std::projected<const 
> >> int*, Proj>>);
> >> +
> >> +static_assert(std::ranges::clamp(+1, 0, 2, Comp2{}, Proj{}) == 1);
> >> +static_assert(std::ranges::clamp(-1, 0, 2, Comp2{}, Proj{}) == 0);
> >> +static_assert(std::ranges::clamp(10, 0, 2, Comp2{}, Proj{}) == 2);
> >> +
> >> --
> >> 2.34.1
> >>
> >
> >
> 

Reply via email to