On Mon, 13 Oct 2025, 09:00 Jonathan Wakely, <[email protected]> wrote:
> > > On Mon, 13 Oct 2025, 05:42 Patrick Palka, <[email protected]> wrote: > >> 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. >> > > ok for trunk > This looks safe for backports too, do we want to do that? > > --- >> libstdc++-v3/include/bits/version.def | 8 ++++++++ >> libstdc++-v3/include/bits/version.h | 10 ++++++++++ >> libstdc++-v3/include/std/type_traits | 7 +++++++ >> .../testsuite/20_util/common_reference/p2655r3.cc | 15 +++++++++++++++ >> 4 files changed, 40 insertions(+) >> create mode 100644 >> libstdc++-v3/testsuite/20_util/common_reference/p2655r3.cc >> >> diff --git a/libstdc++-v3/include/bits/version.def >> b/libstdc++-v3/include/bits/version.def >> index 83f1817bf8e4..e2b064e09b1e 100644 >> --- a/libstdc++-v3/include/bits/version.def >> +++ b/libstdc++-v3/include/bits/version.def >> @@ -1793,6 +1793,14 @@ ftms = { >> }; >> }; >> >> +ftms = { >> + name = common_reference; >> + values = { >> + v = 202302; >> + cxxmin = 20; // We treat P2655R3 as a DR against C++20. >> + }; >> +}; >> + >> ftms = { >> name = formatters; >> values = { >> diff --git a/libstdc++-v3/include/bits/version.h >> b/libstdc++-v3/include/bits/version.h >> index 0d6692d244a6..4581519d3a7d 100644 >> --- a/libstdc++-v3/include/bits/version.h >> +++ b/libstdc++-v3/include/bits/version.h >> @@ -2001,6 +2001,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 8b5110464e50..47cbf21b4c1d 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 >> @@ -4223,6 +4224,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 000000000000..4188dd2fb29f >> --- /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&> >> ); >> -- >> 2.51.0.491.g4b71b29477 >> >>
