//===----------------------------------------------------------------------===// // // 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, c++20, c++23 // These compilers don't support __builtin_is_virtual_base_of yet. // UNSUPPORTED: apple-clang-17 // // std::is_virtual_base_of #include #include #include "test_macros.h" template void test() { // Test the type of the variables { static_assert(std::is_same_v::value)>); static_assert(std::is_same_v)>); } // Test their value { static_assert(std::is_virtual_base_of::value == expected); static_assert(std::is_virtual_base_of::value == expected); static_assert(std::is_virtual_base_of::value == expected); static_assert(std::is_virtual_base_of::value == expected); static_assert(std::is_virtual_base_of_v == expected); static_assert(std::is_virtual_base_of_v == expected); static_assert(std::is_virtual_base_of_v == expected); static_assert(std::is_virtual_base_of_v == expected); } // Check the relationship with is_base_of. If it's not a base of, it can't be a virtual base of. { static_assert(!std::is_base_of_v ? !std::is_virtual_base_of_v : true); } // Make sure they can be referenced at runtime { bool const& a = std::is_virtual_base_of::value; bool const& b = std::is_virtual_base_of_v; assert(a == expected); assert(b == expected); } } struct Incomplete; struct Unrelated {}; union IncompleteUnion; union Union { int i; float f; }; class Base {}; class Derived : Base {}; class Derived2 : Base {}; class Derived2a : Derived {}; class Derived2b : Derived {}; class Derived3Virtual : virtual Derived2a, virtual Derived2b {}; struct DerivedTransitiveViaNonVirtual : Derived3Virtual {}; struct DerivedTransitiveViaVirtual : virtual Derived3Virtual {}; template struct CrazyDerived : T {}; template struct CrazyDerivedVirtual : virtual T {}; struct DerivedPrivate : private virtual Base {}; struct DerivedProtected : protected virtual Base {}; struct DerivedPrivatePrivate : private DerivedPrivate {}; struct DerivedPrivateProtected : private DerivedProtected {}; struct DerivedProtectedPrivate : protected DerivedProtected {}; struct DerivedProtectedProtected : protected DerivedProtected {}; struct DerivedTransitivePrivate : private Derived, private Derived2 {}; int main(int, char**) { // Test with non-virtual inheritance { test(); test(); test(); test(); test(); test(); // Derived must be a complete type if Base and Derived are non-union class types // test(); } // Test with virtual inheritance { #ifdef TEST_COMPILER_GCC // FIXME: Is this a GCC or Clang bug? Or is the standards wording ambiguous? test(); test(); #else test(); test(); #endif test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test>(); test, Base>(); test>(); test, Base>(); } // Test unrelated types { test(); test(); test(); test(); test(); test(); } // Test scalar types { test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); } // Test unions { test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); } return 0; }