|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "mozilla/CheckedInt.h" |
|
7 |
|
8 #include <iostream> |
|
9 #include <climits> |
|
10 |
|
11 using namespace mozilla; |
|
12 |
|
13 int gIntegerTypesTested = 0; |
|
14 int gTestsPassed = 0; |
|
15 int gTestsFailed = 0; |
|
16 |
|
17 void verifyImplFunction(bool x, bool expected, |
|
18 const char* file, int line, |
|
19 int size, bool isTSigned) |
|
20 { |
|
21 if (x == expected) { |
|
22 gTestsPassed++; |
|
23 } else { |
|
24 gTestsFailed++; |
|
25 std::cerr << "Test failed at " << file << ":" << line; |
|
26 std::cerr << " with T a "; |
|
27 if (isTSigned) |
|
28 std::cerr << "signed"; |
|
29 else |
|
30 std::cerr << "unsigned"; |
|
31 std::cerr << " " << CHAR_BIT*size << "-bit integer type" << std::endl; |
|
32 } |
|
33 } |
|
34 |
|
35 #define VERIFY_IMPL(x, expected) \ |
|
36 verifyImplFunction((x), \ |
|
37 (expected), \ |
|
38 __FILE__, \ |
|
39 __LINE__, \ |
|
40 sizeof(T), \ |
|
41 IsSigned<T>::value) |
|
42 |
|
43 #define VERIFY(x) VERIFY_IMPL(x, true) |
|
44 #define VERIFY_IS_FALSE(x) VERIFY_IMPL(x, false) |
|
45 #define VERIFY_IS_VALID(x) VERIFY_IMPL((x).isValid(), true) |
|
46 #define VERIFY_IS_INVALID(x) VERIFY_IMPL((x).isValid(), false) |
|
47 #define VERIFY_IS_VALID_IF(x,condition) VERIFY_IMPL((x).isValid(), (condition)) |
|
48 |
|
49 template<typename T, size_t Size = sizeof(T)> |
|
50 struct testTwiceBiggerType |
|
51 { |
|
52 static void run() |
|
53 { |
|
54 VERIFY(detail::IsSupported<typename detail::TwiceBiggerType<T>::Type>::value); |
|
55 VERIFY(sizeof(typename detail::TwiceBiggerType<T>::Type) |
|
56 == 2 * sizeof(T)); |
|
57 VERIFY(bool(IsSigned<typename detail::TwiceBiggerType<T>::Type>::value) |
|
58 == bool(IsSigned<T>::value)); |
|
59 } |
|
60 }; |
|
61 |
|
62 template<typename T> |
|
63 struct testTwiceBiggerType<T, 8> |
|
64 { |
|
65 static void run() |
|
66 { |
|
67 VERIFY_IS_FALSE(detail::IsSupported< |
|
68 typename detail::TwiceBiggerType<T>::Type |
|
69 >::value); |
|
70 } |
|
71 }; |
|
72 |
|
73 |
|
74 template<typename T> |
|
75 void test() |
|
76 { |
|
77 static bool alreadyRun = false; |
|
78 // Integer types from different families may just be typedefs for types from other families. |
|
79 // e.g. int32_t might be just a typedef for int. No point re-running the same tests then. |
|
80 if (alreadyRun) |
|
81 return; |
|
82 alreadyRun = true; |
|
83 |
|
84 VERIFY(detail::IsSupported<T>::value); |
|
85 const bool isTSigned = IsSigned<T>::value; |
|
86 VERIFY(bool(isTSigned) == !bool(T(-1) > T(0))); |
|
87 |
|
88 testTwiceBiggerType<T>::run(); |
|
89 |
|
90 typedef typename MakeUnsigned<T>::Type unsignedT; |
|
91 |
|
92 VERIFY(sizeof(unsignedT) == sizeof(T)); |
|
93 VERIFY(IsSigned<unsignedT>::value == false); |
|
94 |
|
95 const CheckedInt<T> max(MaxValue<T>::value); |
|
96 const CheckedInt<T> min(MinValue<T>::value); |
|
97 |
|
98 // Check MinValue and MaxValue, since they are custom implementations and a mistake there |
|
99 // could potentially NOT be caught by any other tests... while making everything wrong! |
|
100 |
|
101 unsignedT bit = 1; |
|
102 unsignedT unsignedMinValue(min.value()); |
|
103 unsignedT unsignedMaxValue(max.value()); |
|
104 for (size_t i = 0; i < sizeof(T) * CHAR_BIT - 1; i++) |
|
105 { |
|
106 VERIFY((unsignedMinValue & bit) == 0); |
|
107 bit <<= 1; |
|
108 } |
|
109 VERIFY((unsignedMinValue & bit) == (isTSigned ? bit : unsignedT(0))); |
|
110 VERIFY(unsignedMaxValue == unsignedT(~unsignedMinValue)); |
|
111 |
|
112 const CheckedInt<T> zero(0); |
|
113 const CheckedInt<T> one(1); |
|
114 const CheckedInt<T> two(2); |
|
115 const CheckedInt<T> three(3); |
|
116 const CheckedInt<T> four(4); |
|
117 |
|
118 /* Addition / subtraction checks */ |
|
119 |
|
120 VERIFY_IS_VALID(zero + zero); |
|
121 VERIFY(zero + zero == zero); |
|
122 VERIFY_IS_FALSE(zero + zero == one); // Check that == doesn't always return true |
|
123 VERIFY_IS_VALID(zero + one); |
|
124 VERIFY(zero + one == one); |
|
125 VERIFY_IS_VALID(one + one); |
|
126 VERIFY(one + one == two); |
|
127 |
|
128 const CheckedInt<T> maxMinusOne = max - one; |
|
129 const CheckedInt<T> maxMinusTwo = max - two; |
|
130 VERIFY_IS_VALID(maxMinusOne); |
|
131 VERIFY_IS_VALID(maxMinusTwo); |
|
132 VERIFY_IS_VALID(maxMinusOne + one); |
|
133 VERIFY_IS_VALID(maxMinusTwo + one); |
|
134 VERIFY_IS_VALID(maxMinusTwo + two); |
|
135 VERIFY(maxMinusOne + one == max); |
|
136 VERIFY(maxMinusTwo + one == maxMinusOne); |
|
137 VERIFY(maxMinusTwo + two == max); |
|
138 |
|
139 VERIFY_IS_VALID(max + zero); |
|
140 VERIFY_IS_VALID(max - zero); |
|
141 VERIFY_IS_INVALID(max + one); |
|
142 VERIFY_IS_INVALID(max + two); |
|
143 VERIFY_IS_INVALID(max + maxMinusOne); |
|
144 VERIFY_IS_INVALID(max + max); |
|
145 |
|
146 const CheckedInt<T> minPlusOne = min + one; |
|
147 const CheckedInt<T> minPlusTwo = min + two; |
|
148 VERIFY_IS_VALID(minPlusOne); |
|
149 VERIFY_IS_VALID(minPlusTwo); |
|
150 VERIFY_IS_VALID(minPlusOne - one); |
|
151 VERIFY_IS_VALID(minPlusTwo - one); |
|
152 VERIFY_IS_VALID(minPlusTwo - two); |
|
153 VERIFY(minPlusOne - one == min); |
|
154 VERIFY(minPlusTwo - one == minPlusOne); |
|
155 VERIFY(minPlusTwo - two == min); |
|
156 |
|
157 const CheckedInt<T> minMinusOne = min - one; |
|
158 VERIFY_IS_VALID(min + zero); |
|
159 VERIFY_IS_VALID(min - zero); |
|
160 VERIFY_IS_INVALID(min - one); |
|
161 VERIFY_IS_INVALID(min - two); |
|
162 VERIFY_IS_INVALID(min - minMinusOne); |
|
163 VERIFY_IS_VALID(min - min); |
|
164 |
|
165 const CheckedInt<T> maxOverTwo = max / two; |
|
166 VERIFY_IS_VALID(maxOverTwo + maxOverTwo); |
|
167 VERIFY_IS_VALID(maxOverTwo + one); |
|
168 VERIFY((maxOverTwo + one) - one == maxOverTwo); |
|
169 VERIFY_IS_VALID(maxOverTwo - maxOverTwo); |
|
170 VERIFY(maxOverTwo - maxOverTwo == zero); |
|
171 |
|
172 const CheckedInt<T> minOverTwo = min / two; |
|
173 VERIFY_IS_VALID(minOverTwo + minOverTwo); |
|
174 VERIFY_IS_VALID(minOverTwo + one); |
|
175 VERIFY((minOverTwo + one) - one == minOverTwo); |
|
176 VERIFY_IS_VALID(minOverTwo - minOverTwo); |
|
177 VERIFY(minOverTwo - minOverTwo == zero); |
|
178 |
|
179 VERIFY_IS_INVALID(min - one); |
|
180 VERIFY_IS_INVALID(min - two); |
|
181 |
|
182 if (isTSigned) { |
|
183 VERIFY_IS_INVALID(min + min); |
|
184 VERIFY_IS_INVALID(minOverTwo + minOverTwo + minOverTwo); |
|
185 VERIFY_IS_INVALID(zero - min + min); |
|
186 VERIFY_IS_INVALID(one - min + min); |
|
187 } |
|
188 |
|
189 /* Modulo checks */ |
|
190 VERIFY_IS_INVALID(zero % zero); |
|
191 VERIFY_IS_INVALID(one % zero); |
|
192 VERIFY_IS_VALID(zero % one); |
|
193 VERIFY_IS_VALID(zero % max); |
|
194 VERIFY_IS_VALID(one % max); |
|
195 VERIFY_IS_VALID(max % one); |
|
196 VERIFY_IS_VALID(max % max); |
|
197 if (isTSigned) { |
|
198 const CheckedInt<T> minusOne = zero - one; |
|
199 VERIFY_IS_INVALID(minusOne % minusOne); |
|
200 VERIFY_IS_INVALID(zero % minusOne); |
|
201 VERIFY_IS_INVALID(one % minusOne); |
|
202 VERIFY_IS_INVALID(minusOne % one); |
|
203 |
|
204 VERIFY_IS_INVALID(min % min); |
|
205 VERIFY_IS_INVALID(zero % min); |
|
206 VERIFY_IS_INVALID(min % one); |
|
207 } |
|
208 |
|
209 /* Unary operator- checks */ |
|
210 |
|
211 const CheckedInt<T> negOne = -one; |
|
212 const CheckedInt<T> negTwo = -two; |
|
213 |
|
214 if (isTSigned) { |
|
215 VERIFY_IS_VALID(-max); |
|
216 VERIFY_IS_INVALID(-min); |
|
217 VERIFY(-max - min == one); |
|
218 VERIFY_IS_VALID(-max - one); |
|
219 VERIFY_IS_VALID(negOne); |
|
220 VERIFY_IS_VALID(-max + negOne); |
|
221 VERIFY_IS_VALID(negOne + one); |
|
222 VERIFY(negOne + one == zero); |
|
223 VERIFY_IS_VALID(negTwo); |
|
224 VERIFY_IS_VALID(negOne + negOne); |
|
225 VERIFY(negOne + negOne == negTwo); |
|
226 } else { |
|
227 VERIFY_IS_INVALID(-max); |
|
228 VERIFY_IS_VALID(-min); |
|
229 VERIFY(min == zero); |
|
230 VERIFY_IS_INVALID(negOne); |
|
231 } |
|
232 |
|
233 /* multiplication checks */ |
|
234 |
|
235 VERIFY_IS_VALID(zero * zero); |
|
236 VERIFY(zero * zero == zero); |
|
237 VERIFY_IS_VALID(zero * one); |
|
238 VERIFY(zero * one == zero); |
|
239 VERIFY_IS_VALID(one * zero); |
|
240 VERIFY(one * zero == zero); |
|
241 VERIFY_IS_VALID(one * one); |
|
242 VERIFY(one * one == one); |
|
243 VERIFY_IS_VALID(one * three); |
|
244 VERIFY(one * three == three); |
|
245 VERIFY_IS_VALID(two * two); |
|
246 VERIFY(two * two == four); |
|
247 |
|
248 VERIFY_IS_INVALID(max * max); |
|
249 VERIFY_IS_INVALID(maxOverTwo * max); |
|
250 VERIFY_IS_INVALID(maxOverTwo * maxOverTwo); |
|
251 |
|
252 const CheckedInt<T> maxApproxSqrt(T(T(1) << (CHAR_BIT*sizeof(T)/2))); |
|
253 |
|
254 VERIFY_IS_VALID(maxApproxSqrt); |
|
255 VERIFY_IS_VALID(maxApproxSqrt * two); |
|
256 VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt); |
|
257 VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt * maxApproxSqrt); |
|
258 |
|
259 if (isTSigned) { |
|
260 VERIFY_IS_INVALID(min * min); |
|
261 VERIFY_IS_INVALID(minOverTwo * min); |
|
262 VERIFY_IS_INVALID(minOverTwo * minOverTwo); |
|
263 |
|
264 const CheckedInt<T> minApproxSqrt = -maxApproxSqrt; |
|
265 |
|
266 VERIFY_IS_VALID(minApproxSqrt); |
|
267 VERIFY_IS_VALID(minApproxSqrt * two); |
|
268 VERIFY_IS_INVALID(minApproxSqrt * maxApproxSqrt); |
|
269 VERIFY_IS_INVALID(minApproxSqrt * minApproxSqrt); |
|
270 } |
|
271 |
|
272 // make sure to check all 4 paths in signed multiplication validity check. |
|
273 // test positive * positive |
|
274 VERIFY_IS_VALID(max * one); |
|
275 VERIFY(max * one == max); |
|
276 VERIFY_IS_INVALID(max * two); |
|
277 VERIFY_IS_VALID(maxOverTwo * two); |
|
278 VERIFY((maxOverTwo + maxOverTwo) == (maxOverTwo * two)); |
|
279 |
|
280 if (isTSigned) { |
|
281 // test positive * negative |
|
282 VERIFY_IS_VALID(max * negOne); |
|
283 VERIFY_IS_VALID(-max); |
|
284 VERIFY(max * negOne == -max); |
|
285 VERIFY_IS_VALID(one * min); |
|
286 VERIFY_IS_INVALID(max * negTwo); |
|
287 VERIFY_IS_VALID(maxOverTwo * negTwo); |
|
288 VERIFY_IS_VALID(two * minOverTwo); |
|
289 VERIFY_IS_VALID((maxOverTwo + one) * negTwo); |
|
290 VERIFY_IS_INVALID((maxOverTwo + two) * negTwo); |
|
291 VERIFY_IS_INVALID(two * (minOverTwo - one)); |
|
292 |
|
293 // test negative * positive |
|
294 VERIFY_IS_VALID(min * one); |
|
295 VERIFY_IS_VALID(minPlusOne * one); |
|
296 VERIFY_IS_INVALID(min * two); |
|
297 VERIFY_IS_VALID(minOverTwo * two); |
|
298 VERIFY(minOverTwo * two == min); |
|
299 VERIFY_IS_INVALID((minOverTwo - one) * negTwo); |
|
300 VERIFY_IS_INVALID(negTwo * max); |
|
301 VERIFY_IS_VALID(minOverTwo * two); |
|
302 VERIFY(minOverTwo * two == min); |
|
303 VERIFY_IS_VALID(negTwo * maxOverTwo); |
|
304 VERIFY_IS_INVALID((minOverTwo - one) * two); |
|
305 VERIFY_IS_VALID(negTwo * (maxOverTwo + one)); |
|
306 VERIFY_IS_INVALID(negTwo * (maxOverTwo + two)); |
|
307 |
|
308 // test negative * negative |
|
309 VERIFY_IS_INVALID(min * negOne); |
|
310 VERIFY_IS_VALID(minPlusOne * negOne); |
|
311 VERIFY(minPlusOne * negOne == max); |
|
312 VERIFY_IS_INVALID(min * negTwo); |
|
313 VERIFY_IS_INVALID(minOverTwo * negTwo); |
|
314 VERIFY_IS_INVALID(negOne * min); |
|
315 VERIFY_IS_VALID(negOne * minPlusOne); |
|
316 VERIFY(negOne * minPlusOne == max); |
|
317 VERIFY_IS_INVALID(negTwo * min); |
|
318 VERIFY_IS_INVALID(negTwo * minOverTwo); |
|
319 } |
|
320 |
|
321 /* Division checks */ |
|
322 |
|
323 VERIFY_IS_VALID(one / one); |
|
324 VERIFY(one / one == one); |
|
325 VERIFY_IS_VALID(three / three); |
|
326 VERIFY(three / three == one); |
|
327 VERIFY_IS_VALID(four / two); |
|
328 VERIFY(four / two == two); |
|
329 VERIFY((four*three)/four == three); |
|
330 |
|
331 // Check that div by zero is invalid |
|
332 VERIFY_IS_INVALID(zero / zero); |
|
333 VERIFY_IS_INVALID(one / zero); |
|
334 VERIFY_IS_INVALID(two / zero); |
|
335 VERIFY_IS_INVALID(negOne / zero); |
|
336 VERIFY_IS_INVALID(max / zero); |
|
337 VERIFY_IS_INVALID(min / zero); |
|
338 |
|
339 if (isTSigned) { |
|
340 // Check that min / -1 is invalid |
|
341 VERIFY_IS_INVALID(min / negOne); |
|
342 |
|
343 // Check that the test for div by -1 isn't banning other numerators than min |
|
344 VERIFY_IS_VALID(one / negOne); |
|
345 VERIFY_IS_VALID(zero / negOne); |
|
346 VERIFY_IS_VALID(negOne / negOne); |
|
347 VERIFY_IS_VALID(max / negOne); |
|
348 } |
|
349 |
|
350 /* Check that invalidity is correctly preserved by arithmetic ops */ |
|
351 |
|
352 const CheckedInt<T> someInvalid = max + max; |
|
353 VERIFY_IS_INVALID(someInvalid + zero); |
|
354 VERIFY_IS_INVALID(someInvalid - zero); |
|
355 VERIFY_IS_INVALID(zero + someInvalid); |
|
356 VERIFY_IS_INVALID(zero - someInvalid); |
|
357 VERIFY_IS_INVALID(-someInvalid); |
|
358 VERIFY_IS_INVALID(someInvalid * zero); |
|
359 VERIFY_IS_INVALID(someInvalid * one); |
|
360 VERIFY_IS_INVALID(zero * someInvalid); |
|
361 VERIFY_IS_INVALID(one * someInvalid); |
|
362 VERIFY_IS_INVALID(someInvalid / zero); |
|
363 VERIFY_IS_INVALID(someInvalid / one); |
|
364 VERIFY_IS_INVALID(zero / someInvalid); |
|
365 VERIFY_IS_INVALID(one / someInvalid); |
|
366 VERIFY_IS_INVALID(someInvalid % zero); |
|
367 VERIFY_IS_INVALID(someInvalid % one); |
|
368 VERIFY_IS_INVALID(zero % someInvalid); |
|
369 VERIFY_IS_INVALID(one % someInvalid); |
|
370 VERIFY_IS_INVALID(someInvalid + someInvalid); |
|
371 VERIFY_IS_INVALID(someInvalid - someInvalid); |
|
372 VERIFY_IS_INVALID(someInvalid * someInvalid); |
|
373 VERIFY_IS_INVALID(someInvalid / someInvalid); |
|
374 VERIFY_IS_INVALID(someInvalid % someInvalid); |
|
375 |
|
376 /* Check that mixing checked integers with plain integers in expressions is allowed */ |
|
377 |
|
378 VERIFY(one + T(2) == three); |
|
379 VERIFY(2 + one == three); |
|
380 { |
|
381 CheckedInt<T> x = one; |
|
382 x += 2; |
|
383 VERIFY(x == three); |
|
384 } |
|
385 VERIFY(two - 1 == one); |
|
386 VERIFY(2 - one == one); |
|
387 { |
|
388 CheckedInt<T> x = two; |
|
389 x -= 1; |
|
390 VERIFY(x == one); |
|
391 } |
|
392 VERIFY(one * 2 == two); |
|
393 VERIFY(2 * one == two); |
|
394 { |
|
395 CheckedInt<T> x = one; |
|
396 x *= 2; |
|
397 VERIFY(x == two); |
|
398 } |
|
399 VERIFY(four / 2 == two); |
|
400 VERIFY(4 / two == two); |
|
401 { |
|
402 CheckedInt<T> x = four; |
|
403 x /= 2; |
|
404 VERIFY(x == two); |
|
405 } |
|
406 VERIFY(three % 2 == one); |
|
407 VERIFY(3 % two == one); |
|
408 { |
|
409 CheckedInt<T> x = three; |
|
410 x %= 2; |
|
411 VERIFY(x == one); |
|
412 } |
|
413 |
|
414 VERIFY(one == 1); |
|
415 VERIFY(1 == one); |
|
416 VERIFY_IS_FALSE(two == 1); |
|
417 VERIFY_IS_FALSE(1 == two); |
|
418 VERIFY_IS_FALSE(someInvalid == 1); |
|
419 VERIFY_IS_FALSE(1 == someInvalid); |
|
420 |
|
421 // Check simple casting between different signedness and sizes. |
|
422 { |
|
423 CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(2).toChecked<uint8_t>(); |
|
424 VERIFY_IS_VALID(foo); |
|
425 VERIFY(foo == 2); |
|
426 } |
|
427 { |
|
428 CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(255).toChecked<uint8_t>(); |
|
429 VERIFY_IS_VALID(foo); |
|
430 VERIFY(foo == 255); |
|
431 } |
|
432 { |
|
433 CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(256).toChecked<uint8_t>(); |
|
434 VERIFY_IS_INVALID(foo); |
|
435 } |
|
436 { |
|
437 CheckedInt<uint8_t> foo = CheckedInt<int8_t>(-2).toChecked<uint8_t>(); |
|
438 VERIFY_IS_INVALID(foo); |
|
439 } |
|
440 |
|
441 // Check that construction of CheckedInt from an integer value of a mismatched type is checked |
|
442 // Also check casting between all types. |
|
443 |
|
444 #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,V,PostVExpr) \ |
|
445 { \ |
|
446 bool isUSigned = IsSigned<U>::value; \ |
|
447 VERIFY_IS_VALID(CheckedInt<T>(V( 0)PostVExpr)); \ |
|
448 VERIFY_IS_VALID(CheckedInt<T>(V( 1)PostVExpr)); \ |
|
449 VERIFY_IS_VALID(CheckedInt<T>(V(100)PostVExpr)); \ |
|
450 if (isUSigned) \ |
|
451 VERIFY_IS_VALID_IF(CheckedInt<T>(V(-1)PostVExpr), isTSigned); \ |
|
452 if (sizeof(U) > sizeof(T)) \ |
|
453 VERIFY_IS_INVALID(CheckedInt<T>(V(MaxValue<T>::value)PostVExpr + one.value())); \ |
|
454 VERIFY_IS_VALID_IF(CheckedInt<T>(MaxValue<U>::value), \ |
|
455 (sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \ |
|
456 VERIFY_IS_VALID_IF(CheckedInt<T>(MinValue<U>::value), \ |
|
457 isUSigned == false ? 1 \ |
|
458 : bool(isTSigned) == false ? 0 \ |
|
459 : sizeof(T) >= sizeof(U)); \ |
|
460 } |
|
461 #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \ |
|
462 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,U,+0) \ |
|
463 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,CheckedInt<U>,.toChecked<T>()) |
|
464 |
|
465 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int8_t) |
|
466 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint8_t) |
|
467 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int16_t) |
|
468 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint16_t) |
|
469 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int32_t) |
|
470 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint32_t) |
|
471 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int64_t) |
|
472 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint64_t) |
|
473 |
|
474 typedef signed char signedChar; |
|
475 typedef unsigned char unsignedChar; |
|
476 typedef unsigned short unsignedShort; |
|
477 typedef unsigned int unsignedInt; |
|
478 typedef unsigned long unsignedLong; |
|
479 typedef long long longLong; |
|
480 typedef unsigned long long unsignedLongLong; |
|
481 |
|
482 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(char) |
|
483 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(signedChar) |
|
484 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedChar) |
|
485 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(short) |
|
486 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedShort) |
|
487 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int) |
|
488 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedInt) |
|
489 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(long) |
|
490 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLong) |
|
491 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(longLong) |
|
492 VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLongLong) |
|
493 |
|
494 /* Test increment/decrement operators */ |
|
495 |
|
496 CheckedInt<T> x, y; |
|
497 x = one; |
|
498 y = x++; |
|
499 VERIFY(x == two); |
|
500 VERIFY(y == one); |
|
501 x = one; |
|
502 y = ++x; |
|
503 VERIFY(x == two); |
|
504 VERIFY(y == two); |
|
505 x = one; |
|
506 y = x--; |
|
507 VERIFY(x == zero); |
|
508 VERIFY(y == one); |
|
509 x = one; |
|
510 y = --x; |
|
511 VERIFY(x == zero); |
|
512 VERIFY(y == zero); |
|
513 x = max; |
|
514 VERIFY_IS_VALID(x++); |
|
515 x = max; |
|
516 VERIFY_IS_INVALID(++x); |
|
517 x = min; |
|
518 VERIFY_IS_VALID(x--); |
|
519 x = min; |
|
520 VERIFY_IS_INVALID(--x); |
|
521 |
|
522 gIntegerTypesTested++; |
|
523 } |
|
524 |
|
525 int main() |
|
526 { |
|
527 test<int8_t>(); |
|
528 test<uint8_t>(); |
|
529 test<int16_t>(); |
|
530 test<uint16_t>(); |
|
531 test<int32_t>(); |
|
532 test<uint32_t>(); |
|
533 test<int64_t>(); |
|
534 test<uint64_t>(); |
|
535 |
|
536 test<char>(); |
|
537 test<signed char>(); |
|
538 test<unsigned char>(); |
|
539 test<short>(); |
|
540 test<unsigned short>(); |
|
541 test<int>(); |
|
542 test<unsigned int>(); |
|
543 test<long>(); |
|
544 test<unsigned long>(); |
|
545 test<long long>(); |
|
546 test<unsigned long long>(); |
|
547 |
|
548 const int MIN_TYPES_TESTED = 9; |
|
549 if (gIntegerTypesTested < MIN_TYPES_TESTED) { |
|
550 std::cerr << "Only " << gIntegerTypesTested << " have been tested. " |
|
551 << "This should not be less than " << MIN_TYPES_TESTED << "." |
|
552 << std::endl; |
|
553 gTestsFailed++; |
|
554 } |
|
555 |
|
556 std::cerr << gTestsFailed << " tests failed, " |
|
557 << gTestsPassed << " tests passed out of " |
|
558 << gTestsFailed + gTestsPassed |
|
559 << " tests, covering " << gIntegerTypesTested |
|
560 << " distinct integer types." << std::endl; |
|
561 |
|
562 return gTestsFailed > 0; |
|
563 } |