xref: /llvm-project/libcxx/test/std/concepts/concepts.lang/concept.derived/derived_from.pass.cpp (revision d2baefae6846765eef6a6dd69d4fdf1082ce29ad)
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 
11*24dd2d2fSChristopher Di Bella // template<class Derived, class Base>
12*24dd2d2fSChristopher Di Bella // concept derived_from;
13*24dd2d2fSChristopher Di Bella 
14*24dd2d2fSChristopher Di Bella #include <concepts>
15*24dd2d2fSChristopher Di Bella #include <type_traits>
16*24dd2d2fSChristopher Di Bella 
17*24dd2d2fSChristopher Di Bella struct Base1 {};
18*24dd2d2fSChristopher Di Bella struct Derived1 : Base1 {};
19*24dd2d2fSChristopher Di Bella struct Derived2 : Base1 {};
20*24dd2d2fSChristopher Di Bella 
21*24dd2d2fSChristopher Di Bella struct DerivedPrivate : private Base1 {};
22*24dd2d2fSChristopher Di Bella struct Derived3 : DerivedPrivate {};
23*24dd2d2fSChristopher Di Bella 
24*24dd2d2fSChristopher Di Bella struct DerivedProtected : protected DerivedPrivate {};
25*24dd2d2fSChristopher Di Bella struct Derived4 : DerivedProtected {};
26*24dd2d2fSChristopher Di Bella struct Derived5 : Derived4 {};
27*24dd2d2fSChristopher Di Bella 
28*24dd2d2fSChristopher Di Bella template <typename From, typename To>
CheckNotDerivedFromPointer()29*24dd2d2fSChristopher Di Bella constexpr void CheckNotDerivedFromPointer() {
30*24dd2d2fSChristopher Di Bella   { // From as pointer
31*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, To>);
32*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, const To>);
33*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, volatile To>);
34*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, const volatile To>);
35*24dd2d2fSChristopher Di Bella 
36*24dd2d2fSChristopher Di Bella     if constexpr (!std::same_as<To, void>) {
37*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, To&>);
38*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, const To&>);
39*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, volatile To&>);
40*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, const volatile To&>);
41*24dd2d2fSChristopher Di Bella 
42*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, To&&>);
43*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, const To&&>);
44*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, volatile To&&>);
45*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From*, const volatile To&&>);
46*24dd2d2fSChristopher Di Bella 
47*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, To&>);
48*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, const To&>);
49*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, volatile To&>);
50*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, const volatile To&>);
51*24dd2d2fSChristopher Di Bella 
52*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, To&&>);
53*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, const To&&>);
54*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, volatile To&&>);
55*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From*, const volatile To&&>);
56*24dd2d2fSChristopher Di Bella 
57*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, To&>);
58*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, const To&>);
59*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, volatile To&>);
60*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, const volatile To&>);
61*24dd2d2fSChristopher Di Bella 
62*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, To&&>);
63*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, const To&&>);
64*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, volatile To&&>);
65*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From*, const volatile To&&>);
66*24dd2d2fSChristopher Di Bella 
67*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, To&>);
68*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, const To&>);
69*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, volatile To&>);
70*24dd2d2fSChristopher Di Bella       static_assert(
71*24dd2d2fSChristopher Di Bella           !std::derived_from<const volatile From*, const volatile To&>);
72*24dd2d2fSChristopher Di Bella 
73*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, To&&>);
74*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, const To&&>);
75*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From*, volatile To&&>);
76*24dd2d2fSChristopher Di Bella       static_assert(
77*24dd2d2fSChristopher Di Bella           !std::derived_from<const volatile From*, const volatile To&&>);
78*24dd2d2fSChristopher Di Bella     }
79*24dd2d2fSChristopher Di Bella   }
80*24dd2d2fSChristopher Di Bella   { // To as pointer
81*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To*>);
82*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const To*>);
83*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, volatile To*>);
84*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const volatile To*>);
85*24dd2d2fSChristopher Di Bella 
86*24dd2d2fSChristopher Di Bella     if constexpr (!std::same_as<From, void>) {
87*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&, To*>);
88*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&, const To*>);
89*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&, volatile To*>);
90*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&, const volatile To*>);
91*24dd2d2fSChristopher Di Bella 
92*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&&, To*>);
93*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&&, const To*>);
94*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&&, volatile To*>);
95*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From&&, const volatile To*>);
96*24dd2d2fSChristopher Di Bella 
97*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&, To*>);
98*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&, const To*>);
99*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&, volatile To*>);
100*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&, const volatile To*>);
101*24dd2d2fSChristopher Di Bella 
102*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&&, To*>);
103*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&&, const To*>);
104*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&&, volatile To*>);
105*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const From&&, const volatile To*>);
106*24dd2d2fSChristopher Di Bella 
107*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&, To*>);
108*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&, const To*>);
109*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&, volatile To*>);
110*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&, const volatile To*>);
111*24dd2d2fSChristopher Di Bella 
112*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&&, To*>);
113*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&&, const To*>);
114*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&&, volatile To*>);
115*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<volatile From&&, const volatile To*>);
116*24dd2d2fSChristopher Di Bella 
117*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&, To*>);
118*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&, const To*>);
119*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&, volatile To*>);
120*24dd2d2fSChristopher Di Bella       static_assert(
121*24dd2d2fSChristopher Di Bella           !std::derived_from<const volatile From&, const volatile To*>);
122*24dd2d2fSChristopher Di Bella 
123*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&&, To*>);
124*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&&, const To*>);
125*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<const volatile From&&, volatile To*>);
126*24dd2d2fSChristopher Di Bella       static_assert(
127*24dd2d2fSChristopher Di Bella           !std::derived_from<const volatile From&&, const volatile To*>);
128*24dd2d2fSChristopher Di Bella     }
129*24dd2d2fSChristopher Di Bella   }
130*24dd2d2fSChristopher Di Bella   { // Both as pointers
131*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, To*>);
132*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, const To*>);
133*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, volatile To*>);
134*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From*, const volatile To*>);
135*24dd2d2fSChristopher Di Bella 
136*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From*, To*>);
137*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From*, const To*>);
138*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From*, volatile To*>);
139*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From*, const volatile To*>);
140*24dd2d2fSChristopher Di Bella 
141*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From*, To*>);
142*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From*, const To*>);
143*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From*, volatile To*>);
144*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From*, const volatile To*>);
145*24dd2d2fSChristopher Di Bella 
146*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From*, To*>);
147*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From*, const To*>);
148*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From*, volatile To*>);
149*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From*, const volatile To*>);
150*24dd2d2fSChristopher Di Bella   }
151*24dd2d2fSChristopher Di Bella 
152*24dd2d2fSChristopher Di Bella   // From as the return type of a pointer-to-function
153*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<From>) {
154*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (*)(), To>);
155*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (*)(int), To>);
156*24dd2d2fSChristopher Di Bella   }
157*24dd2d2fSChristopher Di Bella 
158*24dd2d2fSChristopher Di Bella   // To as the return type of a pointer-to-function
159*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<To>) {
160*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To (*)()>);
161*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To (*)(double)>);
162*24dd2d2fSChristopher Di Bella   }
163*24dd2d2fSChristopher Di Bella 
164*24dd2d2fSChristopher Di Bella   // Both as the return type of a pointer-to-function
165*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<From> && !std::is_array_v<To>) {
166*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (*)(), To (*)()>);
167*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (*)(int), To (*)(double)>);
168*24dd2d2fSChristopher Di Bella   }
169*24dd2d2fSChristopher Di Bella   { // pointer-to-member
170*24dd2d2fSChristopher Di Bella     if constexpr (std::is_class_v<From> && !std::same_as<To, void>) {
171*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<To From::*, To>);
172*24dd2d2fSChristopher Di Bella     }
173*24dd2d2fSChristopher Di Bella 
174*24dd2d2fSChristopher Di Bella     if constexpr (std::is_class_v<To> && !std::same_as<From, void>) {
175*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From To::*, From>);
176*24dd2d2fSChristopher Di Bella     }
177*24dd2d2fSChristopher Di Bella   }
178*24dd2d2fSChristopher Di Bella   { // pointer-to-member-functions
179*24dd2d2fSChristopher Di Bella     if constexpr (std::is_class_v<From>) {
180*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<From (From::*)(), To>);
181*24dd2d2fSChristopher Di Bella     }
182*24dd2d2fSChristopher Di Bella 
183*24dd2d2fSChristopher Di Bella     if constexpr (std::is_class_v<To>) {
184*24dd2d2fSChristopher Di Bella       static_assert(!std::derived_from<To (To::*)(), From>);
185*24dd2d2fSChristopher Di Bella     }
186*24dd2d2fSChristopher Di Bella   }
187*24dd2d2fSChristopher Di Bella }
188*24dd2d2fSChristopher Di Bella 
189*24dd2d2fSChristopher Di Bella template <typename From, typename To>
CheckNotDerivedFromReference()190*24dd2d2fSChristopher Di Bella constexpr void CheckNotDerivedFromReference() {
191*24dd2d2fSChristopher Di Bella   if constexpr (!std::same_as<To, void>) {
192*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To&>);
193*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const To&>);
194*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, volatile To&>);
195*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const volatile To&>);
196*24dd2d2fSChristopher Di Bella 
197*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To&&>);
198*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const To&&>);
199*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, volatile To&&>);
200*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, const volatile To&&>);
201*24dd2d2fSChristopher Di Bella   }
202*24dd2d2fSChristopher Di Bella 
203*24dd2d2fSChristopher Di Bella   if constexpr (!std::same_as<From, void>) {
204*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To>);
205*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To>);
206*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To>);
207*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To>);
208*24dd2d2fSChristopher Di Bella 
209*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To>);
210*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To>);
211*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To>);
212*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To>);
213*24dd2d2fSChristopher Di Bella   }
214*24dd2d2fSChristopher Di Bella 
215*24dd2d2fSChristopher Di Bella   // From as lvalue references
216*24dd2d2fSChristopher Di Bella   if constexpr (!std::same_as<From, void> && !std::same_as<To, void>) {
217*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To&>);
218*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, const To&>);
219*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, volatile To&>);
220*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, const volatile To&>);
221*24dd2d2fSChristopher Di Bella 
222*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, To&&>);
223*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, const To&&>);
224*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, volatile To&&>);
225*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&, const volatile To&&>);
226*24dd2d2fSChristopher Di Bella 
227*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, To&>);
228*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, const To&>);
229*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, volatile To&>);
230*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, const volatile To&>);
231*24dd2d2fSChristopher Di Bella 
232*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, To&&>);
233*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, const To&&>);
234*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, volatile To&&>);
235*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&, const volatile To&&>);
236*24dd2d2fSChristopher Di Bella 
237*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, To&>);
238*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, const To&>);
239*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, volatile To&>);
240*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, const volatile To&>);
241*24dd2d2fSChristopher Di Bella 
242*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, To&&>);
243*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, const To&&>);
244*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, volatile To&&>);
245*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&, const volatile To&&>);
246*24dd2d2fSChristopher Di Bella 
247*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, To&>);
248*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, const To&>);
249*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, volatile To&>);
250*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, const volatile To&>);
251*24dd2d2fSChristopher Di Bella 
252*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, To&&>);
253*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, const To&&>);
254*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&, volatile To&&>);
255*24dd2d2fSChristopher Di Bella     static_assert(
256*24dd2d2fSChristopher Di Bella         !std::derived_from<const volatile From&, const volatile To&&>);
257*24dd2d2fSChristopher Di Bella 
258*24dd2d2fSChristopher Di Bella     // From as rvalue references
259*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To&>);
260*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, const To&>);
261*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, volatile To&>);
262*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, const volatile To&>);
263*24dd2d2fSChristopher Di Bella 
264*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, To&&>);
265*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, const To&&>);
266*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, volatile To&&>);
267*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From&&, const volatile To&&>);
268*24dd2d2fSChristopher Di Bella 
269*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, To&>);
270*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, const To&>);
271*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, volatile To&>);
272*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, const volatile To&>);
273*24dd2d2fSChristopher Di Bella 
274*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, To&&>);
275*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, const To&&>);
276*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, volatile To&&>);
277*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const From&&, const volatile To&&>);
278*24dd2d2fSChristopher Di Bella 
279*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, To&>);
280*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, const To&>);
281*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, volatile To&>);
282*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, const volatile To&>);
283*24dd2d2fSChristopher Di Bella 
284*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, To&&>);
285*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, const To&&>);
286*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, volatile To&&>);
287*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<volatile From&&, const volatile To&&>);
288*24dd2d2fSChristopher Di Bella 
289*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, To&>);
290*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, const To&>);
291*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, volatile To&>);
292*24dd2d2fSChristopher Di Bella     static_assert(
293*24dd2d2fSChristopher Di Bella         !std::derived_from<const volatile From&&, const volatile To&>);
294*24dd2d2fSChristopher Di Bella 
295*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, To&&>);
296*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, const To&&>);
297*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<const volatile From&&, volatile To&&>);
298*24dd2d2fSChristopher Di Bella     static_assert(
299*24dd2d2fSChristopher Di Bella         !std::derived_from<const volatile From&&, const volatile To&&>);
300*24dd2d2fSChristopher Di Bella   }
301*24dd2d2fSChristopher Di Bella 
302*24dd2d2fSChristopher Di Bella   // From as the return type of a reference-to-function
303*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<From>) {
304*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (&)(), To>);
305*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (&)(int), To>);
306*24dd2d2fSChristopher Di Bella   }
307*24dd2d2fSChristopher Di Bella   // To as the return type of a reference-to-function
308*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<To>) {
309*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To (&)()>);
310*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From, To (&)(double)>);
311*24dd2d2fSChristopher Di Bella   }
312*24dd2d2fSChristopher Di Bella   // Both as the return type of a reference-to-function
313*24dd2d2fSChristopher Di Bella   if constexpr (!std::is_array_v<From> && !std::is_array_v<To>) {
314*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (&)(), To (&)()>);
315*24dd2d2fSChristopher Di Bella     static_assert(!std::derived_from<From (&)(int), To (&)(double)>);
316*24dd2d2fSChristopher Di Bella   }
317*24dd2d2fSChristopher Di Bella }
318*24dd2d2fSChristopher Di Bella 
319*24dd2d2fSChristopher Di Bella template <typename From, typename To>
CheckDerivedFrom()320*24dd2d2fSChristopher Di Bella constexpr void CheckDerivedFrom() {
321*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<From, To>);
322*24dd2d2fSChristopher Di Bella 
323*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<From, const To>);
324*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<From, volatile To>);
325*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<From, const volatile To>);
326*24dd2d2fSChristopher Di Bella 
327*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const From, const To>);
328*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const From, volatile To>);
329*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const From, const volatile To>);
330*24dd2d2fSChristopher Di Bella 
331*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<volatile From, const To>);
332*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<volatile From, volatile To>);
333*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<volatile From, const volatile To>);
334*24dd2d2fSChristopher Di Bella 
335*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const volatile From, const To>);
336*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const volatile From, volatile To>);
337*24dd2d2fSChristopher Di Bella   static_assert(std::derived_from<const volatile From, const volatile To>);
338*24dd2d2fSChristopher Di Bella 
339*24dd2d2fSChristopher Di Bella   CheckNotDerivedFromPointer<From, To>();
340*24dd2d2fSChristopher Di Bella   CheckNotDerivedFromReference<From, To>();
341*24dd2d2fSChristopher Di Bella }
342*24dd2d2fSChristopher Di Bella 
343*24dd2d2fSChristopher Di Bella template <typename From, typename To>
CheckNotDerivedFrom()344*24dd2d2fSChristopher Di Bella constexpr void CheckNotDerivedFrom() {
345*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<From, To>);
346*24dd2d2fSChristopher Di Bella 
347*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<From, const To>);
348*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<From, volatile To>);
349*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<From, const volatile To>);
350*24dd2d2fSChristopher Di Bella 
351*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const From, const To>);
352*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const From, volatile To>);
353*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const From, const volatile To>);
354*24dd2d2fSChristopher Di Bella 
355*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<volatile From, const To>);
356*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<volatile From, volatile To>);
357*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<volatile From, const volatile To>);
358*24dd2d2fSChristopher Di Bella 
359*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const volatile From, const To>);
360*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const volatile From, volatile To>);
361*24dd2d2fSChristopher Di Bella   static_assert(!std::derived_from<const volatile From, const volatile To>);
362*24dd2d2fSChristopher Di Bella 
363*24dd2d2fSChristopher Di Bella   CheckNotDerivedFromPointer<From, To>();
364*24dd2d2fSChristopher Di Bella   CheckNotDerivedFromReference<From, To>();
365*24dd2d2fSChristopher Di Bella }
366*24dd2d2fSChristopher Di Bella 
367*24dd2d2fSChristopher Di Bella enum Enumeration { Yes, No };
368*24dd2d2fSChristopher Di Bella enum class ScopedEnumeration : int { No, Yes };
369*24dd2d2fSChristopher Di Bella 
main(int,char **)370*24dd2d2fSChristopher Di Bella int main(int, char**) {
371*24dd2d2fSChristopher Di Bella   { // Fundamentals shouldn't be derived from anything
372*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<int, long>();
373*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<signed char, char>();
374*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<double, Base1>();
375*24dd2d2fSChristopher Di Bella 
376*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<int, Enumeration>();
377*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<int, ScopedEnumeration>();
378*24dd2d2fSChristopher Di Bella 
379*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<void, void>();
380*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<int, int>();
381*24dd2d2fSChristopher Di Bella   }
382*24dd2d2fSChristopher Di Bella   { // Nothing should be derived from a fundamental type
383*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Enumeration, int>();
384*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<ScopedEnumeration, int>();
385*24dd2d2fSChristopher Di Bella 
386*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, int>();
387*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, double>();
388*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, char>();
389*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, long long>();
390*24dd2d2fSChristopher Di Bella   }
391*24dd2d2fSChristopher Di Bella   { // Other built-in things shouldn't have derivations
392*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Enumeration, Enumeration>();
393*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<ScopedEnumeration, ScopedEnumeration>();
394*24dd2d2fSChristopher Di Bella 
395*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Enumeration, ScopedEnumeration>();
396*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<ScopedEnumeration, Enumeration>();
397*24dd2d2fSChristopher Di Bella 
398*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1[5], Base1>();
399*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1[5], Base1>();
400*24dd2d2fSChristopher Di Bella 
401*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, Base1[5]>();
402*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, Base1[5]>();
403*24dd2d2fSChristopher Di Bella   }
404*24dd2d2fSChristopher Di Bella 
405*24dd2d2fSChristopher Di Bella   { // Base1 is the subject.
406*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Base1, Base1>();
407*24dd2d2fSChristopher Di Bella 
408*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, void>();
409*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, DerivedPrivate>();
410*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, DerivedProtected>();
411*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, Derived1>();
412*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, Derived2>();
413*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, Derived3>();
414*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Base1, Derived4>();
415*24dd2d2fSChristopher Di Bella   }
416*24dd2d2fSChristopher Di Bella 
417*24dd2d2fSChristopher Di Bella   { // Derived1 is the subject.
418*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived1, Base1>();
419*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived1, Derived1>();
420*24dd2d2fSChristopher Di Bella 
421*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<Derived1, void>();
422*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, DerivedPrivate>();
423*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, DerivedProtected>();
424*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, Derived2>();
425*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, Derived3>();
426*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived1, Derived4>();
427*24dd2d2fSChristopher Di Bella   }
428*24dd2d2fSChristopher Di Bella 
429*24dd2d2fSChristopher Di Bella   { // Derived2 is the subject.
430*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived2, Base1>();
431*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived2, Derived2>();
432*24dd2d2fSChristopher Di Bella 
433*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived2, DerivedPrivate>();
434*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived2, DerivedProtected>();
435*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived2, Derived1>();
436*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived2, Derived3>();
437*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived2, Derived4>();
438*24dd2d2fSChristopher Di Bella   }
439*24dd2d2fSChristopher Di Bella 
440*24dd2d2fSChristopher Di Bella   { // DerivedPrivate is the subject.
441*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<DerivedPrivate, DerivedPrivate>();
442*24dd2d2fSChristopher Di Bella 
443*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, Base1>();
444*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, DerivedProtected>();
445*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, Derived1>();
446*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, Derived2>();
447*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, Derived3>();
448*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<DerivedPrivate, Derived4>();
449*24dd2d2fSChristopher Di Bella   }
450*24dd2d2fSChristopher Di Bella 
451*24dd2d2fSChristopher Di Bella   { // Derived3 is the subject.
452*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived3, DerivedPrivate>();
453*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived3, Derived3>();
454*24dd2d2fSChristopher Di Bella 
455*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived3, Base1>();
456*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived3, DerivedProtected>();
457*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived3, Derived1>();
458*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived3, Derived2>();
459*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived3, Derived4>();
460*24dd2d2fSChristopher Di Bella   }
461*24dd2d2fSChristopher Di Bella 
462*24dd2d2fSChristopher Di Bella   { // DerivedProtected is the subject.
463*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<DerivedProtected, DerivedProtected>();
464*24dd2d2fSChristopher Di Bella 
465*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, Base1>();
466*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, DerivedPrivate>();
467*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, Derived1>();
468*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, Derived2>();
469*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, Derived3>();
470*24dd2d2fSChristopher Di Bella     CheckNotDerivedFromPointer<DerivedProtected, Derived4>();
471*24dd2d2fSChristopher Di Bella   }
472*24dd2d2fSChristopher Di Bella 
473*24dd2d2fSChristopher Di Bella   { // Derived4 is the subject.
474*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived4, DerivedProtected>();
475*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived4, Derived4>();
476*24dd2d2fSChristopher Di Bella 
477*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived4, Base1>();
478*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived4, DerivedPrivate>();
479*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived4, Derived1>();
480*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived4, Derived2>();
481*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived4, Derived3>();
482*24dd2d2fSChristopher Di Bella   }
483*24dd2d2fSChristopher Di Bella 
484*24dd2d2fSChristopher Di Bella   { // Derived5 is the subject.
485*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived5, DerivedProtected>();
486*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived5, Derived4>();
487*24dd2d2fSChristopher Di Bella     CheckDerivedFrom<Derived5, Derived5>();
488*24dd2d2fSChristopher Di Bella 
489*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived5, Base1>();
490*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived5, DerivedPrivate>();
491*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived5, Derived1>();
492*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived5, Derived2>();
493*24dd2d2fSChristopher Di Bella     CheckNotDerivedFrom<Derived5, Derived3>();
494*24dd2d2fSChristopher Di Bella   }
495*24dd2d2fSChristopher Di Bella 
496*24dd2d2fSChristopher Di Bella   return 0;
497*24dd2d2fSChristopher Di Bella }
498