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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // type_traits
10
11 // is_destructible
12
13 // Prevent warning when testing the Abstract test type.
14 #if defined(__clang__)
15 #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor"
16 #endif
17
18 #include <type_traits>
19 #include "test_macros.h"
20
21
22 template <class T>
test_is_destructible()23 void test_is_destructible()
24 {
25 static_assert( std::is_destructible<T>::value, "");
26 static_assert( std::is_destructible<const T>::value, "");
27 static_assert( std::is_destructible<volatile T>::value, "");
28 static_assert( std::is_destructible<const volatile T>::value, "");
29 #if TEST_STD_VER > 14
30 static_assert( std::is_destructible_v<T>, "");
31 static_assert( std::is_destructible_v<const T>, "");
32 static_assert( std::is_destructible_v<volatile T>, "");
33 static_assert( std::is_destructible_v<const volatile T>, "");
34 #endif
35 }
36
37 template <class T>
test_is_not_destructible()38 void test_is_not_destructible()
39 {
40 static_assert(!std::is_destructible<T>::value, "");
41 static_assert(!std::is_destructible<const T>::value, "");
42 static_assert(!std::is_destructible<volatile T>::value, "");
43 static_assert(!std::is_destructible<const volatile T>::value, "");
44 #if TEST_STD_VER > 14
45 static_assert(!std::is_destructible_v<T>, "");
46 static_assert(!std::is_destructible_v<const T>, "");
47 static_assert(!std::is_destructible_v<volatile T>, "");
48 static_assert(!std::is_destructible_v<const volatile T>, "");
49 #endif
50 }
51
52 class Empty {};
53
54 class NotEmpty
55 {
56 virtual ~NotEmpty();
57 };
58
59 union Union {};
60
61 struct bit_zero
62 {
63 int : 0;
64 };
65
66 struct A
67 {
68 ~A();
69 };
70
71 typedef void (Function) ();
72
73 struct PublicAbstract { public: virtual void foo() = 0; };
74 struct ProtectedAbstract { protected: virtual void foo() = 0; };
75 struct PrivateAbstract { private: virtual void foo() = 0; };
76
~PublicDestructorPublicDestructor77 struct PublicDestructor { public: ~PublicDestructor() {}};
~ProtectedDestructorProtectedDestructor78 struct ProtectedDestructor { protected: ~ProtectedDestructor() {}};
~PrivateDestructorPrivateDestructor79 struct PrivateDestructor { private: ~PrivateDestructor() {}};
80
~VirtualPublicDestructorVirtualPublicDestructor81 struct VirtualPublicDestructor { public: virtual ~VirtualPublicDestructor() {}};
~VirtualProtectedDestructorVirtualProtectedDestructor82 struct VirtualProtectedDestructor { protected: virtual ~VirtualProtectedDestructor() {}};
~VirtualPrivateDestructorVirtualPrivateDestructor83 struct VirtualPrivateDestructor { private: virtual ~VirtualPrivateDestructor() {}};
84
85 struct PurePublicDestructor { public: virtual ~PurePublicDestructor() = 0; };
86 struct PureProtectedDestructor { protected: virtual ~PureProtectedDestructor() = 0; };
87 struct PurePrivateDestructor { private: virtual ~PurePrivateDestructor() = 0; };
88
89 #if TEST_STD_VER >= 11
90 struct DeletedPublicDestructor { public: ~DeletedPublicDestructor() = delete; };
91 struct DeletedProtectedDestructor { protected: ~DeletedProtectedDestructor() = delete; };
92 struct DeletedPrivateDestructor { private: ~DeletedPrivateDestructor() = delete; };
93
94 struct DeletedVirtualPublicDestructor { public: virtual ~DeletedVirtualPublicDestructor() = delete; };
95 struct DeletedVirtualProtectedDestructor { protected: virtual ~DeletedVirtualProtectedDestructor() = delete; };
96 struct DeletedVirtualPrivateDestructor { private: virtual ~DeletedVirtualPrivateDestructor() = delete; };
97 #endif
98
99
main(int,char **)100 int main(int, char**)
101 {
102 test_is_destructible<A>();
103 test_is_destructible<int&>();
104 test_is_destructible<Union>();
105 test_is_destructible<Empty>();
106 test_is_destructible<int>();
107 test_is_destructible<double>();
108 test_is_destructible<int*>();
109 test_is_destructible<const int*>();
110 test_is_destructible<char[3]>();
111 test_is_destructible<bit_zero>();
112 test_is_destructible<int[3]>();
113 test_is_destructible<ProtectedAbstract>();
114 test_is_destructible<PublicAbstract>();
115 test_is_destructible<PrivateAbstract>();
116 test_is_destructible<PublicDestructor>();
117 test_is_destructible<VirtualPublicDestructor>();
118 test_is_destructible<PurePublicDestructor>();
119
120 test_is_not_destructible<int[]>();
121 test_is_not_destructible<void>();
122 test_is_not_destructible<Function>();
123
124 #if TEST_STD_VER >= 11
125 // Test access controlled destructors
126 test_is_not_destructible<ProtectedDestructor>();
127 test_is_not_destructible<PrivateDestructor>();
128 test_is_not_destructible<VirtualProtectedDestructor>();
129 test_is_not_destructible<VirtualPrivateDestructor>();
130 test_is_not_destructible<PureProtectedDestructor>();
131 test_is_not_destructible<PurePrivateDestructor>();
132
133 // Test deleted constructors
134 test_is_not_destructible<DeletedPublicDestructor>();
135 test_is_not_destructible<DeletedProtectedDestructor>();
136 test_is_not_destructible<DeletedPrivateDestructor>();
137 //test_is_not_destructible<DeletedVirtualPublicDestructor>(); // previously failed due to clang bug #20268
138 test_is_not_destructible<DeletedVirtualProtectedDestructor>();
139 test_is_not_destructible<DeletedVirtualPrivateDestructor>();
140
141 // Test private destructors
142 test_is_not_destructible<NotEmpty>();
143 #endif
144
145
146 return 0;
147 }
148