00001 #include "config.h"
00002
00003 #include <iostream>
00004 #include <string>
00005 #include <cassert>
00006
00007 #ifdef HAVE_LIMITS
00008 #include <limits>
00009 #endif
00010 #include <limits.h>
00011 #include <float.h>
00012
00013 #include "asserts.h"
00014 #include "types.h"
00015 #include "error.h"
00016 #include "rmath.h"
00017
00018 #define TEST(expected,code) \
00019 thrown = false; \
00020 try { \
00021 code; \
00022 } \
00023 catch(error e) { \
00024 thrown = true; \
00025 if (thrown != expected) { \
00026 std::cerr << e; \
00027 } \
00028 } \
00029 catch(...) { \
00030 assert(0); \
00031 }
00032
00033 void test1(void)
00034 {
00035 {
00036 safe_num<uint8> i8;
00037 bool thrown = false;
00038
00039 i8 = 0;
00040 TEST(false,i8 += 10);
00041 assert(!thrown);
00042 assert(i8 == 10);
00043
00044 TEST(false,i8 += 200);
00045 assert(!thrown);
00046 assert(i8 == 210);
00047
00048 TEST(false,i8 += 45);
00049 assert(!thrown);
00050 assert(i8 == 255);
00051
00052 TEST(true,i8 += 1);
00053 assert(thrown);
00054 assert(i8 == 255);
00055 }
00056 {
00057 safe_num<signed char> i8;
00058 bool thrown = false;
00059
00060 i8 = 0;
00061 TEST(false,i8 += 10);
00062 assert(!thrown);
00063 assert(i8 == 10);
00064
00065 TEST(false,i8 += 110);
00066 assert(!thrown);
00067 assert(i8 == 120);
00068
00069 TEST(false,i8 += 7);
00070 assert(!thrown);
00071 assert(i8 == 127);
00072
00073 TEST(true,i8 += 1);
00074 assert(thrown);
00075 assert(i8 == 127);
00076 }
00077 }
00078
00079 void test2(void)
00080 {
00081 safe_num<uint8> i8;
00082 bool thrown = false;
00083
00084 i8 = 1;
00085 TEST(false,i8 *= 10);
00086 assert(!thrown);
00087 assert(i8 == 10);
00088
00089 TEST(false,i8 *= 25);
00090 assert(!thrown);
00091 assert(i8 == 250);
00092
00093 TEST(true,i8 *= 10);
00094 assert(thrown);
00095 assert(i8 == 250);
00096 }
00097
00098 void test3(void)
00099 {
00100 safe_num<uint64> n1, n2;
00101 safe_num<uint64> num;
00102 bool thrown = false;
00103
00104 for (n1 = 0; n1 < 1250; ++n1) {
00105 for (n2 = 0; n2 < 1250; ++n2) {
00106 num = n1;
00107 TEST(false,num = n1 * n2);
00108 assert(!thrown);
00109 if (num != n1 * n2)
00110 std::cerr
00111 << "*** ERROR: safe_num<uint64> operator*("
00112 << n1
00113 << ", "
00114 << n2
00115 << ") failed"
00116 << std::endl;
00117 assert(num == n1 * n2);
00118 }
00119 TEST(true,num = n1 * (max_limit(n2) - safe_num<uint64>(1)));
00120 }
00121 }
00122
00123 void test4(void)
00124 {
00125 assert(max_limit<bool>() == true);
00126 assert(min_limit<bool>() == false);
00127
00128 assert(max_limit<char>() == CHAR_MAX);
00129 assert(min_limit<char>() == CHAR_MIN);
00130
00131 assert(max_limit<signed char>() == SCHAR_MAX);
00132 assert(min_limit<signed char>() == SCHAR_MIN);
00133
00134 assert(max_limit<unsigned char>() == UCHAR_MAX);
00135 assert(min_limit<unsigned char>() == 0);
00136
00137 assert(max_limit<short>() == SHRT_MAX);
00138 assert(min_limit<short>() == SHRT_MIN);
00139
00140 assert(max_limit<unsigned short>() == USHRT_MAX);
00141 assert(min_limit<unsigned short>() == 0);
00142
00143 assert(max_limit<int>() == INT_MAX);
00144 assert(min_limit<int>() == INT_MIN);
00145
00146 assert(max_limit<unsigned int>() == UINT_MAX);
00147 assert(min_limit<unsigned int>() == 0);
00148
00149 assert(max_limit<long>() == LONG_MAX);
00150 assert(min_limit<long>() == LONG_MIN);
00151
00152 assert(max_limit<unsigned long>() == ULONG_MAX);
00153 assert(min_limit<unsigned long>() == 0);
00154
00155 assert(max_limit<float>() == FLT_MAX);
00156 assert(min_limit<float>() == FLT_MIN);
00157
00158 assert(max_limit<double>() == DBL_MAX);
00159 assert(min_limit<double>() == DBL_MIN);
00160
00161 #ifdef HAVE_LIMITS
00162 assert(max_limit<bool>() == std::numeric_limits<bool>::max());
00163 assert(min_limit<bool>() == std::numeric_limits<bool>::min());
00164
00165 assert(max_limit<char>() == std::numeric_limits<char>::max());
00166 assert(min_limit<char>() == std::numeric_limits<char>::min());
00167
00168 assert(max_limit<signed char>() == std::numeric_limits<signed char>::max());
00169 assert(min_limit<signed char>() == std::numeric_limits<signed char>::min());
00170
00171 assert(max_limit<unsigned char>() == std::numeric_limits<unsigned char>::max());
00172 assert(min_limit<unsigned char>() == std::numeric_limits<unsigned char>::min());
00173
00174 assert(max_limit<short>() == std::numeric_limits<short>::max());
00175 assert(min_limit<short>() == std::numeric_limits<short>::min());
00176
00177 assert(max_limit<unsigned short>() == std::numeric_limits<unsigned short>::max());
00178 assert(min_limit<unsigned short>() == std::numeric_limits<unsigned short>::min());
00179
00180 assert(max_limit<int>() == std::numeric_limits<int>::max());
00181 assert(min_limit<int>() == std::numeric_limits<int>::min());
00182
00183 assert(max_limit<unsigned int>() == std::numeric_limits<unsigned int>::max());
00184 assert(min_limit<unsigned int>() == std::numeric_limits<unsigned int>::min());
00185
00186 assert(max_limit<long>() == std::numeric_limits<long>::max());
00187 assert(min_limit<long>() == std::numeric_limits<long>::min());
00188
00189 assert(max_limit<unsigned long>() == std::numeric_limits<unsigned long>::max());
00190 assert(min_limit<unsigned long>() == std::numeric_limits<unsigned long>::min());
00191
00192 assert(max_limit<float>() == std::numeric_limits<float>::max());
00193 assert(min_limit<float>() == std::numeric_limits<float>::min());
00194
00195 assert(max_limit<double>() == std::numeric_limits<double>::max());
00196 assert(min_limit<double>() == std::numeric_limits<double>::min());
00197 #endif
00198 }
00199
00200 void test5(void)
00201 {
00202 bool thrown;
00203 safe_num<unsigned short> si;
00204
00205 TEST(false,si = 0);
00206 assert(si.value() == 0);
00207 TEST(false,si++ == 0);
00208 assert(si.value() == 1);
00209 TEST(false,si++ == 1);
00210 assert(si.value() == 2);
00211 TEST(false,++si == 3);
00212 assert(si.value() == 3);
00213 TEST(false,si-- == 3);
00214 assert(si.value() == 2);
00215 TEST(false,--si == 1)
00216 assert(si.value() == 1);
00217 TEST(false,--si == 0);
00218 TEST(true,--si == 0);
00219 TEST(false,si = max_limit<unsigned short>());
00220 TEST(true,++si == max_limit<unsigned short>());
00221
00222 safe_num<unsigned short> si1, si2;
00223
00224 si1 = 5;
00225 si2 = 6;
00226 assert(si1 != si2);
00227 assert(si1 < si2);
00228 assert(si2 > si1);
00229 assert(si1 <= si2);
00230 assert(si2 >= si1);
00231 assert(si2 % si1 == 1);
00232
00233 si = 10;
00234 TEST(false,si += 5);
00235 TEST(false,si == 15);
00236 TEST(false,si -= 5);
00237 TEST(false,si == 10);
00238 TEST(false,si *= 5);
00239 TEST(false,si == 50);
00240 TEST(false,si /= 5);
00241 TEST(false,si == 10);
00242 TEST(false,si %= 6);
00243 TEST(false,si == 4);
00244 }
00245
00246 void test6(void)
00247 {
00248 bool thrown;
00249 safe_num<short> si;
00250
00251 TEST(false,si = 0);
00252 assert(si.value() == 0);
00253 TEST(false,si++ == 0);
00254 assert(si.value() == 1);
00255 TEST(false,si++ == 1);
00256 assert(si.value() == 2);
00257 TEST(false,++si == 3);
00258 assert(si.value() == 3);
00259 TEST(false,si-- == 3);
00260 assert(si.value() == 2);
00261 TEST(false,--si == 1)
00262 assert(si.value() == 1);
00263 TEST(false,--si == 0);
00264 TEST(false,--si == -1);
00265 TEST(false,si = max_limit<short>());
00266 TEST(true,++si == max_limit<short>());
00267 TEST(false,si = min_limit<short>());
00268 TEST(true,--si == max_limit<short>());
00269 }
00270
00271 void test7(void)
00272 {
00273 bool thrown;
00274
00275 TEST(false,absolute(-max_limit<char>()));
00276 TEST(true,absolute(min_limit<char>()));
00277 }
00278
00279 void test8(void)
00280 {
00281 short si;
00282 safe_num<char> ci1, ci2, ci;
00283 bool thrown;
00284 bool should_throw;
00285
00286 for (ci1 = min_limit<char>(); ci1 < max_limit<char>(); ++ci1)
00287 {
00288 for (ci2 = min_limit<char>(); ci2 < max_limit<char>(); ++ci2)
00289 {
00290
00291 thrown = false;
00292 try {
00293 ci = ci1 + ci2;
00294 }
00295 catch(...) {
00296 thrown = true;
00297 }
00298 should_throw = false;
00299 si = ci1.value() + ci2.value();
00300 if ((si > max_limit<char>()) || (si < min_limit<char>()))
00301 should_throw = true;
00302 if (ci2 == min_limit<char>())
00303 should_throw = true;
00304 assert(thrown == should_throw);
00305
00306
00307 thrown = false;
00308 try {
00309 ci = ci1 - ci2;
00310 }
00311 catch(...) {
00312 thrown = true;
00313 }
00314 should_throw = false;
00315 si = ci1.value() - ci2.value();
00316 if ((si > max_limit<char>()) || (si < min_limit<char>()))
00317 should_throw = true;
00318 if (ci2 == min_limit<char>())
00319 should_throw = true;
00320 assert(thrown == should_throw);
00321
00322
00323 thrown = false;
00324 try {
00325 ci = ci1 * ci2;
00326 }
00327 catch(...) {
00328 thrown = true;
00329 }
00330 should_throw = false;
00331 si = ci1.value() * ci2.value();
00332 if ((si > max_limit<char>()) || (si < min_limit<char>()))
00333 should_throw = true;
00334 if ((ci1 != 0) && (ci1 != 1) && (ci2 == min_limit<char>()))
00335 should_throw = true;
00336 assert(thrown == should_throw);
00337
00338
00339 thrown = false;
00340 try {
00341 ci = ci1 / ci2;
00342 }
00343 catch(...) {
00344 thrown = true;
00345 }
00346 should_throw = false;
00347 if (ci2.value() == 0)
00348 should_throw = true;
00349 else {
00350 si = ci1.value() / ci2.value();
00351 if ((si > max_limit<char>()) || (si < min_limit<char>()))
00352 should_throw = true;
00353 }
00354 assert(thrown == should_throw);
00355
00356 }
00357 }
00358 }
00359
00360 void test9(void)
00361 {
00362 uint64 free = 0;
00363 uint64 total = 0;
00364 safe_num<uint64> num = 0;
00365
00366 free = 256258287ul;
00367 total = 258030784ul;
00368
00369 num = free;
00370 num *= 100;
00371 num /= total;
00372
00373 free = 131067261ul;
00374 total = 131072000ul;
00375
00376 num = free;
00377 num *= 100;
00378 num /= total;
00379
00380 free = 256258286ul;
00381 total = 258030784ul;
00382
00383 num = free;
00384 num *= 100;
00385 num /= total;
00386
00387 free = 131067260ul;
00388 total = 131072000ul;
00389
00390 num = free;
00391 num *= 100;
00392 num /= total;
00393
00394 free = 256258286ul;
00395 total = 258030784ul;
00396
00397 num = free;
00398 num *= 100;
00399 num /= total;
00400 }
00401
00402 int main(int argc, char *argv[])
00403 {
00404 try {
00405 test1();
00406 test2();
00407 test3();
00408 test4();
00409 test5();
00410 test6();
00411 test7();
00412 test8();
00413 test9();
00414 }
00415 catch(error e) {
00416 std::cerr << e;
00417 assert(0);
00418 }
00419 catch(...) {
00420 std::cerr << err_unknown;
00421 assert(0);
00422 }
00423 return(0);
00424 }
00425