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