On Mon, Mar 31, 2025 at 3:03 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> The boolean-testable requirements don't require the type to be copyable,
> so we need to convert to bool before it might need to be copied.
>
> libstdc++-v3/ChangeLog:
>
>         PR libstdc++/119545
>         * include/std/tuple (operator==): Convert comparison results to
>         bool.
>         * testsuite/20_util/tuple/comparison_operators/119545.cc: New
>         test.
> ---
>
> Tested x86_64-linux.
>
LGTM.

>
> For the recent r15-7897-ge6e7b477bbdbfb change to fix a similar problem
> I used an explicit return type on the lambda, because that was what the
> LWG issue said to do. In this case an explicit return type would also
> work, but I used an explicit conversion to bool on each element of the
> pack expansion instead.

boolean-testable requirements allows you to do that: a && b on
boolean-testable a, bis
required to have the same behavior bool(a) && bool(b), so all good.


> That matches what is done elsewhere in <tuple>
> for the tuple-like equality comparison, so I preferred to be locally
> consistent.
>
We also are no longer triggering lookup for opeartor&& on boolean-testable,
which is required to find nothing, but still will be performed. So I think
converting
to bool before applying &&/|| on boolean-testable is good idea.

>
>  libstdc++-v3/include/std/tuple                |  2 +-
>  .../tuple/comparison_operators/119545.cc      | 24 +++++++++++++++++++
>  2 files changed, 25 insertions(+), 1 deletion(-)
>  create mode 100644
> libstdc++-v3/testsuite/20_util/tuple/comparison_operators/119545.cc
>
> diff --git a/libstdc++-v3/include/std/tuple
> b/libstdc++-v3/include/std/tuple
> index d3deb7bc124..2e69af13a98 100644
> --- a/libstdc++-v3/include/std/tuple
> +++ b/libstdc++-v3/include/std/tuple
> @@ -2534,7 +2534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      {
>        return [&]<size_t... _Inds>(index_sequence<_Inds...>) {
>         // Fold == over the tuples until non-equal elements are found.
> -       return ((std::get<_Inds>(__t) == std::get<_Inds>(__u)) && ...);
> +       return (bool(std::get<_Inds>(__t) == std::get<_Inds>(__u)) && ...);
>        }(index_sequence_for<_Tps...>{});
>      }
>
> diff --git
> a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/119545.cc
> b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/119545.cc
> new file mode 100644
> index 00000000000..3a65ef53b01
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/119545.cc
> @@ -0,0 +1,24 @@
> +// { dg-do compile { target c++11 } }
> +// Bug libstdc++/119545
> +// tuple::operator==()'s help lambda does not specify return type as bool
> +
> +#include <tuple>
> +
> +void
> +test_pr119545()
> +{
> +  struct Bool {
> +    Bool() = default;
> +    Bool(const Bool&) = delete;
> +    operator bool() const { return true; }
> +  };
> +
> +  static Bool b;
> +
> +  struct Object {
> +    const Bool& operator==(const Object&) const { return b; }
> +  };
> +
> +  std::tuple<Object> t;
> +  (void) (t == t);
> +}
> --
> 2.49.0
>
>

Reply via email to