tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestCheckedInt.cpp (18329B)


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