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