1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class Derived, class Base>
12 // concept derived_from;
15 #include <type_traits>
18 struct Derived1
: Base1
{};
19 struct Derived2
: Base1
{};
21 struct DerivedPrivate
: private Base1
{};
22 struct Derived3
: DerivedPrivate
{};
24 struct DerivedProtected
: protected DerivedPrivate
{};
25 struct Derived4
: DerivedProtected
{};
26 struct Derived5
: Derived4
{};
28 template <typename From
, typename To
>
29 constexpr void CheckNotDerivedFromPointer() {
31 static_assert(!std::derived_from
<From
*, To
>);
32 static_assert(!std::derived_from
<From
*, const To
>);
33 static_assert(!std::derived_from
<From
*, volatile To
>);
34 static_assert(!std::derived_from
<From
*, const volatile To
>);
36 if constexpr (!std::same_as
<To
, void>) {
37 static_assert(!std::derived_from
<From
*, To
&>);
38 static_assert(!std::derived_from
<From
*, const To
&>);
39 static_assert(!std::derived_from
<From
*, volatile To
&>);
40 static_assert(!std::derived_from
<From
*, const volatile To
&>);
42 static_assert(!std::derived_from
<From
*, To
&&>);
43 static_assert(!std::derived_from
<From
*, const To
&&>);
44 static_assert(!std::derived_from
<From
*, volatile To
&&>);
45 static_assert(!std::derived_from
<From
*, const volatile To
&&>);
47 static_assert(!std::derived_from
<const From
*, To
&>);
48 static_assert(!std::derived_from
<const From
*, const To
&>);
49 static_assert(!std::derived_from
<const From
*, volatile To
&>);
50 static_assert(!std::derived_from
<const From
*, const volatile To
&>);
52 static_assert(!std::derived_from
<const From
*, To
&&>);
53 static_assert(!std::derived_from
<const From
*, const To
&&>);
54 static_assert(!std::derived_from
<const From
*, volatile To
&&>);
55 static_assert(!std::derived_from
<const From
*, const volatile To
&&>);
57 static_assert(!std::derived_from
<volatile From
*, To
&>);
58 static_assert(!std::derived_from
<volatile From
*, const To
&>);
59 static_assert(!std::derived_from
<volatile From
*, volatile To
&>);
60 static_assert(!std::derived_from
<volatile From
*, const volatile To
&>);
62 static_assert(!std::derived_from
<volatile From
*, To
&&>);
63 static_assert(!std::derived_from
<volatile From
*, const To
&&>);
64 static_assert(!std::derived_from
<volatile From
*, volatile To
&&>);
65 static_assert(!std::derived_from
<volatile From
*, const volatile To
&&>);
67 static_assert(!std::derived_from
<const volatile From
*, To
&>);
68 static_assert(!std::derived_from
<const volatile From
*, const To
&>);
69 static_assert(!std::derived_from
<const volatile From
*, volatile To
&>);
71 !std::derived_from
<const volatile From
*, const volatile To
&>);
73 static_assert(!std::derived_from
<const volatile From
*, To
&&>);
74 static_assert(!std::derived_from
<const volatile From
*, const To
&&>);
75 static_assert(!std::derived_from
<const volatile From
*, volatile To
&&>);
77 !std::derived_from
<const volatile From
*, const volatile To
&&>);
81 static_assert(!std::derived_from
<From
, To
*>);
82 static_assert(!std::derived_from
<From
, const To
*>);
83 static_assert(!std::derived_from
<From
, volatile To
*>);
84 static_assert(!std::derived_from
<From
, const volatile To
*>);
86 if constexpr (!std::same_as
<From
, void>) {
87 static_assert(!std::derived_from
<From
&, To
*>);
88 static_assert(!std::derived_from
<From
&, const To
*>);
89 static_assert(!std::derived_from
<From
&, volatile To
*>);
90 static_assert(!std::derived_from
<From
&, const volatile To
*>);
92 static_assert(!std::derived_from
<From
&&, To
*>);
93 static_assert(!std::derived_from
<From
&&, const To
*>);
94 static_assert(!std::derived_from
<From
&&, volatile To
*>);
95 static_assert(!std::derived_from
<From
&&, const volatile To
*>);
97 static_assert(!std::derived_from
<const From
&, To
*>);
98 static_assert(!std::derived_from
<const From
&, const To
*>);
99 static_assert(!std::derived_from
<const From
&, volatile To
*>);
100 static_assert(!std::derived_from
<const From
&, const volatile To
*>);
102 static_assert(!std::derived_from
<const From
&&, To
*>);
103 static_assert(!std::derived_from
<const From
&&, const To
*>);
104 static_assert(!std::derived_from
<const From
&&, volatile To
*>);
105 static_assert(!std::derived_from
<const From
&&, const volatile To
*>);
107 static_assert(!std::derived_from
<volatile From
&, To
*>);
108 static_assert(!std::derived_from
<volatile From
&, const To
*>);
109 static_assert(!std::derived_from
<volatile From
&, volatile To
*>);
110 static_assert(!std::derived_from
<volatile From
&, const volatile To
*>);
112 static_assert(!std::derived_from
<volatile From
&&, To
*>);
113 static_assert(!std::derived_from
<volatile From
&&, const To
*>);
114 static_assert(!std::derived_from
<volatile From
&&, volatile To
*>);
115 static_assert(!std::derived_from
<volatile From
&&, const volatile To
*>);
117 static_assert(!std::derived_from
<const volatile From
&, To
*>);
118 static_assert(!std::derived_from
<const volatile From
&, const To
*>);
119 static_assert(!std::derived_from
<const volatile From
&, volatile To
*>);
121 !std::derived_from
<const volatile From
&, const volatile To
*>);
123 static_assert(!std::derived_from
<const volatile From
&&, To
*>);
124 static_assert(!std::derived_from
<const volatile From
&&, const To
*>);
125 static_assert(!std::derived_from
<const volatile From
&&, volatile To
*>);
127 !std::derived_from
<const volatile From
&&, const volatile To
*>);
130 { // Both as pointers
131 static_assert(!std::derived_from
<From
*, To
*>);
132 static_assert(!std::derived_from
<From
*, const To
*>);
133 static_assert(!std::derived_from
<From
*, volatile To
*>);
134 static_assert(!std::derived_from
<From
*, const volatile To
*>);
136 static_assert(!std::derived_from
<const From
*, To
*>);
137 static_assert(!std::derived_from
<const From
*, const To
*>);
138 static_assert(!std::derived_from
<const From
*, volatile To
*>);
139 static_assert(!std::derived_from
<const From
*, const volatile To
*>);
141 static_assert(!std::derived_from
<volatile From
*, To
*>);
142 static_assert(!std::derived_from
<volatile From
*, const To
*>);
143 static_assert(!std::derived_from
<volatile From
*, volatile To
*>);
144 static_assert(!std::derived_from
<volatile From
*, const volatile To
*>);
146 static_assert(!std::derived_from
<const volatile From
*, To
*>);
147 static_assert(!std::derived_from
<const volatile From
*, const To
*>);
148 static_assert(!std::derived_from
<const volatile From
*, volatile To
*>);
149 static_assert(!std::derived_from
<const volatile From
*, const volatile To
*>);
152 // From as the return type of a pointer-to-function
153 if constexpr (!std::is_array_v
<From
>) {
154 static_assert(!std::derived_from
<From (*)(), To
>);
155 static_assert(!std::derived_from
<From (*)(int), To
>);
158 // To as the return type of a pointer-to-function
159 if constexpr (!std::is_array_v
<To
>) {
160 static_assert(!std::derived_from
<From
, To (*)()>);
161 static_assert(!std::derived_from
<From
, To (*)(double)>);
164 // Both as the return type of a pointer-to-function
165 if constexpr (!std::is_array_v
<From
> && !std::is_array_v
<To
>) {
166 static_assert(!std::derived_from
<From (*)(), To (*)()>);
167 static_assert(!std::derived_from
<From (*)(int), To (*)(double)>);
169 { // pointer-to-member
170 if constexpr (std::is_class_v
<From
> && !std::same_as
<To
, void>) {
171 static_assert(!std::derived_from
<To
From::*, To
>);
174 if constexpr (std::is_class_v
<To
> && !std::same_as
<From
, void>) {
175 static_assert(!std::derived_from
<From
To::*, From
>);
178 { // pointer-to-member-functions
179 if constexpr (std::is_class_v
<From
>) {
180 static_assert(!std::derived_from
<From (From::*)(), To
>);
183 if constexpr (std::is_class_v
<To
>) {
184 static_assert(!std::derived_from
<To (To::*)(), From
>);
189 template <typename From
, typename To
>
190 constexpr void CheckNotDerivedFromReference() {
191 if constexpr (!std::same_as
<To
, void>) {
192 static_assert(!std::derived_from
<From
, To
&>);
193 static_assert(!std::derived_from
<From
, const To
&>);
194 static_assert(!std::derived_from
<From
, volatile To
&>);
195 static_assert(!std::derived_from
<From
, const volatile To
&>);
197 static_assert(!std::derived_from
<From
, To
&&>);
198 static_assert(!std::derived_from
<From
, const To
&&>);
199 static_assert(!std::derived_from
<From
, volatile To
&&>);
200 static_assert(!std::derived_from
<From
, const volatile To
&&>);
203 if constexpr (!std::same_as
<From
, void>) {
204 static_assert(!std::derived_from
<From
&, To
>);
205 static_assert(!std::derived_from
<From
&, To
>);
206 static_assert(!std::derived_from
<From
&, To
>);
207 static_assert(!std::derived_from
<From
&, To
>);
209 static_assert(!std::derived_from
<From
&&, To
>);
210 static_assert(!std::derived_from
<From
&&, To
>);
211 static_assert(!std::derived_from
<From
&&, To
>);
212 static_assert(!std::derived_from
<From
&&, To
>);
215 // From as lvalue references
216 if constexpr (!std::same_as
<From
, void> && !std::same_as
<To
, void>) {
217 static_assert(!std::derived_from
<From
&, To
&>);
218 static_assert(!std::derived_from
<From
&, const To
&>);
219 static_assert(!std::derived_from
<From
&, volatile To
&>);
220 static_assert(!std::derived_from
<From
&, const volatile To
&>);
222 static_assert(!std::derived_from
<From
&, To
&&>);
223 static_assert(!std::derived_from
<From
&, const To
&&>);
224 static_assert(!std::derived_from
<From
&, volatile To
&&>);
225 static_assert(!std::derived_from
<From
&, const volatile To
&&>);
227 static_assert(!std::derived_from
<const From
&, To
&>);
228 static_assert(!std::derived_from
<const From
&, const To
&>);
229 static_assert(!std::derived_from
<const From
&, volatile To
&>);
230 static_assert(!std::derived_from
<const From
&, const volatile To
&>);
232 static_assert(!std::derived_from
<const From
&, To
&&>);
233 static_assert(!std::derived_from
<const From
&, const To
&&>);
234 static_assert(!std::derived_from
<const From
&, volatile To
&&>);
235 static_assert(!std::derived_from
<const From
&, const volatile To
&&>);
237 static_assert(!std::derived_from
<volatile From
&, To
&>);
238 static_assert(!std::derived_from
<volatile From
&, const To
&>);
239 static_assert(!std::derived_from
<volatile From
&, volatile To
&>);
240 static_assert(!std::derived_from
<volatile From
&, const volatile To
&>);
242 static_assert(!std::derived_from
<volatile From
&, To
&&>);
243 static_assert(!std::derived_from
<volatile From
&, const To
&&>);
244 static_assert(!std::derived_from
<volatile From
&, volatile To
&&>);
245 static_assert(!std::derived_from
<volatile From
&, const volatile To
&&>);
247 static_assert(!std::derived_from
<const volatile From
&, To
&>);
248 static_assert(!std::derived_from
<const volatile From
&, const To
&>);
249 static_assert(!std::derived_from
<const volatile From
&, volatile To
&>);
250 static_assert(!std::derived_from
<const volatile From
&, const volatile To
&>);
252 static_assert(!std::derived_from
<const volatile From
&, To
&&>);
253 static_assert(!std::derived_from
<const volatile From
&, const To
&&>);
254 static_assert(!std::derived_from
<const volatile From
&, volatile To
&&>);
256 !std::derived_from
<const volatile From
&, const volatile To
&&>);
258 // From as rvalue references
259 static_assert(!std::derived_from
<From
&&, To
&>);
260 static_assert(!std::derived_from
<From
&&, const To
&>);
261 static_assert(!std::derived_from
<From
&&, volatile To
&>);
262 static_assert(!std::derived_from
<From
&&, const volatile To
&>);
264 static_assert(!std::derived_from
<From
&&, To
&&>);
265 static_assert(!std::derived_from
<From
&&, const To
&&>);
266 static_assert(!std::derived_from
<From
&&, volatile To
&&>);
267 static_assert(!std::derived_from
<From
&&, const volatile To
&&>);
269 static_assert(!std::derived_from
<const From
&&, To
&>);
270 static_assert(!std::derived_from
<const From
&&, const To
&>);
271 static_assert(!std::derived_from
<const From
&&, volatile To
&>);
272 static_assert(!std::derived_from
<const From
&&, const volatile To
&>);
274 static_assert(!std::derived_from
<const From
&&, To
&&>);
275 static_assert(!std::derived_from
<const From
&&, const To
&&>);
276 static_assert(!std::derived_from
<const From
&&, volatile To
&&>);
277 static_assert(!std::derived_from
<const From
&&, const volatile To
&&>);
279 static_assert(!std::derived_from
<volatile From
&&, To
&>);
280 static_assert(!std::derived_from
<volatile From
&&, const To
&>);
281 static_assert(!std::derived_from
<volatile From
&&, volatile To
&>);
282 static_assert(!std::derived_from
<volatile From
&&, const volatile To
&>);
284 static_assert(!std::derived_from
<volatile From
&&, To
&&>);
285 static_assert(!std::derived_from
<volatile From
&&, const To
&&>);
286 static_assert(!std::derived_from
<volatile From
&&, volatile To
&&>);
287 static_assert(!std::derived_from
<volatile From
&&, const volatile To
&&>);
289 static_assert(!std::derived_from
<const volatile From
&&, To
&>);
290 static_assert(!std::derived_from
<const volatile From
&&, const To
&>);
291 static_assert(!std::derived_from
<const volatile From
&&, volatile To
&>);
293 !std::derived_from
<const volatile From
&&, const volatile To
&>);
295 static_assert(!std::derived_from
<const volatile From
&&, To
&&>);
296 static_assert(!std::derived_from
<const volatile From
&&, const To
&&>);
297 static_assert(!std::derived_from
<const volatile From
&&, volatile To
&&>);
299 !std::derived_from
<const volatile From
&&, const volatile To
&&>);
302 // From as the return type of a reference-to-function
303 if constexpr (!std::is_array_v
<From
>) {
304 static_assert(!std::derived_from
<From (&)(), To
>);
305 static_assert(!std::derived_from
<From (&)(int), To
>);
307 // To as the return type of a reference-to-function
308 if constexpr (!std::is_array_v
<To
>) {
309 static_assert(!std::derived_from
<From
, To (&)()>);
310 static_assert(!std::derived_from
<From
, To (&)(double)>);
312 // Both as the return type of a reference-to-function
313 if constexpr (!std::is_array_v
<From
> && !std::is_array_v
<To
>) {
314 static_assert(!std::derived_from
<From (&)(), To (&)()>);
315 static_assert(!std::derived_from
<From (&)(int), To (&)(double)>);
319 template <typename From
, typename To
>
320 constexpr void CheckDerivedFrom() {
321 static_assert(std::derived_from
<From
, To
>);
323 static_assert(std::derived_from
<From
, const To
>);
324 static_assert(std::derived_from
<From
, volatile To
>);
325 static_assert(std::derived_from
<From
, const volatile To
>);
327 static_assert(std::derived_from
<const From
, const To
>);
328 static_assert(std::derived_from
<const From
, volatile To
>);
329 static_assert(std::derived_from
<const From
, const volatile To
>);
331 static_assert(std::derived_from
<volatile From
, const To
>);
332 static_assert(std::derived_from
<volatile From
, volatile To
>);
333 static_assert(std::derived_from
<volatile From
, const volatile To
>);
335 static_assert(std::derived_from
<const volatile From
, const To
>);
336 static_assert(std::derived_from
<const volatile From
, volatile To
>);
337 static_assert(std::derived_from
<const volatile From
, const volatile To
>);
339 CheckNotDerivedFromPointer
<From
, To
>();
340 CheckNotDerivedFromReference
<From
, To
>();
343 template <typename From
, typename To
>
344 constexpr void CheckNotDerivedFrom() {
345 static_assert(!std::derived_from
<From
, To
>);
347 static_assert(!std::derived_from
<From
, const To
>);
348 static_assert(!std::derived_from
<From
, volatile To
>);
349 static_assert(!std::derived_from
<From
, const volatile To
>);
351 static_assert(!std::derived_from
<const From
, const To
>);
352 static_assert(!std::derived_from
<const From
, volatile To
>);
353 static_assert(!std::derived_from
<const From
, const volatile To
>);
355 static_assert(!std::derived_from
<volatile From
, const To
>);
356 static_assert(!std::derived_from
<volatile From
, volatile To
>);
357 static_assert(!std::derived_from
<volatile From
, const volatile To
>);
359 static_assert(!std::derived_from
<const volatile From
, const To
>);
360 static_assert(!std::derived_from
<const volatile From
, volatile To
>);
361 static_assert(!std::derived_from
<const volatile From
, const volatile To
>);
363 CheckNotDerivedFromPointer
<From
, To
>();
364 CheckNotDerivedFromReference
<From
, To
>();
367 enum Enumeration
{ Yes
, No
};
368 enum class ScopedEnumeration
: int { No
, Yes
};
370 int main(int, char**) {
371 { // Fundamentals shouldn't be derived from anything
372 CheckNotDerivedFrom
<int, long>();
373 CheckNotDerivedFrom
<signed char, char>();
374 CheckNotDerivedFrom
<double, Base1
>();
376 CheckNotDerivedFrom
<int, Enumeration
>();
377 CheckNotDerivedFrom
<int, ScopedEnumeration
>();
379 CheckNotDerivedFrom
<void, void>();
380 CheckNotDerivedFrom
<int, int>();
382 { // Nothing should be derived from a fundamental type
383 CheckNotDerivedFrom
<Enumeration
, int>();
384 CheckNotDerivedFrom
<ScopedEnumeration
, int>();
386 CheckNotDerivedFrom
<Base1
, int>();
387 CheckNotDerivedFrom
<Base1
, double>();
388 CheckNotDerivedFrom
<Derived1
, char>();
389 CheckNotDerivedFrom
<DerivedPrivate
, long long>();
391 { // Other built-in things shouldn't have derivations
392 CheckNotDerivedFrom
<Enumeration
, Enumeration
>();
393 CheckNotDerivedFrom
<ScopedEnumeration
, ScopedEnumeration
>();
395 CheckNotDerivedFrom
<Enumeration
, ScopedEnumeration
>();
396 CheckNotDerivedFrom
<ScopedEnumeration
, Enumeration
>();
398 CheckNotDerivedFrom
<Base1
[5], Base1
>();
399 CheckNotDerivedFrom
<Derived1
[5], Base1
>();
401 CheckNotDerivedFrom
<Base1
, Base1
[5]>();
402 CheckNotDerivedFrom
<Derived1
, Base1
[5]>();
405 { // Base1 is the subject.
406 CheckDerivedFrom
<Base1
, Base1
>();
408 CheckNotDerivedFrom
<Base1
, void>();
409 CheckNotDerivedFrom
<Base1
, DerivedPrivate
>();
410 CheckNotDerivedFrom
<Base1
, DerivedProtected
>();
411 CheckNotDerivedFrom
<Base1
, Derived1
>();
412 CheckNotDerivedFrom
<Base1
, Derived2
>();
413 CheckNotDerivedFrom
<Base1
, Derived3
>();
414 CheckNotDerivedFrom
<Base1
, Derived4
>();
417 { // Derived1 is the subject.
418 CheckDerivedFrom
<Derived1
, Base1
>();
419 CheckDerivedFrom
<Derived1
, Derived1
>();
421 CheckNotDerivedFromPointer
<Derived1
, void>();
422 CheckNotDerivedFrom
<Derived1
, DerivedPrivate
>();
423 CheckNotDerivedFrom
<Derived1
, DerivedProtected
>();
424 CheckNotDerivedFrom
<Derived1
, Derived2
>();
425 CheckNotDerivedFrom
<Derived1
, Derived3
>();
426 CheckNotDerivedFrom
<Derived1
, Derived4
>();
429 { // Derived2 is the subject.
430 CheckDerivedFrom
<Derived2
, Base1
>();
431 CheckDerivedFrom
<Derived2
, Derived2
>();
433 CheckNotDerivedFrom
<Derived2
, DerivedPrivate
>();
434 CheckNotDerivedFrom
<Derived2
, DerivedProtected
>();
435 CheckNotDerivedFrom
<Derived2
, Derived1
>();
436 CheckNotDerivedFrom
<Derived2
, Derived3
>();
437 CheckNotDerivedFrom
<Derived2
, Derived4
>();
440 { // DerivedPrivate is the subject.
441 CheckDerivedFrom
<DerivedPrivate
, DerivedPrivate
>();
443 CheckNotDerivedFrom
<DerivedPrivate
, Base1
>();
444 CheckNotDerivedFrom
<DerivedPrivate
, DerivedProtected
>();
445 CheckNotDerivedFrom
<DerivedPrivate
, Derived1
>();
446 CheckNotDerivedFrom
<DerivedPrivate
, Derived2
>();
447 CheckNotDerivedFrom
<DerivedPrivate
, Derived3
>();
448 CheckNotDerivedFrom
<DerivedPrivate
, Derived4
>();
451 { // Derived3 is the subject.
452 CheckDerivedFrom
<Derived3
, DerivedPrivate
>();
453 CheckDerivedFrom
<Derived3
, Derived3
>();
455 CheckNotDerivedFrom
<Derived3
, Base1
>();
456 CheckNotDerivedFrom
<Derived3
, DerivedProtected
>();
457 CheckNotDerivedFrom
<Derived3
, Derived1
>();
458 CheckNotDerivedFrom
<Derived3
, Derived2
>();
459 CheckNotDerivedFrom
<Derived3
, Derived4
>();
462 { // DerivedProtected is the subject.
463 CheckDerivedFrom
<DerivedProtected
, DerivedProtected
>();
465 CheckNotDerivedFromPointer
<DerivedProtected
, Base1
>();
466 CheckNotDerivedFromPointer
<DerivedProtected
, DerivedPrivate
>();
467 CheckNotDerivedFromPointer
<DerivedProtected
, Derived1
>();
468 CheckNotDerivedFromPointer
<DerivedProtected
, Derived2
>();
469 CheckNotDerivedFromPointer
<DerivedProtected
, Derived3
>();
470 CheckNotDerivedFromPointer
<DerivedProtected
, Derived4
>();
473 { // Derived4 is the subject.
474 CheckDerivedFrom
<Derived4
, DerivedProtected
>();
475 CheckDerivedFrom
<Derived4
, Derived4
>();
477 CheckNotDerivedFrom
<Derived4
, Base1
>();
478 CheckNotDerivedFrom
<Derived4
, DerivedPrivate
>();
479 CheckNotDerivedFrom
<Derived4
, Derived1
>();
480 CheckNotDerivedFrom
<Derived4
, Derived2
>();
481 CheckNotDerivedFrom
<Derived4
, Derived3
>();
484 { // Derived5 is the subject.
485 CheckDerivedFrom
<Derived5
, DerivedProtected
>();
486 CheckDerivedFrom
<Derived5
, Derived4
>();
487 CheckDerivedFrom
<Derived5
, Derived5
>();
489 CheckNotDerivedFrom
<Derived5
, Base1
>();
490 CheckNotDerivedFrom
<Derived5
, DerivedPrivate
>();
491 CheckNotDerivedFrom
<Derived5
, Derived1
>();
492 CheckNotDerivedFrom
<Derived5
, Derived2
>();
493 CheckNotDerivedFrom
<Derived5
, Derived3
>();