Changeset 118:407c08a0eae9 in lemon-1.2 for lemon
- Timestamp:
- 04/11/08 16:20:54 (17 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/assert.h
r112 r118 27 27 28 28 namespace lemon { 29 30 /// @{31 32 ///\e33 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 ///\e44 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 ///\e50 const char* assertion() const { return _assertion; }51 ///\e52 const char* message() const { return _message; }53 ///\e54 const char* file() const { return _file; }55 ///\e56 const char* function() const { return _function; }57 ///\e58 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 }94 29 95 30 inline void assert_fail_log(const char *file, int line, const char *function, … … 105 40 } 106 41 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 122 42 inline void assert_fail_abort(const char *file, int line, 123 43 const char *function, const char* message, … … 128 48 } 129 49 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(); 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 } 137 60 } 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 189 61 } 62 190 63 #endif // LEMON_ASSERT_H 191 64 192 65 #undef LEMON_ASSERT 193 66 #undef LEMON_FIXME 67 #undef LEMON_DEBUG 194 68 195 69 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ 196 70 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ 197 (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \198 (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \199 71 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 200 72 #error "LEMON assertion system is not set properly" … … 203 75 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ 204 76 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ 205 (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \206 (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \207 77 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ 208 78 defined(LEMON_ENABLE_ASSERTS)) && \ 209 defined(LEMON_DISABLE_ASSERTS) 79 (defined(LEMON_DISABLE_ASSERTS) || \ 80 defined(NDEBUG)) 210 81 #error "LEMON assertion system is not set properly" 211 82 #endif … … 218 89 # undef LEMON_ASSERT_HANDLER 219 90 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort 220 #elif defined LEMON_ASSERT_ERROR221 # undef LEMON_ASSERT_HANDLER222 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error223 #elif defined LEMON_ASSERT_EXCEPTION224 # undef LEMON_ASSERT_HANDLER225 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception226 91 #elif defined LEMON_ASSERT_CUSTOM 227 92 # undef LEMON_ASSERT_HANDLER … … 230 95 # endif 231 96 # define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER 232 #elif defined LEMON_ENABLE_ASSERTS 233 # undef LEMON_ASSERT_HANDLER 97 #elif defined LEMON_DISABLE_ASSERTS 98 # undef LEMON_ASSERT_HANDLER 99 #elif defined NDEBUG 100 # undef LEMON_ASSERT_HANDLER 101 #else 234 102 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort 235 #else 236 # undef LEMON_ASSERT_HANDLER 237 #endif 238 103 #endif 239 104 240 105 #ifndef LEMON_FUNCTION_NAME … … 248 113 /// \brief Macro for assertion with customizable message 249 114 /// 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: 260 /// \code 261 /// #define LEMON_ENABLE_ASSERTS 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: 124 /// \code 125 /// #define LEMON_DISABLE_ASSERTS 262 126 /// \endcode 263 127 /// or with compilation parameters: 264 128 /// \code 265 /// g++ -DLEMON_ENABLE_ASSERTS 266 /// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS' 267 /// \endcode 129 /// g++ -DLEMON_DISABLE_ASSERTS 130 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' 131 /// \endcode 132 /// The checking is also disabled when the standard macro \c NDEBUG is defined. 268 133 /// 269 134 /// The LEMON assertion system has a wide range of customization … … 275 140 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log 276 141 /// message to the standard error and continues the execution. 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. 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. 291 145 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler 292 /// functions. Three overloaded functions should be defined with the 293 /// following parameter lists: 146 /// function. 294 147 /// \code 295 148 /// void custom_assert_handler(const char* file, int line, const char* function, 296 149 /// 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);301 150 /// \endcode 302 /// The name of the function sshould be defined as the \c151 /// The name of the function should be defined as the \c 303 152 /// LEMON_CUSTOM_ASSERT_HANDLER macro name. 304 153 /// \code 305 154 /// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler 306 155 /// \endcode 307 /// Whenever an assertion is occured, one ofthe custom assertion308 /// handler sis called with appropiate parameters.156 /// Whenever an assertion is occured, the custom assertion 157 /// handler is called with appropiate parameters. 309 158 /// 310 159 /// The assertion mode can also be changed within one compilation unit. … … 316 165 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ 317 166 LEMON_FUNCTION_NAME, \ 318 msg, #exp), 0))) 319 167 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) 320 168 321 169 /// \ingroup exceptions … … 328 176 /// LEMON_ASSERT(false, msg); 329 177 /// \endcode 178 /// 179 /// \see LEMON_ASSERT 330 180 # define LEMON_FIXME(msg) \ 331 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ 332 "FIXME: " msg, static_cast<const char*>(0))) 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))) 333 213 334 214 #else … … 337 217 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) 338 218 # define LEMON_FIXME(msg) (static_cast<void>(0)) 219 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) 339 220 # else 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) \ 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) \ 346 228 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ 347 "FIXME: " msg, static_cast<const char*>(0))) 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 348 242 # endif 349 243 350 244 #endif 351 245 352 246 #ifdef DOXYGEN 247 248 249 #else 250 251 252 #endif 253 254
Note: See TracChangeset
for help on using the changeset viewer.