aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-12-05 13:43:29 -0500
committerPatrick Palka <ppalka@redhat.com>2025-12-05 13:43:29 -0500
commita9fd651fbb54024548158ee605eb13dce77afe26 (patch)
tree5bc4fcfd25c938c8a06e232e4e4c61db1eb91b8b
parentcbdbbdd1fccfd789e6fbcb37b1b602bb7482de4b (diff)
downloadgcc-a9fd651fbb54024548158ee605eb13dce77afe26.zip
gcc-a9fd651fbb54024548158ee605eb13dce77afe26.tar.gz
gcc-a9fd651fbb54024548158ee605eb13dce77afe26.tar.bz2
libstdc++: Implement P2655R3 changes to common_reference bullet 1
We implement this paper as a DR against C++20 (as do MSVC and libc++). PR libstdc++/120446 libstdc++-v3/ChangeLog: * include/bits/version.def (common_reference): New. * include/bits/version.h: Regenerate. * include/std/type_traits (__glibcxx_want_common_reference): Define. (__common_reference_impl<T1, T2, 1>): Add pointer convertibility constraints as per P2655R3. * testsuite/20_util/common_reference/p2655r3.cc: New test. Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
-rw-r--r--libstdc++-v3/include/bits/version.def8
-rw-r--r--libstdc++-v3/include/bits/version.h10
-rw-r--r--libstdc++-v3/include/std/type_traits7
-rw-r--r--libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc15
4 files changed, 40 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index d20e085..91c1ede 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1822,6 +1822,14 @@ ftms = {
};
ftms = {
+ name = common_reference;
+ values = {
+ v = 202302;
+ cxxmin = 20; // We treat P2655R3 as a DR against C++20.
+ };
+};
+
+ftms = {
name = formatters;
values = {
v = 202302;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index c75368d4..f5ddc86 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2030,6 +2030,16 @@
#endif /* !defined(__cpp_lib_flat_set) */
#undef __glibcxx_want_flat_set
+#if !defined(__cpp_lib_common_reference)
+# if (__cplusplus >= 202002L)
+# define __glibcxx_common_reference 202302L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_common_reference)
+# define __cpp_lib_common_reference 202302L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_common_reference) && defined(__glibcxx_want_common_reference) */
+#undef __glibcxx_want_common_reference
+
#if !defined(__cpp_lib_formatters)
# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
# define __glibcxx_formatters 202302L
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 418e218..7c157ea 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -41,6 +41,7 @@
#define __glibcxx_want_bool_constant
#define __glibcxx_want_bounded_array_traits
+#define __glibcxx_want_common_reference
#define __glibcxx_want_constant_wrapper
#define __glibcxx_want_has_unique_object_representations
#define __glibcxx_want_integral_constant_callable
@@ -4240,6 +4241,12 @@ template<typename _Ret, typename _Fn, typename... _Args>
template<typename _Tp1, typename _Tp2>
requires is_reference_v<_Tp1> && is_reference_v<_Tp2>
&& requires { typename __common_ref<_Tp1, _Tp2>; }
+#if __cpp_lib_common_reference // C++ >= 20
+ && is_convertible_v<add_pointer_t<_Tp1>,
+ add_pointer_t<__common_ref<_Tp1, _Tp2>>>
+ && is_convertible_v<add_pointer_t<_Tp2>,
+ add_pointer_t<__common_ref<_Tp1, _Tp2>>>
+#endif
struct __common_reference_impl<_Tp1, _Tp2, 1>
{ using type = __common_ref<_Tp1, _Tp2>; };
diff --git a/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc b/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
new file mode 100644
index 0000000..4188dd2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc
@@ -0,0 +1,15 @@
+// P2655R3 - common_reference_t of reference_wrapper Should Be a Reference Type
+// Implemented as a DR against C++20
+// { dg-do compile { target c++20 } }
+
+#include <type_traits>
+
+#if __cpp_lib_common_reference != 202302L
+# error "Feature-test macro __cpp_lib_common_reference has wrong value in <type_traits>"
+#endif
+
+struct A { };
+struct B { operator A&() const; };
+
+static_assert( std::is_same_v<std::common_reference_t<A&, const B&>, A&> );
+static_assert( std::is_same_v<std::common_reference_t<const B&, A&>, A&> );