00001 #if !defined (__ASSERTION_HPP)
00002 #define __ASSERTION_HPP
00003
00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022
00023
00024
00025 00026 00027 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206
00207
00208 #if !defined IN_COMMON_HPP
00209 #error Assertion.hpp is included by Common.hpp only.
00210 #endif
00211
00212 namespace corelinux
00213 {
00214
00215
00216 DECLARE_CLASS( Assertion );
00217
00218
00219
00220
00221
00222
00223 Long assertionFailed( AssertionCref rAssertion );
00224 void assertLoopDebugFunction( void );
00225
00226
00227
00228
00229
00230 static Long asstInvert = 0;
00231 static Long asstResult = 0;
00232 static Long asstEval = 0;
00233 static Long asstShortCut = 0;
00234 static Long asstZero = 0;
00235
00236 static struct AssertCt
00237 {
00238 AssertCt( void )
00239 {
00240 asstInvert = asstResult = asstEval = asstShortCut = asstZero = 0;
00241 }
00242
00243 } asstCt;
00244
00245
00246
00247
00248
00249
00250
00251 #define paste(a,b) a##b
00252 #define paste3(a,b,c) a##b##c
00253
00254
00255 #if defined ALL_ASSERTIONS || defined ASSERT_REQUIRE
00256 #define REQUIRE( exp ) \
00257 IGNORE_RETURN ( \
00258 asstResult = asstZero || exp, \
00259 asstResult || assertionFailed( Assertion( Assertion::REQUIRE, \
00260 TEXT( #exp ), \
00261 LOCATION \
00262 )) )
00263
00264 #else
00265 #define REQUIRE( exp )
00266 #endif // defined ALL_ASSERTIONS || ASSERT_REQUIRE
00267
00268 #if defined ALL_ASSERTIONS || defined ASSERT_ENSURE
00269 #define ENSURE( exp ) \
00270 IGNORE_RETURN ( \
00271 asstResult = asstZero || exp, \
00272 asstResult || assertionFailed( Assertion( Assertion::ENSURE, \
00273 TEXT( #exp ), \
00274 LOCATION \
00275 )) )
00276
00277 #else
00278 #define ENSURE( exp )
00279 #endif // defined ALL_ASSERTIONS || ASSERT_ENSURE
00280
00281 #if defined ALL_ASSERTIONS || defined ASSERT_CHECK
00282 #define CHECK( exp ) \
00283 IGNORE_RETURN ( \
00284 asstResult = asstZero || exp, \
00285 asstResult || assertionFailed( Assertion( Assertion::CHECK, \
00286 paste3( \
00287 TEXT("CHECK( "), \
00288 TEXT( #exp ), \
00289 TEXT(" )") \
00290 ), \
00291 LOCATION )) )
00292
00293 #else
00294 #define CHECK( exp )
00295 #endif // defined ALL_ASSERTIONS || ASSERT_CHECK
00296
00297
00298 #define NEVER_GET_HERE \
00299 assertionFailed( Assertion( Assertion::NEVERGETHERE, \
00300 TEXT("NEVER_GET_HERE"), \
00301 LOCATION ))
00302
00303
00304
00305
00306
00307 #if defined ALL_ASSERTIONS
00308 #define INVARIANT \
00309 protected: \
00310 virtual void invariant(void) const { Short executingInvariant = 1;
00311 #define END_INVARIANT }
00312 #define CHECK_INVARIANT invariant()
00313 #else
00314 #define INVARIANT paste(/, *)
00315 #define END_INVARIANT
00316 #define CHECK_INVARIANT
00317 #endif
00318
00319 00320 00321 00322 00323 00324 00325
00326
00327 #if defined ALL_ASSERTIONS
00328 #define STDASSERT( exp ) \
00329 if( executingInvariant ) \
00330 { \
00331 asstResult = asstZero || exp, \
00332 asstResult || \
00333 assertionFailed( Assertion( Assertion::ASSERT, \
00334 TEXT( #exp ), \
00335 LOCATION )); \
00336 } \
00337 else \
00338 { \
00339 throw Exception( \
00340 TEXT("STDASSERT used outside of INVARIANT"), LOCATION ); \
00341 }
00342 #else
00343 #define STDASSERT( exp )
00344 #endif // defined ALL_ASSERTIONS
00345
00346 #if defined ALL_ASSERTIONS
00347 #define BASE_INVARIANT( ClassType ) \
00348 if( executingInvariant ) \
00349 { \
00350 ClassType::invariant(); \
00351 } \
00352 else \
00353 { \
00354 throw Exception( \
00355 TEXT("BASE_INVARIANT used outside of an INVARIANT"), \
00356 LOCATION, \
00357 Exception::ProcessTerminate); \
00358 }
00359
00360 #else
00361 #define BASE_INVARIANT( ClassType )
00362 #endif
00363
00364
00365
00366
00367
00368 #if defined ALL_ASSERTIONS || defined ASSERT_ENSURE
00369 #define USES_OLD( Type ) Type old( clself )
00370 #else
00371 #define USES_OLD( Type )
00372 #endif
00373
00374
00375
00376
00377
00378 #define ASSERT_LOOP( asstFor, asstAll, asstCond ) \
00379 anAssertCt(); \
00380 { \
00381 volatile x = 0; \
00382 Long asstShortCut; \
00383 if( asstDoEval( asstShortCut )) \
00384 { \
00385 Long asstInvert = ::asstInvert; \
00386 asstResult = asstAll; \
00387 for asstFor \
00388 { \
00389 asstResult = x || asstCond; \
00390 if( asstResult != asstAll ) break; \
00391 } \
00392 if(asstInvert) asstResult = !asstResult; \
00393 } \
00394 ::asstShortCut = asstShortCut; \
00395 if( asstResult == 0 ) assertLoopDebugFunction(); \
00396 } \
00397 asstResult = ::asstShortCut ? asstResult : asstResult
00398
00399 #if defined ALL_ASSERTIONS
00400 #define FORALL(asstFor, asstCond ) ASSERT_LOOP( asstFor, 1, asstCond )
00401 #define EXISTS(asstFor, asstCond ) ASSERT_LOOP( asstFor, 0, asstCond )
00402 #else
00403 #define FORALL(asstFor, asstCond ) True
00404 #define EXISTS(asstFor, asstCond ) True
00405 #endif
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00423 class Assertion : public Exception
00424 {
00425
00426
00427
00428
00429
00430 public:
00431
00433
00434 enum Type
00435 {
00436 REQUIRE,
00437 ENSURE,
00438 CHECK,
00439 ASSERT,
00440 NEVERGETHERE
00441 };
00442
00443 public:
00444
00453 Assertion
00454 (
00455 Type aType,
00456 CharPtr aReason,
00457 CharPtr aFile,
00458 LineNum aLine
00459 );
00460
00466 Assertion( AssertionCref rExcept );
00467
00469
00470 virtual ~Assertion( void );
00471
00472
00473
00474
00475
00482 AssertionRef operator=( AssertionCref );
00483
00490 bool operator==( AssertionCref );
00491
00492
00493
00494
00495
00501 Assertion::Type getType( void ) const;
00502
00503 private:
00504
00505 Assertion::Type theType;
00506 };
00507
00508
00509
00510
00511
00512 inline AssertCt & anAssertCt( void )
00513 {
00514 asstInvert = 0;
00515 asstEval = 1;
00516 return asstCt;
00517 };
00518
00519 inline Long asstDoEval( Long & asstShortCut )
00520 {
00521 Long result = asstEval;
00522
00523 asstShortCut = !asstEval && asstResult;
00524
00525 asstEval = 0;
00526
00527 return result;
00528 }
00529
00530 inline const AssertCt & operator !( const AssertCt & a )
00531 {
00532 asstInvert = !asstInvert;
00533 return a;
00534 }
00535
00536 inline Long operator &&( Long left, const AssertCt & )
00537 {
00538 asstEval = left;
00539 return left;
00540 }
00541
00542 inline Long operator ||( int left, const AssertCt & )
00543 {
00544 asstEval = !left;
00545 return left;
00546 }
00547
00548 }
00549
00550 #endif // !defined ASSERT_HPP
00551
00552 00553 00554 00555 00556 00557 00558
00559