public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-9980] libstdc++: Add std::reference_wrapper comparison operators for C++26
@ 2024-04-15 18:29 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2024-04-15 18:29 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:0d58450659ade002666c1c3604c94cd8e0cc6b50
commit r14-9980-g0d58450659ade002666c1c3604c94cd8e0cc6b50
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Mar 22 13:20:21 2024 +0000
libstdc++: Add std::reference_wrapper comparison operators for C++26
This C++26 change was just approved in Tokyo, in P2944R3. It adds
operator== and operator<=> overloads to std::reference_wrapper.
The operator<=> overloads in the paper cause compilation errors for any
type without <=> so they're implemented here with deduced return types
and constrained by a requires clause.
libstdc++-v3/ChangeLog:
* include/bits/refwrap.h (reference_wrapper): Add comparison
operators as proposed by P2944R3.
* include/bits/version.def (reference_wrapper): Define.
* include/bits/version.h: Regenerate.
* include/std/functional: Enable feature test macro.
* testsuite/20_util/reference_wrapper/compare.cc: New test.
Diff:
---
libstdc++-v3/include/bits/refwrap.h | 45 ++++++++++
libstdc++-v3/include/bits/version.def | 8 ++
libstdc++-v3/include/bits/version.h | 10 +++
libstdc++-v3/include/std/functional | 1 +
.../testsuite/20_util/reference_wrapper/compare.cc | 95 ++++++++++++++++++++++
5 files changed, 159 insertions(+)
diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h
index 2d4338b718f..fd1cc2b63e6 100644
--- a/libstdc++-v3/include/bits/refwrap.h
+++ b/libstdc++-v3/include/bits/refwrap.h
@@ -38,6 +38,10 @@
#include <bits/invoke.h>
#include <bits/stl_function.h> // for unary_function and binary_function
+#if __glibcxx_reference_wrapper >= 202403L // >= C++26
+# include <compare>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -358,6 +362,47 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
#endif
return std::__invoke(get(), std::forward<_Args>(__args)...);
}
+
+#if __glibcxx_reference_wrapper >= 202403L // >= C++26
+ // [refwrap.comparisons], comparisons
+ [[nodiscard]]
+ friend constexpr bool
+ operator==(reference_wrapper __x, reference_wrapper __y)
+ requires requires { { __x.get() == __y.get() } -> convertible_to<bool>; }
+ { return __x.get() == __y.get(); }
+
+ [[nodiscard]]
+ friend constexpr bool
+ operator==(reference_wrapper __x, const _Tp& __y)
+ requires requires { { __x.get() == __y } -> convertible_to<bool>; }
+ { return __x.get() == __y; }
+
+ [[nodiscard]]
+ friend constexpr bool
+ operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
+ requires (!is_const_v<_Tp>)
+ && requires { { __x.get() == __y.get() } -> convertible_to<bool>; }
+ { return __x.get() == __y.get(); }
+
+ [[nodiscard]]
+ friend constexpr auto
+ operator<=>(reference_wrapper __x, reference_wrapper<_Tp> __y)
+ requires requires { __detail::__synth3way(__x.get(), __y.get()); }
+ { return __detail::__synth3way(__x.get(), __y.get()); }
+
+ [[nodiscard]]
+ friend constexpr auto
+ operator<=>(reference_wrapper __x, const _Tp& __y)
+ requires requires { __detail::__synth3way(__x.get(), __y); }
+ { return __detail::__synth3way(__x.get(), __y); }
+
+ [[nodiscard]]
+ friend constexpr auto
+ operator<=>(reference_wrapper __x, reference_wrapper<const _Tp> __y)
+ requires (!is_const_v<_Tp>)
+ && requires { __detail::__synth3way(__x.get(), __y.get()); }
+ { return __detail::__synth3way(__x.get(), __y.get()); }
+#endif
};
#if __cpp_deduction_guides
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 5ad44941bff..5c0477fb61e 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1760,6 +1760,14 @@ ftms = {
};
};
+ftms = {
+ name = reference_wrapper;
+ values = {
+ v = 202403;
+ cxxmin = 26;
+ };
+};
+
ftms = {
name = saturation_arithmetic;
values = {
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 460a3e0116a..65e708c73fb 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1963,6 +1963,16 @@
#endif /* !defined(__cpp_lib_ratio) && defined(__glibcxx_want_ratio) */
#undef __glibcxx_want_ratio
+#if !defined(__cpp_lib_reference_wrapper)
+# if (__cplusplus > 202302L)
+# define __glibcxx_reference_wrapper 202403L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_reference_wrapper)
+# define __cpp_lib_reference_wrapper 202403L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_reference_wrapper) && defined(__glibcxx_want_reference_wrapper) */
+#undef __glibcxx_want_reference_wrapper
+
#if !defined(__cpp_lib_saturation_arithmetic)
# if (__cplusplus > 202302L)
# define __glibcxx_saturation_arithmetic 202311L
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 766558b3ce0..99364286a72 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -83,6 +83,7 @@
#define __glibcxx_want_move_only_function
#define __glibcxx_want_not_fn
#define __glibcxx_want_ranges
+#define __glibcxx_want_reference_wrapper
#define __glibcxx_want_transparent_operators
#include <bits/version.h>
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/compare.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/compare.cc
new file mode 100644
index 00000000000..039c9d26496
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/compare.cc
@@ -0,0 +1,95 @@
+// { dg-do compile { target c++26 } }
+
+
+#include <functional>
+
+#ifndef __cpp_lib_reference_wrapper
+# error "Feature-test macro for reference_wrapper missing"
+#elif __cpp_lib_reference_wrapper != 202403
+# error "Feature-test macro for reference_wrapper has wrong value"
+#endif
+
+// P2944R3 Comparisons for reference_wrapper
+
+auto check(int i, std::reference_wrapper<int> r) -> bool {
+ return i == r;
+}
+
+template <class T> using Ref = std::reference_wrapper<T>;
+
+template <class T>
+concept ref_equality_comparable
+= requires (T a, T const ca, Ref<T> r, Ref<T const> cr) {
+ // the usual T is equality-comparable with itself
+ a == a;
+ a == ca;
+ ca == ca;
+
+ // Ref<T> is equality-comparable with itself
+ r == r;
+ r == cr;
+ cr == cr;
+
+ // T and Ref<T> are equality-comparable
+ a == r;
+ a == cr;
+ ca == r;
+ ca == cr;
+};
+
+static_assert( ref_equality_comparable<int> );
+
+struct A {
+ auto operator==(A const&) const -> bool { return true; }
+};
+
+struct B {
+ friend auto operator==(B const&, B const&) -> bool { return true; }
+};
+
+template <class T>
+struct C {
+ friend auto operator==(C const&, C const&) -> bool { return true; }
+};
+
+template <class T>
+struct D { };
+template <class T>
+auto operator==(D<T> const&, D<T> const&) -> bool { return true; }
+
+static_assert(ref_equality_comparable<int>);
+static_assert(ref_equality_comparable<A>);
+static_assert(ref_equality_comparable<B>);
+static_assert(ref_equality_comparable<C<int>>);
+static_assert(ref_equality_comparable<D<int>>);
+#include <string_view>
+static_assert(ref_equality_comparable<std::string_view>);
+
+template <typename T>
+struct ValArray {
+ friend auto operator==(ValArray const&, ValArray const&) -> ValArray<bool> {
+ return {};
+ }
+};
+
+void f(ValArray<int> v) {
+ // this is valid and has type ValArray<bool>
+ v == v;
+
+ // this is also valid today and has the same type
+ std::ref(v) == std::ref(v);
+}
+
+struct ComparesAsInt {
+ friend auto operator==(ComparesAsInt, ComparesAsInt) -> int;
+};
+
+auto f(std::reference_wrapper<ComparesAsInt> a,
+ std::reference_wrapper<ComparesAsInt> b) {
+ // today: compiles and returns int
+ // proposed: compiles and returns bool
+ return a == b;
+}
+
+ComparesAsInt& c();
+static_assert( std::is_same_v<decltype(f(c(), c())), bool> );
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-04-15 18:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-15 18:29 [gcc r14-9980] libstdc++: Add std::reference_wrapper comparison operators for C++26 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).