[PATCH] libstdc++: perfectly forward std::ranges::clamp arguments
Patrick Palka
ppalka@redhat.com
Mon Jan 20 13:26:00 GMT 2025
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!
>
> 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.dangelo@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
>
More information about the Libstdc++
mailing list