1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// template<class From, class To>
12// concept common_reference_with;
13
14#include <concepts>
15#include <type_traits>
16
17#include "test_macros.h"
18
19template <class T, class U>
20constexpr bool CheckCommonReferenceWith() noexcept {
21 static_assert(std::common_reference_with<T, U&>);
22 static_assert(std::common_reference_with<T, const U&>);
23 static_assert(std::common_reference_with<T, volatile U&>);
24 static_assert(std::common_reference_with<T, const volatile U&>);
25 static_assert(std::common_reference_with<T, U&&>);
26 static_assert(std::common_reference_with<T, const U&&>);
27 static_assert(std::common_reference_with<T, volatile U&&>);
28 static_assert(std::common_reference_with<T, const volatile U&&>);
29 static_assert(std::common_reference_with<T&, U&&>);
30 static_assert(std::common_reference_with<T&, const U&&>);
31 static_assert(std::common_reference_with<T&, volatile U&&>);
32 static_assert(std::common_reference_with<T&, const volatile U&&>);
33 static_assert(std::common_reference_with<const T&, U&&>);
34 static_assert(std::common_reference_with<const T&, const U&&>);
35 static_assert(std::common_reference_with<const T&, volatile U&&>);
36 static_assert(std::common_reference_with<const T&, const volatile U&&>);
37 static_assert(std::common_reference_with<volatile T&, U&&>);
38 static_assert(std::common_reference_with<volatile T&, const U&&>);
39 static_assert(std::common_reference_with<volatile T&, volatile U&&>);
40 static_assert(std::common_reference_with<volatile T&, const volatile U&&>);
41 static_assert(std::common_reference_with<const volatile T&, U&&>);
42 static_assert(std::common_reference_with<const volatile T&, const U&&>);
43 static_assert(std::common_reference_with<const volatile T&, volatile U&&>);
44 static_assert(
45 std::common_reference_with<const volatile T&, const volatile U&&>);
46
47 return std::common_reference_with<T, U>;
48}
49
50namespace BuiltinTypes {
51// fundamental types
52static_assert(std::common_reference_with<void, void>);
53static_assert(CheckCommonReferenceWith<int, int>());
54static_assert(CheckCommonReferenceWith<int, long>());
55static_assert(CheckCommonReferenceWith<int, unsigned char>());
56#ifndef TEST_HAS_NO_INT128
57static_assert(CheckCommonReferenceWith<int, __int128_t>());
58#endif
59static_assert(CheckCommonReferenceWith<int, double>());
60
61// arrays
62static_assert(CheckCommonReferenceWith<int[5], int[5]>());
63
64// pointers (common with void*)
65static_assert(CheckCommonReferenceWith<int*, void*>());
66static_assert(CheckCommonReferenceWith<int*, const void*>());
67static_assert(CheckCommonReferenceWith<int*, volatile void*>());
68static_assert(CheckCommonReferenceWith<int*, const volatile void*>());
69static_assert(CheckCommonReferenceWith<const int*, void*>());
70static_assert(CheckCommonReferenceWith<const int*, const void*>());
71static_assert(CheckCommonReferenceWith<const int*, volatile void*>());
72static_assert(CheckCommonReferenceWith<const int*, const volatile void*>());
73static_assert(CheckCommonReferenceWith<volatile int*, void*>());
74static_assert(CheckCommonReferenceWith<volatile int*, const void*>());
75static_assert(CheckCommonReferenceWith<volatile int*, volatile void*>());
76static_assert(CheckCommonReferenceWith<volatile int*, const volatile void*>());
77static_assert(CheckCommonReferenceWith<const volatile int*, void*>());
78static_assert(CheckCommonReferenceWith<const volatile int*, const void*>());
79static_assert(CheckCommonReferenceWith<const volatile int*, volatile void*>());
80static_assert(
81 CheckCommonReferenceWith<const volatile int*, const volatile void*>());
82
83static_assert(CheckCommonReferenceWith<int (*)(), int (*)()>());
84static_assert(CheckCommonReferenceWith<int (*)(), int (*)() noexcept>());
85struct S {};
86static_assert(CheckCommonReferenceWith<int S::*, int S::*>());
87static_assert(CheckCommonReferenceWith<int S::*, const int S::*>());
88static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)()>());
89static_assert(CheckCommonReferenceWith<int (S::*)(), int (S::*)() noexcept>());
90static_assert(
91 CheckCommonReferenceWith<int (S::*)() const, int (S::*)() const>());
92static_assert(CheckCommonReferenceWith<int (S::*)() const,
93 int (S::*)() const noexcept>());
94static_assert(
95 CheckCommonReferenceWith<int (S::*)() volatile, int (S::*)() volatile>());
96static_assert(CheckCommonReferenceWith<int (S::*)() volatile,
97 int (S::*)() volatile noexcept>());
98static_assert(CheckCommonReferenceWith<int (S::*)() const volatile,
99 int (S::*)() const volatile>());
100static_assert(CheckCommonReferenceWith<int (S::*)() const volatile,
101 int (S::*)() const volatile noexcept>());
102
103// nonsense
104static_assert(!std::common_reference_with<double, float*>);
105static_assert(!std::common_reference_with<int, int[5]>);
106static_assert(!std::common_reference_with<int*, long*>);
107static_assert(!std::common_reference_with<int*, unsigned int*>);
108static_assert(!std::common_reference_with<int (*)(), int (*)(int)>);
109static_assert(!std::common_reference_with<int S::*, float S::*>);
110static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() const>);
111static_assert(!std::common_reference_with<int (S::*)(), int (S::*)() volatile>);
112static_assert(
113 !std::common_reference_with<int (S::*)(), int (S::*)() const volatile>);
114static_assert(
115 !std::common_reference_with<int (S::*)() const, int (S::*)() volatile>);
116static_assert(!std::common_reference_with<int (S::*)() const,
117 int (S::*)() const volatile>);
118static_assert(!std::common_reference_with<int (S::*)() volatile,
119 int (S::*)() const volatile>);
120} // namespace BuiltinTypes
121
122namespace NoDefaultCommonReference {
123class T {};
124
125static_assert(!std::common_reference_with<T, int>);
126static_assert(!std::common_reference_with<int, T>);
127static_assert(!std::common_reference_with<T, int[10]>);
128static_assert(!std::common_reference_with<T[10], int>);
129static_assert(!std::common_reference_with<T*, int*>);
130static_assert(!std::common_reference_with<T*, const int*>);
131static_assert(!std::common_reference_with<T*, volatile int*>);
132static_assert(!std::common_reference_with<T*, const volatile int*>);
133static_assert(!std::common_reference_with<const T*, int*>);
134static_assert(!std::common_reference_with<volatile T*, int*>);
135static_assert(!std::common_reference_with<const volatile T*, int*>);
136static_assert(!std::common_reference_with<const T*, const int*>);
137static_assert(!std::common_reference_with<const T*, volatile int*>);
138static_assert(!std::common_reference_with<const T*, const volatile int*>);
139static_assert(!std::common_reference_with<const T*, const int*>);
140static_assert(!std::common_reference_with<volatile T*, const int*>);
141static_assert(!std::common_reference_with<const volatile T*, const int*>);
142static_assert(!std::common_reference_with<volatile T*, const int*>);
143static_assert(!std::common_reference_with<volatile T*, volatile int*>);
144static_assert(!std::common_reference_with<volatile T*, const volatile int*>);
145static_assert(!std::common_reference_with<const T*, volatile int*>);
146static_assert(!std::common_reference_with<volatile T*, volatile int*>);
147static_assert(!std::common_reference_with<const volatile T*, volatile int*>);
148static_assert(!std::common_reference_with<const volatile T*, const int*>);
149static_assert(!std::common_reference_with<const volatile T*, volatile int*>);
150static_assert(
151 !std::common_reference_with<const volatile T*, const volatile int*>);
152static_assert(!std::common_reference_with<const T*, const volatile int*>);
153static_assert(!std::common_reference_with<volatile T*, const volatile int*>);
154static_assert(
155 !std::common_reference_with<const volatile T*, const volatile int*>);
156static_assert(!std::common_reference_with<T&, int&>);
157static_assert(!std::common_reference_with<T&, const int&>);
158static_assert(!std::common_reference_with<T&, volatile int&>);
159static_assert(!std::common_reference_with<T&, const volatile int&>);
160static_assert(!std::common_reference_with<const T&, int&>);
161static_assert(!std::common_reference_with<volatile T&, int&>);
162static_assert(!std::common_reference_with<const volatile T&, int&>);
163static_assert(!std::common_reference_with<const T&, const int&>);
164static_assert(!std::common_reference_with<const T&, volatile int&>);
165static_assert(!std::common_reference_with<const T&, const volatile int&>);
166static_assert(!std::common_reference_with<const T&, const int&>);
167static_assert(!std::common_reference_with<volatile T&, const int&>);
168static_assert(!std::common_reference_with<const volatile T&, const int&>);
169static_assert(!std::common_reference_with<volatile T&, const int&>);
170static_assert(!std::common_reference_with<volatile T&, volatile int&>);
171static_assert(!std::common_reference_with<volatile T&, const volatile int&>);
172static_assert(!std::common_reference_with<const T&, volatile int&>);
173static_assert(!std::common_reference_with<volatile T&, volatile int&>);
174static_assert(!std::common_reference_with<const volatile T&, volatile int&>);
175static_assert(!std::common_reference_with<const volatile T&, const int&>);
176static_assert(!std::common_reference_with<const volatile T&, volatile int&>);
177static_assert(
178 !std::common_reference_with<const volatile T&, const volatile int&>);
179static_assert(!std::common_reference_with<const T&, const volatile int&>);
180static_assert(!std::common_reference_with<volatile T&, const volatile int&>);
181static_assert(
182 !std::common_reference_with<const volatile T&, const volatile int&>);
183static_assert(!std::common_reference_with<T&, int&&>);
184static_assert(!std::common_reference_with<T&, const int&&>);
185static_assert(!std::common_reference_with<T&, volatile int&&>);
186static_assert(!std::common_reference_with<T&, const volatile int&&>);
187static_assert(!std::common_reference_with<const T&, int&&>);
188static_assert(!std::common_reference_with<volatile T&, int&&>);
189static_assert(!std::common_reference_with<const volatile T&, int&&>);
190static_assert(!std::common_reference_with<const T&, const int&&>);
191static_assert(!std::common_reference_with<const T&, volatile int&&>);
192static_assert(!std::common_reference_with<const T&, const volatile int&&>);
193static_assert(!std::common_reference_with<const T&, const int&&>);
194static_assert(!std::common_reference_with<volatile T&, const int&&>);
195static_assert(!std::common_reference_with<const volatile T&, const int&&>);
196static_assert(!std::common_reference_with<volatile T&, const int&&>);
197static_assert(!std::common_reference_with<volatile T&, volatile int&&>);
198static_assert(!std::common_reference_with<volatile T&, const volatile int&&>);
199static_assert(!std::common_reference_with<const T&, volatile int&&>);
200static_assert(!std::common_reference_with<volatile T&, volatile int&&>);
201static_assert(!std::common_reference_with<const volatile T&, volatile int&&>);
202static_assert(!std::common_reference_with<const volatile T&, const int&&>);
203static_assert(!std::common_reference_with<const volatile T&, volatile int&&>);
204static_assert(
205 !std::common_reference_with<const volatile T&, const volatile int&&>);
206static_assert(!std::common_reference_with<const T&, const volatile int&&>);
207static_assert(!std::common_reference_with<volatile T&, const volatile int&&>);
208static_assert(
209 !std::common_reference_with<const volatile T&, const volatile int&&>);
210static_assert(!std::common_reference_with<T&&, int&>);
211static_assert(!std::common_reference_with<T&&, const int&>);
212static_assert(!std::common_reference_with<T&&, volatile int&>);
213static_assert(!std::common_reference_with<T&&, const volatile int&>);
214static_assert(!std::common_reference_with<const T&&, int&>);
215static_assert(!std::common_reference_with<volatile T&&, int&>);
216static_assert(!std::common_reference_with<const volatile T&&, int&>);
217static_assert(!std::common_reference_with<const T&&, const int&>);
218static_assert(!std::common_reference_with<const T&&, volatile int&>);
219static_assert(!std::common_reference_with<const T&&, const volatile int&>);
220static_assert(!std::common_reference_with<const T&&, const int&>);
221static_assert(!std::common_reference_with<volatile T&&, const int&>);
222static_assert(!std::common_reference_with<const volatile T&&, const int&>);
223static_assert(!std::common_reference_with<volatile T&&, const int&>);
224static_assert(!std::common_reference_with<volatile T&&, volatile int&>);
225static_assert(!std::common_reference_with<volatile T&&, const volatile int&>);
226static_assert(!std::common_reference_with<const T&&, volatile int&>);
227static_assert(!std::common_reference_with<volatile T&&, volatile int&>);
228static_assert(!std::common_reference_with<const volatile T&&, volatile int&>);
229static_assert(!std::common_reference_with<const volatile T&&, const int&>);
230static_assert(!std::common_reference_with<const volatile T&&, volatile int&>);
231static_assert(
232 !std::common_reference_with<const volatile T&&, const volatile int&>);
233static_assert(!std::common_reference_with<const T&&, const volatile int&>);
234static_assert(!std::common_reference_with<volatile T&&, const volatile int&>);
235static_assert(
236 !std::common_reference_with<const volatile T&&, const volatile int&>);
237static_assert(!std::common_reference_with<T&&, int&&>);
238static_assert(!std::common_reference_with<T&&, const int&&>);
239static_assert(!std::common_reference_with<T&&, volatile int&&>);
240static_assert(!std::common_reference_with<T&&, const volatile int&&>);
241static_assert(!std::common_reference_with<const T&&, int&&>);
242static_assert(!std::common_reference_with<volatile T&&, int&&>);
243static_assert(!std::common_reference_with<const volatile T&&, int&&>);
244static_assert(!std::common_reference_with<const T&&, const int&&>);
245static_assert(!std::common_reference_with<const T&&, volatile int&&>);
246static_assert(!std::common_reference_with<const T&&, const volatile int&&>);
247static_assert(!std::common_reference_with<const T&&, const int&&>);
248static_assert(!std::common_reference_with<volatile T&&, const int&&>);
249static_assert(!std::common_reference_with<const volatile T&&, const int&&>);
250static_assert(!std::common_reference_with<volatile T&&, const int&&>);
251static_assert(!std::common_reference_with<volatile T&&, volatile int&&>);
252static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>);
253static_assert(!std::common_reference_with<const T&&, volatile int&&>);
254static_assert(!std::common_reference_with<volatile T&&, volatile int&&>);
255static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>);
256static_assert(!std::common_reference_with<const volatile T&&, const int&&>);
257static_assert(!std::common_reference_with<const volatile T&&, volatile int&&>);
258static_assert(
259 !std::common_reference_with<const volatile T&&, const volatile int&&>);
260static_assert(!std::common_reference_with<const T&&, const volatile int&&>);
261static_assert(!std::common_reference_with<volatile T&&, const volatile int&&>);
262static_assert(
263 !std::common_reference_with<const volatile T&&, const volatile int&&>);
264} // namespace NoDefaultCommonReference
265
266struct BadBasicCommonReference {
267 // This test is ill-formed, NDR. If it ever blows up in our faces: that's a good thing.
268 // In the meantime, the test should be included. If compiler support is added, then an include guard
269 // should be placed so the test doesn't get deleted.
270 operator int() const;
271 operator int&();
272};
273static_assert(std::convertible_to<BadBasicCommonReference, int>);
274static_assert(std::convertible_to<BadBasicCommonReference, int&>);
275
276template <template <class> class X, template <class> class Y>
277struct std::basic_common_reference<BadBasicCommonReference, int, X, Y> {
278 using type = BadBasicCommonReference&;
279};
280
281template <template <class> class X, template <class> class Y>
282struct std::basic_common_reference<int, BadBasicCommonReference, X, Y> {
283 using type = int&;
284};
285
286static_assert(!std::common_reference_with<BadBasicCommonReference, int>);
287
288struct StructNotConvertibleToCommonReference {
289 explicit(false) StructNotConvertibleToCommonReference(int);
290};
291static_assert(std::convertible_to<int, StructNotConvertibleToCommonReference>);
292
293template <template <class> class X, template <class> class Y>
294struct std::basic_common_reference<StructNotConvertibleToCommonReference, int, X, Y> {
295 using type = int&;
296};
297
298template <template <class> class X, template <class> class Y>
299struct std::basic_common_reference<int, StructNotConvertibleToCommonReference, X, Y> {
300 using type = int&;
301};
302
303static_assert(
304 !std::common_reference_with<StructNotConvertibleToCommonReference, int>);
305
306struct IntNotConvertibleToCommonReference {
307 operator int&() const;
308};
309
310template <template <class> class X, template <class> class Y>
311struct std::basic_common_reference<IntNotConvertibleToCommonReference, int, X, Y> {
312 using type = int&;
313};
314
315template <template <class> class X, template <class> class Y>
316struct std::basic_common_reference<int, IntNotConvertibleToCommonReference, X, Y> {
317 using type = int&;
318};
319
320static_assert(
321 !std::common_reference_with<StructNotConvertibleToCommonReference, int>);
322
323struct HasCommonReference {
324 explicit(false) HasCommonReference(int);
325 operator int&() const;
326};
327
328template <template <class> class X, template <class> class Y>
329struct std::basic_common_reference<HasCommonReference, int, X, Y> {
330 using type = int&;
331};
332
333template <template <class> class X, template <class> class Y>
334struct std::basic_common_reference<int, HasCommonReference, X, Y> {
335 using type = int&;
336};
337
338static_assert(!std::common_reference_with<HasCommonReference, int>);
339static_assert(std::common_reference_with<HasCommonReference, int&>);
340

source code of libcxx/test/std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp