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 namespace std { 266 template <> 267 struct common_type<BadBasicCommonType, int> { 268 using type = BadBasicCommonType; 269 }; 270 271 template <> 272 struct common_type<int, BadBasicCommonType> { 273 using type = int; 274 }; 275 } // namespace std 276 static_assert(requires { 277 typename std::common_type_t<BadBasicCommonType, int>; 278 }); 279 static_assert(requires { 280 typename std::common_type_t<int, BadBasicCommonType>; 281 }); 282 static_assert(!std::same_as<std::common_type_t<BadBasicCommonType, int>, 283 std::common_type_t<int, BadBasicCommonType> >); 284 static_assert(!CheckCommonWith<BadBasicCommonType, int>()); 285 286 struct DullCommonType {}; 287 static_assert(!std::convertible_to<DullCommonType, int>); 288 289 struct T1 {}; 290 static_assert(!std::convertible_to<DullCommonType, T1>); 291 292 namespace std { 293 template <> 294 struct common_type<T1, int> { 295 using type = DullCommonType; 296 }; 297 298 template <> 299 struct common_type<int, T1> { 300 using type = DullCommonType; 301 }; 302 } // namespace std 303 static_assert(HasValidCommonType<T1, int>()); 304 static_assert(!CheckCommonWith<T1, int>()); 305 306 struct CommonTypeImplicitlyConstructibleFromInt { 307 explicit(false) CommonTypeImplicitlyConstructibleFromInt(int); 308 }; 309 static_assert(requires { 310 static_cast<CommonTypeImplicitlyConstructibleFromInt>(0); 311 }); 312 313 struct T2 {}; 314 static_assert( 315 !std::convertible_to<CommonTypeImplicitlyConstructibleFromInt, T2>); 316 317 namespace std { 318 template <> 319 struct common_type<T2, int> { 320 using type = CommonTypeImplicitlyConstructibleFromInt; 321 }; 322 323 template <> 324 struct common_type<int, T2> { 325 using type = CommonTypeImplicitlyConstructibleFromInt; 326 }; 327 } // namespace std 328 static_assert(HasValidCommonType<T2, int>()); 329 static_assert(!CheckCommonWith<T2, int>()); 330 331 struct CommonTypeExplicitlyConstructibleFromInt { 332 explicit CommonTypeExplicitlyConstructibleFromInt(int); 333 }; 334 static_assert(requires { 335 static_cast<CommonTypeExplicitlyConstructibleFromInt>(0); 336 }); 337 338 struct T3 {}; 339 static_assert( 340 !std::convertible_to<CommonTypeExplicitlyConstructibleFromInt, T2>); 341 342 namespace std { 343 template <> 344 struct common_type<T3, int> { 345 using type = CommonTypeExplicitlyConstructibleFromInt; 346 }; 347 348 template <> 349 struct common_type<int, T3> { 350 using type = CommonTypeExplicitlyConstructibleFromInt; 351 }; 352 } // namespace std 353 static_assert(HasValidCommonType<T3, int>()); 354 static_assert(!CheckCommonWith<T3, int>()); 355 356 struct T4 {}; 357 struct CommonTypeImplicitlyConstructibleFromT4 { 358 explicit(false) CommonTypeImplicitlyConstructibleFromT4(T4); 359 }; 360 static_assert(requires(T4 t4) { 361 static_cast<CommonTypeImplicitlyConstructibleFromT4>(t4); 362 }); 363 364 namespace std { 365 template <> 366 struct common_type<T4, int> { 367 using type = CommonTypeImplicitlyConstructibleFromT4; 368 }; 369 370 template <> 371 struct common_type<int, T4> { 372 using type = CommonTypeImplicitlyConstructibleFromT4; 373 }; 374 } // namespace std 375 static_assert(HasValidCommonType<T4, int>()); 376 static_assert(!CheckCommonWith<T4, int>()); 377 378 struct T5 {}; 379 struct CommonTypeExplicitlyConstructibleFromT5 { 380 explicit CommonTypeExplicitlyConstructibleFromT5(T5); 381 }; 382 static_assert(requires(T5 t5) { 383 static_cast<CommonTypeExplicitlyConstructibleFromT5>(t5); 384 }); 385 386 namespace std { 387 template <> 388 struct common_type<T5, int> { 389 using type = CommonTypeExplicitlyConstructibleFromT5; 390 }; 391 392 template <> 393 struct common_type<int, T5> { 394 using type = CommonTypeExplicitlyConstructibleFromT5; 395 }; 396 } // namespace std 397 static_assert(HasValidCommonType<T5, int>()); 398 static_assert(!CheckCommonWith<T5, int>()); 399 400 struct T6 {}; 401 struct CommonTypeNoCommonReference { 402 CommonTypeNoCommonReference(T6); 403 CommonTypeNoCommonReference(int); 404 }; 405 406 namespace std { 407 template <> 408 struct common_type<T6, int> { 409 using type = CommonTypeNoCommonReference; 410 }; 411 412 template <> 413 struct common_type<int, T6> { 414 using type = CommonTypeNoCommonReference; 415 }; 416 417 template <> 418 struct common_type<T6&, int&> {}; 419 420 template <> 421 struct common_type<int&, T6&> {}; 422 423 template <> 424 struct common_type<T6&, const int&> {}; 425 426 template <> 427 struct common_type<int&, const T6&> {}; 428 429 template <> 430 struct common_type<T6&, volatile int&> {}; 431 432 template <> 433 struct common_type<int&, volatile T6&> {}; 434 435 template <> 436 struct common_type<T6&, const volatile int&> {}; 437 438 template <> 439 struct common_type<int&, const volatile T6&> {}; 440 441 template <> 442 struct common_type<const T6&, int&> {}; 443 444 template <> 445 struct common_type<const int&, T6&> {}; 446 447 template <> 448 struct common_type<const T6&, const int&> {}; 449 450 template <> 451 struct common_type<const int&, const T6&> {}; 452 453 template <> 454 struct common_type<const T6&, volatile int&> {}; 455 456 template <> 457 struct common_type<const int&, volatile T6&> {}; 458 459 template <> 460 struct common_type<const T6&, const volatile int&> {}; 461 462 template <> 463 struct common_type<const int&, const volatile T6&> {}; 464 465 template <> 466 struct common_type<volatile T6&, int&> {}; 467 468 template <> 469 struct common_type<volatile int&, T6&> {}; 470 471 template <> 472 struct common_type<volatile T6&, const int&> {}; 473 474 template <> 475 struct common_type<volatile int&, const T6&> {}; 476 477 template <> 478 struct common_type<volatile T6&, volatile int&> {}; 479 480 template <> 481 struct common_type<volatile int&, volatile T6&> {}; 482 483 template <> 484 struct common_type<volatile T6&, const volatile int&> {}; 485 486 template <> 487 struct common_type<volatile int&, const volatile T6&> {}; 488 489 template <> 490 struct common_type<const volatile T6&, int&> {}; 491 492 template <> 493 struct common_type<const volatile int&, T6&> {}; 494 495 template <> 496 struct common_type<const volatile T6&, const int&> {}; 497 498 template <> 499 struct common_type<const volatile int&, const T6&> {}; 500 501 template <> 502 struct common_type<const volatile T6&, volatile int&> {}; 503 504 template <> 505 struct common_type<const volatile int&, volatile T6&> {}; 506 507 template <> 508 struct common_type<const volatile T6&, const volatile int&> {}; 509 510 template <> 511 struct common_type<const volatile int&, const volatile T6&> {}; 512 } // namespace std 513 514 template <typename T, typename U> 515 constexpr bool HasCommonReference() noexcept { 516 return requires { typename std::common_reference_t<T, U>; }; 517 } 518 519 static_assert(HasValidCommonType<T6, int>()); 520 static_assert(!HasCommonReference<const T6&, const int&>()); 521 static_assert(!CheckCommonWith<T6, int>()); 522 523 struct T7 {}; 524 struct CommonTypeNoMetaCommonReference { 525 CommonTypeNoMetaCommonReference(T7); 526 CommonTypeNoMetaCommonReference(int); 527 }; 528 529 namespace std { 530 template <> 531 struct common_type<T7, int> { 532 using type = CommonTypeNoMetaCommonReference; 533 }; 534 535 template <> 536 struct common_type<int, T7> { 537 using type = CommonTypeNoMetaCommonReference; 538 }; 539 540 template <> 541 struct common_type<T7&, int&> { 542 using type = void; 543 }; 544 545 template <> 546 struct common_type<int&, T7&> { 547 using type = void; 548 }; 549 550 template <> 551 struct common_type<T7&, const int&> { 552 using type = void; 553 }; 554 555 template <> 556 struct common_type<int&, const T7&> { 557 using type = void; 558 }; 559 560 template <> 561 struct common_type<T7&, volatile int&> { 562 using type = void; 563 }; 564 565 template <> 566 struct common_type<int&, volatile T7&> { 567 using type = void; 568 }; 569 570 template <> 571 struct common_type<T7&, const volatile int&> { 572 using type = void; 573 }; 574 575 template <> 576 struct common_type<int&, const volatile T7&> { 577 using type = void; 578 }; 579 580 template <> 581 struct common_type<const T7&, int&> { 582 using type = void; 583 }; 584 585 template <> 586 struct common_type<const int&, T7&> { 587 using type = void; 588 }; 589 590 template <> 591 struct common_type<const T7&, const int&> { 592 using type = void; 593 }; 594 595 template <> 596 struct common_type<const int&, const T7&> { 597 using type = void; 598 }; 599 600 template <> 601 struct common_type<const T7&, volatile int&> { 602 using type = void; 603 }; 604 605 template <> 606 struct common_type<const int&, volatile T7&> { 607 using type = void; 608 }; 609 610 template <> 611 struct common_type<const T7&, const volatile int&> { 612 using type = void; 613 }; 614 615 template <> 616 struct common_type<const int&, const volatile T7&> { 617 using type = void; 618 }; 619 620 template <> 621 struct common_type<volatile T7&, int&> { 622 using type = void; 623 }; 624 625 template <> 626 struct common_type<volatile int&, T7&> { 627 using type = void; 628 }; 629 630 template <> 631 struct common_type<volatile T7&, const int&> { 632 using type = void; 633 }; 634 635 template <> 636 struct common_type<volatile int&, const T7&> { 637 using type = void; 638 }; 639 640 template <> 641 struct common_type<volatile T7&, volatile int&> { 642 using type = void; 643 }; 644 645 template <> 646 struct common_type<volatile int&, volatile T7&> { 647 using type = void; 648 }; 649 650 template <> 651 struct common_type<volatile T7&, const volatile int&> { 652 using type = void; 653 }; 654 655 template <> 656 struct common_type<volatile int&, const volatile T7&> { 657 using type = void; 658 }; 659 660 template <> 661 struct common_type<const volatile T7&, int&> { 662 using type = void; 663 }; 664 665 template <> 666 struct common_type<const volatile int&, T7&> { 667 using type = void; 668 }; 669 670 template <> 671 struct common_type<const volatile T7&, const int&> { 672 using type = void; 673 }; 674 675 template <> 676 struct common_type<const volatile int&, const T7&> { 677 using type = void; 678 }; 679 680 template <> 681 struct common_type<const volatile T7&, volatile int&> { 682 using type = void; 683 }; 684 685 template <> 686 struct common_type<const volatile int&, volatile T7&> { 687 using type = void; 688 }; 689 690 template <> 691 struct common_type<const volatile T7&, const volatile int&> { 692 using type = void; 693 }; 694 695 template <> 696 struct common_type<const volatile int&, const volatile T7&> { 697 using type = void; 698 }; 699 } // namespace std 700 static_assert(HasValidCommonType<T7, int>()); 701 static_assert(HasValidCommonType<const T7&, const int&>()); 702 static_assert(HasCommonReference<const T7&, const int&>()); 703 static_assert( 704 !HasCommonReference<std::common_type_t<T7, int>&, 705 std::common_reference_t<const T7&, const int&> >()); 706 static_assert(!CheckCommonWith<T7, int>()); 707 708 struct CommonWithInt { 709 operator int() const volatile; 710 }; 711 712 namespace std { 713 template <> 714 struct common_type<CommonWithInt, int> { 715 using type = int; 716 }; 717 718 template <> 719 struct common_type<int, CommonWithInt> : common_type<CommonWithInt, int> {}; 720 721 template <> 722 struct common_type<CommonWithInt&, int&> : common_type<CommonWithInt, int> {}; 723 724 template <> 725 struct common_type<int&, CommonWithInt&> : common_type<CommonWithInt, int> {}; 726 727 template <> 728 struct common_type<CommonWithInt&, const int&> 729 : common_type<CommonWithInt, int> {}; 730 731 template <> 732 struct common_type<int&, const CommonWithInt&> 733 : common_type<CommonWithInt, int> {}; 734 735 template <> 736 struct common_type<CommonWithInt&, volatile int&> 737 : common_type<CommonWithInt, int> {}; 738 739 template <> 740 struct common_type<int&, volatile CommonWithInt&> 741 : common_type<CommonWithInt, int> {}; 742 743 template <> 744 struct common_type<CommonWithInt&, const volatile int&> 745 : common_type<CommonWithInt, int> {}; 746 747 template <> 748 struct common_type<int&, const volatile CommonWithInt&> 749 : common_type<CommonWithInt, int> {}; 750 751 template <> 752 struct common_type<const CommonWithInt&, int&> 753 : common_type<CommonWithInt, int> {}; 754 755 template <> 756 struct common_type<const int&, CommonWithInt&> 757 : common_type<CommonWithInt, int> {}; 758 759 template <> 760 struct common_type<const CommonWithInt&, const int&> 761 : common_type<CommonWithInt, int> {}; 762 763 template <> 764 struct common_type<const int&, const CommonWithInt&> 765 : common_type<CommonWithInt, int> {}; 766 767 template <> 768 struct common_type<const CommonWithInt&, volatile int&> 769 : common_type<CommonWithInt, int> {}; 770 771 template <> 772 struct common_type<const int&, volatile CommonWithInt&> 773 : common_type<CommonWithInt, int> {}; 774 775 template <> 776 struct common_type<const CommonWithInt&, const volatile int&> 777 : common_type<CommonWithInt, int> {}; 778 779 template <> 780 struct common_type<const int&, const volatile CommonWithInt&> 781 : common_type<CommonWithInt, int> {}; 782 783 template <> 784 struct common_type<volatile CommonWithInt&, int&> 785 : common_type<CommonWithInt, int> {}; 786 787 template <> 788 struct common_type<volatile int&, CommonWithInt&> 789 : common_type<CommonWithInt, int> {}; 790 791 template <> 792 struct common_type<volatile CommonWithInt&, const int&> 793 : common_type<CommonWithInt, int> {}; 794 795 template <> 796 struct common_type<volatile int&, const CommonWithInt&> 797 : common_type<CommonWithInt, int> {}; 798 799 template <> 800 struct common_type<volatile CommonWithInt&, volatile int&> 801 : common_type<CommonWithInt, int> {}; 802 803 template <> 804 struct common_type<volatile int&, volatile CommonWithInt&> 805 : common_type<CommonWithInt, int> {}; 806 807 template <> 808 struct common_type<volatile CommonWithInt&, const volatile int&> 809 : common_type<CommonWithInt, int> {}; 810 811 template <> 812 struct common_type<volatile int&, const volatile CommonWithInt&> 813 : common_type<CommonWithInt, int> {}; 814 815 template <> 816 struct common_type<const volatile CommonWithInt&, int&> 817 : common_type<CommonWithInt, int> {}; 818 819 template <> 820 struct common_type<const volatile int&, CommonWithInt&> 821 : common_type<CommonWithInt, int> {}; 822 823 template <> 824 struct common_type<const volatile CommonWithInt&, const int&> 825 : common_type<CommonWithInt, int> {}; 826 827 template <> 828 struct common_type<const volatile int&, const CommonWithInt&> 829 : common_type<CommonWithInt, int> {}; 830 831 template <> 832 struct common_type<const volatile CommonWithInt&, volatile int&> 833 : common_type<CommonWithInt, int> {}; 834 835 template <> 836 struct common_type<const volatile int&, volatile CommonWithInt&> 837 : common_type<CommonWithInt, int> {}; 838 839 template <> 840 struct common_type<const volatile CommonWithInt&, const volatile int&> 841 : common_type<CommonWithInt, int> {}; 842 843 template <> 844 struct common_type<const volatile int&, const volatile CommonWithInt&> 845 : common_type<CommonWithInt, int> {}; 846 } // namespace std 847 static_assert(CheckCommonWith<CommonWithInt, int>()); 848 849 struct CommonWithIntButRefLong { 850 operator int() const volatile; 851 }; 852 853 namespace std { 854 template <> 855 struct common_type<CommonWithIntButRefLong, int> { 856 using type = int; 857 }; 858 859 template <> 860 struct common_type<int, CommonWithIntButRefLong> 861 : common_type<CommonWithIntButRefLong, int> {}; 862 863 template <> 864 struct common_type<CommonWithIntButRefLong&, int&> { 865 using type = long; 866 }; 867 868 template <> 869 struct common_type<int&, CommonWithIntButRefLong&> 870 : common_type<CommonWithIntButRefLong&, int&> {}; 871 872 template <> 873 struct common_type<CommonWithIntButRefLong&, const int&> 874 : common_type<CommonWithIntButRefLong&, int&> {}; 875 876 template <> 877 struct common_type<int&, const CommonWithIntButRefLong&> 878 : common_type<CommonWithIntButRefLong&, int&> {}; 879 880 template <> 881 struct common_type<CommonWithIntButRefLong&, volatile int&> 882 : common_type<CommonWithIntButRefLong&, int&> {}; 883 884 template <> 885 struct common_type<int&, volatile CommonWithIntButRefLong&> 886 : common_type<CommonWithIntButRefLong&, int&> {}; 887 888 template <> 889 struct common_type<CommonWithIntButRefLong&, const volatile int&> 890 : common_type<CommonWithIntButRefLong&, int&> {}; 891 892 template <> 893 struct common_type<int&, const volatile CommonWithIntButRefLong&> 894 : common_type<CommonWithIntButRefLong&, int&> {}; 895 896 template <> 897 struct common_type<const CommonWithIntButRefLong&, int&> 898 : common_type<CommonWithIntButRefLong&, int&> {}; 899 900 template <> 901 struct common_type<const int&, CommonWithIntButRefLong&> 902 : common_type<CommonWithIntButRefLong&, int&> {}; 903 904 template <> 905 struct common_type<const CommonWithIntButRefLong&, const int&> 906 : common_type<CommonWithIntButRefLong&, int&> {}; 907 908 template <> 909 struct common_type<const int&, const CommonWithIntButRefLong&> 910 : common_type<CommonWithIntButRefLong&, int&> {}; 911 912 template <> 913 struct common_type<const CommonWithIntButRefLong&, volatile int&> 914 : common_type<CommonWithIntButRefLong&, int&> {}; 915 916 template <> 917 struct common_type<const int&, volatile CommonWithIntButRefLong&> 918 : common_type<CommonWithIntButRefLong&, int&> {}; 919 920 template <> 921 struct common_type<const CommonWithIntButRefLong&, const volatile int&> 922 : common_type<CommonWithIntButRefLong&, int&> {}; 923 924 template <> 925 struct common_type<const int&, const volatile CommonWithIntButRefLong&> 926 : common_type<CommonWithIntButRefLong&, int&> {}; 927 928 template <> 929 struct common_type<volatile CommonWithIntButRefLong&, int&> 930 : common_type<CommonWithIntButRefLong&, int&> {}; 931 932 template <> 933 struct common_type<volatile int&, CommonWithIntButRefLong&> 934 : common_type<CommonWithIntButRefLong&, int&> {}; 935 936 template <> 937 struct common_type<volatile CommonWithIntButRefLong&, const int&> 938 : common_type<CommonWithIntButRefLong&, int&> {}; 939 940 template <> 941 struct common_type<volatile int&, const CommonWithIntButRefLong&> 942 : common_type<CommonWithIntButRefLong&, int&> {}; 943 944 template <> 945 struct common_type<volatile CommonWithIntButRefLong&, volatile int&> 946 : common_type<CommonWithIntButRefLong&, int&> {}; 947 948 template <> 949 struct common_type<volatile int&, volatile CommonWithIntButRefLong&> 950 : common_type<CommonWithIntButRefLong&, int&> {}; 951 952 template <> 953 struct common_type<volatile CommonWithIntButRefLong&, const volatile int&> 954 : common_type<CommonWithIntButRefLong&, int&> {}; 955 956 template <> 957 struct common_type<volatile int&, const volatile CommonWithIntButRefLong&> 958 : common_type<CommonWithIntButRefLong&, int&> {}; 959 960 template <> 961 struct common_type<const volatile CommonWithIntButRefLong&, int&> 962 : common_type<CommonWithIntButRefLong&, int&> {}; 963 964 template <> 965 struct common_type<const volatile int&, CommonWithIntButRefLong&> 966 : common_type<CommonWithIntButRefLong&, int&> {}; 967 968 template <> 969 struct common_type<const volatile CommonWithIntButRefLong&, const int&> 970 : common_type<CommonWithIntButRefLong&, int&> {}; 971 972 template <> 973 struct common_type<const volatile int&, const CommonWithIntButRefLong&> 974 : common_type<CommonWithIntButRefLong&, int&> {}; 975 976 template <> 977 struct common_type<const volatile CommonWithIntButRefLong&, volatile int&> 978 : common_type<CommonWithIntButRefLong&, int&> {}; 979 980 template <> 981 struct common_type<const volatile int&, volatile CommonWithIntButRefLong&> 982 : common_type<CommonWithIntButRefLong&, int&> {}; 983 984 template <> 985 struct common_type<const volatile CommonWithIntButRefLong&, const volatile int&> 986 : common_type<CommonWithIntButRefLong&, int&> {}; 987 988 template <> 989 struct common_type<const volatile int&, const volatile CommonWithIntButRefLong&> 990 : common_type<CommonWithIntButRefLong&, int&> {}; 991 } // namespace std 992 static_assert(CheckCommonWith<CommonWithIntButRefLong, int>()); 993 994 int main(int, char**) { return 0; } 995