public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] libstdc++: Ensure std::variant relops convert to bool [PR115145]
@ 2024-05-22  9:02 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2024-05-22  9:02 UTC (permalink / raw)
  To: libstdc++, gcc-patches

Tested x86_64-linux. Pushed to trunk.

-- >8 --

Ensure that the result of comparing the variant alternatives is
converted to bool immediately rather than copied.

libstdc++-v3/ChangeLog:

	PR libstdc++/115145
	* include/std/variant (operator==, operator!=, operator<)
	(operator<=, operator>, operator>=): Add trailing-return-type to
	lambda expressions to trigger conversion to bool.
	* testsuite/20_util/variant/relops/115145.cc: New test.
---
 libstdc++-v3/include/std/variant              | 63 ++++++++++---------
 .../20_util/variant/relops/115145.cc          | 36 +++++++++++
 2 files changed, 71 insertions(+), 28 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/variant/relops/115145.cc

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index cfb4bcdbcc9..371cbb90f54 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1271,10 +1271,11 @@ namespace __detail::__variant
     operator== [[nodiscard]] (const variant<_Types...>& __lhs,
 			      const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l == __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l == __r;
+				  });
     }
 
   template<typename... _Types>
@@ -1286,10 +1287,11 @@ namespace __detail::__variant
     operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
 			      const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l != __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l != __r;
+				  });
     }
 
   template<typename... _Types>
@@ -1301,10 +1303,11 @@ namespace __detail::__variant
     operator< [[nodiscard]] (const variant<_Types...>& __lhs,
 			     const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l < __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l < __r;
+				  });
     }
 
   template<typename... _Types>
@@ -1316,10 +1319,11 @@ namespace __detail::__variant
     operator<= [[nodiscard]] (const variant<_Types...>& __lhs,
 			      const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l <= __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l <= __r;
+				  });
     }
 
   template<typename... _Types>
@@ -1331,10 +1335,11 @@ namespace __detail::__variant
     operator> [[nodiscard]] (const variant<_Types...>& __lhs,
 			     const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l > __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l > __r;
+				  });
     }
 
   template<typename... _Types>
@@ -1346,10 +1351,11 @@ namespace __detail::__variant
     operator>= [[nodiscard]] (const variant<_Types...>& __lhs,
 			      const variant<_Types...>& __rhs)
     {
-      return __detail::__variant::__compare(true, __lhs, __rhs,
-					    [](auto&& __l, auto&& __r) {
-					      return __l >= __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(true, __lhs, __rhs,
+				  [](auto&& __l, auto&& __r) -> bool {
+				    return __l >= __r;
+				  });
     }
 
   constexpr bool operator==(monostate, monostate) noexcept { return true; }
@@ -1363,10 +1369,11 @@ namespace __detail::__variant
     {
       common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
 	= strong_ordering::equal;
-      return __detail::__variant::__compare(__ret, __v, __w,
-					    [](auto&& __l, auto&& __r) {
-					      return __l <=> __r;
-					    });
+      namespace __variant = __detail::__variant;
+      return __variant::__compare(__ret, __v, __w,
+				  [](auto&& __l, auto&& __r) {
+				    return __l <=> __r;
+				  });
     }
 
   constexpr strong_ordering
diff --git a/libstdc++-v3/testsuite/20_util/variant/relops/115145.cc b/libstdc++-v3/testsuite/20_util/variant/relops/115145.cc
new file mode 100644
index 00000000000..f3443cbbbcc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/relops/115145.cc
@@ -0,0 +1,36 @@
+// { dg-do compile { target c++17 } }
+// PR libstdc++/115145
+// lambda in rewritten std::variant comparisons does not specify return type
+
+#include <variant>
+
+struct Bool {
+  operator bool() & { return val; }
+  const bool val;
+};
+
+Bool t{true}, f{false};
+
+struct A {
+  Bool& operator==(const A&) const { return t; }
+  Bool& operator!=(const A&) const { return f; }
+  Bool& operator<(const A&) const { return f; }
+  Bool& operator>(const A&) const { return f; }
+  Bool& operator<=(const A&) const { return t; }
+  Bool& operator>=(const A&) const { return t; }
+};
+
+bool check_bool(bool);
+template<typename T> void check_bool(T) = delete;
+
+void
+test_pr115145()
+{
+  std::variant<A> v;
+  check_bool( v == v );
+  check_bool( !(v != v) );
+  check_bool( !(v < v) );
+  check_bool( !(v > v) );
+  check_bool( v <= v );
+  check_bool( v >= v );
+}
-- 
2.45.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-22  9:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-22  9:02 [committed] libstdc++: Ensure std::variant relops convert to bool [PR115145] Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).