1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mfbt/tests/TestCheckedInt.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,563 @@ 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/CheckedInt.h" 1.10 + 1.11 +#include <iostream> 1.12 +#include <climits> 1.13 + 1.14 +using namespace mozilla; 1.15 + 1.16 +int gIntegerTypesTested = 0; 1.17 +int gTestsPassed = 0; 1.18 +int gTestsFailed = 0; 1.19 + 1.20 +void verifyImplFunction(bool x, bool expected, 1.21 + const char* file, int line, 1.22 + int size, bool isTSigned) 1.23 +{ 1.24 + if (x == expected) { 1.25 + gTestsPassed++; 1.26 + } else { 1.27 + gTestsFailed++; 1.28 + std::cerr << "Test failed at " << file << ":" << line; 1.29 + std::cerr << " with T a "; 1.30 + if (isTSigned) 1.31 + std::cerr << "signed"; 1.32 + else 1.33 + std::cerr << "unsigned"; 1.34 + std::cerr << " " << CHAR_BIT*size << "-bit integer type" << std::endl; 1.35 + } 1.36 +} 1.37 + 1.38 +#define VERIFY_IMPL(x, expected) \ 1.39 + verifyImplFunction((x), \ 1.40 + (expected), \ 1.41 + __FILE__, \ 1.42 + __LINE__, \ 1.43 + sizeof(T), \ 1.44 + IsSigned<T>::value) 1.45 + 1.46 +#define VERIFY(x) VERIFY_IMPL(x, true) 1.47 +#define VERIFY_IS_FALSE(x) VERIFY_IMPL(x, false) 1.48 +#define VERIFY_IS_VALID(x) VERIFY_IMPL((x).isValid(), true) 1.49 +#define VERIFY_IS_INVALID(x) VERIFY_IMPL((x).isValid(), false) 1.50 +#define VERIFY_IS_VALID_IF(x,condition) VERIFY_IMPL((x).isValid(), (condition)) 1.51 + 1.52 +template<typename T, size_t Size = sizeof(T)> 1.53 +struct testTwiceBiggerType 1.54 +{ 1.55 + static void run() 1.56 + { 1.57 + VERIFY(detail::IsSupported<typename detail::TwiceBiggerType<T>::Type>::value); 1.58 + VERIFY(sizeof(typename detail::TwiceBiggerType<T>::Type) 1.59 + == 2 * sizeof(T)); 1.60 + VERIFY(bool(IsSigned<typename detail::TwiceBiggerType<T>::Type>::value) 1.61 + == bool(IsSigned<T>::value)); 1.62 + } 1.63 +}; 1.64 + 1.65 +template<typename T> 1.66 +struct testTwiceBiggerType<T, 8> 1.67 +{ 1.68 + static void run() 1.69 + { 1.70 + VERIFY_IS_FALSE(detail::IsSupported< 1.71 + typename detail::TwiceBiggerType<T>::Type 1.72 + >::value); 1.73 + } 1.74 +}; 1.75 + 1.76 + 1.77 +template<typename T> 1.78 +void test() 1.79 +{ 1.80 + static bool alreadyRun = false; 1.81 + // Integer types from different families may just be typedefs for types from other families. 1.82 + // e.g. int32_t might be just a typedef for int. No point re-running the same tests then. 1.83 + if (alreadyRun) 1.84 + return; 1.85 + alreadyRun = true; 1.86 + 1.87 + VERIFY(detail::IsSupported<T>::value); 1.88 + const bool isTSigned = IsSigned<T>::value; 1.89 + VERIFY(bool(isTSigned) == !bool(T(-1) > T(0))); 1.90 + 1.91 + testTwiceBiggerType<T>::run(); 1.92 + 1.93 + typedef typename MakeUnsigned<T>::Type unsignedT; 1.94 + 1.95 + VERIFY(sizeof(unsignedT) == sizeof(T)); 1.96 + VERIFY(IsSigned<unsignedT>::value == false); 1.97 + 1.98 + const CheckedInt<T> max(MaxValue<T>::value); 1.99 + const CheckedInt<T> min(MinValue<T>::value); 1.100 + 1.101 + // Check MinValue and MaxValue, since they are custom implementations and a mistake there 1.102 + // could potentially NOT be caught by any other tests... while making everything wrong! 1.103 + 1.104 + unsignedT bit = 1; 1.105 + unsignedT unsignedMinValue(min.value()); 1.106 + unsignedT unsignedMaxValue(max.value()); 1.107 + for (size_t i = 0; i < sizeof(T) * CHAR_BIT - 1; i++) 1.108 + { 1.109 + VERIFY((unsignedMinValue & bit) == 0); 1.110 + bit <<= 1; 1.111 + } 1.112 + VERIFY((unsignedMinValue & bit) == (isTSigned ? bit : unsignedT(0))); 1.113 + VERIFY(unsignedMaxValue == unsignedT(~unsignedMinValue)); 1.114 + 1.115 + const CheckedInt<T> zero(0); 1.116 + const CheckedInt<T> one(1); 1.117 + const CheckedInt<T> two(2); 1.118 + const CheckedInt<T> three(3); 1.119 + const CheckedInt<T> four(4); 1.120 + 1.121 + /* Addition / subtraction checks */ 1.122 + 1.123 + VERIFY_IS_VALID(zero + zero); 1.124 + VERIFY(zero + zero == zero); 1.125 + VERIFY_IS_FALSE(zero + zero == one); // Check that == doesn't always return true 1.126 + VERIFY_IS_VALID(zero + one); 1.127 + VERIFY(zero + one == one); 1.128 + VERIFY_IS_VALID(one + one); 1.129 + VERIFY(one + one == two); 1.130 + 1.131 + const CheckedInt<T> maxMinusOne = max - one; 1.132 + const CheckedInt<T> maxMinusTwo = max - two; 1.133 + VERIFY_IS_VALID(maxMinusOne); 1.134 + VERIFY_IS_VALID(maxMinusTwo); 1.135 + VERIFY_IS_VALID(maxMinusOne + one); 1.136 + VERIFY_IS_VALID(maxMinusTwo + one); 1.137 + VERIFY_IS_VALID(maxMinusTwo + two); 1.138 + VERIFY(maxMinusOne + one == max); 1.139 + VERIFY(maxMinusTwo + one == maxMinusOne); 1.140 + VERIFY(maxMinusTwo + two == max); 1.141 + 1.142 + VERIFY_IS_VALID(max + zero); 1.143 + VERIFY_IS_VALID(max - zero); 1.144 + VERIFY_IS_INVALID(max + one); 1.145 + VERIFY_IS_INVALID(max + two); 1.146 + VERIFY_IS_INVALID(max + maxMinusOne); 1.147 + VERIFY_IS_INVALID(max + max); 1.148 + 1.149 + const CheckedInt<T> minPlusOne = min + one; 1.150 + const CheckedInt<T> minPlusTwo = min + two; 1.151 + VERIFY_IS_VALID(minPlusOne); 1.152 + VERIFY_IS_VALID(minPlusTwo); 1.153 + VERIFY_IS_VALID(minPlusOne - one); 1.154 + VERIFY_IS_VALID(minPlusTwo - one); 1.155 + VERIFY_IS_VALID(minPlusTwo - two); 1.156 + VERIFY(minPlusOne - one == min); 1.157 + VERIFY(minPlusTwo - one == minPlusOne); 1.158 + VERIFY(minPlusTwo - two == min); 1.159 + 1.160 + const CheckedInt<T> minMinusOne = min - one; 1.161 + VERIFY_IS_VALID(min + zero); 1.162 + VERIFY_IS_VALID(min - zero); 1.163 + VERIFY_IS_INVALID(min - one); 1.164 + VERIFY_IS_INVALID(min - two); 1.165 + VERIFY_IS_INVALID(min - minMinusOne); 1.166 + VERIFY_IS_VALID(min - min); 1.167 + 1.168 + const CheckedInt<T> maxOverTwo = max / two; 1.169 + VERIFY_IS_VALID(maxOverTwo + maxOverTwo); 1.170 + VERIFY_IS_VALID(maxOverTwo + one); 1.171 + VERIFY((maxOverTwo + one) - one == maxOverTwo); 1.172 + VERIFY_IS_VALID(maxOverTwo - maxOverTwo); 1.173 + VERIFY(maxOverTwo - maxOverTwo == zero); 1.174 + 1.175 + const CheckedInt<T> minOverTwo = min / two; 1.176 + VERIFY_IS_VALID(minOverTwo + minOverTwo); 1.177 + VERIFY_IS_VALID(minOverTwo + one); 1.178 + VERIFY((minOverTwo + one) - one == minOverTwo); 1.179 + VERIFY_IS_VALID(minOverTwo - minOverTwo); 1.180 + VERIFY(minOverTwo - minOverTwo == zero); 1.181 + 1.182 + VERIFY_IS_INVALID(min - one); 1.183 + VERIFY_IS_INVALID(min - two); 1.184 + 1.185 + if (isTSigned) { 1.186 + VERIFY_IS_INVALID(min + min); 1.187 + VERIFY_IS_INVALID(minOverTwo + minOverTwo + minOverTwo); 1.188 + VERIFY_IS_INVALID(zero - min + min); 1.189 + VERIFY_IS_INVALID(one - min + min); 1.190 + } 1.191 + 1.192 + /* Modulo checks */ 1.193 + VERIFY_IS_INVALID(zero % zero); 1.194 + VERIFY_IS_INVALID(one % zero); 1.195 + VERIFY_IS_VALID(zero % one); 1.196 + VERIFY_IS_VALID(zero % max); 1.197 + VERIFY_IS_VALID(one % max); 1.198 + VERIFY_IS_VALID(max % one); 1.199 + VERIFY_IS_VALID(max % max); 1.200 + if (isTSigned) { 1.201 + const CheckedInt<T> minusOne = zero - one; 1.202 + VERIFY_IS_INVALID(minusOne % minusOne); 1.203 + VERIFY_IS_INVALID(zero % minusOne); 1.204 + VERIFY_IS_INVALID(one % minusOne); 1.205 + VERIFY_IS_INVALID(minusOne % one); 1.206 + 1.207 + VERIFY_IS_INVALID(min % min); 1.208 + VERIFY_IS_INVALID(zero % min); 1.209 + VERIFY_IS_INVALID(min % one); 1.210 + } 1.211 + 1.212 + /* Unary operator- checks */ 1.213 + 1.214 + const CheckedInt<T> negOne = -one; 1.215 + const CheckedInt<T> negTwo = -two; 1.216 + 1.217 + if (isTSigned) { 1.218 + VERIFY_IS_VALID(-max); 1.219 + VERIFY_IS_INVALID(-min); 1.220 + VERIFY(-max - min == one); 1.221 + VERIFY_IS_VALID(-max - one); 1.222 + VERIFY_IS_VALID(negOne); 1.223 + VERIFY_IS_VALID(-max + negOne); 1.224 + VERIFY_IS_VALID(negOne + one); 1.225 + VERIFY(negOne + one == zero); 1.226 + VERIFY_IS_VALID(negTwo); 1.227 + VERIFY_IS_VALID(negOne + negOne); 1.228 + VERIFY(negOne + negOne == negTwo); 1.229 + } else { 1.230 + VERIFY_IS_INVALID(-max); 1.231 + VERIFY_IS_VALID(-min); 1.232 + VERIFY(min == zero); 1.233 + VERIFY_IS_INVALID(negOne); 1.234 + } 1.235 + 1.236 + /* multiplication checks */ 1.237 + 1.238 + VERIFY_IS_VALID(zero * zero); 1.239 + VERIFY(zero * zero == zero); 1.240 + VERIFY_IS_VALID(zero * one); 1.241 + VERIFY(zero * one == zero); 1.242 + VERIFY_IS_VALID(one * zero); 1.243 + VERIFY(one * zero == zero); 1.244 + VERIFY_IS_VALID(one * one); 1.245 + VERIFY(one * one == one); 1.246 + VERIFY_IS_VALID(one * three); 1.247 + VERIFY(one * three == three); 1.248 + VERIFY_IS_VALID(two * two); 1.249 + VERIFY(two * two == four); 1.250 + 1.251 + VERIFY_IS_INVALID(max * max); 1.252 + VERIFY_IS_INVALID(maxOverTwo * max); 1.253 + VERIFY_IS_INVALID(maxOverTwo * maxOverTwo); 1.254 + 1.255 + const CheckedInt<T> maxApproxSqrt(T(T(1) << (CHAR_BIT*sizeof(T)/2))); 1.256 + 1.257 + VERIFY_IS_VALID(maxApproxSqrt); 1.258 + VERIFY_IS_VALID(maxApproxSqrt * two); 1.259 + VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt); 1.260 + VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt * maxApproxSqrt); 1.261 + 1.262 + if (isTSigned) { 1.263 + VERIFY_IS_INVALID(min * min); 1.264 + VERIFY_IS_INVALID(minOverTwo * min); 1.265 + VERIFY_IS_INVALID(minOverTwo * minOverTwo); 1.266 + 1.267 + const CheckedInt<T> minApproxSqrt = -maxApproxSqrt; 1.268 + 1.269 + VERIFY_IS_VALID(minApproxSqrt); 1.270 + VERIFY_IS_VALID(minApproxSqrt * two); 1.271 + VERIFY_IS_INVALID(minApproxSqrt * maxApproxSqrt); 1.272 + VERIFY_IS_INVALID(minApproxSqrt * minApproxSqrt); 1.273 + } 1.274 + 1.275 + // make sure to check all 4 paths in signed multiplication validity check. 1.276 + // test positive * positive 1.277 + VERIFY_IS_VALID(max * one); 1.278 + VERIFY(max * one == max); 1.279 + VERIFY_IS_INVALID(max * two); 1.280 + VERIFY_IS_VALID(maxOverTwo * two); 1.281 + VERIFY((maxOverTwo + maxOverTwo) == (maxOverTwo * two)); 1.282 + 1.283 + if (isTSigned) { 1.284 + // test positive * negative 1.285 + VERIFY_IS_VALID(max * negOne); 1.286 + VERIFY_IS_VALID(-max); 1.287 + VERIFY(max * negOne == -max); 1.288 + VERIFY_IS_VALID(one * min); 1.289 + VERIFY_IS_INVALID(max * negTwo); 1.290 + VERIFY_IS_VALID(maxOverTwo * negTwo); 1.291 + VERIFY_IS_VALID(two * minOverTwo); 1.292 + VERIFY_IS_VALID((maxOverTwo + one) * negTwo); 1.293 + VERIFY_IS_INVALID((maxOverTwo + two) * negTwo); 1.294 + VERIFY_IS_INVALID(two * (minOverTwo - one)); 1.295 + 1.296 + // test negative * positive 1.297 + VERIFY_IS_VALID(min * one); 1.298 + VERIFY_IS_VALID(minPlusOne * one); 1.299 + VERIFY_IS_INVALID(min * two); 1.300 + VERIFY_IS_VALID(minOverTwo * two); 1.301 + VERIFY(minOverTwo * two == min); 1.302 + VERIFY_IS_INVALID((minOverTwo - one) * negTwo); 1.303 + VERIFY_IS_INVALID(negTwo * max); 1.304 + VERIFY_IS_VALID(minOverTwo * two); 1.305 + VERIFY(minOverTwo * two == min); 1.306 + VERIFY_IS_VALID(negTwo * maxOverTwo); 1.307 + VERIFY_IS_INVALID((minOverTwo - one) * two); 1.308 + VERIFY_IS_VALID(negTwo * (maxOverTwo + one)); 1.309 + VERIFY_IS_INVALID(negTwo * (maxOverTwo + two)); 1.310 + 1.311 + // test negative * negative 1.312 + VERIFY_IS_INVALID(min * negOne); 1.313 + VERIFY_IS_VALID(minPlusOne * negOne); 1.314 + VERIFY(minPlusOne * negOne == max); 1.315 + VERIFY_IS_INVALID(min * negTwo); 1.316 + VERIFY_IS_INVALID(minOverTwo * negTwo); 1.317 + VERIFY_IS_INVALID(negOne * min); 1.318 + VERIFY_IS_VALID(negOne * minPlusOne); 1.319 + VERIFY(negOne * minPlusOne == max); 1.320 + VERIFY_IS_INVALID(negTwo * min); 1.321 + VERIFY_IS_INVALID(negTwo * minOverTwo); 1.322 + } 1.323 + 1.324 + /* Division checks */ 1.325 + 1.326 + VERIFY_IS_VALID(one / one); 1.327 + VERIFY(one / one == one); 1.328 + VERIFY_IS_VALID(three / three); 1.329 + VERIFY(three / three == one); 1.330 + VERIFY_IS_VALID(four / two); 1.331 + VERIFY(four / two == two); 1.332 + VERIFY((four*three)/four == three); 1.333 + 1.334 + // Check that div by zero is invalid 1.335 + VERIFY_IS_INVALID(zero / zero); 1.336 + VERIFY_IS_INVALID(one / zero); 1.337 + VERIFY_IS_INVALID(two / zero); 1.338 + VERIFY_IS_INVALID(negOne / zero); 1.339 + VERIFY_IS_INVALID(max / zero); 1.340 + VERIFY_IS_INVALID(min / zero); 1.341 + 1.342 + if (isTSigned) { 1.343 + // Check that min / -1 is invalid 1.344 + VERIFY_IS_INVALID(min / negOne); 1.345 + 1.346 + // Check that the test for div by -1 isn't banning other numerators than min 1.347 + VERIFY_IS_VALID(one / negOne); 1.348 + VERIFY_IS_VALID(zero / negOne); 1.349 + VERIFY_IS_VALID(negOne / negOne); 1.350 + VERIFY_IS_VALID(max / negOne); 1.351 + } 1.352 + 1.353 + /* Check that invalidity is correctly preserved by arithmetic ops */ 1.354 + 1.355 + const CheckedInt<T> someInvalid = max + max; 1.356 + VERIFY_IS_INVALID(someInvalid + zero); 1.357 + VERIFY_IS_INVALID(someInvalid - zero); 1.358 + VERIFY_IS_INVALID(zero + someInvalid); 1.359 + VERIFY_IS_INVALID(zero - someInvalid); 1.360 + VERIFY_IS_INVALID(-someInvalid); 1.361 + VERIFY_IS_INVALID(someInvalid * zero); 1.362 + VERIFY_IS_INVALID(someInvalid * one); 1.363 + VERIFY_IS_INVALID(zero * someInvalid); 1.364 + VERIFY_IS_INVALID(one * someInvalid); 1.365 + VERIFY_IS_INVALID(someInvalid / zero); 1.366 + VERIFY_IS_INVALID(someInvalid / one); 1.367 + VERIFY_IS_INVALID(zero / someInvalid); 1.368 + VERIFY_IS_INVALID(one / someInvalid); 1.369 + VERIFY_IS_INVALID(someInvalid % zero); 1.370 + VERIFY_IS_INVALID(someInvalid % one); 1.371 + VERIFY_IS_INVALID(zero % someInvalid); 1.372 + VERIFY_IS_INVALID(one % someInvalid); 1.373 + VERIFY_IS_INVALID(someInvalid + someInvalid); 1.374 + VERIFY_IS_INVALID(someInvalid - someInvalid); 1.375 + VERIFY_IS_INVALID(someInvalid * someInvalid); 1.376 + VERIFY_IS_INVALID(someInvalid / someInvalid); 1.377 + VERIFY_IS_INVALID(someInvalid % someInvalid); 1.378 + 1.379 + /* Check that mixing checked integers with plain integers in expressions is allowed */ 1.380 + 1.381 + VERIFY(one + T(2) == three); 1.382 + VERIFY(2 + one == three); 1.383 + { 1.384 + CheckedInt<T> x = one; 1.385 + x += 2; 1.386 + VERIFY(x == three); 1.387 + } 1.388 + VERIFY(two - 1 == one); 1.389 + VERIFY(2 - one == one); 1.390 + { 1.391 + CheckedInt<T> x = two; 1.392 + x -= 1; 1.393 + VERIFY(x == one); 1.394 + } 1.395 + VERIFY(one * 2 == two); 1.396 + VERIFY(2 * one == two); 1.397 + { 1.398 + CheckedInt<T> x = one; 1.399 + x *= 2; 1.400 + VERIFY(x == two); 1.401 + } 1.402 + VERIFY(four / 2 == two); 1.403 + VERIFY(4 / two == two); 1.404 + { 1.405 + CheckedInt<T> x = four; 1.406 + x /= 2; 1.407 + VERIFY(x == two); 1.408 + } 1.409 + VERIFY(three % 2 == one); 1.410 + VERIFY(3 % two == one); 1.411 + { 1.412 + CheckedInt<T> x = three; 1.413 + x %= 2; 1.414 + VERIFY(x == one); 1.415 + } 1.416 + 1.417 + VERIFY(one == 1); 1.418 + VERIFY(1 == one); 1.419 + VERIFY_IS_FALSE(two == 1); 1.420 + VERIFY_IS_FALSE(1 == two); 1.421 + VERIFY_IS_FALSE(someInvalid == 1); 1.422 + VERIFY_IS_FALSE(1 == someInvalid); 1.423 + 1.424 + // Check simple casting between different signedness and sizes. 1.425 + { 1.426 + CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(2).toChecked<uint8_t>(); 1.427 + VERIFY_IS_VALID(foo); 1.428 + VERIFY(foo == 2); 1.429 + } 1.430 + { 1.431 + CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(255).toChecked<uint8_t>(); 1.432 + VERIFY_IS_VALID(foo); 1.433 + VERIFY(foo == 255); 1.434 + } 1.435 + { 1.436 + CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(256).toChecked<uint8_t>(); 1.437 + VERIFY_IS_INVALID(foo); 1.438 + } 1.439 + { 1.440 + CheckedInt<uint8_t> foo = CheckedInt<int8_t>(-2).toChecked<uint8_t>(); 1.441 + VERIFY_IS_INVALID(foo); 1.442 + } 1.443 + 1.444 + // Check that construction of CheckedInt from an integer value of a mismatched type is checked 1.445 + // Also check casting between all types. 1.446 + 1.447 + #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,V,PostVExpr) \ 1.448 + { \ 1.449 + bool isUSigned = IsSigned<U>::value; \ 1.450 + VERIFY_IS_VALID(CheckedInt<T>(V( 0)PostVExpr)); \ 1.451 + VERIFY_IS_VALID(CheckedInt<T>(V( 1)PostVExpr)); \ 1.452 + VERIFY_IS_VALID(CheckedInt<T>(V(100)PostVExpr)); \ 1.453 + if (isUSigned) \ 1.454 + VERIFY_IS_VALID_IF(CheckedInt<T>(V(-1)PostVExpr), isTSigned); \ 1.455 + if (sizeof(U) > sizeof(T)) \ 1.456 + VERIFY_IS_INVALID(CheckedInt<T>(V(MaxValue<T>::value)PostVExpr + one.value())); \ 1.457 + VERIFY_IS_VALID_IF(CheckedInt<T>(MaxValue<U>::value), \ 1.458 + (sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \ 1.459 + VERIFY_IS_VALID_IF(CheckedInt<T>(MinValue<U>::value), \ 1.460 + isUSigned == false ? 1 \ 1.461 + : bool(isTSigned) == false ? 0 \ 1.462 + : sizeof(T) >= sizeof(U)); \ 1.463 + } 1.464 + #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \ 1.465 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,U,+0) \ 1.466 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,CheckedInt<U>,.toChecked<T>()) 1.467 + 1.468 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int8_t) 1.469 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint8_t) 1.470 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int16_t) 1.471 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint16_t) 1.472 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int32_t) 1.473 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint32_t) 1.474 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int64_t) 1.475 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint64_t) 1.476 + 1.477 + typedef signed char signedChar; 1.478 + typedef unsigned char unsignedChar; 1.479 + typedef unsigned short unsignedShort; 1.480 + typedef unsigned int unsignedInt; 1.481 + typedef unsigned long unsignedLong; 1.482 + typedef long long longLong; 1.483 + typedef unsigned long long unsignedLongLong; 1.484 + 1.485 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(char) 1.486 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(signedChar) 1.487 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedChar) 1.488 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(short) 1.489 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedShort) 1.490 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int) 1.491 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedInt) 1.492 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(long) 1.493 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLong) 1.494 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(longLong) 1.495 + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLongLong) 1.496 + 1.497 + /* Test increment/decrement operators */ 1.498 + 1.499 + CheckedInt<T> x, y; 1.500 + x = one; 1.501 + y = x++; 1.502 + VERIFY(x == two); 1.503 + VERIFY(y == one); 1.504 + x = one; 1.505 + y = ++x; 1.506 + VERIFY(x == two); 1.507 + VERIFY(y == two); 1.508 + x = one; 1.509 + y = x--; 1.510 + VERIFY(x == zero); 1.511 + VERIFY(y == one); 1.512 + x = one; 1.513 + y = --x; 1.514 + VERIFY(x == zero); 1.515 + VERIFY(y == zero); 1.516 + x = max; 1.517 + VERIFY_IS_VALID(x++); 1.518 + x = max; 1.519 + VERIFY_IS_INVALID(++x); 1.520 + x = min; 1.521 + VERIFY_IS_VALID(x--); 1.522 + x = min; 1.523 + VERIFY_IS_INVALID(--x); 1.524 + 1.525 + gIntegerTypesTested++; 1.526 +} 1.527 + 1.528 +int main() 1.529 +{ 1.530 + test<int8_t>(); 1.531 + test<uint8_t>(); 1.532 + test<int16_t>(); 1.533 + test<uint16_t>(); 1.534 + test<int32_t>(); 1.535 + test<uint32_t>(); 1.536 + test<int64_t>(); 1.537 + test<uint64_t>(); 1.538 + 1.539 + test<char>(); 1.540 + test<signed char>(); 1.541 + test<unsigned char>(); 1.542 + test<short>(); 1.543 + test<unsigned short>(); 1.544 + test<int>(); 1.545 + test<unsigned int>(); 1.546 + test<long>(); 1.547 + test<unsigned long>(); 1.548 + test<long long>(); 1.549 + test<unsigned long long>(); 1.550 + 1.551 + const int MIN_TYPES_TESTED = 9; 1.552 + if (gIntegerTypesTested < MIN_TYPES_TESTED) { 1.553 + std::cerr << "Only " << gIntegerTypesTested << " have been tested. " 1.554 + << "This should not be less than " << MIN_TYPES_TESTED << "." 1.555 + << std::endl; 1.556 + gTestsFailed++; 1.557 + } 1.558 + 1.559 + std::cerr << gTestsFailed << " tests failed, " 1.560 + << gTestsPassed << " tests passed out of " 1.561 + << gTestsFailed + gTestsPassed 1.562 + << " tests, covering " << gIntegerTypesTested 1.563 + << " distinct integer types." << std::endl; 1.564 + 1.565 + return gTestsFailed > 0; 1.566 +}