Changes in lemon/assert.h [118:407c08a0eae9:112:d2ee5e7f00ef] in lemon-1.2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/assert.h
r118 r112 27 27 28 28 namespace lemon { 29 30 /// @{ 31 32 ///\e 33 class AssertionFailedError : public LogicError { 34 protected: 35 const char *_assertion; 36 const char *_file; 37 int _line; 38 const char *_function; 39 const char *_message; 40 41 mutable ExceptionMember<std::string> _message_holder; 42 public: 43 ///\e 44 AssertionFailedError(const char *file, int line, const char *function, 45 const char *msg, const char *assertion = 0) : 46 _assertion(assertion), _file(file), _line(line), 47 _function(function), _message(msg) {} 48 49 ///\e 50 const char* assertion() const { return _assertion; } 51 ///\e 52 const char* message() const { return _message; } 53 ///\e 54 const char* file() const { return _file; } 55 ///\e 56 const char* function() const { return _function; } 57 ///\e 58 int line() const { return _line; } 59 60 61 virtual const char* what() const throw() { 62 try { 63 std::ostringstream ostr; 64 ostr << _file << ":" << _line << ": "; 65 if (_function) 66 ostr << _function << ": "; 67 ostr << _message; 68 if (_assertion) 69 ostr << " (assertion '" << _assertion << "' failed)"; 70 _message_holder.set(ostr.str()); 71 return ostr.str().c_str(); 72 } 73 catch(...) {} 74 if( _message_holder.valid() ) return _message_holder.get().c_str(); 75 return "lemon::AssertionFailedError"; 76 } 77 virtual ~AssertionFailedError() throw() {} 78 }; 79 80 81 inline void assert_fail_log(const char *file, int line, 82 const char *function, 83 const std::exception& exception, 84 const char *assertion) 85 { 86 std::cerr << file << ":" << line << ": "; 87 if (function) 88 std::cerr << function << ": "; 89 std::cerr << exception.what(); 90 if (assertion) 91 std::cerr << " (assertion '" << assertion << "' failed)"; 92 std::cerr << std::endl; 93 } 29 94 30 95 inline void assert_fail_log(const char *file, int line, const char *function, … … 40 105 } 41 106 107 inline void assert_fail_log(const char *file, int line, const char *function, 108 const std::string& message, const char *assertion) 109 { 110 assert_fail_log(file, line, function, message.c_str(), assertion); 111 } 112 113 inline void assert_fail_abort(const char *file, int line, 114 const char *function, 115 const std::exception& exception, 116 const char *assertion) 117 { 118 assert_fail_log(file, line, function, exception, assertion); 119 std::abort(); 120 } 121 42 122 inline void assert_fail_abort(const char *file, int line, 43 123 const char *function, const char* message, … … 48 128 } 49 129 50 namespace _assert_bits { 51 52 53 inline const char* cstringify(const std::string& str) { 54 return str.c_str(); 55 } 56 57 inline const char* cstringify(const char* str) { 58 return str; 59 } 60 } 130 inline void assert_fail_abort(const char *file, int line, 131 const char *function, 132 const std::string& message, 133 const char *assertion) 134 { 135 assert_fail_log(file, line, function, message.c_str(), assertion); 136 std::abort(); 137 } 138 139 inline void assert_fail_error(const char *file, int line, 140 const char *function, 141 const std::exception& exception, 142 const char *assertion) 143 { 144 throw AssertionFailedError(file, line, function, 145 exception.what(), assertion); 146 } 147 148 inline void assert_fail_error(const char *file, int line, 149 const char *function, const char *message, 150 const char *assertion) 151 { 152 throw AssertionFailedError(file, line, function, message, assertion); 153 } 154 155 inline void assert_fail_error(const char *file, int line, 156 const char *function, 157 const std::string& message, 158 const char *assertion) 159 { 160 throw AssertionFailedError(file, line, function, message.c_str(), assertion); 161 } 162 163 template <typename Exception> 164 inline void assert_fail_exception(const char *, int, const char *, 165 const Exception& exception, 166 const char *, const std::exception* = 167 static_cast<const Exception*>(0)) 168 { 169 throw exception; 170 } 171 172 inline void assert_fail_exception(const char *file, int line, 173 const char *function, const char *message, 174 const char *assertion) 175 { 176 throw AssertionFailedError(file, line, function, message, assertion); 177 } 178 179 inline void assert_fail_exception(const char *file, int line, 180 const char *function, 181 const std::string& message, 182 const char *assertion) 183 { 184 throw AssertionFailedError(file, line, function, message.c_str(), assertion); 185 } 186 187 /// @} 188 61 189 } 62 63 190 #endif // LEMON_ASSERT_H 64 191 65 192 #undef LEMON_ASSERT 66 193 #undef LEMON_FIXME 67 #undef LEMON_DEBUG68 194 69 195 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ 70 196 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ 197 (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \ 198 (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \ 71 199 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 72 200 #error "LEMON assertion system is not set properly" … … 75 203 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ 76 204 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ 205 (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \ 206 (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \ 77 207 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ 78 208 defined(LEMON_ENABLE_ASSERTS)) && \ 79 (defined(LEMON_DISABLE_ASSERTS) || \ 80 defined(NDEBUG)) 209 defined(LEMON_DISABLE_ASSERTS) 81 210 #error "LEMON assertion system is not set properly" 82 211 #endif … … 89 218 # undef LEMON_ASSERT_HANDLER 90 219 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort 220 #elif defined LEMON_ASSERT_ERROR 221 # undef LEMON_ASSERT_HANDLER 222 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error 223 #elif defined LEMON_ASSERT_EXCEPTION 224 # undef LEMON_ASSERT_HANDLER 225 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception 91 226 #elif defined LEMON_ASSERT_CUSTOM 92 227 # undef LEMON_ASSERT_HANDLER … … 95 230 # endif 96 231 # define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER 97 #elif defined LEMON_DISABLE_ASSERTS 98 # undef LEMON_ASSERT_HANDLER 99 #elif defined NDEBUG 100 # undef LEMON_ASSERT_HANDLER 232 #elif defined LEMON_ENABLE_ASSERTS 233 # undef LEMON_ASSERT_HANDLER 234 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort 101 235 #else 102 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort 103 #endif 236 # undef LEMON_ASSERT_HANDLER 237 #endif 238 104 239 105 240 #ifndef LEMON_FUNCTION_NAME … … 113 248 /// \brief Macro for assertion with customizable message 114 249 /// 115 /// Macro for assertion with customizable message. \param exp An 116 /// expression that must be convertible to \c bool. If it is \c 117 /// false, then an assertion is raised. The concrete behaviour depends 118 /// on the settings of the assertion system. \param msg A <tt>const 119 /// char*</tt> parameter, which can be used to provide information 120 /// about the circumstances of the failed assertion. 121 /// 122 /// The assertions are enabled in the default behaviour. 123 /// You can disable them with the following code: 250 /// Macro for assertion with customizable message. 251 /// \param exp An expression that must be convertible to \c bool. 252 /// If it is \c false, then an assertion is raised. The concrete 253 /// behaviour depends on the settings of the assertion system. 254 /// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or 255 /// a <tt>const std::exception&</tt> parameter, which can be used to 256 /// provide information about the circumstances of the failed assertion. 257 /// 258 /// The assertions are disabled in the default behaviour. 259 /// You can enable them with the following code: 124 260 /// \code 125 /// #define LEMON_ DISABLE_ASSERTS261 /// #define LEMON_ENABLE_ASSERTS 126 262 /// \endcode 127 263 /// or with compilation parameters: 128 264 /// \code 129 /// g++ -DLEMON_ DISABLE_ASSERTS130 /// make CXXFLAGS='-DLEMON_ DISABLE_ASSERTS'265 /// g++ -DLEMON_ENABLE_ASSERTS 266 /// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS' 131 267 /// \endcode 132 /// The checking is also disabled when the standard macro \c NDEBUG is defined.133 268 /// 134 269 /// The LEMON assertion system has a wide range of customization … … 140 275 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log 141 276 /// message to the standard error and continues the execution. 142 /// - \c LEMON_ASSERT_ABORT This mode is similar to the \c 143 /// LEMON_ASSERT_LOG, but it aborts the program. It is the default 144 /// behaviour. 277 /// - \c LEMON_ASSERT_ABORT This mode is similar to the 278 /// \c LEMON_ASSERT_LOG, but it aborts the program. It is the default 279 /// behaviour mode when the assertions are enabled with 280 /// \c LEMON_ENABLE_ASSERTS. 281 /// - \c LEMON_ASSERT_ERROR The assertion throws an 282 /// \ref lemon::AssertionFailedError "AssertionFailedError". 283 /// If the \c msg parameter is an exception, then the result of the 284 /// \ref lemon::Exception::what() "what()" member function is passed 285 /// as error message. 286 /// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an 287 /// exception, then it raised directly (solving that the exception 288 /// can not be thrown polymorphically), otherwise an \ref 289 /// lemon::AssertionFailedError "AssertionFailedError" is thrown with 290 /// the given parameters. 145 291 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler 146 /// function. 292 /// functions. Three overloaded functions should be defined with the 293 /// following parameter lists: 147 294 /// \code 148 295 /// void custom_assert_handler(const char* file, int line, const char* function, 149 296 /// const char* message, const char* assertion); 297 /// void custom_assert_handler(const char* file, int line, const char* function, 298 /// const std::string& message, const char* assertion); 299 /// void custom_assert_handler(const char* file, int line, const char* function, 300 /// const std::exception& message, const char* assertion); 150 301 /// \endcode 151 /// The name of the function should be defined as the \c302 /// The name of the functions should be defined as the \c 152 303 /// LEMON_CUSTOM_ASSERT_HANDLER macro name. 153 304 /// \code 154 305 /// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler 155 306 /// \endcode 156 /// Whenever an assertion is occured, the custom assertion157 /// handler is called with appropiate parameters.307 /// Whenever an assertion is occured, one of the custom assertion 308 /// handlers is called with appropiate parameters. 158 309 /// 159 310 /// The assertion mode can also be changed within one compilation unit. … … 165 316 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 166 317 LEMON_FUNCTION_NAME, \ 167 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) 318 msg, #exp), 0))) 319 168 320 169 321 /// \ingroup exceptions … … 176 328 /// LEMON_ASSERT(false, msg); 177 329 /// \endcode 178 ///179 /// \see LEMON_ASSERT180 330 # define LEMON_FIXME(msg) \ 181 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ 182 ::lemon::_assert_bits::cstringify(msg), \ 183 static_cast<const char*>(0))) 184 185 /// \ingroup exceptions 186 /// 187 /// \brief Macro for internal assertions 188 /// 189 /// Macro for internal assertions, it is used in the library to check 190 /// the consistency of results of algorithms, several pre- and 191 /// postconditions and invariants. The checking is disabled by 192 /// default, but it can be turned on with the macro \c 193 /// LEMON_ENABLE_DEBUG. 194 /// \code 195 /// #define LEMON_ENABLE_DEBUG 196 /// \endcode 197 /// or with compilation parameters: 198 /// \code 199 /// g++ -DLEMON_ENABLE_DEBUG 200 /// make CXXFLAGS='-DLEMON_ENABLE_DEBUG' 201 /// \endcode 202 /// 203 /// This macro works like the \c LEMON_ASSERT macro, therefore the 204 /// current behaviour depends on the settings of \c LEMON_ASSERT 205 /// macro. 206 /// 207 /// \see LEMON_ASSERT 208 # define LEMON_DEBUG(exp, msg) \ 209 (static_cast<void> (!!(exp) ? 0 : ( \ 210 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 211 LEMON_FUNCTION_NAME, \ 212 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) 331 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ 332 "FIXME: " msg, static_cast<const char*>(0))) 213 333 214 334 #else … … 217 337 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) 218 338 # define LEMON_FIXME(msg) (static_cast<void>(0)) 219 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0))220 339 # else 221 # define LEMON_ASSERT(exp, msg) \ 222 (static_cast<void> (!!(exp) ? 0 : ( \ 223 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 224 LEMON_FUNCTION_NAME, \ 225 ::lemon::_assert_bits::cstringify(msg), \ 226 #exp), 0))) 227 # define LEMON_FIXME(msg) \ 340 # define LEMON_ASSERT(exp, msg) \ 341 (static_cast<void> (!!(exp) ? 0 : ( \ 342 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 343 LEMON_FUNCTION_NAME, \ 344 msg, #exp), 0))) 345 # define LEMON_FIXME(msg) \ 228 346 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ 229 ::lemon::_assert_bits::cstringify(msg), \ 230 static_cast<const char*>(0))) 231 232 # if LEMON_ENABLE_DEBUG 233 # define LEMON_DEBUG(exp, msg) 234 (static_cast<void> (!!(exp) ? 0 : ( \ 235 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 236 LEMON_FUNCTION_NAME, \ 237 ::lemon::_assert_bits::cstringify(msg), \ 238 #exp), 0))) 239 # else 240 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) 241 # endif 347 "FIXME: " msg, static_cast<const char*>(0))) 242 348 # endif 243 349 244 350 #endif 245 351 246 #ifdef DOXYGEN 247 248 249 #else 250 251 252 #endif 253 254 352
Note: See TracChangeset
for help on using the changeset viewer.