1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/tests/TestTypeTraits.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,301 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/Assertions.h" 1.10 +#include "mozilla/TypeTraits.h" 1.11 + 1.12 +using mozilla::IsArray; 1.13 +using mozilla::IsBaseOf; 1.14 +using mozilla::IsClass; 1.15 +using mozilla::IsConvertible; 1.16 +using mozilla::IsEmpty; 1.17 +using mozilla::IsLvalueReference; 1.18 +using mozilla::IsReference; 1.19 +using mozilla::IsRvalueReference; 1.20 +using mozilla::IsSame; 1.21 +using mozilla::IsSigned; 1.22 +using mozilla::IsUnsigned; 1.23 +using mozilla::MakeSigned; 1.24 +using mozilla::MakeUnsigned; 1.25 + 1.26 +static_assert(!IsArray<bool>::value, "bool not an array"); 1.27 +static_assert(IsArray<bool[]>::value, "bool[] is an array"); 1.28 +static_assert(IsArray<bool[5]>::value, "bool[5] is an array"); 1.29 + 1.30 +static_assert(!IsLvalueReference<bool>::value, "bool not an lvalue reference"); 1.31 +static_assert(!IsLvalueReference<bool*>::value, "bool* not an lvalue reference"); 1.32 +static_assert(IsLvalueReference<bool&>::value, "bool& is an lvalue reference"); 1.33 +static_assert(!IsLvalueReference<bool&&>::value, "bool&& not an lvalue reference"); 1.34 + 1.35 +static_assert(!IsLvalueReference<void>::value, "void not an lvalue reference"); 1.36 +static_assert(!IsLvalueReference<void*>::value, "void* not an lvalue reference"); 1.37 + 1.38 +static_assert(!IsLvalueReference<int>::value, "int not an lvalue reference"); 1.39 +static_assert(!IsLvalueReference<int*>::value, "int* not an lvalue reference"); 1.40 +static_assert(IsLvalueReference<int&>::value, "int& is an lvalue reference"); 1.41 +static_assert(!IsLvalueReference<int&&>::value, "int&& not an lvalue reference"); 1.42 + 1.43 +static_assert(!IsRvalueReference<bool>::value, "bool not an rvalue reference"); 1.44 +static_assert(!IsRvalueReference<bool*>::value, "bool* not an rvalue reference"); 1.45 +static_assert(!IsRvalueReference<bool&>::value, "bool& not an rvalue reference"); 1.46 +static_assert(IsRvalueReference<bool&&>::value, "bool&& is an rvalue reference"); 1.47 + 1.48 +static_assert(!IsRvalueReference<void>::value, "void not an rvalue reference"); 1.49 +static_assert(!IsRvalueReference<void*>::value, "void* not an rvalue reference"); 1.50 + 1.51 +static_assert(!IsRvalueReference<int>::value, "int not an rvalue reference"); 1.52 +static_assert(!IsRvalueReference<int*>::value, "int* not an rvalue reference"); 1.53 +static_assert(!IsRvalueReference<int&>::value, "int& not an rvalue reference"); 1.54 +static_assert(IsRvalueReference<int&&>::value, "int&& is an rvalue reference"); 1.55 + 1.56 +static_assert(!IsReference<bool>::value, "bool not a reference"); 1.57 +static_assert(!IsReference<bool*>::value, "bool* not a reference"); 1.58 +static_assert(IsReference<bool&>::value, "bool& is a reference"); 1.59 +static_assert(IsReference<bool&&>::value, "bool&& is a reference"); 1.60 + 1.61 +static_assert(!IsReference<void>::value, "void not a reference"); 1.62 +static_assert(!IsReference<void*>::value, "void* not a reference"); 1.63 + 1.64 +static_assert(!IsReference<int>::value, "int not a reference"); 1.65 +static_assert(!IsReference<int*>::value, "int* not a reference"); 1.66 +static_assert(IsReference<int&>::value, "int& is a reference"); 1.67 +static_assert(IsReference<int&&>::value, "int&& is a reference"); 1.68 + 1.69 +struct S1 {}; 1.70 +union U1 { int x; }; 1.71 + 1.72 +static_assert(!IsClass<int>::value, "int isn't a class"); 1.73 +static_assert(IsClass<const S1>::value, "S is a class"); 1.74 +static_assert(!IsClass<U1>::value, "U isn't a class"); 1.75 + 1.76 +static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty"); 1.77 +static_assert(!mozilla::IsEmpty<bool[5]>::value, "not a class => not empty"); 1.78 + 1.79 +static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty"); 1.80 + 1.81 +struct E1 {}; 1.82 +struct E2 { int : 0; }; 1.83 +struct E3 : E1 {}; 1.84 +struct E4 : E2 {}; 1.85 + 1.86 +static_assert(IsEmpty<const volatile S1>::value, "S should be empty"); 1.87 + 1.88 +static_assert(mozilla::IsEmpty<E1>::value && 1.89 + mozilla::IsEmpty<E2>::value && 1.90 + mozilla::IsEmpty<E3>::value && 1.91 + mozilla::IsEmpty<E4>::value, 1.92 + "all empty"); 1.93 + 1.94 +union U2 { E1 e1; }; 1.95 +static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty"); 1.96 + 1.97 +struct NE1 { int x; }; 1.98 +struct NE2 : virtual E1 {}; 1.99 +struct NE3 : E2 { virtual ~NE3() {} }; 1.100 +struct NE4 { virtual void f() {} }; 1.101 + 1.102 +static_assert(!mozilla::IsEmpty<NE1>::value && 1.103 + !mozilla::IsEmpty<NE2>::value && 1.104 + !mozilla::IsEmpty<NE3>::value && 1.105 + !mozilla::IsEmpty<NE4>::value, 1.106 + "all empty"); 1.107 + 1.108 +static_assert(!IsSigned<bool>::value, "bool shouldn't be signed"); 1.109 +static_assert(IsUnsigned<bool>::value, "bool should be unsigned"); 1.110 + 1.111 +static_assert(!IsSigned<const bool>::value, "const bool shouldn't be signed"); 1.112 +static_assert(IsUnsigned<const bool>::value, "const bool should be unsigned"); 1.113 + 1.114 +static_assert(!IsSigned<volatile bool>::value, "volatile bool shouldn't be signed"); 1.115 +static_assert(IsUnsigned<volatile bool>::value, "volatile bool should be unsigned"); 1.116 + 1.117 +static_assert(!IsSigned<unsigned char>::value, "unsigned char shouldn't be signed"); 1.118 +static_assert(IsUnsigned<unsigned char>::value, "unsigned char should be unsigned"); 1.119 +static_assert(IsSigned<signed char>::value, "signed char should be signed"); 1.120 +static_assert(!IsUnsigned<signed char>::value, "signed char shouldn't be unsigned"); 1.121 + 1.122 +static_assert(!IsSigned<unsigned short>::value, "unsigned short shouldn't be signed"); 1.123 +static_assert(IsUnsigned<unsigned short>::value, "unsigned short should be unsigned"); 1.124 +static_assert(IsSigned<short>::value, "short should be signed"); 1.125 +static_assert(!IsUnsigned<short>::value, "short shouldn't be unsigned"); 1.126 + 1.127 +static_assert(!IsSigned<unsigned int>::value, "unsigned int shouldn't be signed"); 1.128 +static_assert(IsUnsigned<unsigned int>::value, "unsigned int should be unsigned"); 1.129 +static_assert(IsSigned<int>::value, "int should be signed"); 1.130 +static_assert(!IsUnsigned<int>::value, "int shouldn't be unsigned"); 1.131 + 1.132 +static_assert(!IsSigned<unsigned long>::value, "unsigned long shouldn't be signed"); 1.133 +static_assert(IsUnsigned<unsigned long>::value, "unsigned long should be unsigned"); 1.134 +static_assert(IsSigned<long>::value, "long should be signed"); 1.135 +static_assert(!IsUnsigned<long>::value, "long shouldn't be unsigned"); 1.136 + 1.137 +static_assert(IsSigned<float>::value, "float should be signed"); 1.138 +static_assert(!IsUnsigned<float>::value, "float shouldn't be unsigned"); 1.139 + 1.140 +static_assert(IsSigned<const float>::value, "const float should be signed"); 1.141 +static_assert(!IsUnsigned<const float>::value, "const float shouldn't be unsigned"); 1.142 + 1.143 +static_assert(IsSigned<double>::value, "double should be signed"); 1.144 +static_assert(!IsUnsigned<double>::value, "double shouldn't be unsigned"); 1.145 + 1.146 +static_assert(IsSigned<volatile double>::value, "volatile double should be signed"); 1.147 +static_assert(!IsUnsigned<volatile double>::value, "volatile double shouldn't be unsigned"); 1.148 + 1.149 +static_assert(IsSigned<long double>::value, "long double should be signed"); 1.150 +static_assert(!IsUnsigned<long double>::value, "long double shouldn't be unsigned"); 1.151 + 1.152 +static_assert(IsSigned<const volatile long double>::value, 1.153 + "const volatile long double should be signed"); 1.154 +static_assert(!IsUnsigned<const volatile long double>::value, 1.155 + "const volatile long double shouldn't be unsigned"); 1.156 + 1.157 +namespace CPlusPlus11IsBaseOf { 1.158 + 1.159 +// Adapted from C++11 ยง 20.9.6. 1.160 +struct B {}; 1.161 +struct B1 : B {}; 1.162 +struct B2 : B {}; 1.163 +struct D : private B1, private B2 {}; 1.164 + 1.165 +static void 1.166 +StandardIsBaseOfTests() 1.167 +{ 1.168 + static_assert((IsBaseOf<B, D>::value) == true, "IsBaseOf fails on diamond"); 1.169 + static_assert((IsBaseOf<const B, D>::value) == true, "IsBaseOf fails on diamond plus constness change"); 1.170 + static_assert((IsBaseOf<B, const D>::value) == true, "IsBaseOf fails on diamond plus constness change"); 1.171 + static_assert((IsBaseOf<B, const B>::value) == true, "IsBaseOf fails on constness change"); 1.172 + static_assert((IsBaseOf<D, B>::value) == false, "IsBaseOf got the direction of inheritance wrong"); 1.173 + static_assert((IsBaseOf<B&, D&>::value) == false, "IsBaseOf should return false on references"); 1.174 + static_assert((IsBaseOf<B[3], D[3]>::value) == false, "IsBaseOf should return false on arrays"); 1.175 + // We fail at the following test. To fix it, we need to specialize IsBaseOf 1.176 + // for all built-in types. 1.177 + // static_assert((IsBaseOf<int, int>::value) == false); 1.178 +} 1.179 + 1.180 +} /* namespace CPlusPlus11IsBaseOf */ 1.181 + 1.182 +class A { }; 1.183 +class B : public A { }; 1.184 +class C : private A { }; 1.185 +class D { }; 1.186 +class E : public A { }; 1.187 +class F : public B, public E { }; 1.188 + 1.189 +static void 1.190 +TestIsBaseOf() 1.191 +{ 1.192 + static_assert((IsBaseOf<A, B>::value), 1.193 + "A is a base of B"); 1.194 + static_assert((!IsBaseOf<B, A>::value), 1.195 + "B is not a base of A"); 1.196 + static_assert((IsBaseOf<A, C>::value), 1.197 + "A is a base of C"); 1.198 + static_assert((!IsBaseOf<C, A>::value), 1.199 + "C is not a base of A"); 1.200 + static_assert((IsBaseOf<A, F>::value), 1.201 + "A is a base of F"); 1.202 + static_assert((!IsBaseOf<F, A>::value), 1.203 + "F is not a base of A"); 1.204 + static_assert((!IsBaseOf<A, D>::value), 1.205 + "A is not a base of D"); 1.206 + static_assert((!IsBaseOf<D, A>::value), 1.207 + "D is not a base of A"); 1.208 + static_assert((IsBaseOf<B, B>::value), 1.209 + "B is the same as B (and therefore, a base of B)"); 1.210 +} 1.211 + 1.212 +static void 1.213 +TestIsConvertible() 1.214 +{ 1.215 + // Pointer type convertibility 1.216 + static_assert((IsConvertible<A*, A*>::value), 1.217 + "A* should convert to A*"); 1.218 + static_assert((IsConvertible<B*, A*>::value), 1.219 + "B* should convert to A*"); 1.220 + static_assert((!IsConvertible<A*, B*>::value), 1.221 + "A* shouldn't convert to B*"); 1.222 + static_assert((!IsConvertible<A*, C*>::value), 1.223 + "A* shouldn't convert to C*"); 1.224 + static_assert((!IsConvertible<A*, D*>::value), 1.225 + "A* shouldn't convert to unrelated D*"); 1.226 + static_assert((!IsConvertible<D*, A*>::value), 1.227 + "D* shouldn't convert to unrelated A*"); 1.228 + 1.229 + // Instance type convertibility 1.230 + static_assert((IsConvertible<A, A>::value), 1.231 + "A is A"); 1.232 + static_assert((IsConvertible<B, A>::value), 1.233 + "B converts to A"); 1.234 + static_assert((!IsConvertible<D, A>::value), 1.235 + "D and A are unrelated"); 1.236 + static_assert((!IsConvertible<A, D>::value), 1.237 + "A and D are unrelated"); 1.238 + 1.239 + // These cases seem to require C++11 support to properly implement them, so 1.240 + // for now just disable them. 1.241 + //static_assert((!IsConvertible<C*, A*>::value), 1.242 + // "C* shouldn't convert to A* (private inheritance)"); 1.243 + //static_assert((!IsConvertible<C, A>::value), 1.244 + // "C doesn't convert to A (private inheritance)"); 1.245 +} 1.246 + 1.247 +static_assert(IsSame<MakeSigned<const unsigned char>::Type, const signed char>::value, 1.248 + "const unsigned char won't signify correctly"); 1.249 +static_assert(IsSame<MakeSigned<volatile unsigned short>::Type, volatile signed short>::value, 1.250 + "volatile unsigned short won't signify correctly"); 1.251 +static_assert(IsSame<MakeSigned<const volatile unsigned int>::Type, const volatile signed int>::value, 1.252 + "const volatile unsigned int won't signify correctly"); 1.253 +static_assert(IsSame<MakeSigned<unsigned long>::Type, signed long>::value, 1.254 + "unsigned long won't signify correctly"); 1.255 +static_assert(IsSame<MakeSigned<const signed char>::Type, const signed char>::value, 1.256 + "const signed char won't signify correctly"); 1.257 + 1.258 +static_assert(IsSame<MakeSigned<volatile signed short>::Type, volatile signed short>::value, 1.259 + "volatile signed short won't signify correctly"); 1.260 +static_assert(IsSame<MakeSigned<const volatile signed int>::Type, const volatile signed int>::value, 1.261 + "const volatile signed int won't signify correctly"); 1.262 +static_assert(IsSame<MakeSigned<signed long>::Type, signed long>::value, 1.263 + "signed long won't signify correctly"); 1.264 + 1.265 +static_assert(IsSame<MakeSigned<char>::Type, signed char>::value, 1.266 + "char won't signify correctly"); 1.267 +static_assert(IsSame<MakeSigned<volatile char>::Type, volatile signed char>::value, 1.268 + "volatile char won't signify correctly"); 1.269 +static_assert(IsSame<MakeSigned<const char>::Type, const signed char>::value, 1.270 + "const char won't signify correctly"); 1.271 + 1.272 +static_assert(IsSame<MakeUnsigned<const signed char>::Type, const unsigned char>::value, 1.273 + "const signed char won't unsignify correctly"); 1.274 +static_assert(IsSame<MakeUnsigned<volatile signed short>::Type, volatile unsigned short>::value, 1.275 + "volatile signed short won't unsignify correctly"); 1.276 +static_assert(IsSame<MakeUnsigned<const volatile signed int>::Type, const volatile unsigned int>::value, 1.277 + "const volatile signed int won't unsignify correctly"); 1.278 +static_assert(IsSame<MakeUnsigned<signed long>::Type, unsigned long>::value, 1.279 + "signed long won't unsignify correctly"); 1.280 + 1.281 +static_assert(IsSame<MakeUnsigned<const unsigned char>::Type, const unsigned char>::value, 1.282 + "const unsigned char won't unsignify correctly"); 1.283 + 1.284 +static_assert(IsSame<MakeUnsigned<volatile unsigned short>::Type, volatile unsigned short>::value, 1.285 + "volatile unsigned short won't unsignify correctly"); 1.286 +static_assert(IsSame<MakeUnsigned<const volatile unsigned int>::Type, const volatile unsigned int>::value, 1.287 + "const volatile unsigned int won't unsignify correctly"); 1.288 +static_assert(IsSame<MakeUnsigned<unsigned long>::Type, unsigned long>::value, 1.289 + "signed long won't unsignify correctly"); 1.290 + 1.291 +static_assert(IsSame<MakeUnsigned<char>::Type, unsigned char>::value, 1.292 + "char won't unsignify correctly"); 1.293 +static_assert(IsSame<MakeUnsigned<volatile char>::Type, volatile unsigned char>::value, 1.294 + "volatile char won't unsignify correctly"); 1.295 +static_assert(IsSame<MakeUnsigned<const char>::Type, const unsigned char>::value, 1.296 + "const char won't unsignify correctly"); 1.297 + 1.298 +int 1.299 +main() 1.300 +{ 1.301 + CPlusPlus11IsBaseOf::StandardIsBaseOfTests(); 1.302 + TestIsBaseOf(); 1.303 + TestIsConvertible(); 1.304 +}