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