1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class From, class To>
12 // concept common_reference_with;
15 #include <type_traits>
17 #include "test_macros.h"
19 template <class T
, class U
>
20 constexpr bool CheckCommonReferenceWith() noexcept
{
21 static_assert(std::common_reference_with
<T
, U
&>);
22 static_assert(std::common_reference_with
<T
, const U
&>);
23 static_assert(std::common_reference_with
<T
, volatile U
&>);
24 static_assert(std::common_reference_with
<T
, const volatile U
&>);
25 static_assert(std::common_reference_with
<T
, U
&&>);
26 static_assert(std::common_reference_with
<T
, const U
&&>);
27 static_assert(std::common_reference_with
<T
, volatile U
&&>);
28 static_assert(std::common_reference_with
<T
, const volatile U
&&>);
29 static_assert(std::common_reference_with
<T
&, U
&&>);
30 static_assert(std::common_reference_with
<T
&, const U
&&>);
31 static_assert(std::common_reference_with
<T
&, volatile U
&&>);
32 static_assert(std::common_reference_with
<T
&, const volatile U
&&>);
33 static_assert(std::common_reference_with
<const T
&, U
&&>);
34 static_assert(std::common_reference_with
<const T
&, const U
&&>);
35 static_assert(std::common_reference_with
<const T
&, volatile U
&&>);
36 static_assert(std::common_reference_with
<const T
&, const volatile U
&&>);
37 static_assert(std::common_reference_with
<volatile T
&, U
&&>);
38 static_assert(std::common_reference_with
<volatile T
&, const U
&&>);
39 static_assert(std::common_reference_with
<volatile T
&, volatile U
&&>);
40 static_assert(std::common_reference_with
<volatile T
&, const volatile U
&&>);
41 static_assert(std::common_reference_with
<const volatile T
&, U
&&>);
42 static_assert(std::common_reference_with
<const volatile T
&, const U
&&>);
43 static_assert(std::common_reference_with
<const volatile T
&, volatile U
&&>);
45 std::common_reference_with
<const volatile T
&, const volatile U
&&>);
47 return std::common_reference_with
<T
, U
>;
50 namespace BuiltinTypes
{
52 static_assert(std::common_reference_with
<void, void>);
53 static_assert(CheckCommonReferenceWith
<int, int>());
54 static_assert(CheckCommonReferenceWith
<int, long>());
55 static_assert(CheckCommonReferenceWith
<int, unsigned char>());
56 #ifndef TEST_HAS_NO_INT128
57 static_assert(CheckCommonReferenceWith
<int, __int128_t
>());
59 static_assert(CheckCommonReferenceWith
<int, double>());
62 static_assert(CheckCommonReferenceWith
<int[5], int[5]>());
64 // pointers (common with void*)
65 static_assert(CheckCommonReferenceWith
<int*, void*>());
66 static_assert(CheckCommonReferenceWith
<int*, const void*>());
67 static_assert(CheckCommonReferenceWith
<int*, volatile void*>());
68 static_assert(CheckCommonReferenceWith
<int*, const volatile void*>());
69 static_assert(CheckCommonReferenceWith
<const int*, void*>());
70 static_assert(CheckCommonReferenceWith
<const int*, const void*>());
71 static_assert(CheckCommonReferenceWith
<const int*, volatile void*>());
72 static_assert(CheckCommonReferenceWith
<const int*, const volatile void*>());
73 static_assert(CheckCommonReferenceWith
<volatile int*, void*>());
74 static_assert(CheckCommonReferenceWith
<volatile int*, const void*>());
75 static_assert(CheckCommonReferenceWith
<volatile int*, volatile void*>());
76 static_assert(CheckCommonReferenceWith
<volatile int*, const volatile void*>());
77 static_assert(CheckCommonReferenceWith
<const volatile int*, void*>());
78 static_assert(CheckCommonReferenceWith
<const volatile int*, const void*>());
79 static_assert(CheckCommonReferenceWith
<const volatile int*, volatile void*>());
81 CheckCommonReferenceWith
<const volatile int*, const volatile void*>());
83 static_assert(CheckCommonReferenceWith
<int (*)(), int (*)()>());
84 static_assert(CheckCommonReferenceWith
<int (*)(), int (*)() noexcept
>());
86 static_assert(CheckCommonReferenceWith
<int S::*, int S::*>());
87 static_assert(CheckCommonReferenceWith
<int S::*, const int S::*>());
88 static_assert(CheckCommonReferenceWith
<int (S::*)(), int (S::*)()>());
89 static_assert(CheckCommonReferenceWith
<int (S::*)(), int (S::*)() noexcept
>());
91 CheckCommonReferenceWith
<int (S::*)() const, int (S::*)() const>());
92 static_assert(CheckCommonReferenceWith
<int (S::*)() const,
93 int (S::*)() const noexcept
>());
95 CheckCommonReferenceWith
<int (S::*)() volatile, int (S::*)() volatile>());
96 static_assert(CheckCommonReferenceWith
<int (S::*)() volatile,
97 int (S::*)() volatile noexcept
>());
98 static_assert(CheckCommonReferenceWith
<int (S::*)() const volatile,
99 int (S::*)() const volatile>());
100 static_assert(CheckCommonReferenceWith
<int (S::*)() const volatile,
101 int (S::*)() const volatile noexcept
>());
104 static_assert(!std::common_reference_with
<double, float*>);
105 static_assert(!std::common_reference_with
<int, int[5]>);
106 static_assert(!std::common_reference_with
<int*, long*>);
107 static_assert(!std::common_reference_with
<int*, unsigned int*>);
108 static_assert(!std::common_reference_with
<int (*)(), int (*)(int)>);
109 static_assert(!std::common_reference_with
<int S::*, float S::*>);
110 static_assert(!std::common_reference_with
<int (S::*)(), int (S::*)() const>);
111 static_assert(!std::common_reference_with
<int (S::*)(), int (S::*)() volatile>);
113 !std::common_reference_with
<int (S::*)(), int (S::*)() const volatile>);
115 !std::common_reference_with
<int (S::*)() const, int (S::*)() volatile>);
116 static_assert(!std::common_reference_with
<int (S::*)() const,
117 int (S::*)() const volatile>);
118 static_assert(!std::common_reference_with
<int (S::*)() volatile,
119 int (S::*)() const volatile>);
120 } // namespace BuiltinTypes
122 namespace NoDefaultCommonReference
{
125 static_assert(!std::common_reference_with
<T
, int>);
126 static_assert(!std::common_reference_with
<int, T
>);
127 static_assert(!std::common_reference_with
<T
, int[10]>);
128 static_assert(!std::common_reference_with
<T
[10], int>);
129 static_assert(!std::common_reference_with
<T
*, int*>);
130 static_assert(!std::common_reference_with
<T
*, const int*>);
131 static_assert(!std::common_reference_with
<T
*, volatile int*>);
132 static_assert(!std::common_reference_with
<T
*, const volatile int*>);
133 static_assert(!std::common_reference_with
<const T
*, int*>);
134 static_assert(!std::common_reference_with
<volatile T
*, int*>);
135 static_assert(!std::common_reference_with
<const volatile T
*, int*>);
136 static_assert(!std::common_reference_with
<const T
*, const int*>);
137 static_assert(!std::common_reference_with
<const T
*, volatile int*>);
138 static_assert(!std::common_reference_with
<const T
*, const volatile int*>);
139 static_assert(!std::common_reference_with
<const T
*, const int*>);
140 static_assert(!std::common_reference_with
<volatile T
*, const int*>);
141 static_assert(!std::common_reference_with
<const volatile T
*, const int*>);
142 static_assert(!std::common_reference_with
<volatile T
*, const int*>);
143 static_assert(!std::common_reference_with
<volatile T
*, volatile int*>);
144 static_assert(!std::common_reference_with
<volatile T
*, const volatile int*>);
145 static_assert(!std::common_reference_with
<const T
*, volatile int*>);
146 static_assert(!std::common_reference_with
<volatile T
*, volatile int*>);
147 static_assert(!std::common_reference_with
<const volatile T
*, volatile int*>);
148 static_assert(!std::common_reference_with
<const volatile T
*, const int*>);
149 static_assert(!std::common_reference_with
<const volatile T
*, volatile int*>);
151 !std::common_reference_with
<const volatile T
*, const volatile int*>);
152 static_assert(!std::common_reference_with
<const T
*, const volatile int*>);
153 static_assert(!std::common_reference_with
<volatile T
*, const volatile int*>);
155 !std::common_reference_with
<const volatile T
*, const volatile int*>);
156 static_assert(!std::common_reference_with
<T
&, int&>);
157 static_assert(!std::common_reference_with
<T
&, const int&>);
158 static_assert(!std::common_reference_with
<T
&, volatile int&>);
159 static_assert(!std::common_reference_with
<T
&, const volatile int&>);
160 static_assert(!std::common_reference_with
<const T
&, int&>);
161 static_assert(!std::common_reference_with
<volatile T
&, int&>);
162 static_assert(!std::common_reference_with
<const volatile T
&, int&>);
163 static_assert(!std::common_reference_with
<const T
&, const int&>);
164 static_assert(!std::common_reference_with
<const T
&, volatile int&>);
165 static_assert(!std::common_reference_with
<const T
&, const volatile int&>);
166 static_assert(!std::common_reference_with
<const T
&, const int&>);
167 static_assert(!std::common_reference_with
<volatile T
&, const int&>);
168 static_assert(!std::common_reference_with
<const volatile T
&, const int&>);
169 static_assert(!std::common_reference_with
<volatile T
&, const int&>);
170 static_assert(!std::common_reference_with
<volatile T
&, volatile int&>);
171 static_assert(!std::common_reference_with
<volatile T
&, const volatile int&>);
172 static_assert(!std::common_reference_with
<const T
&, volatile int&>);
173 static_assert(!std::common_reference_with
<volatile T
&, volatile int&>);
174 static_assert(!std::common_reference_with
<const volatile T
&, volatile int&>);
175 static_assert(!std::common_reference_with
<const volatile T
&, const int&>);
176 static_assert(!std::common_reference_with
<const volatile T
&, volatile int&>);
178 !std::common_reference_with
<const volatile T
&, const volatile int&>);
179 static_assert(!std::common_reference_with
<const T
&, const volatile int&>);
180 static_assert(!std::common_reference_with
<volatile T
&, const volatile int&>);
182 !std::common_reference_with
<const volatile T
&, const volatile int&>);
183 static_assert(!std::common_reference_with
<T
&, int&&>);
184 static_assert(!std::common_reference_with
<T
&, const int&&>);
185 static_assert(!std::common_reference_with
<T
&, volatile int&&>);
186 static_assert(!std::common_reference_with
<T
&, const volatile int&&>);
187 static_assert(!std::common_reference_with
<const T
&, int&&>);
188 static_assert(!std::common_reference_with
<volatile T
&, int&&>);
189 static_assert(!std::common_reference_with
<const volatile T
&, int&&>);
190 static_assert(!std::common_reference_with
<const T
&, const int&&>);
191 static_assert(!std::common_reference_with
<const T
&, volatile int&&>);
192 static_assert(!std::common_reference_with
<const T
&, const volatile int&&>);
193 static_assert(!std::common_reference_with
<const T
&, const int&&>);
194 static_assert(!std::common_reference_with
<volatile T
&, const int&&>);
195 static_assert(!std::common_reference_with
<const volatile T
&, const int&&>);
196 static_assert(!std::common_reference_with
<volatile T
&, const int&&>);
197 static_assert(!std::common_reference_with
<volatile T
&, volatile int&&>);
198 static_assert(!std::common_reference_with
<volatile T
&, const volatile int&&>);
199 static_assert(!std::common_reference_with
<const T
&, volatile int&&>);
200 static_assert(!std::common_reference_with
<volatile T
&, volatile int&&>);
201 static_assert(!std::common_reference_with
<const volatile T
&, volatile int&&>);
202 static_assert(!std::common_reference_with
<const volatile T
&, const int&&>);
203 static_assert(!std::common_reference_with
<const volatile T
&, volatile int&&>);
205 !std::common_reference_with
<const volatile T
&, const volatile int&&>);
206 static_assert(!std::common_reference_with
<const T
&, const volatile int&&>);
207 static_assert(!std::common_reference_with
<volatile T
&, const volatile int&&>);
209 !std::common_reference_with
<const volatile T
&, const volatile int&&>);
210 static_assert(!std::common_reference_with
<T
&&, int&>);
211 static_assert(!std::common_reference_with
<T
&&, const int&>);
212 static_assert(!std::common_reference_with
<T
&&, volatile int&>);
213 static_assert(!std::common_reference_with
<T
&&, const volatile int&>);
214 static_assert(!std::common_reference_with
<const T
&&, int&>);
215 static_assert(!std::common_reference_with
<volatile T
&&, int&>);
216 static_assert(!std::common_reference_with
<const volatile T
&&, int&>);
217 static_assert(!std::common_reference_with
<const T
&&, const int&>);
218 static_assert(!std::common_reference_with
<const T
&&, volatile int&>);
219 static_assert(!std::common_reference_with
<const T
&&, const volatile int&>);
220 static_assert(!std::common_reference_with
<const T
&&, const int&>);
221 static_assert(!std::common_reference_with
<volatile T
&&, const int&>);
222 static_assert(!std::common_reference_with
<const volatile T
&&, const int&>);
223 static_assert(!std::common_reference_with
<volatile T
&&, const int&>);
224 static_assert(!std::common_reference_with
<volatile T
&&, volatile int&>);
225 static_assert(!std::common_reference_with
<volatile T
&&, const volatile int&>);
226 static_assert(!std::common_reference_with
<const T
&&, volatile int&>);
227 static_assert(!std::common_reference_with
<volatile T
&&, volatile int&>);
228 static_assert(!std::common_reference_with
<const volatile T
&&, volatile int&>);
229 static_assert(!std::common_reference_with
<const volatile T
&&, const int&>);
230 static_assert(!std::common_reference_with
<const volatile T
&&, volatile int&>);
232 !std::common_reference_with
<const volatile T
&&, const volatile int&>);
233 static_assert(!std::common_reference_with
<const T
&&, const volatile int&>);
234 static_assert(!std::common_reference_with
<volatile T
&&, const volatile int&>);
236 !std::common_reference_with
<const volatile T
&&, const volatile int&>);
237 static_assert(!std::common_reference_with
<T
&&, int&&>);
238 static_assert(!std::common_reference_with
<T
&&, const int&&>);
239 static_assert(!std::common_reference_with
<T
&&, volatile int&&>);
240 static_assert(!std::common_reference_with
<T
&&, const volatile int&&>);
241 static_assert(!std::common_reference_with
<const T
&&, int&&>);
242 static_assert(!std::common_reference_with
<volatile T
&&, int&&>);
243 static_assert(!std::common_reference_with
<const volatile T
&&, int&&>);
244 static_assert(!std::common_reference_with
<const T
&&, const int&&>);
245 static_assert(!std::common_reference_with
<const T
&&, volatile int&&>);
246 static_assert(!std::common_reference_with
<const T
&&, const volatile int&&>);
247 static_assert(!std::common_reference_with
<const T
&&, const int&&>);
248 static_assert(!std::common_reference_with
<volatile T
&&, const int&&>);
249 static_assert(!std::common_reference_with
<const volatile T
&&, const int&&>);
250 static_assert(!std::common_reference_with
<volatile T
&&, const int&&>);
251 static_assert(!std::common_reference_with
<volatile T
&&, volatile int&&>);
252 static_assert(!std::common_reference_with
<volatile T
&&, const volatile int&&>);
253 static_assert(!std::common_reference_with
<const T
&&, volatile int&&>);
254 static_assert(!std::common_reference_with
<volatile T
&&, volatile int&&>);
255 static_assert(!std::common_reference_with
<const volatile T
&&, volatile int&&>);
256 static_assert(!std::common_reference_with
<const volatile T
&&, const int&&>);
257 static_assert(!std::common_reference_with
<const volatile T
&&, volatile int&&>);
259 !std::common_reference_with
<const volatile T
&&, const volatile int&&>);
260 static_assert(!std::common_reference_with
<const T
&&, const volatile int&&>);
261 static_assert(!std::common_reference_with
<volatile T
&&, const volatile int&&>);
263 !std::common_reference_with
<const volatile T
&&, const volatile int&&>);
264 } // namespace NoDefaultCommonReference
266 struct BadBasicCommonReference
{
267 // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing.
268 // In the meantime, the test should be included. If compiler support is added, then an include guard
269 // should be placed so the test doesn't get deleted.
270 operator int() const;
273 static_assert(std::convertible_to
<BadBasicCommonReference
, int>);
274 static_assert(std::convertible_to
<BadBasicCommonReference
, int&>);
276 template <template <class> class X
, template <class> class Y
>
277 struct std::basic_common_reference
<BadBasicCommonReference
, int, X
, Y
> {
278 using type
= BadBasicCommonReference
&;
281 template <template <class> class X
, template <class> class Y
>
282 struct std::basic_common_reference
<int, BadBasicCommonReference
, X
, Y
> {
286 static_assert(!std::common_reference_with
<BadBasicCommonReference
, int>);
288 struct StructNotConvertibleToCommonReference
{
289 explicit(false) StructNotConvertibleToCommonReference(int);
291 static_assert(std::convertible_to
<int, StructNotConvertibleToCommonReference
>);
293 template <template <class> class X
, template <class> class Y
>
294 struct std::basic_common_reference
<StructNotConvertibleToCommonReference
, int, X
, Y
> {
298 template <template <class> class X
, template <class> class Y
>
299 struct std::basic_common_reference
<int, StructNotConvertibleToCommonReference
, X
, Y
> {
304 !std::common_reference_with
<StructNotConvertibleToCommonReference
, int>);
306 struct IntNotConvertibleToCommonReference
{
307 operator int&() const;
310 template <template <class> class X
, template <class> class Y
>
311 struct std::basic_common_reference
<IntNotConvertibleToCommonReference
, int, X
, Y
> {
315 template <template <class> class X
, template <class> class Y
>
316 struct std::basic_common_reference
<int, IntNotConvertibleToCommonReference
, X
, Y
> {
321 !std::common_reference_with
<StructNotConvertibleToCommonReference
, int>);
323 struct HasCommonReference
{
324 explicit(false) HasCommonReference(int);
325 operator int&() const;
328 template <template <class> class X
, template <class> class Y
>
329 struct std::basic_common_reference
<HasCommonReference
, int, X
, Y
> {
333 template <template <class> class X
, template <class> class Y
>
334 struct std::basic_common_reference
<int, HasCommonReference
, X
, Y
> {
338 static_assert(!std::common_reference_with
<HasCommonReference
, int>);
339 static_assert(std::common_reference_with
<HasCommonReference
, int&>);