Skip to content

Commit 0d1e5ab

Browse files
authored
[libc++] P2655R3 common_reference_t of reference_wrapper Should Be a Reference Type (#141408)
Fixes #105260 This patch applies the change as a DR to C++20. The rationale is that the paper is more like a bug fix. It does not introduce new features, it simply changes an existing behaviour (as a bug fix). MSVC STL DRed this paper to C++20 as well.
1 parent f1549be commit 0d1e5ab

File tree

14 files changed

+382
-26
lines changed

14 files changed

+382
-26
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ Status
198198
---------------------------------------------------------- -----------------
199199
``__cpp_lib_char8_t`` ``201907L``
200200
---------------------------------------------------------- -----------------
201+
``__cpp_lib_common_reference`` ``202302L``
202+
---------------------------------------------------------- -----------------
203+
``__cpp_lib_common_reference_wrapper`` ``202302L``
204+
---------------------------------------------------------- -----------------
201205
``__cpp_lib_concepts`` ``202002L``
202206
---------------------------------------------------------- -----------------
203207
``__cpp_lib_constexpr_algorithms`` ``201806L``

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Implemented Papers
5151
- P2441R2: ``views::join_with`` (`Github <https://github.com/llvm/llvm-project/issues/105185>`__)
5252
- P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
5353
- P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
54+
- P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
5455

5556
Improvements and New Features
5657
-----------------------------

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``","2023-02 (Issaquah)","|Partial|","","The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is not implemented yet"
114114
"`P2679R2 <https://wg21.link/P2679R2>`__","Fixing ``std::start_lifetime_as`` for arrays","2023-02 (Issaquah)","","",""
115115
"`P2674R1 <https://wg21.link/P2674R1>`__","A trait for implicit lifetime types","2023-02 (Issaquah)","|Complete|","20",""
116-
"`P2655R3 <https://wg21.link/P2655R3>`__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","","",""
116+
"`P2655R3 <https://wg21.link/P2655R3>`__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","|Complete|","21","The paper is implemented as a DR to C++20"
117117
"`P2652R2 <https://wg21.link/P2652R2>`__","Disallow User Specialization of ``allocator_traits``","2023-02 (Issaquah)","|Complete|","19",""
118118
"`P2787R1 <https://wg21.link/P2787R1>`__","``pmr::generator`` - Promise Types are not Values","2023-02 (Issaquah)","","",""
119119
"`P2614R2 <https://wg21.link/P2614R2>`__","Deprecate ``numeric_limits::has_denorm``","2023-02 (Issaquah)","|Complete|","18",""

libcxx/include/__functional/reference_wrapper.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,18 @@
1111
#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
1212

1313
#include <__compare/synth_three_way.h>
14+
#include <__concepts/convertible_to.h>
1415
#include <__config>
1516
#include <__functional/weak_result_type.h>
1617
#include <__memory/addressof.h>
18+
#include <__type_traits/common_reference.h>
1719
#include <__type_traits/desugars_to.h>
1820
#include <__type_traits/enable_if.h>
1921
#include <__type_traits/invoke.h>
2022
#include <__type_traits/is_const.h>
2123
#include <__type_traits/is_core_convertible.h>
2224
#include <__type_traits/is_same.h>
25+
#include <__type_traits/is_specialization.h>
2326
#include <__type_traits/remove_cvref.h>
2427
#include <__type_traits/void_t.h>
2528
#include <__utility/declval.h>
@@ -156,6 +159,32 @@ template <class _CanonicalTag, class _Operation, class... _Args>
156159
inline const bool __desugars_to_v<_CanonicalTag, reference_wrapper<_Operation>, _Args...> =
157160
__desugars_to_v<_CanonicalTag, _Operation, _Args...>;
158161

162+
#if _LIBCPP_STD_VER >= 20
163+
164+
template <class _Tp>
165+
inline constexpr bool __is_ref_wrapper = __is_specialization_v<_Tp, reference_wrapper>;
166+
167+
template <class _Rp, class _Tp, class _RpQual, class _TpQual>
168+
concept __ref_wrap_common_reference_exists_with = __is_ref_wrapper<_Rp> && requires {
169+
typename common_reference_t<typename _Rp::type&, _TpQual>;
170+
} && convertible_to<_RpQual, common_reference_t<typename _Rp::type&, _TpQual>>;
171+
172+
template <class _Rp, class _Tp, template <class> class _RpQual, template <class> class _TpQual>
173+
requires(__ref_wrap_common_reference_exists_with<_Rp, _Tp, _RpQual<_Rp>, _TpQual<_Tp>> &&
174+
!__ref_wrap_common_reference_exists_with<_Tp, _Rp, _TpQual<_Tp>, _RpQual<_Rp>>)
175+
struct basic_common_reference<_Rp, _Tp, _RpQual, _TpQual> {
176+
using type _LIBCPP_NODEBUG = common_reference_t<typename _Rp::type&, _TpQual<_Tp>>;
177+
};
178+
179+
template <class _Tp, class _Rp, template <class> class _TpQual, template <class> class _RpQual>
180+
requires(__ref_wrap_common_reference_exists_with<_Rp, _Tp, _RpQual<_Rp>, _TpQual<_Tp>> &&
181+
!__ref_wrap_common_reference_exists_with<_Tp, _Rp, _TpQual<_Tp>, _RpQual<_Rp>>)
182+
struct basic_common_reference<_Tp, _Rp, _TpQual, _RpQual> {
183+
using type _LIBCPP_NODEBUG = common_reference_t<typename _Rp::type&, _TpQual<_Tp>>;
184+
};
185+
186+
#endif // _LIBCPP_STD_VER >= 20
187+
159188
_LIBCPP_END_NAMESPACE_STD
160189

161190
#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H

libcxx/include/__type_traits/common_reference.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H
1111

1212
#include <__config>
13+
#include <__type_traits/add_pointer.h>
1314
#include <__type_traits/common_type.h>
1415
#include <__type_traits/copy_cv.h>
1516
#include <__type_traits/copy_cvref.h>
@@ -139,13 +140,17 @@ struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up>
139140
template <class _Tp, class _Up>
140141
struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {};
141142

142-
// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then
143-
// the member typedef `type` denotes that type.
143+
// sub-bullet 1 - Let R be COMMON-REF(T1, T2). If T1 and T2 are reference types, R is well-formed, and
144+
// is_convertible_v<add_pointer_t<T1>, add_pointer_t<R>> && is_convertible_v<add_pointer_t<T2>, add_pointer_t<R>> is
145+
// true, then the member typedef type denotes R.
146+
144147
template <class _Tp, class _Up>
145148
struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {};
146149

147150
template <class _Tp, class _Up>
148-
requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; }
151+
requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; } &&
152+
is_convertible_v<add_pointer_t<_Tp>, add_pointer_t<__common_ref_t<_Tp, _Up>>> &&
153+
is_convertible_v<add_pointer_t<_Up>, add_pointer_t<__common_ref_t<_Tp, _Up>>>
149154
struct __common_reference_sub_bullet1<_Tp, _Up> {
150155
using type _LIBCPP_NODEBUG = __common_ref_t<_Tp, _Up>;
151156
};

