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_convertible |
12 | |
13 | #include <type_traits> |
14 | #include "test_macros.h" |
15 | |
16 | template <class T, class U> |
17 | void test_is_convertible() |
18 | { |
19 | static_assert((std::is_convertible<T, U>::value), "" ); |
20 | static_assert((std::is_convertible<const T, U>::value), "" ); |
21 | static_assert((std::is_convertible<T, const U>::value), "" ); |
22 | static_assert((std::is_convertible<const T, const U>::value), "" ); |
23 | #if TEST_STD_VER > 14 |
24 | static_assert((std::is_convertible_v<T, U>), "" ); |
25 | static_assert((std::is_convertible_v<const T, U>), "" ); |
26 | static_assert((std::is_convertible_v<T, const U>), "" ); |
27 | static_assert((std::is_convertible_v<const T, const U>), "" ); |
28 | #endif |
29 | } |
30 | |
31 | template <class T, class U> |
32 | void test_is_not_convertible() |
33 | { |
34 | static_assert((!std::is_convertible<T, U>::value), "" ); |
35 | static_assert((!std::is_convertible<const T, U>::value), "" ); |
36 | static_assert((!std::is_convertible<T, const U>::value), "" ); |
37 | static_assert((!std::is_convertible<const T, const U>::value), "" ); |
38 | #if TEST_STD_VER > 14 |
39 | static_assert((!std::is_convertible_v<T, U>), "" ); |
40 | static_assert((!std::is_convertible_v<const T, U>), "" ); |
41 | static_assert((!std::is_convertible_v<T, const U>), "" ); |
42 | static_assert((!std::is_convertible_v<const T, const U>), "" ); |
43 | #endif |
44 | } |
45 | |
46 | typedef void Function(); |
47 | typedef void ConstFunction() const; |
48 | typedef char Array[1]; |
49 | |
50 | struct StringType { |
51 | StringType(const char*) {} |
52 | }; |
53 | |
54 | class NonCopyable { |
55 | NonCopyable(NonCopyable&); |
56 | }; |
57 | |
58 | template <typename T> |
59 | class CannotInstantiate { |
60 | enum { X = T::ThisExpressionWillBlowUp }; |
61 | }; |
62 | |
63 | struct abstract { virtual int f() = 0; }; |
64 | |
65 | int main(int, char**) |
66 | { |
67 | // void |
68 | test_is_convertible<void,void> (); |
69 | test_is_not_convertible<void,Function> (); |
70 | test_is_not_convertible<void,Function&> (); |
71 | test_is_not_convertible<void,Function*> (); |
72 | test_is_not_convertible<void,Array> (); |
73 | test_is_not_convertible<void,Array&> (); |
74 | test_is_not_convertible<void,char> (); |
75 | test_is_not_convertible<void,char&> (); |
76 | test_is_not_convertible<void,char*> (); |
77 | test_is_not_convertible<char, void>(); |
78 | |
79 | // Function |
80 | test_is_not_convertible<Function, void> (); |
81 | test_is_not_convertible<Function, Function> (); |
82 | test_is_convertible<Function, Function&> (); |
83 | test_is_convertible<Function, Function*> (); |
84 | test_is_convertible<Function, Function*const> (); |
85 | |
86 | static_assert(( std::is_convertible<Function, Function&&>::value), "" ); |
87 | |
88 | test_is_not_convertible<Function, Array> (); |
89 | test_is_not_convertible<Function, Array&> (); |
90 | test_is_not_convertible<Function, char> (); |
91 | test_is_not_convertible<Function, char&> (); |
92 | test_is_not_convertible<Function, char*> (); |
93 | |
94 | // Function& |
95 | test_is_not_convertible<Function&, void> (); |
96 | test_is_not_convertible<Function&, Function> (); |
97 | test_is_convertible<Function&, Function&> (); |
98 | |
99 | test_is_convertible<Function&, Function*> (); |
100 | test_is_not_convertible<Function&, Array> (); |
101 | test_is_not_convertible<Function&, Array&> (); |
102 | test_is_not_convertible<Function&, char> (); |
103 | test_is_not_convertible<Function&, char&> (); |
104 | test_is_not_convertible<Function&, char*> (); |
105 | |
106 | // Function* |
107 | test_is_not_convertible<Function*, void> (); |
108 | test_is_not_convertible<Function*, Function> (); |
109 | test_is_not_convertible<Function*, Function&> (); |
110 | test_is_convertible<Function*, Function*> (); |
111 | |
112 | test_is_not_convertible<Function*, Array> (); |
113 | test_is_not_convertible<Function*, Array&> (); |
114 | test_is_not_convertible<Function*, char> (); |
115 | test_is_not_convertible<Function*, char&> (); |
116 | test_is_not_convertible<Function*, char*> (); |
117 | |
118 | // Non-referencable function type |
119 | static_assert((!std::is_convertible<ConstFunction, Function>::value), "" ); |
120 | // TODO(LLVM-19): Re-enable this once we switch to GCC 14. This is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109680 |
121 | #ifndef TEST_COMPILER_GCC |
122 | static_assert((!std::is_convertible<ConstFunction, Function*>::value), "" ); |
123 | static_assert((!std::is_convertible<ConstFunction, Function&>::value), "" ); |
124 | static_assert((!std::is_convertible<ConstFunction, Function&&>::value), "" ); |
125 | #endif |
126 | static_assert((!std::is_convertible<Function*, ConstFunction>::value), "" ); |
127 | static_assert((!std::is_convertible<Function&, ConstFunction>::value), "" ); |
128 | static_assert((!std::is_convertible<ConstFunction, ConstFunction>::value), "" ); |
129 | static_assert((!std::is_convertible<ConstFunction, void>::value), "" ); |
130 | |
131 | // Array |
132 | test_is_not_convertible<Array, void> (); |
133 | test_is_not_convertible<Array, Function> (); |
134 | test_is_not_convertible<Array, Function&> (); |
135 | test_is_not_convertible<Array, Function*> (); |
136 | test_is_not_convertible<Array, Array> (); |
137 | |
138 | static_assert((!std::is_convertible<Array, Array&>::value), "" ); |
139 | static_assert(( std::is_convertible<Array, const Array&>::value), "" ); |
140 | static_assert((!std::is_convertible<Array, const volatile Array&>::value), "" ); |
141 | |
142 | static_assert((!std::is_convertible<const Array, Array&>::value), "" ); |
143 | static_assert(( std::is_convertible<const Array, const Array&>::value), "" ); |
144 | static_assert((!std::is_convertible<Array, volatile Array&>::value), "" ); |
145 | static_assert((!std::is_convertible<Array, const volatile Array&>::value), "" ); |
146 | |
147 | static_assert(( std::is_convertible<Array, Array&&>::value), "" ); |
148 | static_assert(( std::is_convertible<Array, const Array&&>::value), "" ); |
149 | static_assert(( std::is_convertible<Array, volatile Array&&>::value), "" ); |
150 | static_assert(( std::is_convertible<Array, const volatile Array&&>::value), "" ); |
151 | static_assert(( std::is_convertible<const Array, const Array&&>::value), "" ); |
152 | static_assert((!std::is_convertible<Array&, Array&&>::value), "" ); |
153 | static_assert((!std::is_convertible<Array&&, Array&>::value), "" ); |
154 | |
155 | test_is_not_convertible<Array, char> (); |
156 | test_is_not_convertible<Array, char&> (); |
157 | |
158 | static_assert(( std::is_convertible<Array, char*>::value), "" ); |
159 | static_assert(( std::is_convertible<Array, const char*>::value), "" ); |
160 | static_assert(( std::is_convertible<Array, char* const>::value), "" ); |
161 | static_assert(( std::is_convertible<Array, char* const volatile>::value), "" ); |
162 | |
163 | static_assert((!std::is_convertible<const Array, char*>::value), "" ); |
164 | static_assert(( std::is_convertible<const Array, const char*>::value), "" ); |
165 | |
166 | static_assert((!std::is_convertible<char[42][42], char*>::value), "" ); |
167 | static_assert((!std::is_convertible<char[][1], char*>::value), "" ); |
168 | |
169 | // Array& |
170 | test_is_not_convertible<Array&, void> (); |
171 | test_is_not_convertible<Array&, Function> (); |
172 | test_is_not_convertible<Array&, Function&> (); |
173 | test_is_not_convertible<Array&, Function*> (); |
174 | test_is_not_convertible<Array&, Array> (); |
175 | |
176 | static_assert(( std::is_convertible<Array&, Array&>::value), "" ); |
177 | static_assert(( std::is_convertible<Array&, const Array&>::value), "" ); |
178 | static_assert((!std::is_convertible<const Array&, Array&>::value), "" ); |
179 | static_assert(( std::is_convertible<const Array&, const Array&>::value), "" ); |
180 | |
181 | test_is_not_convertible<Array&, char> (); |
182 | test_is_not_convertible<Array&, char&> (); |
183 | |
184 | static_assert(( std::is_convertible<Array&, char*>::value), "" ); |
185 | static_assert(( std::is_convertible<Array&, const char*>::value), "" ); |
186 | static_assert((!std::is_convertible<const Array&, char*>::value), "" ); |
187 | static_assert(( std::is_convertible<const Array&, const char*>::value), "" ); |
188 | |
189 | static_assert((std::is_convertible<Array, StringType>::value), "" ); |
190 | static_assert((std::is_convertible<char(&)[], StringType>::value), "" ); |
191 | |
192 | // char |
193 | test_is_not_convertible<char, void> (); |
194 | test_is_not_convertible<char, Function> (); |
195 | test_is_not_convertible<char, Function&> (); |
196 | test_is_not_convertible<char, Function*> (); |
197 | test_is_not_convertible<char, Array> (); |
198 | test_is_not_convertible<char, Array&> (); |
199 | |
200 | test_is_convertible<char, char> (); |
201 | |
202 | static_assert((!std::is_convertible<char, char&>::value), "" ); |
203 | static_assert(( std::is_convertible<char, const char&>::value), "" ); |
204 | static_assert((!std::is_convertible<const char, char&>::value), "" ); |
205 | static_assert(( std::is_convertible<const char, const char&>::value), "" ); |
206 | |
207 | test_is_not_convertible<char, char*> (); |
208 | |
209 | // char& |
210 | test_is_not_convertible<char&, void> (); |
211 | test_is_not_convertible<char&, Function> (); |
212 | test_is_not_convertible<char&, Function&> (); |
213 | test_is_not_convertible<char&, Function*> (); |
214 | test_is_not_convertible<char&, Array> (); |
215 | test_is_not_convertible<char&, Array&> (); |
216 | |
217 | test_is_convertible<char&, char> (); |
218 | |
219 | static_assert(( std::is_convertible<char&, char&>::value), "" ); |
220 | static_assert(( std::is_convertible<char&, const char&>::value), "" ); |
221 | static_assert((!std::is_convertible<const char&, char&>::value), "" ); |
222 | static_assert(( std::is_convertible<const char&, const char&>::value), "" ); |
223 | |
224 | test_is_not_convertible<char&, char*> (); |
225 | |
226 | // char* |
227 | test_is_not_convertible<char*, void> (); |
228 | test_is_not_convertible<char*, Function> (); |
229 | test_is_not_convertible<char*, Function&> (); |
230 | test_is_not_convertible<char*, Function*> (); |
231 | test_is_not_convertible<char*, Array> (); |
232 | test_is_not_convertible<char*, Array&> (); |
233 | |
234 | test_is_not_convertible<char*, char> (); |
235 | test_is_not_convertible<char*, char&> (); |
236 | |
237 | static_assert(( std::is_convertible<char*, char*>::value), "" ); |
238 | static_assert(( std::is_convertible<char*, const char*>::value), "" ); |
239 | static_assert((!std::is_convertible<const char*, char*>::value), "" ); |
240 | static_assert(( std::is_convertible<const char*, const char*>::value), "" ); |
241 | |
242 | // NonCopyable |
243 | static_assert((std::is_convertible<NonCopyable&, NonCopyable&>::value), "" ); |
244 | static_assert((std::is_convertible<NonCopyable&, const NonCopyable&>::value), "" ); |
245 | static_assert((std::is_convertible<NonCopyable&, const volatile NonCopyable&>::value), "" ); |
246 | static_assert((std::is_convertible<NonCopyable&, volatile NonCopyable&>::value), "" ); |
247 | static_assert((std::is_convertible<const NonCopyable&, const NonCopyable&>::value), "" ); |
248 | static_assert((std::is_convertible<const NonCopyable&, const volatile NonCopyable&>::value), "" ); |
249 | static_assert((std::is_convertible<volatile NonCopyable&, const volatile NonCopyable&>::value), "" ); |
250 | static_assert((std::is_convertible<const volatile NonCopyable&, const volatile NonCopyable&>::value), "" ); |
251 | static_assert((!std::is_convertible<const NonCopyable&, NonCopyable&>::value), "" ); |
252 | |
253 | // This test requires Access control SFINAE which we only have in C++11 or when |
254 | // we are using the compiler builtin for is_convertible. |
255 | test_is_not_convertible<NonCopyable&, NonCopyable>(); |
256 | |
257 | |
258 | // Ensure that CannotInstantiate is not instantiated by is_convertible when it is not needed. |
259 | // For example CannotInstantiate is instantiated as a part of ADL lookup for arguments of type CannotInstantiate*. |
260 | static_assert((std::is_convertible<CannotInstantiate<int>*, CannotInstantiate<int>*>::value), "" ); |
261 | |
262 | // Test for PR13592 |
263 | static_assert(!std::is_convertible<abstract, abstract>::value, "" ); |
264 | |
265 | return 0; |
266 | } |
267 | |