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?


>
>>
>> libstdc++-v3/ChangeLog:
>>
>>       PR libstdc++/118185
>>         PR libstdc++/100249
>>       * 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)))
>>         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