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