No bug, Manual HPKP preload list update. a=hpkp-update
[gecko.git] / mfbt / tests / TestTypeTraits.cpp
blob5ecdf9c1f385aebd2849b89ddbec7b81c26f60bc
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Assertions.h"
8 #include "mozilla/TypeTraits.h"
10 using mozilla::AddLvalueReference;
11 using mozilla::IsArray;
12 using mozilla::IsBaseOf;
13 using mozilla::IsClass;
14 using mozilla::IsConvertible;
15 using mozilla::IsEmpty;
16 using mozilla::IsLvalueReference;
17 using mozilla::IsReference;
18 using mozilla::IsRvalueReference;
19 using mozilla::IsSame;
20 using mozilla::IsSigned;
21 using mozilla::IsUnsigned;
22 using mozilla::MakeSigned;
23 using mozilla::MakeUnsigned;
24 using mozilla::RemoveExtent;
26 static_assert(!IsArray<bool>::value,
27 "bool not an array");
28 static_assert(IsArray<bool[]>::value,
29 "bool[] is an array");
30 static_assert(IsArray<bool[5]>::value,
31 "bool[5] is an array");
33 static_assert(!IsLvalueReference<bool>::value,
34 "bool not an lvalue reference");
35 static_assert(!IsLvalueReference<bool*>::value,
36 "bool* not an lvalue reference");
37 static_assert(IsLvalueReference<bool&>::value,
38 "bool& is an lvalue reference");
39 static_assert(!IsLvalueReference<bool&&>::value,
40 "bool&& not an lvalue reference");
42 static_assert(!IsLvalueReference<void>::value,
43 "void not an lvalue reference");
44 static_assert(!IsLvalueReference<void*>::value,
45 "void* not an lvalue reference");
47 static_assert(!IsLvalueReference<int>::value,
48 "int not an lvalue reference");
49 static_assert(!IsLvalueReference<int*>::value,
50 "int* not an lvalue reference");
51 static_assert(IsLvalueReference<int&>::value,
52 "int& is an lvalue reference");
53 static_assert(!IsLvalueReference<int&&>::value,
54 "int&& not an lvalue reference");
56 static_assert(!IsRvalueReference<bool>::value,
57 "bool not an rvalue reference");
58 static_assert(!IsRvalueReference<bool*>::value,
59 "bool* not an rvalue reference");
60 static_assert(!IsRvalueReference<bool&>::value,
61 "bool& not an rvalue reference");
62 static_assert(IsRvalueReference<bool&&>::value,
63 "bool&& is an rvalue reference");
65 static_assert(!IsRvalueReference<void>::value,
66 "void not an rvalue reference");
67 static_assert(!IsRvalueReference<void*>::value,
68 "void* not an rvalue reference");
70 static_assert(!IsRvalueReference<int>::value,
71 "int not an rvalue reference");
72 static_assert(!IsRvalueReference<int*>::value,
73 "int* not an rvalue reference");
74 static_assert(!IsRvalueReference<int&>::value,
75 "int& not an rvalue reference");
76 static_assert(IsRvalueReference<int&&>::value,
77 "int&& is an rvalue reference");
79 static_assert(!IsReference<bool>::value,
80 "bool not a reference");
81 static_assert(!IsReference<bool*>::value,
82 "bool* not a reference");
83 static_assert(IsReference<bool&>::value,
84 "bool& is a reference");
85 static_assert(IsReference<bool&&>::value,
86 "bool&& is a reference");
88 static_assert(!IsReference<void>::value,
89 "void not a reference");
90 static_assert(!IsReference<void*>::value,
91 "void* not a reference");
93 static_assert(!IsReference<int>::value,
94 "int not a reference");
95 static_assert(!IsReference<int*>::value,
96 "int* not a reference");
97 static_assert(IsReference<int&>::value,
98 "int& is a reference");
99 static_assert(IsReference<int&&>::value,
100 "int&& is a reference");
102 struct S1 {};
103 union U1 { int mX; };
105 static_assert(!IsClass<int>::value,
106 "int isn't a class");
107 static_assert(IsClass<const S1>::value,
108 "S is a class");
109 static_assert(!IsClass<U1>::value,
110 "U isn't a class");
112 static_assert(!mozilla::IsEmpty<int>::value,
113 "not a class => not empty");
114 static_assert(!mozilla::IsEmpty<bool[5]>::value,
115 "not a class => not empty");
117 static_assert(!mozilla::IsEmpty<U1>::value,
118 "not a class => not empty");
120 struct E1 {};
121 struct E2 { int : 0; };
122 struct E3 : E1 {};
123 struct E4 : E2 {};
125 static_assert(IsEmpty<const volatile S1>::value,
126 "S should be empty");
128 static_assert(mozilla::IsEmpty<E1>::value &&
129 mozilla::IsEmpty<E2>::value &&
130 mozilla::IsEmpty<E3>::value &&
131 mozilla::IsEmpty<E4>::value,
132 "all empty");
134 union U2 { E1 e1; };
135 static_assert(!mozilla::IsEmpty<U2>::value,
136 "not a class => not empty");
138 struct NE1 { int mX; };
139 struct NE2 : virtual E1 {};
140 struct NE3 : E2 { virtual ~NE3() {} };
141 struct NE4 { virtual void f() {} };
143 static_assert(!mozilla::IsEmpty<NE1>::value &&
144 !mozilla::IsEmpty<NE2>::value &&
145 !mozilla::IsEmpty<NE3>::value &&
146 !mozilla::IsEmpty<NE4>::value,
147 "all empty");
149 static_assert(!IsSigned<bool>::value,
150 "bool shouldn't be signed");
151 static_assert(IsUnsigned<bool>::value,
152 "bool should be unsigned");
154 static_assert(!IsSigned<const bool>::value,
155 "const bool shouldn't be signed");
156 static_assert(IsUnsigned<const bool>::value,
157 "const bool should be unsigned");
159 static_assert(!IsSigned<volatile bool>::value,
160 "volatile bool shouldn't be signed");
161 static_assert(IsUnsigned<volatile bool>::value,
162 "volatile bool should be unsigned");
164 static_assert(!IsSigned<unsigned char>::value,
165 "unsigned char shouldn't be signed");
166 static_assert(IsUnsigned<unsigned char>::value,
167 "unsigned char should be unsigned");
168 static_assert(IsSigned<signed char>::value,
169 "signed char should be signed");
170 static_assert(!IsUnsigned<signed char>::value,
171 "signed char shouldn't be unsigned");
173 static_assert(!IsSigned<unsigned short>::value,
174 "unsigned short shouldn't be signed");
175 static_assert(IsUnsigned<unsigned short>::value,
176 "unsigned short should be unsigned");
177 static_assert(IsSigned<short>::value,
178 "short should be signed");
179 static_assert(!IsUnsigned<short>::value,
180 "short shouldn't be unsigned");
182 static_assert(!IsSigned<unsigned int>::value,
183 "unsigned int shouldn't be signed");
184 static_assert(IsUnsigned<unsigned int>::value,
185 "unsigned int should be unsigned");
186 static_assert(IsSigned<int>::value,
187 "int should be signed");
188 static_assert(!IsUnsigned<int>::value,
189 "int shouldn't be unsigned");
191 static_assert(!IsSigned<unsigned long>::value,
192 "unsigned long shouldn't be signed");
193 static_assert(IsUnsigned<unsigned long>::value,
194 "unsigned long should be unsigned");
195 static_assert(IsSigned<long>::value,
196 "long should be signed");
197 static_assert(!IsUnsigned<long>::value,
198 "long shouldn't be unsigned");
200 static_assert(IsSigned<float>::value,
201 "float should be signed");
202 static_assert(!IsUnsigned<float>::value,
203 "float shouldn't be unsigned");
205 static_assert(IsSigned<const float>::value,
206 "const float should be signed");
207 static_assert(!IsUnsigned<const float>::value,
208 "const float shouldn't be unsigned");
210 static_assert(IsSigned<double>::value,
211 "double should be signed");
212 static_assert(!IsUnsigned<double>::value,
213 "double shouldn't be unsigned");
215 static_assert(IsSigned<volatile double>::value,
216 "volatile double should be signed");
217 static_assert(!IsUnsigned<volatile double>::value,
218 "volatile double shouldn't be unsigned");
220 static_assert(IsSigned<long double>::value,
221 "long double should be signed");
222 static_assert(!IsUnsigned<long double>::value,
223 "long double shouldn't be unsigned");
225 static_assert(IsSigned<const volatile long double>::value,
226 "const volatile long double should be signed");
227 static_assert(!IsUnsigned<const volatile long double>::value,
228 "const volatile long double shouldn't be unsigned");
230 class NotIntConstructible
232 NotIntConstructible(int) MOZ_DELETE;
235 static_assert(!IsSigned<NotIntConstructible>::value,
236 "non-arithmetic types are not signed");
237 static_assert(!IsUnsigned<NotIntConstructible>::value,
238 "non-arithmetic types are not unsigned");
240 namespace CPlusPlus11IsBaseOf {
242 // Adapted from C++11 ยง 20.9.6.
243 struct B {};
244 struct B1 : B {};
245 struct B2 : B {};
246 struct D : private B1, private B2 {};
248 static void
249 StandardIsBaseOfTests()
251 static_assert((IsBaseOf<B, D>::value) == true,
252 "IsBaseOf fails on diamond");
253 static_assert((IsBaseOf<const B, D>::value) == true,
254 "IsBaseOf fails on diamond plus constness change");
255 static_assert((IsBaseOf<B, const D>::value) == true,
256 "IsBaseOf fails on diamond plus constness change");
257 static_assert((IsBaseOf<B, const B>::value) == true,
258 "IsBaseOf fails on constness change");
259 static_assert((IsBaseOf<D, B>::value) == false,
260 "IsBaseOf got the direction of inheritance wrong");
261 static_assert((IsBaseOf<B&, D&>::value) == false,
262 "IsBaseOf should return false on references");
263 static_assert((IsBaseOf<B[3], D[3]>::value) == false,
264 "IsBaseOf should return false on arrays");
265 // We fail at the following test. To fix it, we need to specialize IsBaseOf
266 // for all built-in types.
267 // static_assert((IsBaseOf<int, int>::value) == false);
270 } /* namespace CPlusPlus11IsBaseOf */
272 class A { };
273 class B : public A { };
274 class C : private A { };
275 class D { };
276 class E : public A { };
277 class F : public B, public E { };
279 static void
280 TestIsBaseOf()
282 static_assert((IsBaseOf<A, B>::value),
283 "A is a base of B");
284 static_assert((!IsBaseOf<B, A>::value),
285 "B is not a base of A");
286 static_assert((IsBaseOf<A, C>::value),
287 "A is a base of C");
288 static_assert((!IsBaseOf<C, A>::value),
289 "C is not a base of A");
290 static_assert((IsBaseOf<A, F>::value),
291 "A is a base of F");
292 static_assert((!IsBaseOf<F, A>::value),
293 "F is not a base of A");
294 static_assert((!IsBaseOf<A, D>::value),
295 "A is not a base of D");
296 static_assert((!IsBaseOf<D, A>::value),
297 "D is not a base of A");
298 static_assert((IsBaseOf<B, B>::value),
299 "B is the same as B (and therefore, a base of B)");
302 static void
303 TestIsConvertible()
305 // Pointer type convertibility
306 static_assert((IsConvertible<A*, A*>::value),
307 "A* should convert to A*");
308 static_assert((IsConvertible<B*, A*>::value),
309 "B* should convert to A*");
310 static_assert((!IsConvertible<A*, B*>::value),
311 "A* shouldn't convert to B*");
312 static_assert((!IsConvertible<A*, C*>::value),
313 "A* shouldn't convert to C*");
314 static_assert((!IsConvertible<A*, D*>::value),
315 "A* shouldn't convert to unrelated D*");
316 static_assert((!IsConvertible<D*, A*>::value),
317 "D* shouldn't convert to unrelated A*");
319 // Instance type convertibility
320 static_assert((IsConvertible<A, A>::value),
321 "A is A");
322 static_assert((IsConvertible<B, A>::value),
323 "B converts to A");
324 static_assert((!IsConvertible<D, A>::value),
325 "D and A are unrelated");
326 static_assert((!IsConvertible<A, D>::value),
327 "A and D are unrelated");
329 // These cases seem to require C++11 support to properly implement them, so
330 // for now just disable them.
331 //static_assert((!IsConvertible<C*, A*>::value),
332 // "C* shouldn't convert to A* (private inheritance)");
333 //static_assert((!IsConvertible<C, A>::value),
334 // "C doesn't convert to A (private inheritance)");
337 static_assert(IsSame<AddLvalueReference<int>::Type, int&>::value,
338 "not adding & to int correctly");
339 static_assert(IsSame<AddLvalueReference<volatile int&>::Type, volatile int&>::value,
340 "not adding & to volatile int& correctly");
341 static_assert(IsSame<AddLvalueReference<void*>::Type, void*&>::value,
342 "not adding & to void* correctly");
343 static_assert(IsSame<AddLvalueReference<void>::Type, void>::value,
344 "void shouldn't be transformed by AddLvalueReference");
345 static_assert(IsSame<AddLvalueReference<struct S1&&>::Type, struct S1&>::value,
346 "not reference-collapsing struct S1&& & to struct S1& correctly");
348 static_assert(IsSame<MakeSigned<const unsigned char>::Type, const signed char>::value,
349 "const unsigned char won't signify correctly");
350 static_assert(IsSame<MakeSigned<volatile unsigned short>::Type, volatile signed short>::value,
351 "volatile unsigned short won't signify correctly");
352 static_assert(IsSame<MakeSigned<const volatile unsigned int>::Type, const volatile signed int>::value,
353 "const volatile unsigned int won't signify correctly");
354 static_assert(IsSame<MakeSigned<unsigned long>::Type, signed long>::value,
355 "unsigned long won't signify correctly");
356 static_assert(IsSame<MakeSigned<const signed char>::Type, const signed char>::value,
357 "const signed char won't signify correctly");
359 static_assert(IsSame<MakeSigned<volatile signed short>::Type, volatile signed short>::value,
360 "volatile signed short won't signify correctly");
361 static_assert(IsSame<MakeSigned<const volatile signed int>::Type, const volatile signed int>::value,
362 "const volatile signed int won't signify correctly");
363 static_assert(IsSame<MakeSigned<signed long>::Type, signed long>::value,
364 "signed long won't signify correctly");
366 static_assert(IsSame<MakeSigned<char>::Type, signed char>::value,
367 "char won't signify correctly");
368 static_assert(IsSame<MakeSigned<volatile char>::Type, volatile signed char>::value,
369 "volatile char won't signify correctly");
370 static_assert(IsSame<MakeSigned<const char>::Type, const signed char>::value,
371 "const char won't signify correctly");
373 static_assert(IsSame<MakeUnsigned<const signed char>::Type, const unsigned char>::value,
374 "const signed char won't unsignify correctly");
375 static_assert(IsSame<MakeUnsigned<volatile signed short>::Type, volatile unsigned short>::value,
376 "volatile signed short won't unsignify correctly");
377 static_assert(IsSame<MakeUnsigned<const volatile signed int>::Type, const volatile unsigned int>::value,
378 "const volatile signed int won't unsignify correctly");
379 static_assert(IsSame<MakeUnsigned<signed long>::Type, unsigned long>::value,
380 "signed long won't unsignify correctly");
382 static_assert(IsSame<MakeUnsigned<const unsigned char>::Type, const unsigned char>::value,
383 "const unsigned char won't unsignify correctly");
385 static_assert(IsSame<MakeUnsigned<volatile unsigned short>::Type, volatile unsigned short>::value,
386 "volatile unsigned short won't unsignify correctly");
387 static_assert(IsSame<MakeUnsigned<const volatile unsigned int>::Type, const volatile unsigned int>::value,
388 "const volatile unsigned int won't unsignify correctly");
389 static_assert(IsSame<MakeUnsigned<unsigned long>::Type, unsigned long>::value,
390 "signed long won't unsignify correctly");
392 static_assert(IsSame<MakeUnsigned<char>::Type, unsigned char>::value,
393 "char won't unsignify correctly");
394 static_assert(IsSame<MakeUnsigned<volatile char>::Type, volatile unsigned char>::value,
395 "volatile char won't unsignify correctly");
396 static_assert(IsSame<MakeUnsigned<const char>::Type, const unsigned char>::value,
397 "const char won't unsignify correctly");
399 static_assert(IsSame<RemoveExtent<int>::Type, int>::value,
400 "removing extent from non-array must return the non-array");
401 static_assert(IsSame<RemoveExtent<const int[]>::Type, const int>::value,
402 "removing extent from unknown-bound array must return element type");
403 static_assert(IsSame<RemoveExtent<volatile int[5]>::Type, volatile int>::value,
404 "removing extent from known-bound array must return element type");
405 static_assert(IsSame<RemoveExtent<long[][17]>::Type, long[17]>::value,
406 "removing extent from multidimensional array must return element type");
409 * Android's broken [u]intptr_t inttype macros are broken because its PRI*PTR
410 * macros are defined as "ld", but sizeof(long) is 8 and sizeof(intptr_t)
411 * is 4 on 32-bit Android. We redefine Android's PRI*PTR macros in
412 * IntegerPrintfMacros.h and assert here that our new definitions match the
413 * actual type sizes seen at compile time.
415 #if defined(ANDROID) && !defined(__LP64__)
416 static_assert(mozilla::IsSame<int, intptr_t>::value,
417 "emulated PRI[di]PTR definitions will be wrong");
418 static_assert(mozilla::IsSame<unsigned int, uintptr_t>::value,
419 "emulated PRI[ouxX]PTR definitions will be wrong");
420 #endif
423 main()
425 CPlusPlus11IsBaseOf::StandardIsBaseOfTests();
426 TestIsBaseOf();
427 TestIsConvertible();
428 return 0;