00001 #ifndef ROOT_CORE_UTILS__ASSERT_H
00002 #define ROOT_CORE_UTILS__ASSERT_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016
00022
00028
00035
00036
00043
00044
00045
00046
00047
00048
00049 #include <RootCoreUtils/Global.h>
00050
00051 namespace RCU
00052 {
00053 namespace Check
00054 {
00055 enum Type
00056 {
00058 assert_soft,
00059 assert_hard,
00060 assert_noimp,
00061
00063 require_soft,
00064 require_hard,
00065 require_noimp,
00066
00068 provide_soft,
00069 provide_hard,
00070 provide_noimp,
00071
00073 invariant
00074 };
00075 const int typeNum = invariant + 1;
00076 extern const char *typeLiteral [typeNum];
00077 extern bool typeAbort [typeNum];
00078
00079
00089 void fail (const char *package, const char *file, unsigned line,
00090 Type type, const char *error);
00091
00092
00098 typedef void (*TestInvariantFunction) (const void *object);
00099 template<class T> void
00100 testInvariantVoid (const void *object)
00101 {
00102 static_cast<const T *>(object)->testInvariant ();
00103 }
00104
00105
00106
00107 struct TestInvariant
00108 {
00112
00113 TestInvariant (TestInvariantFunction function,
00114 const void *object);
00115 ~TestInvariant ();
00116
00117 private:
00118 TestInvariantFunction m_function;
00119 const void *m_object;
00120 };
00121
00122
00123
00126 template<class T> inline TestInvariant invariant_tester (T *object)
00127 {
00128 return TestInvariant (testInvariantVoid<T>, object);
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136
00137 #ifndef ROOTCORE_PACKAGE
00138 #define ROOTCORE_PACKAGE 0
00139 #endif
00140
00144 #define RCU_CHECK(type,condition,message) \
00145 (condition) ? (void) 0 : ::RCU::Check::fail (ROOTCORE_PACKAGE, __FILE__, __LINE__, ::RCU::Check::type, message)
00146
00148 #define RCU_CHECK_JOIN2(a,b) RCU_CHECK_JOIN2_HIDDEN(a,b)
00149 #define RCU_CHECK_JOIN2_HIDDEN(a,b) a ## b
00150
00151
00152
00153 #define RCU_REQUIRE_SOFT(x) \
00154 RCU_CHECK (require_soft, x, #x)
00155 #define RCU_REQUIRE2_SOFT(x,y) \
00156 RCU_CHECK (require_soft, x, y)
00157 #define RCU_REQUIRE0_SOFT(y) \
00158 RCU_CHECK (require_soft, 0, y)
00159
00160 #define RCU_PROVIDE_SOFT(x) \
00161 RCU_CHECK (provide_soft, x, #x)
00162 #define RCU_PROVIDE2_SOFT(x,y) \
00163 RCU_CHECK (provide_soft, x, y)
00164 #define RCU_PROVIDE0_SOFT(y) \
00165 RCU_CHECK (provide_soft, 0, y)
00166
00167 #define RCU_ASSERT_SOFT(x) \
00168 RCU_CHECK (assert_soft, x, #x)
00169 #define RCU_ASSERT2_SOFT(x,y) \
00170 RCU_CHECK (assert_soft, x, y)
00171 #define RCU_ASSERT0_SOFT(y) \
00172 RCU_CHECK (assert_soft, 0, y)
00173
00174
00175
00176 #define RCU_REQUIRE_NOIMP(x) \
00177 RCU_CHECK (require_noimp, x, #x)
00178 #define RCU_REQUIRE2_NOIMP(x,y) \
00179 RCU_CHECK (require_noimp, x, y)
00180 #define RCU_REQUIRE0_NOIMP(y) \
00181 RCU_CHECK (require_noimp, 0, y)
00182
00183 #define RCU_PROVIDE_NOIMP(x) \
00184 RCU_CHECK (provide_noimp, x, #x)
00185 #define RCU_PROVIDE2_NOIMP(x,y) \
00186 RCU_CHECK (provide_noimp, x, y)
00187 #define RCU_PROVIDE0_NOIMP(y) \
00188 RCU_CHECK (provide_noimp, 0, y)
00189
00190 #define RCU_ASSERT_NOIMP(x) \
00191 RCU_CHECK (assert_noimp, x, #x)
00192 #define RCU_ASSERT2_NOIMP(x,y) \
00193 RCU_CHECK (assert_noimp, x, y)
00194 #define RCU_ASSERT0_NOIMP(y) \
00195 RCU_CHECK (assert_noimp, 0, y)
00196
00197
00198
00199 #ifndef NDEBUG
00200
00201 #define RCU_INVARIANT(x) \
00202 RCU_CHECK (invariant, x, #x)
00203 #define RCU_INVARIANT2(x,y) \
00204 RCU_CHECK (invariant, x, y)
00205 #define RCU_INVARIANT0(y) \
00206 RCU_CHECK (invariant, 0, y)
00207
00208 #define RCU_REQUIRE(x) \
00209 RCU_CHECK (require_hard, x, #x)
00210 #define RCU_REQUIRE2(x,y) \
00211 RCU_CHECK (require_hard, x, y)
00212 #define RCU_REQUIRE0(y) \
00213 RCU_CHECK (require_hard, 0, y)
00214
00215 #define RCU_PROVIDE(x) \
00216 RCU_CHECK (provide_hard, x, #x)
00217 #define RCU_PROVIDE2(x,y) \
00218 RCU_CHECK (provide_hard, x, y)
00219 #define RCU_PROVIDE0(y) \
00220 RCU_CHECK (provide_hard, 0, y)
00221
00222 #define RCU_ASSERT(x) \
00223 RCU_CHECK (assert_hard, x, #x)
00224 #define RCU_ASSERT2(x,y) \
00225 RCU_CHECK (assert_hard, x, y)
00226 #define RCU_ASSERT0(y) \
00227 RCU_CHECK (assert_hard, 0, y)
00228
00229 #define RCU_READ_INVARIANT(x) \
00230 (x)->testInvariant ()
00231 #define RCU_CHANGE_INVARIANT(x) \
00232 ::RCU::Check::TestInvariant RCU_CHECK_JOIN2 (invariant, __LINE__) = ::RCU::Check::invariant_tester (x);
00233 #define RCU_NEW_INVARIANT(x) \
00234 (x)->testInvariant ()
00235 #define RCU_DESTROY_INVARIANT(x) \
00236 (x)->testInvariant ()
00237
00238
00239
00240 #else
00241
00242 #define RCU_INVARIANT(x) \
00243 (void) 0
00244 #define RCU_INVARIANT2(x,y) \
00245 (void) 0
00246 #define RCU_INVARIANT0(y) \
00247 (void) 0
00248 #define RCU_REQUIRE(x) \
00249 (void) 0
00250 #define RCU_REQUIRE2(x,y) \
00251 (void) 0
00252 #define RCU_REQUIRE0(y) \
00253 (void) 0
00254 #define RCU_PROVIDE(x) \
00255 (void) 0
00256 #define RCU_PROVIDE2(x,y) \
00257 (void) 0
00258 #define RCU_PROVIDE0(y) \
00259 (void) 0
00260 #define RCU_ASSERT(x) \
00261 (void) 0
00262 #define RCU_ASSERT2(x,y) \
00263 (void) 0
00264 #define RCU_ASSERT0(y) \
00265 (void) 0
00266 #define RCU_READ_INVARIANT(x) \
00267 (void) 0
00268 #define RCU_CHANGE_INVARIANT(x) \
00269 (void) 0
00270 #define RCU_NEW_INVARIANT(x) \
00271 (void) 0
00272 #define RCU_DESTROY_INVARIANT(x) \
00273 (void) 0
00274
00275 #endif
00276
00277
00278
00279
00280
00281 #ifdef RCU_DEBUG_SLOW
00282
00283 #define RCU_REQUIRE_SLOW(x) \
00284 RCU_REQUIRE(x)
00285 #define RCU_REQUIRE2_SLOW(x,y) \
00286 RCU_REQUIRE2(x,y)
00287 #define RCU_PROVIDE_SLOW(x) \
00288 RCU_PROVIDE(x)
00289 #define RCU_PROVIDE2_SLOW(x,y) \
00290 RCU_PROVIDE2(x,y)
00291 #define RCU_ASSERT_SLOW(x) \
00292 RCU_ASSERT(x)
00293 #define RCU_ASSERT2_SLOW(x,y) \
00294 RCU_ASSERT2(x,y)
00295 #define RCU_READ_INVARIANT_SLOW(x) \
00296 RCU_READ_INVARIANT (x)
00297 #define RCU_CHANGE_INVARIANT_SLOW(x) \
00298 RCU_CHANGE_INVARIANT (x)
00299 #define RCU_NEW_INVARIANT_SLOW(x) \
00300 RCU_NEW_INVARIANT (x)
00301 #define RCU_DESTROY_INVARIANT_SLOW(x) \
00302 RCU_DESTROY_INVARIANT (x)
00303
00304 #else
00305
00306 #define RCU_REQUIRE_SLOW(x) \
00307 (void) 0
00308 #define RCU_REQUIRE2_SLOW(x,y) \
00309 (void) 0
00310 #define RCU_PROVIDE_SLOW(x) \
00311 (void) 0
00312 #define RCU_PROVIDE2_SLOW(x,y) \
00313 (void) 0
00314 #define RCU_ASSERT_SLOW(x) \
00315 (void) 0
00316 #define RCU_ASSERT2_SLOW(x,y) \
00317 (void) 0
00318 #define RCU_READ_INVARIANT_SLOW(x) \
00319 (void) 0
00320 #define RCU_CHANGE_INVARIANT_SLOW(x) \
00321 (void) 0
00322 #define RCU_NEW_INVARIANT_SLOW(x) \
00323 (void) 0
00324 #define RCU_DESTROY_INVARIANT_SLOW(x) \
00325 (void) 0
00326
00327 #endif
00328
00329
00330 #endif