1*24dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
2*24dd2d2fSChristopher Di Bella //
3*24dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*24dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
5*24dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*24dd2d2fSChristopher Di Bella //
7*24dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
8*24dd2d2fSChristopher Di Bella 
9*24dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17
10*24dd2d2fSChristopher Di Bella // UNSUPPORTED: libcpp-no-concepts
11*24dd2d2fSChristopher Di Bella 
12*24dd2d2fSChristopher Di Bella // template<class T, class U>
13*24dd2d2fSChristopher Di Bella // concept same_as;
14*24dd2d2fSChristopher Di Bella 
15*24dd2d2fSChristopher Di Bella #include <concepts>
16*24dd2d2fSChristopher Di Bella #include <type_traits>
17*24dd2d2fSChristopher Di Bella 
18*24dd2d2fSChristopher Di Bella struct S1 {};
19*24dd2d2fSChristopher Di Bella struct S2 {
20*24dd2d2fSChristopher Di Bella   int i;
21*24dd2d2fSChristopher Di Bella 
22*24dd2d2fSChristopher Di Bella   int& f();
23*24dd2d2fSChristopher Di Bella   double g(int x) const;
24*24dd2d2fSChristopher Di Bella };
25*24dd2d2fSChristopher Di Bella struct S3 {
26*24dd2d2fSChristopher Di Bella   int& r;
27*24dd2d2fSChristopher Di Bella };
28*24dd2d2fSChristopher Di Bella struct S4 {
29*24dd2d2fSChristopher Di Bella   int&& r;
30*24dd2d2fSChristopher Di Bella };
31*24dd2d2fSChristopher Di Bella struct S5 {
32*24dd2d2fSChristopher Di Bella   int* p;
33*24dd2d2fSChristopher Di Bella };
34*24dd2d2fSChristopher Di Bella 
35*24dd2d2fSChristopher Di Bella class C1 {};
36*24dd2d2fSChristopher Di Bella class C2 {
37*24dd2d2fSChristopher Di Bella   [[maybe_unused]] int i;
38*24dd2d2fSChristopher Di Bella };
39*24dd2d2fSChristopher Di Bella 
40*24dd2d2fSChristopher Di Bella class C3 {
41*24dd2d2fSChristopher Di Bella public:
42*24dd2d2fSChristopher Di Bella   int i;
43*24dd2d2fSChristopher Di Bella };
44*24dd2d2fSChristopher Di Bella 
45*24dd2d2fSChristopher Di Bella template <class T1, class T2 = T1>
46*24dd2d2fSChristopher Di Bella class C4 {
47*24dd2d2fSChristopher Di Bella   int t1;
48*24dd2d2fSChristopher Di Bella   int t2;
49*24dd2d2fSChristopher Di Bella };
50*24dd2d2fSChristopher Di Bella 
51*24dd2d2fSChristopher Di Bella template <class T1, class T2 = T1>
52*24dd2d2fSChristopher Di Bella class C5 {
53*24dd2d2fSChristopher Di Bella   [[maybe_unused]] T1 t1;
54*24dd2d2fSChristopher Di Bella 
55*24dd2d2fSChristopher Di Bella public:
56*24dd2d2fSChristopher Di Bella   T2 t2;
57*24dd2d2fSChristopher Di Bella };
58*24dd2d2fSChristopher Di Bella 
59*24dd2d2fSChristopher Di Bella template <class T1, class T2 = T1>
60*24dd2d2fSChristopher Di Bella class C6 {
61*24dd2d2fSChristopher Di Bella public:
62*24dd2d2fSChristopher Di Bella   [[maybe_unused]] T1 t1;
63*24dd2d2fSChristopher Di Bella   [[maybe_unused]] T2 t2;
64*24dd2d2fSChristopher Di Bella };
65*24dd2d2fSChristopher Di Bella 
66*24dd2d2fSChristopher Di Bella template <class T>
67*24dd2d2fSChristopher Di Bella struct identity {
68*24dd2d2fSChristopher Di Bella   using type = T;
69*24dd2d2fSChristopher Di Bella };
70*24dd2d2fSChristopher Di Bella 
71*24dd2d2fSChristopher Di Bella template <template <typename> class Modifier = identity>
72*24dd2d2fSChristopher Di Bella void CheckSameAs() {
73*24dd2d2fSChristopher Di Bella   static_assert(
74*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<int>::type, typename Modifier<int>::type>);
75*24dd2d2fSChristopher Di Bella   static_assert(
76*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<S1>::type, typename Modifier<S1>::type>);
77*24dd2d2fSChristopher Di Bella   static_assert(
78*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<S2>::type, typename Modifier<S2>::type>);
79*24dd2d2fSChristopher Di Bella   static_assert(
80*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<S3>::type, typename Modifier<S3>::type>);
81*24dd2d2fSChristopher Di Bella   static_assert(
82*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<S4>::type, typename Modifier<S4>::type>);
83*24dd2d2fSChristopher Di Bella   static_assert(
84*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<S5>::type, typename Modifier<S5>::type>);
85*24dd2d2fSChristopher Di Bella   static_assert(
86*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<C1>::type, typename Modifier<C1>::type>);
87*24dd2d2fSChristopher Di Bella   static_assert(
88*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<C2>::type, typename Modifier<C2>::type>);
89*24dd2d2fSChristopher Di Bella   static_assert(
90*24dd2d2fSChristopher Di Bella       std::same_as<typename Modifier<C3>::type, typename Modifier<C3>::type>);
91*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C4<int> >::type,
92*24dd2d2fSChristopher Di Bella                              typename Modifier<C4<int> >::type>);
93*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C4<int&> >::type,
94*24dd2d2fSChristopher Di Bella                              typename Modifier<C4<int&> >::type>);
95*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C4<int&&> >::type,
96*24dd2d2fSChristopher Di Bella                              typename Modifier<C4<int&&> >::type>);
97*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C5<int> >::type,
98*24dd2d2fSChristopher Di Bella                              typename Modifier<C5<int> >::type>);
99*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C5<int&> >::type,
100*24dd2d2fSChristopher Di Bella                              typename Modifier<C5<int&> >::type>);
101*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C5<int&&> >::type,
102*24dd2d2fSChristopher Di Bella                              typename Modifier<C5<int&&> >::type>);
103*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C6<int> >::type,
104*24dd2d2fSChristopher Di Bella                              typename Modifier<C6<int> >::type>);
105*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C6<int&> >::type,
106*24dd2d2fSChristopher Di Bella                              typename Modifier<C6<int&> >::type>);
107*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<C6<int&&> >::type,
108*24dd2d2fSChristopher Di Bella                              typename Modifier<C6<int&&> >::type>);
109*24dd2d2fSChristopher Di Bella 
110*24dd2d2fSChristopher Di Bella   static_assert(std::same_as<typename Modifier<void>::type,
111*24dd2d2fSChristopher Di Bella                              typename Modifier<void>::type>);
112*24dd2d2fSChristopher Di Bella }
113*24dd2d2fSChristopher Di Bella 
114*24dd2d2fSChristopher Di Bella template <template <typename> class Modifier1,
115*24dd2d2fSChristopher Di Bella           template <typename> class Modifier2>
116*24dd2d2fSChristopher Di Bella void CheckNotSameAs() {
117*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<int>::type,
118*24dd2d2fSChristopher Di Bella                               typename Modifier2<int>::type>);
119*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<S1>::type,
120*24dd2d2fSChristopher Di Bella                               typename Modifier2<S1>::type>);
121*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<S2>::type,
122*24dd2d2fSChristopher Di Bella                               typename Modifier2<S2>::type>);
123*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<S3>::type,
124*24dd2d2fSChristopher Di Bella                               typename Modifier2<S3>::type>);
125*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<S4>::type,
126*24dd2d2fSChristopher Di Bella                               typename Modifier2<S4>::type>);
127*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<S5>::type,
128*24dd2d2fSChristopher Di Bella                               typename Modifier2<S5>::type>);
129*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C1>::type,
130*24dd2d2fSChristopher Di Bella                               typename Modifier2<C1>::type>);
131*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C2>::type,
132*24dd2d2fSChristopher Di Bella                               typename Modifier2<C2>::type>);
133*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C3>::type,
134*24dd2d2fSChristopher Di Bella                               typename Modifier2<C3>::type>);
135*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C4<int> >::type,
136*24dd2d2fSChristopher Di Bella                               typename Modifier2<C4<int> >::type>);
137*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C4<int&> >::type,
138*24dd2d2fSChristopher Di Bella                               typename Modifier2<C4<int&> >::type>);
139*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C4<int&&> >::type,
140*24dd2d2fSChristopher Di Bella                               typename Modifier2<C4<int&&> >::type>);
141*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C5<int> >::type,
142*24dd2d2fSChristopher Di Bella                               typename Modifier2<C5<int> >::type>);
143*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C5<int&> >::type,
144*24dd2d2fSChristopher Di Bella                               typename Modifier2<C5<int&> >::type>);
145*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C5<int&&> >::type,
146*24dd2d2fSChristopher Di Bella                               typename Modifier2<C5<int&&> >::type>);
147*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C6<int> >::type,
148*24dd2d2fSChristopher Di Bella                               typename Modifier2<C6<int> >::type>);
149*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C6<int&> >::type,
150*24dd2d2fSChristopher Di Bella                               typename Modifier2<C6<int&> >::type>);
151*24dd2d2fSChristopher Di Bella   static_assert(!std::same_as<typename Modifier1<C6<int&&> >::type,
152*24dd2d2fSChristopher Di Bella                               typename Modifier2<C6<int&&> >::type>);
153*24dd2d2fSChristopher Di Bella }
154*24dd2d2fSChristopher Di Bella 
155*24dd2d2fSChristopher Di Bella // Checks subsumption works as intended
156*24dd2d2fSChristopher Di Bella template <class T, class U>
157*24dd2d2fSChristopher Di Bella requires std::same_as<T, U> void SubsumptionTest();
158*24dd2d2fSChristopher Di Bella 
159*24dd2d2fSChristopher Di Bella // clang-format off
160*24dd2d2fSChristopher Di Bella template <class T, class U>
161*24dd2d2fSChristopher Di Bella requires std::same_as<U, T> && true // NOLINT(readability-simplify-boolean-expr)
162*24dd2d2fSChristopher Di Bella int SubsumptionTest();
163*24dd2d2fSChristopher Di Bella // clang-format on
164*24dd2d2fSChristopher Di Bella 
165*24dd2d2fSChristopher Di Bella static_assert(std::same_as<int, decltype(SubsumptionTest<int, int>())>);
166*24dd2d2fSChristopher Di Bella static_assert(std::same_as<int, decltype(SubsumptionTest<void, void>())>);
167*24dd2d2fSChristopher Di Bella static_assert(
168*24dd2d2fSChristopher Di Bella     std::same_as<int, decltype(SubsumptionTest<int (*)(), int (*)()>())>);
169*24dd2d2fSChristopher Di Bella static_assert(
170*24dd2d2fSChristopher Di Bella     std::same_as<
171*24dd2d2fSChristopher Di Bella         int, decltype(SubsumptionTest<double (&)(int), double (&)(int)>())>);
172*24dd2d2fSChristopher Di Bella static_assert(
173*24dd2d2fSChristopher Di Bella     std::same_as<int, decltype(SubsumptionTest<int S2::*, int S2::*>())>);
174*24dd2d2fSChristopher Di Bella static_assert(
175*24dd2d2fSChristopher Di Bella     std::same_as<int,
176*24dd2d2fSChristopher Di Bella                  decltype(SubsumptionTest<int& (S2::*)(), int& (S2::*)()>())>);
177*24dd2d2fSChristopher Di Bella 
178*24dd2d2fSChristopher Di Bella int main(int, char**) {
179*24dd2d2fSChristopher Di Bella   { // Checks std::same_as<T, T> is true
180*24dd2d2fSChristopher Di Bella     CheckSameAs();
181*24dd2d2fSChristopher Di Bella 
182*24dd2d2fSChristopher Di Bella     // Checks std::same_as<T&, T&> is true
183*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_lvalue_reference>();
184*24dd2d2fSChristopher Di Bella 
185*24dd2d2fSChristopher Di Bella     // Checks std::same_as<T&&, T&&> is true
186*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_rvalue_reference>();
187*24dd2d2fSChristopher Di Bella 
188*24dd2d2fSChristopher Di Bella     // Checks std::same_as<const T, const T> is true
189*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_const>();
190*24dd2d2fSChristopher Di Bella 
191*24dd2d2fSChristopher Di Bella     // Checks std::same_as<volatile T, volatile T> is true
192*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_volatile>();
193*24dd2d2fSChristopher Di Bella 
194*24dd2d2fSChristopher Di Bella     // Checks std::same_as<const volatile T, const volatile T> is true
195*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_cv>();
196*24dd2d2fSChristopher Di Bella 
197*24dd2d2fSChristopher Di Bella     // Checks std::same_as<T*, T*> is true
198*24dd2d2fSChristopher Di Bella     CheckSameAs<std::add_pointer>();
199*24dd2d2fSChristopher Di Bella 
200*24dd2d2fSChristopher Di Bella     // Checks concrete types are identical
201*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<void, void>);
202*24dd2d2fSChristopher Di Bella 
203*24dd2d2fSChristopher Di Bella     using Void = void;
204*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<void, Void>);
205*24dd2d2fSChristopher Di Bella 
206*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<int[1], int[1]>);
207*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<int[2], int[2]>);
208*24dd2d2fSChristopher Di Bella 
209*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<int (*)(), int (*)()>);
210*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<void (&)(), void (&)()>);
211*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<S1& (*)(S1), S1& (*)(S1)>);
212*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<C1& (&)(S1, int), C1& (&)(S1, int)>);
213*24dd2d2fSChristopher Di Bella 
214*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<int S2::*, int S2::*>);
215*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<double S2::*, double S2::*>);
216*24dd2d2fSChristopher Di Bella 
217*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<int& (S2::*)(), int& (S2::*)()>);
218*24dd2d2fSChristopher Di Bella     static_assert(std::same_as<double& (S2::*)(int), double& (S2::*)(int)>);
219*24dd2d2fSChristopher Di Bella   }
220*24dd2d2fSChristopher Di Bella 
221*24dd2d2fSChristopher Di Bella   { // Checks that `T` and `T&` are distinct types
222*24dd2d2fSChristopher Di Bella     CheckNotSameAs<identity, std::add_lvalue_reference>();
223*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_lvalue_reference, identity>();
224*24dd2d2fSChristopher Di Bella 
225*24dd2d2fSChristopher Di Bella     // Checks that `T` and `T&&` are distinct types
226*24dd2d2fSChristopher Di Bella     CheckNotSameAs<identity, std::add_rvalue_reference>();
227*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_rvalue_reference, identity>();
228*24dd2d2fSChristopher Di Bella 
229*24dd2d2fSChristopher Di Bella     // Checks that `T` and `const T` are distinct types
230*24dd2d2fSChristopher Di Bella     CheckNotSameAs<identity, std::add_const>();
231*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_const, identity>();
232*24dd2d2fSChristopher Di Bella 
233*24dd2d2fSChristopher Di Bella     // Checks that `T` and `volatile T` are distinct types
234*24dd2d2fSChristopher Di Bella     CheckNotSameAs<identity, std::add_volatile>();
235*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_volatile, identity>();
236*24dd2d2fSChristopher Di Bella 
237*24dd2d2fSChristopher Di Bella     // Checks that `T` and `const volatile T` are distinct types
238*24dd2d2fSChristopher Di Bella     CheckNotSameAs<identity, std::add_cv>();
239*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_cv, identity>();
240*24dd2d2fSChristopher Di Bella 
241*24dd2d2fSChristopher Di Bella     // Checks that `const T` and `volatile T` are distinct types
242*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_const, std::add_volatile>();
243*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_volatile, std::add_const>();
244*24dd2d2fSChristopher Di Bella 
245*24dd2d2fSChristopher Di Bella     // Checks that `const T` and `const volatile T` are distinct types
246*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_const, std::add_cv>();
247*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_cv, std::add_const>();
248*24dd2d2fSChristopher Di Bella 
249*24dd2d2fSChristopher Di Bella     // Checks that `volatile T` and `const volatile T` are distinct types
250*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_volatile, std::add_cv>();
251*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_cv, std::add_volatile>();
252*24dd2d2fSChristopher Di Bella 
253*24dd2d2fSChristopher Di Bella     // Checks `T&` and `T&&` are distinct types
254*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_lvalue_reference, std::add_rvalue_reference>();
255*24dd2d2fSChristopher Di Bella     CheckNotSameAs<std::add_rvalue_reference, std::add_lvalue_reference>();
256*24dd2d2fSChristopher Di Bella   }
257*24dd2d2fSChristopher Di Bella 
258*24dd2d2fSChristopher Di Bella   { // Checks different type names are distinct types
259*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<S1, C1>);
260*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<C4<int>, C5<int> >);
261*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<C4<int>, C5<int> >);
262*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<C5<int, double>, C5<double, int> >);
263*24dd2d2fSChristopher Di Bella 
264*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, const int&>);
265*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, volatile int&>);
266*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, const volatile int&>);
267*24dd2d2fSChristopher Di Bella 
268*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, const int&>);
269*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, volatile int&>);
270*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, const volatile int&>);
271*24dd2d2fSChristopher Di Bella 
272*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, const int&&>);
273*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, volatile int&&>);
274*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&, const volatile int&&>);
275*24dd2d2fSChristopher Di Bella 
276*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, const int&&>);
277*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, volatile int&&>);
278*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int&&, const volatile int&&>);
279*24dd2d2fSChristopher Di Bella 
280*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<void, int>);
281*24dd2d2fSChristopher Di Bella 
282*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int[1], int[2]>);
283*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<double[1], int[2]>);
284*24dd2d2fSChristopher Di Bella 
285*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int* (*)(), const int* (*)()>);
286*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<void (&)(), void (&)(S1)>);
287*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<S1 (*)(S1), S1& (*)(S1)>);
288*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<C3 (&)(int), C1& (&)(S1, int)>);
289*24dd2d2fSChristopher Di Bella 
290*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int S2::*, double S2::*>);
291*24dd2d2fSChristopher Di Bella 
292*24dd2d2fSChristopher Di Bella     static_assert(!std::same_as<int& (S2::*)(), double& (S2::*)(int)>);
293*24dd2d2fSChristopher Di Bella   }
294*24dd2d2fSChristopher Di Bella 
295*24dd2d2fSChristopher Di Bella   return 0;
296*24dd2d2fSChristopher Di Bella }
297