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