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