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