//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 // template // concept common_with; #include #include #include "test_macros.h" template constexpr bool CheckCommonWith() noexcept { constexpr bool result = std::common_with; static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); static_assert(std::common_with == result); return result; } template constexpr bool HasValidCommonType() noexcept { return requires { typename std::common_type_t; } &&std::same_as, std::common_type_t >; } namespace BuiltinTypes { // fundamental types static_assert(std::common_with); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); #ifndef TEST_HAS_NO_INT128 static_assert(CheckCommonWith()); #endif static_assert(CheckCommonWith()); // arrays static_assert(CheckCommonWith()); // pointers static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); struct S {}; static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); static_assert( CheckCommonWith()); static_assert(CheckCommonWith()); static_assert( CheckCommonWith()); static_assert(CheckCommonWith()); static_assert(CheckCommonWith()); // nonsense static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert( !CheckCommonWith()); static_assert( !CheckCommonWith()); } // namespace BuiltinTypes namespace NoDefaultCommonType { class T {}; static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); static_assert(!CheckCommonWith()); } // namespace NoDefaultCommonType struct BadBasicCommonType { // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing. // In the meantime, the test should be included. If compiler support is added, then an include guard // should be placed so the test doesn't get deleted. }; template <> struct std::common_type { using type = BadBasicCommonType; }; template <> struct std::common_type { using type = int; }; static_assert(requires { typename std::common_type_t; }); static_assert(requires { typename std::common_type_t; }); static_assert(!std::same_as, std::common_type_t >); static_assert(!CheckCommonWith()); struct DullCommonType {}; static_assert(!std::convertible_to); struct T1 {}; static_assert(!std::convertible_to); template <> struct std::common_type { using type = DullCommonType; }; template <> struct std::common_type { using type = DullCommonType; }; static_assert(HasValidCommonType()); static_assert(!CheckCommonWith()); struct CommonTypeImplicitlyConstructibleFromInt { explicit(false) CommonTypeImplicitlyConstructibleFromInt(int); }; static_assert(requires { static_cast(0); }); struct T2 {}; static_assert( !std::convertible_to); template <> struct std::common_type { using type = CommonTypeImplicitlyConstructibleFromInt; }; template <> struct std::common_type { using type = CommonTypeImplicitlyConstructibleFromInt; }; static_assert(HasValidCommonType()); static_assert(!CheckCommonWith()); struct CommonTypeExplicitlyConstructibleFromInt { explicit CommonTypeExplicitlyConstructibleFromInt(int); }; static_assert(requires { static_cast(0); }); struct T3 {}; static_assert( !std::convertible_to); template <> struct std::common_type { using type = CommonTypeExplicitlyConstructibleFromInt; }; template <> struct std::common_type { using type = CommonTypeExplicitlyConstructibleFromInt; }; static_assert(HasValidCommonType()); static_assert(!CheckCommonWith()); struct T4 {}; struct CommonTypeImplicitlyConstructibleFromT4 { explicit(false) CommonTypeImplicitlyConstructibleFromT4(T4); }; static_assert(requires(T4 t4) { static_cast(t4); }); template <> struct std::common_type { using type = CommonTypeImplicitlyConstructibleFromT4; }; template <> struct std::common_type { using type = CommonTypeImplicitlyConstructibleFromT4; }; static_assert(HasValidCommonType()); static_assert(!CheckCommonWith()); struct T5 {}; struct CommonTypeExplicitlyConstructibleFromT5 { explicit CommonTypeExplicitlyConstructibleFromT5(T5); }; static_assert(requires(T5 t5) { static_cast(t5); }); template <> struct std::common_type { using type = CommonTypeExplicitlyConstructibleFromT5; }; template <> struct std::common_type { using type = CommonTypeExplicitlyConstructibleFromT5; }; static_assert(HasValidCommonType()); static_assert(!CheckCommonWith()); struct T6 {}; struct CommonTypeNoCommonReference { CommonTypeNoCommonReference(T6); CommonTypeNoCommonReference(int); }; template <> struct std::common_type { using type = CommonTypeNoCommonReference; }; template <> struct std::common_type { using type = CommonTypeNoCommonReference; }; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template <> struct std::common_type {}; template constexpr bool HasCommonReference() noexcept { return requires { typename std::common_reference_t; }; } static_assert(HasValidCommonType()); static_assert(!HasCommonReference()); static_assert(!CheckCommonWith()); struct T7 {}; struct CommonTypeNoMetaCommonReference { CommonTypeNoMetaCommonReference(T7); CommonTypeNoMetaCommonReference(int); }; template <> struct std::common_type { using type = CommonTypeNoMetaCommonReference; }; template <> struct std::common_type { using type = CommonTypeNoMetaCommonReference; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; template <> struct std::common_type { using type = void; }; static_assert(HasValidCommonType()); static_assert(HasValidCommonType()); static_assert(HasCommonReference()); static_assert( !HasCommonReference&, std::common_reference_t >()); static_assert(!CheckCommonWith()); struct CommonWithInt { operator int() const volatile; }; template <> struct std::common_type { using type = int; }; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; static_assert(CheckCommonWith()); struct CommonWithIntButRefLong { operator int() const volatile; }; template <> struct std::common_type { using type = int; }; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type { using type = long; }; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type { }; template <> struct std::common_type : std::common_type { }; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; template <> struct std::common_type : std::common_type {}; static_assert(CheckCommonWith());