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