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