1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // template<class From, class To>
12 // concept common_with;
13
14 #include <concepts>
15 #include <type_traits>
16
17 #include "test_macros.h"
18
19 template <class T, class U>
CheckCommonWith()20 constexpr bool CheckCommonWith() noexcept {
21 constexpr bool result = std::common_with<T, U>;
22 static_assert(std::common_with<T, U&> == result);
23 static_assert(std::common_with<T, const U&> == result);
24 static_assert(std::common_with<T, volatile U&> == result);
25 static_assert(std::common_with<T, const volatile U&> == result);
26 static_assert(std::common_with<T, U&&> == result);
27 static_assert(std::common_with<T, const U&&> == result);
28 static_assert(std::common_with<T, volatile U&&> == result);
29 static_assert(std::common_with<T, const volatile U&&> == result);
30 static_assert(std::common_with<T&, U&&> == result);
31 static_assert(std::common_with<T&, const U&&> == result);
32 static_assert(std::common_with<T&, volatile U&&> == result);
33 static_assert(std::common_with<T&, const volatile U&&> == result);
34 static_assert(std::common_with<const T&, U&&> == result);
35 static_assert(std::common_with<const T&, const U&&> == result);
36 static_assert(std::common_with<const T&, volatile U&&> == result);
37 static_assert(std::common_with<const T&, const volatile U&&> == result);
38 static_assert(std::common_with<volatile T&, U&&> == result);
39 static_assert(std::common_with<volatile T&, const U&&> == result);
40 static_assert(std::common_with<volatile T&, volatile U&&> == result);
41 static_assert(std::common_with<volatile T&, const volatile U&&> == result);
42 static_assert(std::common_with<const volatile T&, U&&> == result);
43 static_assert(std::common_with<const volatile T&, const U&&> == result);
44 static_assert(std::common_with<const volatile T&, volatile U&&> == result);
45 static_assert(std::common_with<const volatile T&, const volatile U&&> ==
46 result);
47 return result;
48 }
49
50 template <class T, class U>
HasValidCommonType()51 constexpr bool HasValidCommonType() noexcept {
52 return requires { typename std::common_type_t<T, U>; }
53 &&std::same_as<std::common_type_t<T, U>, std::common_type_t<U, T> >;
54 }
55
56 namespace BuiltinTypes {
57 // fundamental types
58 static_assert(std::common_with<void, void>);
59 static_assert(CheckCommonWith<int, int>());
60 static_assert(CheckCommonWith<int, long>());
61 static_assert(CheckCommonWith<int, unsigned char>());
62 #ifndef TEST_HAS_NO_INT128
63 static_assert(CheckCommonWith<int, __int128_t>());
64 #endif
65 static_assert(CheckCommonWith<int, double>());
66
67 // arrays
68 static_assert(CheckCommonWith<int[5], int[5]>());
69
70 // pointers
71 static_assert(CheckCommonWith<int*, int*>());
72 static_assert(CheckCommonWith<int*, const int*>());
73 static_assert(CheckCommonWith<int*, volatile int*>());
74 static_assert(CheckCommonWith<int*, const volatile int*>());
75 static_assert(CheckCommonWith<const int*, const int*>());
76 static_assert(CheckCommonWith<const int*, volatile int*>());
77 static_assert(CheckCommonWith<const int*, const volatile int*>());
78 static_assert(CheckCommonWith<volatile int*, const int*>());
79 static_assert(CheckCommonWith<volatile int*, volatile int*>());
80 static_assert(CheckCommonWith<volatile int*, const volatile int*>());
81 static_assert(CheckCommonWith<const volatile int*, const int*>());
82 static_assert(CheckCommonWith<const volatile int*, volatile int*>());
83 static_assert(CheckCommonWith<const volatile int*, const volatile int*>());
84
85 static_assert(CheckCommonWith<int (*)(), int (*)()>());
86 static_assert(CheckCommonWith<int (*)(), int (*)() noexcept>());
87 static_assert(CheckCommonWith<int (&)(), int (&)()>());
88 static_assert(CheckCommonWith<int (&)(), int (&)() noexcept>());
89 static_assert(CheckCommonWith<int (&)(), int (*)()>());
90 static_assert(CheckCommonWith<int (&)(), int (*)() noexcept>());
91
92 struct S {};
93 static_assert(CheckCommonWith<int S::*, int S::*>());
94 static_assert(CheckCommonWith<int S::*, const int S::*>());
95 static_assert(CheckCommonWith<int (S::*)(), int (S::*)()>());
96 static_assert(CheckCommonWith<int (S::*)(), int (S::*)() noexcept>());
97 static_assert(CheckCommonWith<int (S::*)() const, int (S::*)() const>());
98 static_assert(
99 CheckCommonWith<int (S::*)() const, int (S::*)() const noexcept>());
100 static_assert(CheckCommonWith<int (S::*)() volatile, int (S::*)() volatile>());
101 static_assert(
102 CheckCommonWith<int (S::*)() volatile, int (S::*)() volatile noexcept>());
103 static_assert(CheckCommonWith<int (S::*)() const volatile,
104 int (S::*)() const volatile>());
105 static_assert(CheckCommonWith<int (S::*)() const volatile,
106 int (S::*)() const volatile noexcept>());
107
108 // nonsense
109 static_assert(!CheckCommonWith<double, float*>());
110 static_assert(!CheckCommonWith<int, int[5]>());
111 static_assert(!CheckCommonWith<int*, long*>());
112 static_assert(!CheckCommonWith<int*, unsigned int*>());
113 static_assert(!CheckCommonWith<int (*)(), int (*)(int)>());
114 static_assert(!CheckCommonWith<int S::*, float S::*>());
115 static_assert(!CheckCommonWith<int (S::*)(), int (S::*)() const>());
116 static_assert(!CheckCommonWith<int (S::*)(), int (S::*)() volatile>());
117 static_assert(!CheckCommonWith<int (S::*)(), int (S::*)() const volatile>());
118 static_assert(!CheckCommonWith<int (S::*)() const, int (S::*)() volatile>());
119 static_assert(
120 !CheckCommonWith<int (S::*)() const, int (S::*)() const volatile>());
121 static_assert(
122 !CheckCommonWith<int (S::*)() volatile, int (S::*)() const volatile>());
123 } // namespace BuiltinTypes
124
125 namespace NoDefaultCommonType {
126 class T {};
127
128 static_assert(!CheckCommonWith<T, int>());
129 static_assert(!CheckCommonWith<int, T>());
130 static_assert(!CheckCommonWith<T, int[10]>());
131 static_assert(!CheckCommonWith<T[10], int>());
132 static_assert(!CheckCommonWith<T*, int*>());
133 static_assert(!CheckCommonWith<T*, const int*>());
134 static_assert(!CheckCommonWith<T*, volatile int*>());
135 static_assert(!CheckCommonWith<T*, const volatile int*>());
136 static_assert(!CheckCommonWith<const T*, int*>());
137 static_assert(!CheckCommonWith<volatile T*, int*>());
138 static_assert(!CheckCommonWith<const volatile T*, int*>());
139 static_assert(!CheckCommonWith<const T*, const int*>());
140 static_assert(!CheckCommonWith<const T*, volatile int*>());
141 static_assert(!CheckCommonWith<const T*, const volatile int*>());
142 static_assert(!CheckCommonWith<const T*, const int*>());
143 static_assert(!CheckCommonWith<volatile T*, const int*>());
144 static_assert(!CheckCommonWith<const volatile T*, const int*>());
145 static_assert(!CheckCommonWith<volatile T*, const int*>());
146 static_assert(!CheckCommonWith<volatile T*, volatile int*>());
147 static_assert(!CheckCommonWith<volatile T*, const volatile int*>());
148 static_assert(!CheckCommonWith<const T*, volatile int*>());
149 static_assert(!CheckCommonWith<volatile T*, volatile int*>());
150 static_assert(!CheckCommonWith<const volatile T*, volatile int*>());
151 static_assert(!CheckCommonWith<const volatile T*, const int*>());
152 static_assert(!CheckCommonWith<const volatile T*, volatile int*>());
153 static_assert(!CheckCommonWith<const volatile T*, const volatile int*>());
154 static_assert(!CheckCommonWith<const T*, const volatile int*>());
155 static_assert(!CheckCommonWith<volatile T*, const volatile int*>());
156 static_assert(!CheckCommonWith<const volatile T*, const volatile int*>());
157 static_assert(!CheckCommonWith<T&, int&>());
158 static_assert(!CheckCommonWith<T&, const int&>());
159 static_assert(!CheckCommonWith<T&, volatile int&>());
160 static_assert(!CheckCommonWith<T&, const volatile int&>());
161 static_assert(!CheckCommonWith<const T&, int&>());
162 static_assert(!CheckCommonWith<volatile T&, int&>());
163 static_assert(!CheckCommonWith<const volatile T&, int&>());
164 static_assert(!CheckCommonWith<const T&, const int&>());
165 static_assert(!CheckCommonWith<const T&, volatile int&>());
166 static_assert(!CheckCommonWith<const T&, const volatile int&>());
167 static_assert(!CheckCommonWith<const T&, const int&>());
168 static_assert(!CheckCommonWith<volatile T&, const int&>());
169 static_assert(!CheckCommonWith<const volatile T&, const int&>());
170 static_assert(!CheckCommonWith<volatile T&, const int&>());
171 static_assert(!CheckCommonWith<volatile T&, volatile int&>());
172 static_assert(!CheckCommonWith<volatile T&, const volatile int&>());
173 static_assert(!CheckCommonWith<const T&, volatile int&>());
174 static_assert(!CheckCommonWith<volatile T&, volatile int&>());
175 static_assert(!CheckCommonWith<const volatile T&, volatile int&>());
176 static_assert(!CheckCommonWith<const volatile T&, const int&>());
177 static_assert(!CheckCommonWith<const volatile T&, volatile int&>());
178 static_assert(!CheckCommonWith<const volatile T&, const volatile int&>());
179 static_assert(!CheckCommonWith<const T&, const volatile int&>());
180 static_assert(!CheckCommonWith<volatile T&, const volatile int&>());
181 static_assert(!CheckCommonWith<const volatile T&, const volatile int&>());
182 static_assert(!CheckCommonWith<T&, int&&>());
183 static_assert(!CheckCommonWith<T&, const int&&>());
184 static_assert(!CheckCommonWith<T&, volatile int&&>());
185 static_assert(!CheckCommonWith<T&, const volatile int&&>());
186 static_assert(!CheckCommonWith<const T&, int&&>());
187 static_assert(!CheckCommonWith<volatile T&, int&&>());
188 static_assert(!CheckCommonWith<const volatile T&, int&&>());
189 static_assert(!CheckCommonWith<const T&, const int&&>());
190 static_assert(!CheckCommonWith<const T&, volatile int&&>());
191 static_assert(!CheckCommonWith<const T&, const volatile int&&>());
192 static_assert(!CheckCommonWith<const T&, const int&&>());
193 static_assert(!CheckCommonWith<volatile T&, const int&&>());
194 static_assert(!CheckCommonWith<const volatile T&, const int&&>());
195 static_assert(!CheckCommonWith<volatile T&, const int&&>());
196 static_assert(!CheckCommonWith<volatile T&, volatile int&&>());
197 static_assert(!CheckCommonWith<volatile T&, const volatile int&&>());
198 static_assert(!CheckCommonWith<const T&, volatile int&&>());
199 static_assert(!CheckCommonWith<volatile T&, volatile int&&>());
200 static_assert(!CheckCommonWith<const volatile T&, volatile int&&>());
201 static_assert(!CheckCommonWith<const volatile T&, const int&&>());
202 static_assert(!CheckCommonWith<const volatile T&, volatile int&&>());
203 static_assert(!CheckCommonWith<const volatile T&, const volatile int&&>());
204 static_assert(!CheckCommonWith<const T&, const volatile int&&>());
205 static_assert(!CheckCommonWith<volatile T&, const volatile int&&>());
206 static_assert(!CheckCommonWith<const volatile T&, const volatile int&&>());
207 static_assert(!CheckCommonWith<T&&, int&>());
208 static_assert(!CheckCommonWith<T&&, const int&>());
209 static_assert(!CheckCommonWith<T&&, volatile int&>());
210 static_assert(!CheckCommonWith<T&&, const volatile int&>());
211 static_assert(!CheckCommonWith<const T&&, int&>());
212 static_assert(!CheckCommonWith<volatile T&&, int&>());
213 static_assert(!CheckCommonWith<const volatile T&&, int&>());
214 static_assert(!CheckCommonWith<const T&&, const int&>());
215 static_assert(!CheckCommonWith<const T&&, volatile int&>());
216 static_assert(!CheckCommonWith<const T&&, const volatile int&>());
217 static_assert(!CheckCommonWith<const T&&, const int&>());
218 static_assert(!CheckCommonWith<volatile T&&, const int&>());
219 static_assert(!CheckCommonWith<const volatile T&&, const int&>());
220 static_assert(!CheckCommonWith<volatile T&&, const int&>());
221 static_assert(!CheckCommonWith<volatile T&&, volatile int&>());
222 static_assert(!CheckCommonWith<volatile T&&, const volatile int&>());
223 static_assert(!CheckCommonWith<const T&&, volatile int&>());
224 static_assert(!CheckCommonWith<volatile T&&, volatile int&>());
225 static_assert(!CheckCommonWith<const volatile T&&, volatile int&>());
226 static_assert(!CheckCommonWith<const volatile T&&, const int&>());
227 static_assert(!CheckCommonWith<const volatile T&&, volatile int&>());
228 static_assert(!CheckCommonWith<const volatile T&&, const volatile int&>());
229 static_assert(!CheckCommonWith<const T&&, const volatile int&>());
230 static_assert(!CheckCommonWith<volatile T&&, const volatile int&>());
231 static_assert(!CheckCommonWith<const volatile T&&, const volatile int&>());
232 static_assert(!CheckCommonWith<T&&, int&&>());
233 static_assert(!CheckCommonWith<T&&, const int&&>());
234 static_assert(!CheckCommonWith<T&&, volatile int&&>());
235 static_assert(!CheckCommonWith<T&&, const volatile int&&>());
236 static_assert(!CheckCommonWith<const T&&, int&&>());
237 static_assert(!CheckCommonWith<volatile T&&, int&&>());
238 static_assert(!CheckCommonWith<const volatile T&&, int&&>());
239 static_assert(!CheckCommonWith<const T&&, const int&&>());
240 static_assert(!CheckCommonWith<const T&&, volatile int&&>());
241 static_assert(!CheckCommonWith<const T&&, const volatile int&&>());
242 static_assert(!CheckCommonWith<const T&&, const int&&>());
243 static_assert(!CheckCommonWith<volatile T&&, const int&&>());
244 static_assert(!CheckCommonWith<const volatile T&&, const int&&>());
245 static_assert(!CheckCommonWith<volatile T&&, const int&&>());
246 static_assert(!CheckCommonWith<volatile T&&, volatile int&&>());
247 static_assert(!CheckCommonWith<volatile T&&, const volatile int&&>());
248 static_assert(!CheckCommonWith<const T&&, volatile int&&>());
249 static_assert(!CheckCommonWith<volatile T&&, volatile int&&>());
250 static_assert(!CheckCommonWith<const volatile T&&, volatile int&&>());
251 static_assert(!CheckCommonWith<const volatile T&&, const int&&>());
252 static_assert(!CheckCommonWith<const volatile T&&, volatile int&&>());
253 static_assert(!CheckCommonWith<const volatile T&&, const volatile int&&>());
254 static_assert(!CheckCommonWith<const T&&, const volatile int&&>());
255 static_assert(!CheckCommonWith<volatile T&&, const volatile int&&>());
256 static_assert(!CheckCommonWith<const volatile T&&, const volatile int&&>());
257 } // namespace NoDefaultCommonType
258
259 struct BadBasicCommonType {
260 // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing.
261 // In the meantime, the test should be included. If compiler support is added, then an include guard
262 // should be placed so the test doesn't get deleted.
263 };
264
265 namespace std {
266 template <>
267 struct common_type<BadBasicCommonType, int> {
268 using type = BadBasicCommonType;
269 };
270
271 template <>
272 struct common_type<int, BadBasicCommonType> {
273 using type = int;
274 };
275 } // namespace std
276 static_assert(requires {
277 typename std::common_type_t<BadBasicCommonType, int>;
278 });
279 static_assert(requires {
280 typename std::common_type_t<int, BadBasicCommonType>;
281 });
282 static_assert(!std::same_as<std::common_type_t<BadBasicCommonType, int>,
283 std::common_type_t<int, BadBasicCommonType> >);
284 static_assert(!CheckCommonWith<BadBasicCommonType, int>());
285
286 struct DullCommonType {};
287 static_assert(!std::convertible_to<DullCommonType, int>);
288
289 struct T1 {};
290 static_assert(!std::convertible_to<DullCommonType, T1>);
291
292 namespace std {
293 template <>
294 struct common_type<T1, int> {
295 using type = DullCommonType;
296 };
297
298 template <>
299 struct common_type<int, T1> {
300 using type = DullCommonType;
301 };
302 } // namespace std
303 static_assert(HasValidCommonType<T1, int>());
304 static_assert(!CheckCommonWith<T1, int>());
305
306 struct CommonTypeImplicitlyConstructibleFromInt {
307 explicit(false) CommonTypeImplicitlyConstructibleFromInt(int);
308 };
309 static_assert(requires {
310 static_cast<CommonTypeImplicitlyConstructibleFromInt>(0);
311 });
312
313 struct T2 {};
314 static_assert(
315 !std::convertible_to<CommonTypeImplicitlyConstructibleFromInt, T2>);
316
317 namespace std {
318 template <>
319 struct common_type<T2, int> {
320 using type = CommonTypeImplicitlyConstructibleFromInt;
321 };
322
323 template <>
324 struct common_type<int, T2> {
325 using type = CommonTypeImplicitlyConstructibleFromInt;
326 };
327 } // namespace std
328 static_assert(HasValidCommonType<T2, int>());
329 static_assert(!CheckCommonWith<T2, int>());
330
331 struct CommonTypeExplicitlyConstructibleFromInt {
332 explicit CommonTypeExplicitlyConstructibleFromInt(int);
333 };
334 static_assert(requires {
335 static_cast<CommonTypeExplicitlyConstructibleFromInt>(0);
336 });
337
338 struct T3 {};
339 static_assert(
340 !std::convertible_to<CommonTypeExplicitlyConstructibleFromInt, T2>);
341
342 namespace std {
343 template <>
344 struct common_type<T3, int> {
345 using type = CommonTypeExplicitlyConstructibleFromInt;
346 };
347
348 template <>
349 struct common_type<int, T3> {
350 using type = CommonTypeExplicitlyConstructibleFromInt;
351 };
352 } // namespace std
353 static_assert(HasValidCommonType<T3, int>());
354 static_assert(!CheckCommonWith<T3, int>());
355
356 struct T4 {};
357 struct CommonTypeImplicitlyConstructibleFromT4 {
358 explicit(false) CommonTypeImplicitlyConstructibleFromT4(T4);
359 };
360 static_assert(requires(T4 t4) {
361 static_cast<CommonTypeImplicitlyConstructibleFromT4>(t4);
362 });
363
364 namespace std {
365 template <>
366 struct common_type<T4, int> {
367 using type = CommonTypeImplicitlyConstructibleFromT4;
368 };
369
370 template <>
371 struct common_type<int, T4> {
372 using type = CommonTypeImplicitlyConstructibleFromT4;
373 };
374 } // namespace std
375 static_assert(HasValidCommonType<T4, int>());
376 static_assert(!CheckCommonWith<T4, int>());
377
378 struct T5 {};
379 struct CommonTypeExplicitlyConstructibleFromT5 {
380 explicit CommonTypeExplicitlyConstructibleFromT5(T5);
381 };
382 static_assert(requires(T5 t5) {
383 static_cast<CommonTypeExplicitlyConstructibleFromT5>(t5);
384 });
385
386 namespace std {
387 template <>
388 struct common_type<T5, int> {
389 using type = CommonTypeExplicitlyConstructibleFromT5;
390 };
391
392 template <>
393 struct common_type<int, T5> {
394 using type = CommonTypeExplicitlyConstructibleFromT5;
395 };
396 } // namespace std
397 static_assert(HasValidCommonType<T5, int>());
398 static_assert(!CheckCommonWith<T5, int>());
399
400 struct T6 {};
401 struct CommonTypeNoCommonReference {
402 CommonTypeNoCommonReference(T6);
403 CommonTypeNoCommonReference(int);
404 };
405
406 namespace std {
407 template <>
408 struct common_type<T6, int> {
409 using type = CommonTypeNoCommonReference;
410 };
411
412 template <>
413 struct common_type<int, T6> {
414 using type = CommonTypeNoCommonReference;
415 };
416
417 template <>
418 struct common_type<T6&, int&> {};
419
420 template <>
421 struct common_type<int&, T6&> {};
422
423 template <>
424 struct common_type<T6&, const int&> {};
425
426 template <>
427 struct common_type<int&, const T6&> {};
428
429 template <>
430 struct common_type<T6&, volatile int&> {};
431
432 template <>
433 struct common_type<int&, volatile T6&> {};
434
435 template <>
436 struct common_type<T6&, const volatile int&> {};
437
438 template <>
439 struct common_type<int&, const volatile T6&> {};
440
441 template <>
442 struct common_type<const T6&, int&> {};
443
444 template <>
445 struct common_type<const int&, T6&> {};
446
447 template <>
448 struct common_type<const T6&, const int&> {};
449
450 template <>
451 struct common_type<const int&, const T6&> {};
452
453 template <>
454 struct common_type<const T6&, volatile int&> {};
455
456 template <>
457 struct common_type<const int&, volatile T6&> {};
458
459 template <>
460 struct common_type<const T6&, const volatile int&> {};
461
462 template <>
463 struct common_type<const int&, const volatile T6&> {};
464
465 template <>
466 struct common_type<volatile T6&, int&> {};
467
468 template <>
469 struct common_type<volatile int&, T6&> {};
470
471 template <>
472 struct common_type<volatile T6&, const int&> {};
473
474 template <>
475 struct common_type<volatile int&, const T6&> {};
476
477 template <>
478 struct common_type<volatile T6&, volatile int&> {};
479
480 template <>
481 struct common_type<volatile int&, volatile T6&> {};
482
483 template <>
484 struct common_type<volatile T6&, const volatile int&> {};
485
486 template <>
487 struct common_type<volatile int&, const volatile T6&> {};
488
489 template <>
490 struct common_type<const volatile T6&, int&> {};
491
492 template <>
493 struct common_type<const volatile int&, T6&> {};
494
495 template <>
496 struct common_type<const volatile T6&, const int&> {};
497
498 template <>
499 struct common_type<const volatile int&, const T6&> {};
500
501 template <>
502 struct common_type<const volatile T6&, volatile int&> {};
503
504 template <>
505 struct common_type<const volatile int&, volatile T6&> {};
506
507 template <>
508 struct common_type<const volatile T6&, const volatile int&> {};
509
510 template <>
511 struct common_type<const volatile int&, const volatile T6&> {};
512 } // namespace std
513
514 template <typename T, typename U>
HasCommonReference()515 constexpr bool HasCommonReference() noexcept {
516 return requires { typename std::common_reference_t<T, U>; };
517 }
518
519 static_assert(HasValidCommonType<T6, int>());
520 static_assert(!HasCommonReference<const T6&, const int&>());
521 static_assert(!CheckCommonWith<T6, int>());
522
523 struct T7 {};
524 struct CommonTypeNoMetaCommonReference {
525 CommonTypeNoMetaCommonReference(T7);
526 CommonTypeNoMetaCommonReference(int);
527 };
528
529 namespace std {
530 template <>
531 struct common_type<T7, int> {
532 using type = CommonTypeNoMetaCommonReference;
533 };
534
535 template <>
536 struct common_type<int, T7> {
537 using type = CommonTypeNoMetaCommonReference;
538 };
539
540 template <>
541 struct common_type<T7&, int&> {
542 using type = void;
543 };
544
545 template <>
546 struct common_type<int&, T7&> {
547 using type = void;
548 };
549
550 template <>
551 struct common_type<T7&, const int&> {
552 using type = void;
553 };
554
555 template <>
556 struct common_type<int&, const T7&> {
557 using type = void;
558 };
559
560 template <>
561 struct common_type<T7&, volatile int&> {
562 using type = void;
563 };
564
565 template <>
566 struct common_type<int&, volatile T7&> {
567 using type = void;
568 };
569
570 template <>
571 struct common_type<T7&, const volatile int&> {
572 using type = void;
573 };
574
575 template <>
576 struct common_type<int&, const volatile T7&> {
577 using type = void;
578 };
579
580 template <>
581 struct common_type<const T7&, int&> {
582 using type = void;
583 };
584
585 template <>
586 struct common_type<const int&, T7&> {
587 using type = void;
588 };
589
590 template <>
591 struct common_type<const T7&, const int&> {
592 using type = void;
593 };
594
595 template <>
596 struct common_type<const int&, const T7&> {
597 using type = void;
598 };
599
600 template <>
601 struct common_type<const T7&, volatile int&> {
602 using type = void;
603 };
604
605 template <>
606 struct common_type<const int&, volatile T7&> {
607 using type = void;
608 };
609
610 template <>
611 struct common_type<const T7&, const volatile int&> {
612 using type = void;
613 };
614
615 template <>
616 struct common_type<const int&, const volatile T7&> {
617 using type = void;
618 };
619
620 template <>
621 struct common_type<volatile T7&, int&> {
622 using type = void;
623 };
624
625 template <>
626 struct common_type<volatile int&, T7&> {
627 using type = void;
628 };
629
630 template <>
631 struct common_type<volatile T7&, const int&> {
632 using type = void;
633 };
634
635 template <>
636 struct common_type<volatile int&, const T7&> {
637 using type = void;
638 };
639
640 template <>
641 struct common_type<volatile T7&, volatile int&> {
642 using type = void;
643 };
644
645 template <>
646 struct common_type<volatile int&, volatile T7&> {
647 using type = void;
648 };
649
650 template <>
651 struct common_type<volatile T7&, const volatile int&> {
652 using type = void;
653 };
654
655 template <>
656 struct common_type<volatile int&, const volatile T7&> {
657 using type = void;
658 };
659
660 template <>
661 struct common_type<const volatile T7&, int&> {
662 using type = void;
663 };
664
665 template <>
666 struct common_type<const volatile int&, T7&> {
667 using type = void;
668 };
669
670 template <>
671 struct common_type<const volatile T7&, const int&> {
672 using type = void;
673 };
674
675 template <>
676 struct common_type<const volatile int&, const T7&> {
677 using type = void;
678 };
679
680 template <>
681 struct common_type<const volatile T7&, volatile int&> {
682 using type = void;
683 };
684
685 template <>
686 struct common_type<const volatile int&, volatile T7&> {
687 using type = void;
688 };
689
690 template <>
691 struct common_type<const volatile T7&, const volatile int&> {
692 using type = void;
693 };
694
695 template <>
696 struct common_type<const volatile int&, const volatile T7&> {
697 using type = void;
698 };
699 } // namespace std
700 static_assert(HasValidCommonType<T7, int>());
701 static_assert(HasValidCommonType<const T7&, const int&>());
702 static_assert(HasCommonReference<const T7&, const int&>());
703 static_assert(
704 !HasCommonReference<std::common_type_t<T7, int>&,
705 std::common_reference_t<const T7&, const int&> >());
706 static_assert(!CheckCommonWith<T7, int>());
707
708 struct CommonWithInt {
709 operator int() const volatile;
710 };
711
712 namespace std {
713 template <>
714 struct common_type<CommonWithInt, int> {
715 using type = int;
716 };
717
718 template <>
719 struct common_type<int, CommonWithInt> : common_type<CommonWithInt, int> {};
720
721 template <>
722 struct common_type<CommonWithInt&, int&> : common_type<CommonWithInt, int> {};
723
724 template <>
725 struct common_type<int&, CommonWithInt&> : common_type<CommonWithInt, int> {};
726
727 template <>
728 struct common_type<CommonWithInt&, const int&>
729 : common_type<CommonWithInt, int> {};
730
731 template <>
732 struct common_type<int&, const CommonWithInt&>
733 : common_type<CommonWithInt, int> {};
734
735 template <>
736 struct common_type<CommonWithInt&, volatile int&>
737 : common_type<CommonWithInt, int> {};
738
739 template <>
740 struct common_type<int&, volatile CommonWithInt&>
741 : common_type<CommonWithInt, int> {};
742
743 template <>
744 struct common_type<CommonWithInt&, const volatile int&>
745 : common_type<CommonWithInt, int> {};
746
747 template <>
748 struct common_type<int&, const volatile CommonWithInt&>
749 : common_type<CommonWithInt, int> {};
750
751 template <>
752 struct common_type<const CommonWithInt&, int&>
753 : common_type<CommonWithInt, int> {};
754
755 template <>
756 struct common_type<const int&, CommonWithInt&>
757 : common_type<CommonWithInt, int> {};
758
759 template <>
760 struct common_type<const CommonWithInt&, const int&>
761 : common_type<CommonWithInt, int> {};
762
763 template <>
764 struct common_type<const int&, const CommonWithInt&>
765 : common_type<CommonWithInt, int> {};
766
767 template <>
768 struct common_type<const CommonWithInt&, volatile int&>
769 : common_type<CommonWithInt, int> {};
770
771 template <>
772 struct common_type<const int&, volatile CommonWithInt&>
773 : common_type<CommonWithInt, int> {};
774
775 template <>
776 struct common_type<const CommonWithInt&, const volatile int&>
777 : common_type<CommonWithInt, int> {};
778
779 template <>
780 struct common_type<const int&, const volatile CommonWithInt&>
781 : common_type<CommonWithInt, int> {};
782
783 template <>
784 struct common_type<volatile CommonWithInt&, int&>
785 : common_type<CommonWithInt, int> {};
786
787 template <>
788 struct common_type<volatile int&, CommonWithInt&>
789 : common_type<CommonWithInt, int> {};
790
791 template <>
792 struct common_type<volatile CommonWithInt&, const int&>
793 : common_type<CommonWithInt, int> {};
794
795 template <>
796 struct common_type<volatile int&, const CommonWithInt&>
797 : common_type<CommonWithInt, int> {};
798
799 template <>
800 struct common_type<volatile CommonWithInt&, volatile int&>
801 : common_type<CommonWithInt, int> {};
802
803 template <>
804 struct common_type<volatile int&, volatile CommonWithInt&>
805 : common_type<CommonWithInt, int> {};
806
807 template <>
808 struct common_type<volatile CommonWithInt&, const volatile int&>
809 : common_type<CommonWithInt, int> {};
810
811 template <>
812 struct common_type<volatile int&, const volatile CommonWithInt&>
813 : common_type<CommonWithInt, int> {};
814
815 template <>
816 struct common_type<const volatile CommonWithInt&, int&>
817 : common_type<CommonWithInt, int> {};
818
819 template <>
820 struct common_type<const volatile int&, CommonWithInt&>
821 : common_type<CommonWithInt, int> {};
822
823 template <>
824 struct common_type<const volatile CommonWithInt&, const int&>
825 : common_type<CommonWithInt, int> {};
826
827 template <>
828 struct common_type<const volatile int&, const CommonWithInt&>
829 : common_type<CommonWithInt, int> {};
830
831 template <>
832 struct common_type<const volatile CommonWithInt&, volatile int&>
833 : common_type<CommonWithInt, int> {};
834
835 template <>
836 struct common_type<const volatile int&, volatile CommonWithInt&>
837 : common_type<CommonWithInt, int> {};
838
839 template <>
840 struct common_type<const volatile CommonWithInt&, const volatile int&>
841 : common_type<CommonWithInt, int> {};
842
843 template <>
844 struct common_type<const volatile int&, const volatile CommonWithInt&>
845 : common_type<CommonWithInt, int> {};
846 } // namespace std
847 static_assert(CheckCommonWith<CommonWithInt, int>());
848
849 struct CommonWithIntButRefLong {
850 operator int() const volatile;
851 };
852
853 namespace std {
854 template <>
855 struct common_type<CommonWithIntButRefLong, int> {
856 using type = int;
857 };
858
859 template <>
860 struct common_type<int, CommonWithIntButRefLong>
861 : common_type<CommonWithIntButRefLong, int> {};
862
863 template <>
864 struct common_type<CommonWithIntButRefLong&, int&> {
865 using type = long;
866 };
867
868 template <>
869 struct common_type<int&, CommonWithIntButRefLong&>
870 : common_type<CommonWithIntButRefLong&, int&> {};
871
872 template <>
873 struct common_type<CommonWithIntButRefLong&, const int&>
874 : common_type<CommonWithIntButRefLong&, int&> {};
875
876 template <>
877 struct common_type<int&, const CommonWithIntButRefLong&>
878 : common_type<CommonWithIntButRefLong&, int&> {};
879
880 template <>
881 struct common_type<CommonWithIntButRefLong&, volatile int&>
882 : common_type<CommonWithIntButRefLong&, int&> {};
883
884 template <>
885 struct common_type<int&, volatile CommonWithIntButRefLong&>
886 : common_type<CommonWithIntButRefLong&, int&> {};
887
888 template <>
889 struct common_type<CommonWithIntButRefLong&, const volatile int&>
890 : common_type<CommonWithIntButRefLong&, int&> {};
891
892 template <>
893 struct common_type<int&, const volatile CommonWithIntButRefLong&>
894 : common_type<CommonWithIntButRefLong&, int&> {};
895
896 template <>
897 struct common_type<const CommonWithIntButRefLong&, int&>
898 : common_type<CommonWithIntButRefLong&, int&> {};
899
900 template <>
901 struct common_type<const int&, CommonWithIntButRefLong&>
902 : common_type<CommonWithIntButRefLong&, int&> {};
903
904 template <>
905 struct common_type<const CommonWithIntButRefLong&, const int&>
906 : common_type<CommonWithIntButRefLong&, int&> {};
907
908 template <>
909 struct common_type<const int&, const CommonWithIntButRefLong&>
910 : common_type<CommonWithIntButRefLong&, int&> {};
911
912 template <>
913 struct common_type<const CommonWithIntButRefLong&, volatile int&>
914 : common_type<CommonWithIntButRefLong&, int&> {};
915
916 template <>
917 struct common_type<const int&, volatile CommonWithIntButRefLong&>
918 : common_type<CommonWithIntButRefLong&, int&> {};
919
920 template <>
921 struct common_type<const CommonWithIntButRefLong&, const volatile int&>
922 : common_type<CommonWithIntButRefLong&, int&> {};
923
924 template <>
925 struct common_type<const int&, const volatile CommonWithIntButRefLong&>
926 : common_type<CommonWithIntButRefLong&, int&> {};
927
928 template <>
929 struct common_type<volatile CommonWithIntButRefLong&, int&>
930 : common_type<CommonWithIntButRefLong&, int&> {};
931
932 template <>
933 struct common_type<volatile int&, CommonWithIntButRefLong&>
934 : common_type<CommonWithIntButRefLong&, int&> {};
935
936 template <>
937 struct common_type<volatile CommonWithIntButRefLong&, const int&>
938 : common_type<CommonWithIntButRefLong&, int&> {};
939
940 template <>
941 struct common_type<volatile int&, const CommonWithIntButRefLong&>
942 : common_type<CommonWithIntButRefLong&, int&> {};
943
944 template <>
945 struct common_type<volatile CommonWithIntButRefLong&, volatile int&>
946 : common_type<CommonWithIntButRefLong&, int&> {};
947
948 template <>
949 struct common_type<volatile int&, volatile CommonWithIntButRefLong&>
950 : common_type<CommonWithIntButRefLong&, int&> {};
951
952 template <>
953 struct common_type<volatile CommonWithIntButRefLong&, const volatile int&>
954 : common_type<CommonWithIntButRefLong&, int&> {};
955
956 template <>
957 struct common_type<volatile int&, const volatile CommonWithIntButRefLong&>
958 : common_type<CommonWithIntButRefLong&, int&> {};
959
960 template <>
961 struct common_type<const volatile CommonWithIntButRefLong&, int&>
962 : common_type<CommonWithIntButRefLong&, int&> {};
963
964 template <>
965 struct common_type<const volatile int&, CommonWithIntButRefLong&>
966 : common_type<CommonWithIntButRefLong&, int&> {};
967
968 template <>
969 struct common_type<const volatile CommonWithIntButRefLong&, const int&>
970 : common_type<CommonWithIntButRefLong&, int&> {};
971
972 template <>
973 struct common_type<const volatile int&, const CommonWithIntButRefLong&>
974 : common_type<CommonWithIntButRefLong&, int&> {};
975
976 template <>
977 struct common_type<const volatile CommonWithIntButRefLong&, volatile int&>
978 : common_type<CommonWithIntButRefLong&, int&> {};
979
980 template <>
981 struct common_type<const volatile int&, volatile CommonWithIntButRefLong&>
982 : common_type<CommonWithIntButRefLong&, int&> {};
983
984 template <>
985 struct common_type<const volatile CommonWithIntButRefLong&, const volatile int&>
986 : common_type<CommonWithIntButRefLong&, int&> {};
987
988 template <>
989 struct common_type<const volatile int&, const volatile CommonWithIntButRefLong&>
990 : common_type<CommonWithIntButRefLong&, int&> {};
991 } // namespace std
992 static_assert(CheckCommonWith<CommonWithIntButRefLong, int>());
993