00001
00002
00003
00004
00005
00006
00007 #ifndef __RD_INVARIANT_H__
00008 #define __RD_INVARIANT_H__
00009
00010 #include <assert.h>
00011 #include <string>
00012 #include <iostream>
00013 #include <stdexcept>
00014
00015 #include <RDGeneral/RDLog.h>
00016
00017
00018
00019 #if !defined INVARIANT_EXCEPTION_METHOD && \
00020 !defined INVARIANT_ASSERT_METHOD && \
00021 !defined INVARIANT_SILENT_METHOD
00022 #define INVARIANT_EXCEPTION_METHOD 1
00023 #endif
00024
00025
00026
00027
00028 #if !INVARIANT_EXCEPTION_METHOD && \
00029 !INVARIANT_ASSERT_METHOD && \
00030 !INVARIANT_SILENT_METHOD
00031 #undef INVARIANT_EXCEPTION_METHOD
00032 #define INVARIANT_EXCEPTION_METHOD 1
00033 #endif
00034
00035
00036 namespace Invar {
00037
00038 class Invariant : public std::runtime_error {
00039
00040 public:
00041
00042 Invariant( const char * prefix, const char * mess, const char * expr, const char * const file, int line )
00043 : std::runtime_error( prefix ),
00044 mess_d( mess ),
00045 expr_d( expr ),
00046 stringRep_d( prefix ),
00047 file_dp( file ),
00048 line_d( line )
00049 {
00050 }
00051 Invariant( const char * prefix, std::string mess, const char * expr, const char * const file, int line )
00052 : std::runtime_error( prefix ),
00053 mess_d( mess.c_str() ),
00054 expr_d( expr ),
00055 stringRep_d( prefix ),
00056 file_dp( file ),
00057 line_d( line )
00058 {
00059 }
00060 ~Invariant() throw () {};
00061
00062 std::string&
00063 getMessage()
00064 { return mess_d; }
00065
00066 const char * const
00067 getFile()
00068 { return file_dp; }
00069
00070 std::string&
00071 getExpression()
00072 { return expr_d; }
00073
00074 int
00075 getLine()
00076 { return line_d; }
00077
00078 std::string &
00079 toString();
00080
00081
00082 private:
00083
00084 std::string
00085 mess_d,
00086 expr_d,
00087 stringRep_d;
00088
00089 const char
00090 * const file_dp;
00091
00092 int
00093 line_d;
00094 };
00095
00096 std::ostream& operator<<( std::ostream & s, Invariant & inv );
00097
00098 };
00099
00100
00101
00102 #define ASSERT_INVARIANT( expr, mess ) \
00103 assert( expr )
00104
00105
00106
00107
00108
00109 #if INVARIANT_EXCEPTION_METHOD
00110
00111 #define CHECK_INVARIANT( expr, mess ) if ( !(expr) ) {\
00112 Invar::Invariant inv( "Invariant Violation", mess, \
00113 #expr, __FILE__, __LINE__ ); \
00114 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv; }
00115
00116 #define PRECONDITION( expr, mess ) if ( !(expr) ) {\
00117 Invar::Invariant inv( "Pre-condition Violation", mess, \
00118 #expr, __FILE__, __LINE__ ); \
00119 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv; }
00120
00121 #define POSTCONDITION( expr, mess ) if ( !(expr) ) { \
00122 Invar::Invariant inv( "Post-condition Violation", mess, \
00123 #expr, __FILE__, __LINE__ );\
00124 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv; }
00125
00126 #define UNDER_CONSTRUCTION( fn ) Invar::Invariant inv( "Incomplete Code", \
00127 "This routine is still under development", fn, __FILE__, __LINE__ ); \
00128 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv;
00129
00130 #define RANGE_CHECK( lo, x, hi ) if ( (lo)>(hi) || (x)<(lo) || (x)>(hi) ) {\
00131 std::stringstream errstr;\
00132 errstr << lo << " <= " << x <<" <= "<<hi;\
00133 Invar::Invariant inv( "Range Error", #x, errstr.str().c_str(), __FILE__, __LINE__ );\
00134 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv; }
00135
00136 #define TEST_ASSERT( expr ) if ( !(expr) ) {\
00137 Invar::Invariant inv( "Test Assert", "Expression Failed: ", \
00138 #expr, __FILE__, __LINE__ ); \
00139 BOOST_LOG(rdErrorLog) << "\n\n****\n" << inv << "****\n\n"; throw inv; }
00140
00141
00142 #elif INVARIANT_ASSERT_METHOD
00143
00144 #define CHECK_INVARIANT( expr, mess ) assert( expr );
00145 #define PRECONDITION( expr, mess ) assert( expr );
00146 #define POSTCONDITION( expr, mess ) assert( expr );
00147 #define UNDER_CONSTRUCTION(fn ) assert(0);
00148 #define RANGE_CHECK( lo, x, hi ) assert( (lo)<=(hi) && (x)>=(lo) && (x)<=(hi) );
00149 #define TEST_ASSERT( expr ) assert(expr);
00150
00151 #elif INVARIANT_SILENT_METHOD
00152
00153 #define CHECK_INVARIANT( expr, mess )
00154 #define PRECONDITION( expr, mess )
00155 #define POSTCONDITION( expr, mess )
00156 #define UNDER_CONSTRUCTION( fn )
00157 #define RANGE_CHECK( lo, x, hi )
00158 #define TEST_ASSERT( expr )
00159
00160 #endif
00161
00162 #endif
00163