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
,
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");
103 union U1
{ int mX
; };
105 static_assert(!IsClass
<int>::value
,
106 "int isn't a class");
107 static_assert(IsClass
<const S1
>::value
,
109 static_assert(!IsClass
<U1
>::value
,
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");
121 struct E2
{ int : 0; };
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
,
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
,
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.
246 struct D
: private B1
, private B2
{};
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 */
273 class B
: public A
{ };
274 class C
: private A
{ };
276 class E
: public A
{ };
277 class F
: public B
, public E
{ };
282 static_assert((IsBaseOf
<A
, B
>::value
),
284 static_assert((!IsBaseOf
<B
, A
>::value
),
285 "B is not a base of A");
286 static_assert((IsBaseOf
<A
, C
>::value
),
288 static_assert((!IsBaseOf
<C
, A
>::value
),
289 "C is not a base of A");
290 static_assert((IsBaseOf
<A
, F
>::value
),
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)");
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
),
322 static_assert((IsConvertible
<B
, A
>::value
),
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");
425 CPlusPlus11IsBaseOf::StandardIsBaseOfTests();