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, c++20, c++23
11 // These compilers don't support __builtin_is_virtual_base_of yet.
12 // UNSUPPORTED: clang-17, clang-18, clang-19, gcc-14, apple-clang-16, apple-clang-17
16 // std::is_virtual_base_of
18 #include <type_traits>
21 template <bool expected
, class Base
, class Derived
>
23 // Test the type of the variables
25 static_assert(std::is_same_v
<bool const, decltype(std::is_virtual_base_of
<Base
, Derived
>::value
)>);
26 static_assert(std::is_same_v
<bool const, decltype(std::is_virtual_base_of_v
<Base
, Derived
>)>);
31 static_assert(std::is_virtual_base_of
<Base
, Derived
>::value
== expected
);
32 static_assert(std::is_virtual_base_of
<const Base
, Derived
>::value
== expected
);
33 static_assert(std::is_virtual_base_of
<Base
, const Derived
>::value
== expected
);
34 static_assert(std::is_virtual_base_of
<const Base
, const Derived
>::value
== expected
);
36 static_assert(std::is_virtual_base_of_v
<Base
, Derived
> == expected
);
37 static_assert(std::is_virtual_base_of_v
<const Base
, Derived
> == expected
);
38 static_assert(std::is_virtual_base_of_v
<Base
, const Derived
> == expected
);
39 static_assert(std::is_virtual_base_of_v
<const Base
, const Derived
> == expected
);
42 // Check the relationship with is_base_of. If it's not a base of, it can't be a virtual base of.
43 { static_assert(!std::is_base_of_v
<Base
, Derived
> ? !std::is_virtual_base_of_v
<Base
, Derived
> : true); }
45 // Make sure they can be referenced at runtime
47 bool const& a
= std::is_virtual_base_of
<Base
, Derived
>::value
;
48 bool const& b
= std::is_virtual_base_of_v
<Base
, Derived
>;
49 assert(a
== expected
);
50 assert(b
== expected
);
56 union IncompleteUnion
;
63 class Derived
: Base
{};
64 class Derived2
: Base
{};
65 class Derived2a
: Derived
{};
66 class Derived2b
: Derived
{};
67 class Derived3Virtual
: virtual Derived2a
, virtual Derived2b
{};
69 struct DerivedTransitiveViaNonVirtual
: Derived3Virtual
{};
70 struct DerivedTransitiveViaVirtual
: virtual Derived3Virtual
{};
73 struct CrazyDerived
: T
{};
75 struct CrazyDerivedVirtual
: virtual T
{};
77 struct DerivedPrivate
: private virtual Base
{};
78 struct DerivedProtected
: protected virtual Base
{};
79 struct DerivedPrivatePrivate
: private DerivedPrivate
{};
80 struct DerivedPrivateProtected
: private DerivedProtected
{};
81 struct DerivedProtectedPrivate
: protected DerivedProtected
{};
82 struct DerivedProtectedProtected
: protected DerivedProtected
{};
83 struct DerivedTransitivePrivate
: private Derived
, private Derived2
{};
85 int main(int, char**) {
86 // Test with non-virtual inheritance
88 test
<false, Base
, Base
>();
89 test
<false, Base
, Derived
>();
90 test
<false, Base
, Derived2
>();
91 test
<false, Derived
, DerivedTransitivePrivate
>();
92 test
<false, Derived
, Base
>();
93 test
<false, Incomplete
, Derived
>();
95 // Derived must be a complete type if Base and Derived are non-union class types
96 // test<false, Base, Incomplete>();
99 // Test with virtual inheritance
101 test
<false, Base
, Derived3Virtual
>();
102 test
<false, Derived
, Derived3Virtual
>();
103 test
<true, Derived2b
, Derived3Virtual
>();
104 test
<true, Derived2a
, Derived3Virtual
>();
105 test
<true, Base
, DerivedPrivate
>();
106 test
<true, Base
, DerivedProtected
>();
107 test
<true, Base
, DerivedPrivatePrivate
>();
108 test
<true, Base
, DerivedPrivateProtected
>();
109 test
<true, Base
, DerivedProtectedPrivate
>();
110 test
<true, Base
, DerivedProtectedProtected
>();
111 test
<true, Derived2a
, DerivedTransitiveViaNonVirtual
>();
112 test
<true, Derived2b
, DerivedTransitiveViaNonVirtual
>();
113 test
<true, Derived2a
, DerivedTransitiveViaVirtual
>();
114 test
<true, Derived2b
, DerivedTransitiveViaVirtual
>();
115 test
<false, Base
, CrazyDerived
<Base
>>();
116 test
<false, CrazyDerived
<Base
>, Base
>();
117 test
<true, Base
, CrazyDerivedVirtual
<Base
>>();
118 test
<false, CrazyDerivedVirtual
<Base
>, Base
>();
121 // Test unrelated types
123 test
<false, Base
&, Derived
&>();
124 test
<false, Base
[3], Derived
[3]>();
125 test
<false, Unrelated
, Derived
>();
126 test
<false, Base
, Unrelated
>();
127 test
<false, Base
, void>();
128 test
<false, void, Derived
>();
133 test
<false, int, Base
>();
134 test
<false, int, Derived
>();
135 test
<false, int, Incomplete
>();
136 test
<false, int, int>();
138 test
<false, Base
, int>();
139 test
<false, Derived
, int>();
140 test
<false, Incomplete
, int>();
142 test
<false, int[], int[]>();
143 test
<false, long, int>();
144 test
<false, int, long>();
149 test
<false, Union
, Union
>();
150 test
<false, IncompleteUnion
, IncompleteUnion
>();
151 test
<false, Union
, IncompleteUnion
>();
152 test
<false, IncompleteUnion
, Union
>();
153 test
<false, Incomplete
, IncompleteUnion
>();
154 test
<false, IncompleteUnion
, Incomplete
>();
155 test
<false, Unrelated
, IncompleteUnion
>();
156 test
<false, IncompleteUnion
, Unrelated
>();
157 test
<false, int, IncompleteUnion
>();
158 test
<false, IncompleteUnion
, int>();
159 test
<false, Unrelated
, Union
>();
160 test
<false, Union
, Unrelated
>();
161 test
<false, int, Unrelated
>();
162 test
<false, Union
, int>();