[libcxx-commits] [libcxx] c63de22 - [libcxx] adds concept std::derived_from
Christopher Di Bella via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 10 11:30:32 PST 2021
Author: Christopher Di Bella
Date: 2021-02-10T19:30:08Z
New Revision: c63de225fdd7c7adf6ed041c0bff318d9ae75c00
URL: https://github.com/llvm/llvm-project/commit/c63de225fdd7c7adf6ed041c0bff318d9ae75c00
DIFF: https://github.com/llvm/llvm-project/commit/c63de225fdd7c7adf6ed041c0bff318d9ae75c00.diff
LOG: [libcxx] adds concept std::derived_from
Implements parts of:
- P0898R3 Standard Library Concepts
- P1754 Rename concepts to standard_case for C++20, while we still can
Reviewed By: ldionne, #libc
Differential Revision: https://reviews.llvm.org/D74292
Added:
libcxx/test/std/concepts/lang/derived.compile.pass.cpp
Modified:
libcxx/include/concepts
Removed:
################################################################################
diff --git a/libcxx/include/concepts b/libcxx/include/concepts
index b44e8ccb80bf..7c42dc87b177 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -157,6 +157,12 @@ concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value;
template<class _Tp, class _Up>
concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
+// [concept.derived]
+template<class _Dp, class _Bp>
+concept derived_from =
+ is_base_of_v<_Bp, _Dp> &&
+ is_convertible_v<const volatile _Dp*, const volatile _Bp*>;
+
// [concept.convertible]
template<class _From, class _To>
concept convertible_to =
diff --git a/libcxx/test/std/concepts/lang/derived.compile.pass.cpp b/libcxx/test/std/concepts/lang/derived.compile.pass.cpp
new file mode 100644
index 000000000000..1aca4e4df178
--- /dev/null
+++ b/libcxx/test/std/concepts/lang/derived.compile.pass.cpp
@@ -0,0 +1,498 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++98, 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;
+}
More information about the libcxx-commits
mailing list