124dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 224dd2d2fSChristopher Di Bella // 324dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 424dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 524dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 624dd2d2fSChristopher Di Bella // 724dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 824dd2d2fSChristopher Di Bella 924dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17 1024dd2d2fSChristopher Di Bella 1124dd2d2fSChristopher Di Bella // template<class From, class To> 1224dd2d2fSChristopher Di Bella // concept common_reference_with; 1324dd2d2fSChristopher Di Bella 1424dd2d2fSChristopher Di Bella #include <concepts> 153d2d3b3eSArthur O'Dwyer #include <type_traits> 1624dd2d2fSChristopher Di Bella 175d3ab6a2SMark de Wever #include "test_macros.h" 185d3ab6a2SMark de Wever 1924dd2d2fSChristopher Di Bella template <class T, class U> 2024dd2d2fSChristopher Di Bella constexpr bool CheckCommonReferenceWith() noexcept { 2124dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, U&>); 2224dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, const U&>); 2324dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, volatile U&>); 2424dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, const volatile U&>); 2524dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, U&&>); 2624dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, const U&&>); 2724dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, volatile U&&>); 2824dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T, const volatile U&&>); 2924dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T&, U&&>); 3024dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T&, const U&&>); 3124dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T&, volatile U&&>); 3224dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<T&, const volatile U&&>); 3324dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const T&, U&&>); 3424dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const T&, const U&&>); 3524dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const T&, volatile U&&>); 3624dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const T&, const volatile U&&>); 3724dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<volatile T&, U&&>); 3824dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<volatile T&, const U&&>); 3924dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<volatile T&, volatile U&&>); 4024dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<volatile T&, const volatile U&&>); 4124dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const volatile T&, U&&>); 4224dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const volatile T&, const U&&>); 4324dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<const volatile T&, volatile U&&>); 4424dd2d2fSChristopher Di Bella static_assert( 4524dd2d2fSChristopher Di Bella std::common_reference_with<const volatile T&, const volatile U&&>); 4624dd2d2fSChristopher Di Bella 4724dd2d2fSChristopher Di Bella return std::common_reference_with<T, U>; 4824dd2d2fSChristopher Di Bella } 4924dd2d2fSChristopher Di Bella 5024dd2d2fSChristopher Di Bella namespace BuiltinTypes { 5124dd2d2fSChristopher Di Bella // fundamental types 5224dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<void, void>); 5324dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int, int>()); 5424dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int, long>()); 5524dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int, unsigned char>()); 568f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 5724dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int, __int128_t>()); 5824dd2d2fSChristopher Di Bella #endif 5924dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int, double>()); 6024dd2d2fSChristopher Di Bella 6124dd2d2fSChristopher Di Bella // arrays 6224dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int[5], int[5]>()); 6324dd2d2fSChristopher Di Bella 6424dd2d2fSChristopher Di Bella // pointers (common with void*) 6524dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int*, void*>()); 6624dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int*, const void*>()); 6724dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int*, volatile void*>()); 6824dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int*, const volatile void*>()); 6924dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const int*, void*>()); 7024dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const int*, const void*>()); 7124dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const int*, volatile void*>()); 7224dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const int*, const volatile void*>()); 7324dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<volatile int*, void*>()); 7424dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<volatile int*, const void*>()); 7524dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<volatile int*, volatile void*>()); 7624dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<volatile int*, const volatile void*>()); 7724dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const volatile int*, void*>()); 7824dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const volatile int*, const void*>()); 7924dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<const volatile int*, volatile void*>()); 8024dd2d2fSChristopher Di Bella static_assert( 8124dd2d2fSChristopher Di Bella CheckCommonReferenceWith<const volatile int*, const volatile void*>()); 8224dd2d2fSChristopher Di Bella 8324dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (*)(), int (*)()>()); 8424dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (*)(), int (*)() noexcept>()); 8524dd2d2fSChristopher Di Bella struct S {}; 8624dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int S::*, int S::*>()); 8724dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int S::*, const int S::*>()); 8824dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)()>()); 8924dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)() noexcept>()); 9024dd2d2fSChristopher Di Bella static_assert( 9124dd2d2fSChristopher Di Bella CheckCommonReferenceWith<int (S::*)() const, int (S::*)() const>()); 9224dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)() const, 9324dd2d2fSChristopher Di Bella int (S::*)() const noexcept>()); 9424dd2d2fSChristopher Di Bella static_assert( 9524dd2d2fSChristopher Di Bella CheckCommonReferenceWith<int (S::*)() volatile, int (S::*)() volatile>()); 9624dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)() volatile, 9724dd2d2fSChristopher Di Bella int (S::*)() volatile noexcept>()); 9824dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)() const volatile, 9924dd2d2fSChristopher Di Bella int (S::*)() const volatile>()); 10024dd2d2fSChristopher Di Bella static_assert(CheckCommonReferenceWith<int (S::*)() const volatile, 10124dd2d2fSChristopher Di Bella int (S::*)() const volatile noexcept>()); 10224dd2d2fSChristopher Di Bella 10324dd2d2fSChristopher Di Bella // nonsense 10424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<double, float*>); 10524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int, int[5]>); 10624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int*, long*>); 10724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int*, unsigned int*>); 10824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int (*)(), int (*)(int)>); 10924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int S::*, float S::*>); 11024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() const>); 11124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() volatile>); 11224dd2d2fSChristopher Di Bella static_assert( 11324dd2d2fSChristopher Di Bella !std::common_reference_with<int (S::*)(), int (S::*)() const volatile>); 11424dd2d2fSChristopher Di Bella static_assert( 11524dd2d2fSChristopher Di Bella !std::common_reference_with<int (S::*)() const, int (S::*)() volatile>); 11624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int (S::*)() const, 11724dd2d2fSChristopher Di Bella int (S::*)() const volatile>); 11824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int (S::*)() volatile, 11924dd2d2fSChristopher Di Bella int (S::*)() const volatile>); 12024dd2d2fSChristopher Di Bella } // namespace BuiltinTypes 12124dd2d2fSChristopher Di Bella 12224dd2d2fSChristopher Di Bella namespace NoDefaultCommonReference { 12324dd2d2fSChristopher Di Bella class T {}; 12424dd2d2fSChristopher Di Bella 12524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T, int>); 12624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<int, T>); 12724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T, int[10]>); 12824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T[10], int>); 12924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T*, int*>); 13024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T*, const int*>); 13124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T*, volatile int*>); 13224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T*, const volatile int*>); 13324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, int*>); 13424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, int*>); 13524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T*, int*>); 13624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, const int*>); 13724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, volatile int*>); 13824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, const volatile int*>); 13924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, const int*>); 14024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, const int*>); 14124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T*, const int*>); 14224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, const int*>); 14324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, volatile int*>); 14424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, const volatile int*>); 14524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, volatile int*>); 14624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, volatile int*>); 14724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T*, volatile int*>); 14824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T*, const int*>); 14924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T*, volatile int*>); 15024dd2d2fSChristopher Di Bella static_assert( 15124dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T*, const volatile int*>); 15224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T*, const volatile int*>); 15324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T*, const volatile int*>); 15424dd2d2fSChristopher Di Bella static_assert( 15524dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T*, const volatile int*>); 15624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, int&>); 15724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, const int&>); 15824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, volatile int&>); 15924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, const volatile int&>); 16024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, int&>); 16124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, int&>); 16224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, int&>); 16324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const int&>); 16424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, volatile int&>); 16524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const volatile int&>); 16624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const int&>); 16724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const int&>); 16824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, const int&>); 16924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const int&>); 17024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, volatile int&>); 17124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const volatile int&>); 17224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, volatile int&>); 17324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, volatile int&>); 17424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, volatile int&>); 17524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, const int&>); 17624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, volatile int&>); 17724dd2d2fSChristopher Di Bella static_assert( 17824dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&, const volatile int&>); 17924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const volatile int&>); 18024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const volatile int&>); 18124dd2d2fSChristopher Di Bella static_assert( 18224dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&, const volatile int&>); 18324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, int&&>); 18424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, const int&&>); 18524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, volatile int&&>); 18624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&, const volatile int&&>); 18724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, int&&>); 18824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, int&&>); 18924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, int&&>); 19024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const int&&>); 19124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, volatile int&&>); 19224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const volatile int&&>); 19324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const int&&>); 19424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const int&&>); 19524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, const int&&>); 19624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const int&&>); 19724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, volatile int&&>); 19824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const volatile int&&>); 19924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, volatile int&&>); 20024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, volatile int&&>); 20124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, volatile int&&>); 20224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, const int&&>); 20324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&, volatile int&&>); 20424dd2d2fSChristopher Di Bella static_assert( 20524dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&, const volatile int&&>); 20624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&, const volatile int&&>); 20724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&, const volatile int&&>); 20824dd2d2fSChristopher Di Bella static_assert( 20924dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&, const volatile int&&>); 21024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, int&>); 21124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, const int&>); 21224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, volatile int&>); 21324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, const volatile int&>); 21424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, int&>); 21524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, int&>); 21624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, int&>); 21724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const int&>); 21824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, volatile int&>); 21924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const volatile int&>); 22024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const int&>); 22124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const int&>); 22224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, const int&>); 22324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const int&>); 22424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, volatile int&>); 22524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const volatile int&>); 22624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, volatile int&>); 22724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, volatile int&>); 22824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, volatile int&>); 22924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, const int&>); 23024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, volatile int&>); 23124dd2d2fSChristopher Di Bella static_assert( 23224dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&&, const volatile int&>); 23324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const volatile int&>); 23424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const volatile int&>); 23524dd2d2fSChristopher Di Bella static_assert( 23624dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&&, const volatile int&>); 23724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, int&&>); 23824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, const int&&>); 23924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, volatile int&&>); 24024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<T&&, const volatile int&&>); 24124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, int&&>); 24224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, int&&>); 24324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, int&&>); 24424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const int&&>); 24524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, volatile int&&>); 24624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const volatile int&&>); 24724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const int&&>); 24824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const int&&>); 24924dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, const int&&>); 25024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const int&&>); 25124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, volatile int&&>); 25224dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>); 25324dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, volatile int&&>); 25424dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, volatile int&&>); 25524dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>); 25624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, const int&&>); 25724dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>); 25824dd2d2fSChristopher Di Bella static_assert( 25924dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&&, const volatile int&&>); 26024dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<const T&&, const volatile int&&>); 26124dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>); 26224dd2d2fSChristopher Di Bella static_assert( 26324dd2d2fSChristopher Di Bella !std::common_reference_with<const volatile T&&, const volatile int&&>); 26424dd2d2fSChristopher Di Bella } // namespace NoDefaultCommonReference 26524dd2d2fSChristopher Di Bella 26624dd2d2fSChristopher Di Bella struct BadBasicCommonReference { 26724dd2d2fSChristopher Di Bella // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing. 26824dd2d2fSChristopher Di Bella // In the meantime, the test should be included. If compiler support is added, then an include guard 26924dd2d2fSChristopher Di Bella // should be placed so the test doesn't get deleted. 27024dd2d2fSChristopher Di Bella operator int() const; 27124dd2d2fSChristopher Di Bella operator int&(); 27224dd2d2fSChristopher Di Bella }; 27324dd2d2fSChristopher Di Bella static_assert(std::convertible_to<BadBasicCommonReference, int>); 27424dd2d2fSChristopher Di Bella static_assert(std::convertible_to<BadBasicCommonReference, int&>); 27524dd2d2fSChristopher Di Bella 27624dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 277*5dfdac74SNikolas Klauser struct std::basic_common_reference<BadBasicCommonReference, int, X, Y> { 27824dd2d2fSChristopher Di Bella using type = BadBasicCommonReference&; 27924dd2d2fSChristopher Di Bella }; 28024dd2d2fSChristopher Di Bella 28124dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 282*5dfdac74SNikolas Klauser struct std::basic_common_reference<int, BadBasicCommonReference, X, Y> { 28324dd2d2fSChristopher Di Bella using type = int&; 28424dd2d2fSChristopher Di Bella }; 285*5dfdac74SNikolas Klauser 28624dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<BadBasicCommonReference, int>); 28724dd2d2fSChristopher Di Bella 28824dd2d2fSChristopher Di Bella struct StructNotConvertibleToCommonReference { 28924dd2d2fSChristopher Di Bella explicit(false) StructNotConvertibleToCommonReference(int); 29024dd2d2fSChristopher Di Bella }; 29124dd2d2fSChristopher Di Bella static_assert(std::convertible_to<int, StructNotConvertibleToCommonReference>); 29224dd2d2fSChristopher Di Bella 29324dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 294*5dfdac74SNikolas Klauser struct std::basic_common_reference<StructNotConvertibleToCommonReference, int, X, Y> { 29524dd2d2fSChristopher Di Bella using type = int&; 29624dd2d2fSChristopher Di Bella }; 29724dd2d2fSChristopher Di Bella 29824dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 299*5dfdac74SNikolas Klauser struct std::basic_common_reference<int, StructNotConvertibleToCommonReference, X, Y> { 30024dd2d2fSChristopher Di Bella using type = int&; 30124dd2d2fSChristopher Di Bella }; 302*5dfdac74SNikolas Klauser 30324dd2d2fSChristopher Di Bella static_assert( 30424dd2d2fSChristopher Di Bella !std::common_reference_with<StructNotConvertibleToCommonReference, int>); 30524dd2d2fSChristopher Di Bella 30624dd2d2fSChristopher Di Bella struct IntNotConvertibleToCommonReference { 30724dd2d2fSChristopher Di Bella operator int&() const; 30824dd2d2fSChristopher Di Bella }; 30924dd2d2fSChristopher Di Bella 31024dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 311*5dfdac74SNikolas Klauser struct std::basic_common_reference<IntNotConvertibleToCommonReference, int, X, Y> { 31224dd2d2fSChristopher Di Bella using type = int&; 31324dd2d2fSChristopher Di Bella }; 31424dd2d2fSChristopher Di Bella 31524dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 316*5dfdac74SNikolas Klauser struct std::basic_common_reference<int, IntNotConvertibleToCommonReference, X, Y> { 31724dd2d2fSChristopher Di Bella using type = int&; 31824dd2d2fSChristopher Di Bella }; 319*5dfdac74SNikolas Klauser 32024dd2d2fSChristopher Di Bella static_assert( 32124dd2d2fSChristopher Di Bella !std::common_reference_with<StructNotConvertibleToCommonReference, int>); 32224dd2d2fSChristopher Di Bella 32324dd2d2fSChristopher Di Bella struct HasCommonReference { 32424dd2d2fSChristopher Di Bella explicit(false) HasCommonReference(int); 32524dd2d2fSChristopher Di Bella operator int&() const; 32624dd2d2fSChristopher Di Bella }; 32724dd2d2fSChristopher Di Bella 32824dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 329*5dfdac74SNikolas Klauser struct std::basic_common_reference<HasCommonReference, int, X, Y> { 33024dd2d2fSChristopher Di Bella using type = int&; 33124dd2d2fSChristopher Di Bella }; 33224dd2d2fSChristopher Di Bella 33324dd2d2fSChristopher Di Bella template <template <class> class X, template <class> class Y> 334*5dfdac74SNikolas Klauser struct std::basic_common_reference<int, HasCommonReference, X, Y> { 33524dd2d2fSChristopher Di Bella using type = int&; 33624dd2d2fSChristopher Di Bella }; 337*5dfdac74SNikolas Klauser 33824dd2d2fSChristopher Di Bella static_assert(!std::common_reference_with<HasCommonReference, int>); 33924dd2d2fSChristopher Di Bella static_assert(std::common_reference_with<HasCommonReference, int&>); 340