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