brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.5 KiB · b057102 Raw
498 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template<class Derived, class Base>12// concept derived_from;13 14#include <concepts>15#include <type_traits>16 17struct Base1 {};18struct Derived1 : Base1 {};19struct Derived2 : Base1 {};20 21struct DerivedPrivate : private Base1 {};22struct Derived3 : DerivedPrivate {};23 24struct DerivedProtected : protected DerivedPrivate {};25struct Derived4 : DerivedProtected {};26struct Derived5 : Derived4 {};27 28template <typename From, typename To>29constexpr void CheckNotDerivedFromPointer() {30  { // From as pointer31    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>);35 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&>);41 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&&>);46 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&>);51 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&&>);56 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&>);61 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&&>);66 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&>);70      static_assert(71          !std::derived_from<const volatile From*, const volatile To&>);72 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&&>);76      static_assert(77          !std::derived_from<const volatile From*, const volatile To&&>);78    }79  }80  { // To as pointer81    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*>);85 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*>);91 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*>);96 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*>);101 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*>);106 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*>);111 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*>);116 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*>);120      static_assert(121          !std::derived_from<const volatile From&, const volatile To*>);122 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*>);126      static_assert(127          !std::derived_from<const volatile From&&, const volatile To*>);128    }129  }130  { // Both as pointers131    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*>);135 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*>);140 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*>);145 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*>);150  }151 152  // From as the return type of a pointer-to-function153  if constexpr (!std::is_array_v<From>) {154    static_assert(!std::derived_from<From (*)(), To>);155    static_assert(!std::derived_from<From (*)(int), To>);156  }157 158  // To as the return type of a pointer-to-function159  if constexpr (!std::is_array_v<To>) {160    static_assert(!std::derived_from<From, To (*)()>);161    static_assert(!std::derived_from<From, To (*)(double)>);162  }163 164  // Both as the return type of a pointer-to-function165  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)>);168  }169  { // pointer-to-member170    if constexpr (std::is_class_v<From> && !std::same_as<To, void>) {171      static_assert(!std::derived_from<To From::*, To>);172    }173 174    if constexpr (std::is_class_v<To> && !std::same_as<From, void>) {175      static_assert(!std::derived_from<From To::*, From>);176    }177  }178  { // pointer-to-member-functions179    if constexpr (std::is_class_v<From>) {180      static_assert(!std::derived_from<From (From::*)(), To>);181    }182 183    if constexpr (std::is_class_v<To>) {184      static_assert(!std::derived_from<To (To::*)(), From>);185    }186  }187}188 189template <typename From, typename To>190constexpr 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&>);196 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&&>);201  }202 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>);208 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>);213  }214 215  // From as lvalue references216  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&>);221 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&&>);226 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&>);231 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&&>);236 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&>);241 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&&>);246 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&>);251 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&&>);255    static_assert(256        !std::derived_from<const volatile From&, const volatile To&&>);257 258    // From as rvalue references259    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&>);263 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&&>);268 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&>);273 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&&>);278 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&>);283 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&&>);288 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&>);292    static_assert(293        !std::derived_from<const volatile From&&, const volatile To&>);294 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&&>);298    static_assert(299        !std::derived_from<const volatile From&&, const volatile To&&>);300  }301 302  // From as the return type of a reference-to-function303  if constexpr (!std::is_array_v<From>) {304    static_assert(!std::derived_from<From (&)(), To>);305    static_assert(!std::derived_from<From (&)(int), To>);306  }307  // To as the return type of a reference-to-function308  if constexpr (!std::is_array_v<To>) {309    static_assert(!std::derived_from<From, To (&)()>);310    static_assert(!std::derived_from<From, To (&)(double)>);311  }312  // Both as the return type of a reference-to-function313  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)>);316  }317}318 319template <typename From, typename To>320constexpr void CheckDerivedFrom() {321  static_assert(std::derived_from<From, To>);322 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>);326 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>);330 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>);334 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>);338 339  CheckNotDerivedFromPointer<From, To>();340  CheckNotDerivedFromReference<From, To>();341}342 343template <typename From, typename To>344constexpr void CheckNotDerivedFrom() {345  static_assert(!std::derived_from<From, To>);346 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>);350 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>);354 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>);358 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>);362 363  CheckNotDerivedFromPointer<From, To>();364  CheckNotDerivedFromReference<From, To>();365}366 367enum Enumeration { Yes, No };368enum class ScopedEnumeration : int { No, Yes };369 370int main(int, char**) {371  { // Fundamentals shouldn't be derived from anything372    CheckNotDerivedFrom<int, long>();373    CheckNotDerivedFrom<signed char, char>();374    CheckNotDerivedFrom<double, Base1>();375 376    CheckNotDerivedFrom<int, Enumeration>();377    CheckNotDerivedFrom<int, ScopedEnumeration>();378 379    CheckNotDerivedFrom<void, void>();380    CheckNotDerivedFrom<int, int>();381  }382  { // Nothing should be derived from a fundamental type383    CheckNotDerivedFrom<Enumeration, int>();384    CheckNotDerivedFrom<ScopedEnumeration, int>();385 386    CheckNotDerivedFrom<Base1, int>();387    CheckNotDerivedFrom<Base1, double>();388    CheckNotDerivedFrom<Derived1, char>();389    CheckNotDerivedFrom<DerivedPrivate, long long>();390  }391  { // Other built-in things shouldn't have derivations392    CheckNotDerivedFrom<Enumeration, Enumeration>();393    CheckNotDerivedFrom<ScopedEnumeration, ScopedEnumeration>();394 395    CheckNotDerivedFrom<Enumeration, ScopedEnumeration>();396    CheckNotDerivedFrom<ScopedEnumeration, Enumeration>();397 398    CheckNotDerivedFrom<Base1[5], Base1>();399    CheckNotDerivedFrom<Derived1[5], Base1>();400 401    CheckNotDerivedFrom<Base1, Base1[5]>();402    CheckNotDerivedFrom<Derived1, Base1[5]>();403  }404 405  { // Base1 is the subject.406    CheckDerivedFrom<Base1, Base1>();407 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>();415  }416 417  { // Derived1 is the subject.418    CheckDerivedFrom<Derived1, Base1>();419    CheckDerivedFrom<Derived1, Derived1>();420 421    CheckNotDerivedFromPointer<Derived1, void>();422    CheckNotDerivedFrom<Derived1, DerivedPrivate>();423    CheckNotDerivedFrom<Derived1, DerivedProtected>();424    CheckNotDerivedFrom<Derived1, Derived2>();425    CheckNotDerivedFrom<Derived1, Derived3>();426    CheckNotDerivedFrom<Derived1, Derived4>();427  }428 429  { // Derived2 is the subject.430    CheckDerivedFrom<Derived2, Base1>();431    CheckDerivedFrom<Derived2, Derived2>();432 433    CheckNotDerivedFrom<Derived2, DerivedPrivate>();434    CheckNotDerivedFrom<Derived2, DerivedProtected>();435    CheckNotDerivedFrom<Derived2, Derived1>();436    CheckNotDerivedFrom<Derived2, Derived3>();437    CheckNotDerivedFrom<Derived2, Derived4>();438  }439 440  { // DerivedPrivate is the subject.441    CheckDerivedFrom<DerivedPrivate, DerivedPrivate>();442 443    CheckNotDerivedFrom<DerivedPrivate, Base1>();444    CheckNotDerivedFrom<DerivedPrivate, DerivedProtected>();445    CheckNotDerivedFrom<DerivedPrivate, Derived1>();446    CheckNotDerivedFrom<DerivedPrivate, Derived2>();447    CheckNotDerivedFrom<DerivedPrivate, Derived3>();448    CheckNotDerivedFrom<DerivedPrivate, Derived4>();449  }450 451  { // Derived3 is the subject.452    CheckDerivedFrom<Derived3, DerivedPrivate>();453    CheckDerivedFrom<Derived3, Derived3>();454 455    CheckNotDerivedFrom<Derived3, Base1>();456    CheckNotDerivedFrom<Derived3, DerivedProtected>();457    CheckNotDerivedFrom<Derived3, Derived1>();458    CheckNotDerivedFrom<Derived3, Derived2>();459    CheckNotDerivedFrom<Derived3, Derived4>();460  }461 462  { // DerivedProtected is the subject.463    CheckDerivedFrom<DerivedProtected, DerivedProtected>();464 465    CheckNotDerivedFromPointer<DerivedProtected, Base1>();466    CheckNotDerivedFromPointer<DerivedProtected, DerivedPrivate>();467    CheckNotDerivedFromPointer<DerivedProtected, Derived1>();468    CheckNotDerivedFromPointer<DerivedProtected, Derived2>();469    CheckNotDerivedFromPointer<DerivedProtected, Derived3>();470    CheckNotDerivedFromPointer<DerivedProtected, Derived4>();471  }472 473  { // Derived4 is the subject.474    CheckDerivedFrom<Derived4, DerivedProtected>();475    CheckDerivedFrom<Derived4, Derived4>();476 477    CheckNotDerivedFrom<Derived4, Base1>();478    CheckNotDerivedFrom<Derived4, DerivedPrivate>();479    CheckNotDerivedFrom<Derived4, Derived1>();480    CheckNotDerivedFrom<Derived4, Derived2>();481    CheckNotDerivedFrom<Derived4, Derived3>();482  }483 484  { // Derived5 is the subject.485    CheckDerivedFrom<Derived5, DerivedProtected>();486    CheckDerivedFrom<Derived5, Derived4>();487    CheckDerivedFrom<Derived5, Derived5>();488 489    CheckNotDerivedFrom<Derived5, Base1>();490    CheckNotDerivedFrom<Derived5, DerivedPrivate>();491    CheckNotDerivedFrom<Derived5, Derived1>();492    CheckNotDerivedFrom<Derived5, Derived2>();493    CheckNotDerivedFrom<Derived5, Derived3>();494  }495 496  return 0;497}498