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