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