libcxx/include/functional

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited
565565
# include <__functional/bind_front.h>
566566
# include <__functional/identity.h>
567567
# include <__functional/ranges_operations.h>
568+
# include <__type_traits/common_reference.h>
568569
# include <__type_traits/unwrap_ref.h>
569570
# endif
570571

libcxx/include/version

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ __cpp_lib_char8_t 201907L <atomic> <filesy
5959
__cpp_lib_chrono 201611L <chrono>
6060
__cpp_lib_chrono_udls 201304L <chrono>
6161
__cpp_lib_clamp 201603L <algorithm>
62+
__cpp_lib_common_reference 202302L <type_traits>
63+
__cpp_lib_common_reference_wrapper 202302L <functional>
6264
__cpp_lib_complex_udls 201309L <complex>
6365
__cpp_lib_concepts 202002L <concepts>
6466
__cpp_lib_constexpr_algorithms 202306L <algorithm> <utility>
@@ -402,6 +404,8 @@ __cpp_lib_void_t 201411L <type_traits>
402404
# if _LIBCPP_HAS_CHAR8_T
403405
# define __cpp_lib_char8_t 201907L
404406
# endif
407+
# define __cpp_lib_common_reference 202302L
408+
# define __cpp_lib_common_reference_wrapper 202302L
405409
# define __cpp_lib_concepts 202002L
406410
# define __cpp_lib_constexpr_algorithms 201806L
407411
# define __cpp_lib_constexpr_complex 201711L

