499 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			499 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
// UNSUPPORTED: c++03, c++11, c++14, c++17
 | 
						|
// UNSUPPORTED: libcpp-no-concepts
 | 
						|
 | 
						|
// template<class Derived, class Base>
 | 
						|
// concept derived_from;
 | 
						|
 | 
						|
#include <concepts>
 | 
						|
#include <type_traits>
 | 
						|
 | 
						|
struct Base1 {};
 | 
						|
struct Derived1 : Base1 {};
 | 
						|
struct Derived2 : Base1 {};
 | 
						|
 | 
						|
struct DerivedPrivate : private Base1 {};
 | 
						|
struct Derived3 : DerivedPrivate {};
 | 
						|
 | 
						|
struct DerivedProtected : protected DerivedPrivate {};
 | 
						|
struct Derived4 : DerivedProtected {};
 | 
						|
struct Derived5 : Derived4 {};
 | 
						|
 | 
						|
template <typename From, typename To>
 | 
						|
constexpr void CheckNotDerivedFromPointer() {
 | 
						|
  { // From as pointer
 | 
						|
    static_assert(!std::derived_from<From*, To>);
 | 
						|
    static_assert(!std::derived_from<From*, const To>);
 | 
						|
    static_assert(!std::derived_from<From*, volatile To>);
 | 
						|
    static_assert(!std::derived_from<From*, const volatile To>);
 | 
						|
 | 
						|
    if constexpr (!std::same_as<To, void>) {
 | 
						|
      static_assert(!std::derived_from<From*, To&>);
 | 
						|
      static_assert(!std::derived_from<From*, const To&>);
 | 
						|
      static_assert(!std::derived_from<From*, volatile To&>);
 | 
						|
      static_assert(!std::derived_from<From*, const volatile To&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<From*, To&&>);
 | 
						|
      static_assert(!std::derived_from<From*, const To&&>);
 | 
						|
      static_assert(!std::derived_from<From*, volatile To&&>);
 | 
						|
      static_assert(!std::derived_from<From*, const volatile To&&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const From*, To&>);
 | 
						|
      static_assert(!std::derived_from<const From*, const To&>);
 | 
						|
      static_assert(!std::derived_from<const From*, volatile To&>);
 | 
						|
      static_assert(!std::derived_from<const From*, const volatile To&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const From*, To&&>);
 | 
						|
      static_assert(!std::derived_from<const From*, const To&&>);
 | 
						|
      static_assert(!std::derived_from<const From*, volatile To&&>);
 | 
						|
      static_assert(!std::derived_from<const From*, const volatile To&&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<volatile From*, To&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, const To&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, volatile To&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, const volatile To&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<volatile From*, To&&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, const To&&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, volatile To&&>);
 | 
						|
      static_assert(!std::derived_from<volatile From*, const volatile To&&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const volatile From*, To&>);
 | 
						|
      static_assert(!std::derived_from<const volatile From*, const To&>);
 | 
						|
      static_assert(!std::derived_from<const volatile From*, volatile To&>);
 | 
						|
      static_assert(
 | 
						|
          !std::derived_from<const volatile From*, const volatile To&>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const volatile From*, To&&>);
 | 
						|
      static_assert(!std::derived_from<const volatile From*, const To&&>);
 | 
						|
      static_assert(!std::derived_from<const volatile From*, volatile To&&>);
 | 
						|
      static_assert(
 | 
						|
          !std::derived_from<const volatile From*, const volatile To&&>);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  { // To as pointer
 | 
						|
    static_assert(!std::derived_from<From, To*>);
 | 
						|
    static_assert(!std::derived_from<From, const To*>);
 | 
						|
    static_assert(!std::derived_from<From, volatile To*>);
 | 
						|
    static_assert(!std::derived_from<From, const volatile To*>);
 | 
						|
 | 
						|
    if constexpr (!std::same_as<From, void>) {
 | 
						|
      static_assert(!std::derived_from<From&, To*>);
 | 
						|
      static_assert(!std::derived_from<From&, const To*>);
 | 
						|
      static_assert(!std::derived_from<From&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<From&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<From&&, To*>);
 | 
						|
      static_assert(!std::derived_from<From&&, const To*>);
 | 
						|
      static_assert(!std::derived_from<From&&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<From&&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const From&, To*>);
 | 
						|
      static_assert(!std::derived_from<const From&, const To*>);
 | 
						|
      static_assert(!std::derived_from<const From&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<const From&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const From&&, To*>);
 | 
						|
      static_assert(!std::derived_from<const From&&, const To*>);
 | 
						|
      static_assert(!std::derived_from<const From&&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<const From&&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<volatile From&, To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&, const To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<volatile From&&, To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&&, const To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&&, volatile To*>);
 | 
						|
      static_assert(!std::derived_from<volatile From&&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const volatile From&, To*>);
 | 
						|
      static_assert(!std::derived_from<const volatile From&, const To*>);
 | 
						|
      static_assert(!std::derived_from<const volatile From&, volatile To*>);
 | 
						|
      static_assert(
 | 
						|
          !std::derived_from<const volatile From&, const volatile To*>);
 | 
						|
 | 
						|
      static_assert(!std::derived_from<const volatile From&&, To*>);
 | 
						|
      static_assert(!std::derived_from<const volatile From&&, const To*>);
 | 
						|
      static_assert(!std::derived_from<const volatile From&&, volatile To*>);
 | 
						|
      static_assert(
 | 
						|
          !std::derived_from<const volatile From&&, const volatile To*>);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  { // Both as pointers
 | 
						|
    static_assert(!std::derived_from<From*, To*>);
 | 
						|
    static_assert(!std::derived_from<From*, const To*>);
 | 
						|
    static_assert(!std::derived_from<From*, volatile To*>);
 | 
						|
    static_assert(!std::derived_from<From*, const volatile To*>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const From*, To*>);
 | 
						|
    static_assert(!std::derived_from<const From*, const To*>);
 | 
						|
    static_assert(!std::derived_from<const From*, volatile To*>);
 | 
						|
    static_assert(!std::derived_from<const From*, const volatile To*>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<volatile From*, To*>);
 | 
						|
    static_assert(!std::derived_from<volatile From*, const To*>);
 | 
						|
    static_assert(!std::derived_from<volatile From*, volatile To*>);
 | 
						|
    static_assert(!std::derived_from<volatile From*, const volatile To*>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const volatile From*, To*>);
 | 
						|
    static_assert(!std::derived_from<const volatile From*, const To*>);
 | 
						|
    static_assert(!std::derived_from<const volatile From*, volatile To*>);
 | 
						|
    static_assert(!std::derived_from<const volatile From*, const volatile To*>);
 | 
						|
  }
 | 
						|
 | 
						|
  // From as the return type of a pointer-to-function
 | 
						|
  if constexpr (!std::is_array_v<From>) {
 | 
						|
    static_assert(!std::derived_from<From (*)(), To>);
 | 
						|
    static_assert(!std::derived_from<From (*)(int), To>);
 | 
						|
  }
 | 
						|
 | 
						|
  // To as the return type of a pointer-to-function
 | 
						|
  if constexpr (!std::is_array_v<To>) {
 | 
						|
    static_assert(!std::derived_from<From, To (*)()>);
 | 
						|
    static_assert(!std::derived_from<From, To (*)(double)>);
 | 
						|
  }
 | 
						|
 | 
						|
  // Both as the return type of a pointer-to-function
 | 
						|
  if constexpr (!std::is_array_v<From> && !std::is_array_v<To>) {
 | 
						|
    static_assert(!std::derived_from<From (*)(), To (*)()>);
 | 
						|
    static_assert(!std::derived_from<From (*)(int), To (*)(double)>);
 | 
						|
  }
 | 
						|
  { // pointer-to-member
 | 
						|
    if constexpr (std::is_class_v<From> && !std::same_as<To, void>) {
 | 
						|
      static_assert(!std::derived_from<To From::*, To>);
 | 
						|
    }
 | 
						|
 | 
						|
    if constexpr (std::is_class_v<To> && !std::same_as<From, void>) {
 | 
						|
      static_assert(!std::derived_from<From To::*, From>);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  { // pointer-to-member-functions
 | 
						|
    if constexpr (std::is_class_v<From>) {
 | 
						|
      static_assert(!std::derived_from<From (From::*)(), To>);
 | 
						|
    }
 | 
						|
 | 
						|
    if constexpr (std::is_class_v<To>) {
 | 
						|
      static_assert(!std::derived_from<To (To::*)(), From>);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
template <typename From, typename To>
 | 
						|
constexpr void CheckNotDerivedFromReference() {
 | 
						|
  if constexpr (!std::same_as<To, void>) {
 | 
						|
    static_assert(!std::derived_from<From, To&>);
 | 
						|
    static_assert(!std::derived_from<From, const To&>);
 | 
						|
    static_assert(!std::derived_from<From, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<From, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<From, To&&>);
 | 
						|
    static_assert(!std::derived_from<From, const To&&>);
 | 
						|
    static_assert(!std::derived_from<From, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<From, const volatile To&&>);
 | 
						|
  }
 | 
						|
 | 
						|
  if constexpr (!std::same_as<From, void>) {
 | 
						|
    static_assert(!std::derived_from<From&, To>);
 | 
						|
    static_assert(!std::derived_from<From&, To>);
 | 
						|
    static_assert(!std::derived_from<From&, To>);
 | 
						|
    static_assert(!std::derived_from<From&, To>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<From&&, To>);
 | 
						|
    static_assert(!std::derived_from<From&&, To>);
 | 
						|
    static_assert(!std::derived_from<From&&, To>);
 | 
						|
    static_assert(!std::derived_from<From&&, To>);
 | 
						|
  }
 | 
						|
 | 
						|
  // From as lvalue references
 | 
						|
  if constexpr (!std::same_as<From, void> && !std::same_as<To, void>) {
 | 
						|
    static_assert(!std::derived_from<From&, To&>);
 | 
						|
    static_assert(!std::derived_from<From&, const To&>);
 | 
						|
    static_assert(!std::derived_from<From&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<From&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<From&, To&&>);
 | 
						|
    static_assert(!std::derived_from<From&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<From&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<From&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const From&, To&>);
 | 
						|
    static_assert(!std::derived_from<const From&, const To&>);
 | 
						|
    static_assert(!std::derived_from<const From&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<const From&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const From&, To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<volatile From&, To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, const To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<volatile From&, To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const volatile From&, To&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&, const To&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const volatile From&, To&&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&, volatile To&&>);
 | 
						|
    static_assert(
 | 
						|
        !std::derived_from<const volatile From&, const volatile To&&>);
 | 
						|
 | 
						|
    // From as rvalue references
 | 
						|
    static_assert(!std::derived_from<From&&, To&>);
 | 
						|
    static_assert(!std::derived_from<From&&, const To&>);
 | 
						|
    static_assert(!std::derived_from<From&&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<From&&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<From&&, To&&>);
 | 
						|
    static_assert(!std::derived_from<From&&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<From&&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<From&&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const From&&, To&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, const To&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const From&&, To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<const From&&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<volatile From&&, To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, const To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, volatile To&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<volatile From&&, To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, volatile To&&>);
 | 
						|
    static_assert(!std::derived_from<volatile From&&, const volatile To&&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, To&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, const To&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, volatile To&>);
 | 
						|
    static_assert(
 | 
						|
        !std::derived_from<const volatile From&&, const volatile To&>);
 | 
						|
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, To&&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, const To&&>);
 | 
						|
    static_assert(!std::derived_from<const volatile From&&, volatile To&&>);
 | 
						|
    static_assert(
 | 
						|
        !std::derived_from<const volatile From&&, const volatile To&&>);
 | 
						|
  }
 | 
						|
 | 
						|
  // From as the return type of a reference-to-function
 | 
						|
  if constexpr (!std::is_array_v<From>) {
 | 
						|
    static_assert(!std::derived_from<From (&)(), To>);
 | 
						|
    static_assert(!std::derived_from<From (&)(int), To>);
 | 
						|
  }
 | 
						|
  // To as the return type of a reference-to-function
 | 
						|
  if constexpr (!std::is_array_v<To>) {
 | 
						|
    static_assert(!std::derived_from<From, To (&)()>);
 | 
						|
    static_assert(!std::derived_from<From, To (&)(double)>);
 | 
						|
  }
 | 
						|
  // Both as the return type of a reference-to-function
 | 
						|
  if constexpr (!std::is_array_v<From> && !std::is_array_v<To>) {
 | 
						|
    static_assert(!std::derived_from<From (&)(), To (&)()>);
 | 
						|
    static_assert(!std::derived_from<From (&)(int), To (&)(double)>);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
template <typename From, typename To>
 | 
						|
constexpr void CheckDerivedFrom() {
 | 
						|
  static_assert(std::derived_from<From, To>);
 | 
						|
 | 
						|
  static_assert(std::derived_from<From, const To>);
 | 
						|
  static_assert(std::derived_from<From, volatile To>);
 | 
						|
  static_assert(std::derived_from<From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(std::derived_from<const From, const To>);
 | 
						|
  static_assert(std::derived_from<const From, volatile To>);
 | 
						|
  static_assert(std::derived_from<const From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(std::derived_from<volatile From, const To>);
 | 
						|
  static_assert(std::derived_from<volatile From, volatile To>);
 | 
						|
  static_assert(std::derived_from<volatile From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(std::derived_from<const volatile From, const To>);
 | 
						|
  static_assert(std::derived_from<const volatile From, volatile To>);
 | 
						|
  static_assert(std::derived_from<const volatile From, const volatile To>);
 | 
						|
 | 
						|
  CheckNotDerivedFromPointer<From, To>();
 | 
						|
  CheckNotDerivedFromReference<From, To>();
 | 
						|
}
 | 
						|
 | 
						|
template <typename From, typename To>
 | 
						|
constexpr void CheckNotDerivedFrom() {
 | 
						|
  static_assert(!std::derived_from<From, To>);
 | 
						|
 | 
						|
  static_assert(!std::derived_from<From, const To>);
 | 
						|
  static_assert(!std::derived_from<From, volatile To>);
 | 
						|
  static_assert(!std::derived_from<From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(!std::derived_from<const From, const To>);
 | 
						|
  static_assert(!std::derived_from<const From, volatile To>);
 | 
						|
  static_assert(!std::derived_from<const From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(!std::derived_from<volatile From, const To>);
 | 
						|
  static_assert(!std::derived_from<volatile From, volatile To>);
 | 
						|
  static_assert(!std::derived_from<volatile From, const volatile To>);
 | 
						|
 | 
						|
  static_assert(!std::derived_from<const volatile From, const To>);
 | 
						|
  static_assert(!std::derived_from<const volatile From, volatile To>);
 | 
						|
  static_assert(!std::derived_from<const volatile From, const volatile To>);
 | 
						|
 | 
						|
  CheckNotDerivedFromPointer<From, To>();
 | 
						|
  CheckNotDerivedFromReference<From, To>();
 | 
						|
}
 | 
						|
 | 
						|
enum Enumeration { Yes, No };
 | 
						|
enum class ScopedEnumeration : int { No, Yes };
 | 
						|
 | 
						|
int main(int, char**) {
 | 
						|
  { // Fundamentals shouldn't be derived from anything
 | 
						|
    CheckNotDerivedFrom<int, long>();
 | 
						|
    CheckNotDerivedFrom<signed char, char>();
 | 
						|
    CheckNotDerivedFrom<double, Base1>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<int, Enumeration>();
 | 
						|
    CheckNotDerivedFrom<int, ScopedEnumeration>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<void, void>();
 | 
						|
    CheckNotDerivedFrom<int, int>();
 | 
						|
  }
 | 
						|
  { // Nothing should be derived from a fundamental type
 | 
						|
    CheckNotDerivedFrom<Enumeration, int>();
 | 
						|
    CheckNotDerivedFrom<ScopedEnumeration, int>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Base1, int>();
 | 
						|
    CheckNotDerivedFrom<Base1, double>();
 | 
						|
    CheckNotDerivedFrom<Derived1, char>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, long long>();
 | 
						|
  }
 | 
						|
  { // Other built-in things shouldn't have derivations
 | 
						|
    CheckNotDerivedFrom<Enumeration, Enumeration>();
 | 
						|
    CheckNotDerivedFrom<ScopedEnumeration, ScopedEnumeration>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Enumeration, ScopedEnumeration>();
 | 
						|
    CheckNotDerivedFrom<ScopedEnumeration, Enumeration>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Base1[5], Base1>();
 | 
						|
    CheckNotDerivedFrom<Derived1[5], Base1>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Base1, Base1[5]>();
 | 
						|
    CheckNotDerivedFrom<Derived1, Base1[5]>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Base1 is the subject.
 | 
						|
    CheckDerivedFrom<Base1, Base1>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Base1, void>();
 | 
						|
    CheckNotDerivedFrom<Base1, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFrom<Base1, DerivedProtected>();
 | 
						|
    CheckNotDerivedFrom<Base1, Derived1>();
 | 
						|
    CheckNotDerivedFrom<Base1, Derived2>();
 | 
						|
    CheckNotDerivedFrom<Base1, Derived3>();
 | 
						|
    CheckNotDerivedFrom<Base1, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Derived1 is the subject.
 | 
						|
    CheckDerivedFrom<Derived1, Base1>();
 | 
						|
    CheckDerivedFrom<Derived1, Derived1>();
 | 
						|
 | 
						|
    CheckNotDerivedFromPointer<Derived1, void>();
 | 
						|
    CheckNotDerivedFrom<Derived1, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFrom<Derived1, DerivedProtected>();
 | 
						|
    CheckNotDerivedFrom<Derived1, Derived2>();
 | 
						|
    CheckNotDerivedFrom<Derived1, Derived3>();
 | 
						|
    CheckNotDerivedFrom<Derived1, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Derived2 is the subject.
 | 
						|
    CheckDerivedFrom<Derived2, Base1>();
 | 
						|
    CheckDerivedFrom<Derived2, Derived2>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Derived2, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFrom<Derived2, DerivedProtected>();
 | 
						|
    CheckNotDerivedFrom<Derived2, Derived1>();
 | 
						|
    CheckNotDerivedFrom<Derived2, Derived3>();
 | 
						|
    CheckNotDerivedFrom<Derived2, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // DerivedPrivate is the subject.
 | 
						|
    CheckDerivedFrom<DerivedPrivate, DerivedPrivate>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, Base1>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, DerivedProtected>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, Derived1>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, Derived2>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, Derived3>();
 | 
						|
    CheckNotDerivedFrom<DerivedPrivate, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Derived3 is the subject.
 | 
						|
    CheckDerivedFrom<Derived3, DerivedPrivate>();
 | 
						|
    CheckDerivedFrom<Derived3, Derived3>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Derived3, Base1>();
 | 
						|
    CheckNotDerivedFrom<Derived3, DerivedProtected>();
 | 
						|
    CheckNotDerivedFrom<Derived3, Derived1>();
 | 
						|
    CheckNotDerivedFrom<Derived3, Derived2>();
 | 
						|
    CheckNotDerivedFrom<Derived3, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // DerivedProtected is the subject.
 | 
						|
    CheckDerivedFrom<DerivedProtected, DerivedProtected>();
 | 
						|
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, Base1>();
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, Derived1>();
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, Derived2>();
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, Derived3>();
 | 
						|
    CheckNotDerivedFromPointer<DerivedProtected, Derived4>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Derived4 is the subject.
 | 
						|
    CheckDerivedFrom<Derived4, DerivedProtected>();
 | 
						|
    CheckDerivedFrom<Derived4, Derived4>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Derived4, Base1>();
 | 
						|
    CheckNotDerivedFrom<Derived4, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFrom<Derived4, Derived1>();
 | 
						|
    CheckNotDerivedFrom<Derived4, Derived2>();
 | 
						|
    CheckNotDerivedFrom<Derived4, Derived3>();
 | 
						|
  }
 | 
						|
 | 
						|
  { // Derived5 is the subject.
 | 
						|
    CheckDerivedFrom<Derived5, DerivedProtected>();
 | 
						|
    CheckDerivedFrom<Derived5, Derived4>();
 | 
						|
    CheckDerivedFrom<Derived5, Derived5>();
 | 
						|
 | 
						|
    CheckNotDerivedFrom<Derived5, Base1>();
 | 
						|
    CheckNotDerivedFrom<Derived5, DerivedPrivate>();
 | 
						|
    CheckNotDerivedFrom<Derived5, Derived1>();
 | 
						|
    CheckNotDerivedFrom<Derived5, Derived2>();
 | 
						|
    CheckNotDerivedFrom<Derived5, Derived3>();
 | 
						|
  }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 |