libcxx/modules/std/functional.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export namespace std {
1414
using std::invoke_r;
1515
#endif
1616

17+
#if _LIBCPP_STD_VER >= 20
18+
using std::basic_common_reference;
19+
#endif
20+
1721
// [refwrap], reference_wrapper
1822
using std::reference_wrapper;
1923

libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
3333
# endif
3434

35+
# ifdef __cpp_lib_common_reference_wrapper
36+
# error "__cpp_lib_common_reference_wrapper should not be defined before c++20"
37+
# endif
38+
3539
# ifdef __cpp_lib_constexpr_functional
3640
# error "__cpp_lib_constexpr_functional should not be defined before c++20"
3741
# endif
@@ -94,6 +98,10 @@
9498
# error "__cpp_lib_boyer_moore_searcher should not be defined before c++17"
9599
# endif
96100

101+
# ifdef __cpp_lib_common_reference_wrapper
102+
# error "__cpp_lib_common_reference_wrapper should not be defined before c++20"
103+
# endif
104+
97105
# ifdef __cpp_lib_constexpr_functional
98106
# error "__cpp_lib_constexpr_functional should not be defined before c++20"
99107
# endif
@@ -165,6 +173,10 @@
165173
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17"
166174
# endif
167175

176+
# ifdef __cpp_lib_common_reference_wrapper
177+
# error "__cpp_lib_common_reference_wrapper should not be defined before c++20"
178+
# endif
179+
168180
# ifdef __cpp_lib_constexpr_functional
169181
# error "__cpp_lib_constexpr_functional should not be defined before c++20"
170182
# endif
@@ -245,6 +257,13 @@
245257
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20"
246258
# endif
247259

260+
# ifndef __cpp_lib_common_reference_wrapper
261+
# error "__cpp_lib_common_reference_wrapper should be defined in c++20"
262+
# endif
263+
# if __cpp_lib_common_reference_wrapper != 202302L
264+
# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++20"
265+
# endif
266+
248267
# ifndef __cpp_lib_constexpr_functional
249268
# error "__cpp_lib_constexpr_functional should be defined in c++20"
250269
# endif
@@ -337,6 +356,13 @@
337356
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++23"
338357
# endif
339358

359+
# ifndef __cpp_lib_common_reference_wrapper
360+
# error "__cpp_lib_common_reference_wrapper should be defined in c++23"
361+
# endif
362+
# if __cpp_lib_common_reference_wrapper != 202302L
363+
# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++23"
364+
# endif
365+
340366
# ifndef __cpp_lib_constexpr_functional
341367
# error "__cpp_lib_constexpr_functional should be defined in c++23"
342368
# endif
@@ -441,6 +467,13 @@
441467
# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++26"
442468
# endif
443469

470+
# ifndef __cpp_lib_common_reference_wrapper
471+
# error "__cpp_lib_common_reference_wrapper should be defined in c++26"
472+
# endif
473+
# if __cpp_lib_common_reference_wrapper != 202302L
474+
# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++26"
475+
# endif
476+
444477
# ifndef __cpp_lib_constexpr_functional
445478
# error "__cpp_lib_constexpr_functional should be defined in c++26"
446479
# endif

libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
# error "__cpp_lib_bounded_array_traits should not be defined before c++20"
2929
# endif
3030

31+
# ifdef __cpp_lib_common_reference
32+
# error "__cpp_lib_common_reference should not be defined before c++20"
33+
# endif
34+
3135
# ifdef __cpp_lib_has_unique_object_representations
3236
# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
3337
# endif
@@ -130,6 +134,10 @@
130134
# error "__cpp_lib_bounded_array_traits should not be defined before c++20"
131135
# endif
132136

137+
# ifdef __cpp_lib_common_reference
138+
# error "__cpp_lib_common_reference should not be defined before c++20"
139+
# endif
140+
133141
# ifdef __cpp_lib_has_unique_object_representations
134142
# error "__cpp_lib_has_unique_object_representations should not be defined before c++17"
135143
# endif
@@ -250,6 +258,10 @@
250258
# error "__cpp_lib_bounded_array_traits should not be defined before c++20"
251259
# endif
252260

261+
# ifdef __cpp_lib_common_reference
262+
# error "__cpp_lib_common_reference should not be defined before c++20"
263+
# endif
264+
253265
# ifndef __cpp_lib_has_unique_object_representations
254266
# error "__cpp_lib_has_unique_object_representations should be defined in c++17"
255267
# endif
@@ -394,6 +406,13 @@
394406
# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20"
395407
# endif
396408

409+
# ifndef __cpp_lib_common_reference
410+
# error "__cpp_lib_common_reference should be defined in c++20"
411+
# endif
412+
# if __cpp_lib_common_reference != 202302L
413+
# error "__cpp_lib_common_reference should have the value 202302L in c++20"
414+
# endif
415+
397416
# ifndef __cpp_lib_has_unique_object_representations
398417
# error "__cpp_lib_has_unique_object_representations should be defined in c++20"
399418
# endif
@@ -568,6 +587,13 @@
568587
# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++23"
569588
# endif
570589

590+
# ifndef __cpp_lib_common_reference
591+
# error "__cpp_lib_common_reference should be defined in c++23"
592+
# endif
593+
# if __cpp_lib_common_reference != 202302L
594+
# error "__cpp_lib_common_reference should have the value 202302L in c++23"
595+
# endif
596+
571597
# ifndef __cpp_lib_has_unique_object_representations
572598
# error "__cpp_lib_has_unique_object_representations should be defined in c++23"
573599
# endif
@@ -763,6 +789,13 @@
763789
# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++26"
764790
# endif
765791

792+
# ifndef __cpp_lib_common_reference
793+
# error "__cpp_lib_common_reference should be defined in c++26"
794+
# endif
795+
# if __cpp_lib_common_reference != 202302L
796+
# error "__cpp_lib_common_reference should have the value 202302L in c++26"
797+
# endif
798+
766799
# ifndef __cpp_lib_has_unique_object_representations
767800
# error "__cpp_lib_has_unique_object_representations should be defined in c++26"
768801
# endif

0 commit comments

Comments
 (0)