1.1 --- a/lemon/error.h Fri Mar 21 22:25:40 2008 +0000
1.2 +++ b/lemon/error.h Tue Mar 25 16:36:44 2008 +0100
1.3 @@ -93,7 +93,7 @@
1.4 std::auto_ptr<_Type> ptr;
1.5 };
1.6
1.7 - /// Exception-safe convenient "error message" class.
1.8 + /// Exception-safe convenient error message builder class.
1.9
1.10 /// Helper class which provides a convenient ostream-like (operator <<
1.11 /// based) interface to create a string message. Mostly useful in
1.12 @@ -413,263 +413,8 @@
1.13 virtual ~IoParameterError() throw() {}
1.14 };
1.15
1.16 -
1.17 - ///\e
1.18 - class AssertionFailedError : public LogicError {
1.19 - protected:
1.20 - const char *assertion;
1.21 - const char *file;
1.22 - int line;
1.23 - const char *function;
1.24 - const char *message;
1.25 -
1.26 - mutable ExceptionMember<std::string> _message_holder;
1.27 - public:
1.28 - ///\e
1.29 - AssertionFailedError(const char *_file, int _line, const char *func,
1.30 - const char *msg, const char *_assertion = 0) :
1.31 - assertion(_assertion), file(_file), line(_line), function(func),
1.32 - message(msg) {}
1.33 -
1.34 - ///\e
1.35 - const char* get_assertion() const { return assertion; }
1.36 - ///\e
1.37 - const char* get_message() const { return message; }
1.38 - ///\e
1.39 - const char* get_file() const { return file; }
1.40 - ///\e
1.41 - const char* get_function() const { return function; }
1.42 - ///\e
1.43 - int get_line() const { return line; }
1.44 -
1.45 -
1.46 - virtual const char* what() const throw() {
1.47 - try {
1.48 - std::ostringstream ostr;
1.49 - ostr << file << ":" << line << ": ";
1.50 - if( function )
1.51 - ostr << function << ": ";
1.52 - ostr << message;
1.53 - if( assertion )
1.54 - ostr << " (assertion '" << assertion << "' failed)";
1.55 - _message_holder.set(ostr.str());
1.56 - return ostr.str().c_str();
1.57 - }
1.58 - catch(...) {}
1.59 - if( _message_holder.valid() ) return _message_holder.get().c_str();
1.60 - return "lemon::AssertionFailedError";
1.61 - }
1.62 - virtual ~AssertionFailedError() throw() {}
1.63 - };
1.64 -
1.65 -
1.66 - /**************** Macros ****************/
1.67 -
1.68 -
1.69 - template <typename Exception>
1.70 - inline void assert_fail(const char *file, int line,
1.71 - const char *func,
1.72 - Exception exception,
1.73 - const char *assertion = 0,
1.74 - bool do_abort=true)
1.75 - {
1.76 - using namespace std;
1.77 - cerr << file << ":" << line << ": ";
1.78 - if (func)
1.79 - cerr << func << ": ";
1.80 - cerr << exception.what();
1.81 - if (assertion)
1.82 - cerr << " (assertion '" << assertion << "' failed)";
1.83 - cerr << endl;
1.84 - if (do_abort)
1.85 - abort();
1.86 - }
1.87 -
1.88 - template <>
1.89 - inline void assert_fail<const char *>(const char *file, int line,
1.90 - const char *func,
1.91 - const char *message,
1.92 - const char *assertion,
1.93 - bool do_abort)
1.94 - {
1.95 - using namespace std;
1.96 - cerr << file << ":" << line << ": ";
1.97 - if (func)
1.98 - cerr << func << ": ";
1.99 - cerr << message;
1.100 - if (assertion)
1.101 - cerr << " (assertion '" << assertion << "' failed)";
1.102 - cerr << endl;
1.103 - if (do_abort)
1.104 - abort();
1.105 - }
1.106 -
1.107 - template <>
1.108 - inline void assert_fail<std::string>(const char *file, int line,
1.109 - const char *func,
1.110 - std::string message,
1.111 - const char *assertion,
1.112 - bool do_abort)
1.113 - {
1.114 - assert_fail(file, line, func, message.c_str(), assertion, do_abort);
1.115 - }
1.116 -
1.117 - template <typename Exception>
1.118 - inline void assert_fail_failure(const char *file, int line, const char *func,
1.119 - Exception exception,
1.120 - const char *assertion = 0,
1.121 - bool = true)
1.122 - {
1.123 - throw AssertionFailedError(file, line, func, exception.what(), assertion);
1.124 - }
1.125 -
1.126 - template <>
1.127 - inline void assert_fail_failure<const char *>(const char *file, int line,
1.128 - const char *func,
1.129 - const char *message,
1.130 - const char *assertion,
1.131 - bool)
1.132 - {
1.133 - throw AssertionFailedError(file, line, func, message, assertion);
1.134 - }
1.135 -
1.136 - template <>
1.137 - inline void assert_fail_failure<std::string>(const char *file, int line,
1.138 - const char *func,
1.139 - std::string message,
1.140 - const char *assertion,
1.141 - bool)
1.142 - {
1.143 - assert_fail_failure(file, line, func, message.c_str(), assertion, true);
1.144 - }
1.145 -
1.146 - template <typename Exception>
1.147 - inline void assert_fail_exception(const char *file, int line, const char *func,
1.148 - Exception exception,
1.149 - const char *assertion = 0, bool = true)
1.150 - {
1.151 - throw exception;
1.152 - }
1.153 -
1.154 - template <>
1.155 - inline void assert_fail_exception<const char *>(const char *file, int line,
1.156 - const char *func,
1.157 - const char *message,
1.158 - const char *assertion,
1.159 - bool)
1.160 - {
1.161 - throw AssertionFailedError(file, line, func, message, assertion);
1.162 - }
1.163 -
1.164 - template <>
1.165 - inline void assert_fail_exception<std::string>(const char *file, int line,
1.166 - const char *func,
1.167 - std::string message,
1.168 - const char *assertion,
1.169 - bool)
1.170 - {
1.171 - assert_fail_exception(file, line, func, message.c_str(), assertion, true);
1.172 - }
1.173 -
1.174 -/// @}
1.175 + /// @}
1.176
1.177 }
1.178 +
1.179 #endif // LEMON_ERROR_H
1.180 -
1.181 -#undef LEMON_ASSERT
1.182 -#undef LEMON_FIXME
1.183 -
1.184 -#ifdef LEMON_ENABLE_ASSERTS
1.185 -# define LEMON_ASSERT_ABORT
1.186 -#endif
1.187 -
1.188 -#ifndef LEMON_ASSERT_DO_ABORT
1.189 -# define LEMON_ASSERT_DO_ABORT 1
1.190 -#endif
1.191 -
1.192 -#ifndef LEMON_ASSERT_HANDLER
1.193 -# if defined LEMON_ASSERT_EXCEPTION
1.194 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
1.195 -# elif defined LEMON_ASSERT_FAILURE
1.196 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
1.197 -# elif defined LEMON_ASSERT_ABORT
1.198 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
1.199 -# else
1.200 -# define LEMON_DISABLE_ASSERTS
1.201 -# endif
1.202 -#endif
1.203 -
1.204 -#ifdef DOXYGEN
1.205 -
1.206 -/// \brief Macro for assertions with customizable message
1.207 -///
1.208 -/// Macro for assertions with customizable message.
1.209 -///
1.210 -/// The assertions are disabled in the default behaviour. You can
1.211 -/// enable the assertions with the
1.212 -/// \code
1.213 -/// #define LEMON_ENABLE_ASSERTS
1.214 -/// \endcode
1.215 -/// Then an assert
1.216 -/// provides a log on the standard error about the assertion and aborts
1.217 -/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the
1.218 -/// program keeps on running).
1.219 -/// By defining LEMON_ASSERT_FAILURE or
1.220 -/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the
1.221 -/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT
1.222 -/// will always throw an \c AssertionFailedError exception with
1.223 -/// the \c msg error message. By using
1.224 -/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.
1.225 -///
1.226 -/// The LEMON_ASSERT macro should be called with the \c exp parameter
1.227 -/// which should be an expression convertible to bool. If the given
1.228 -/// parameter is false the assertion is raised and one of the assertion
1.229 -/// behaviour will be activated. The \c msg should be either a const
1.230 -/// char* message or an exception. When the \c msg is an exception the
1.231 -/// \ref lemon::Exception::what() "what()" function is called to retrieve and
1.232 -/// display the error message.
1.233 -///
1.234 -/// \todo We should provide some way to reset to the default behaviour,
1.235 -/// shouldn't we?
1.236 -///
1.237 -/// \todo This whole 'assert' business should be placed in a separate
1.238 -/// include file. The boost assert is not guarded by header sentries
1.239 -/// which may help to change the behaviour of the assertions in
1.240 -/// the files.
1.241 -///
1.242 -/// \todo __PRETTY_FUNCTION__ should be replaced by something
1.243 -/// compiler-independent, like BOOST_CURRENT_FUNCTION
1.244 -
1.245 -# define LEMON_ASSERT(exp, msg) \
1.246 - (static_cast<void> (!!(exp) ? 0 : ( \
1.247 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
1.248 - __PRETTY_FUNCTION__, \
1.249 - msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
1.250 -
1.251 -#else
1.252 -# if defined LEMON_DISABLE_ASSERTS
1.253 -
1.254 -# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
1.255 -
1.256 -# else
1.257 -# define LEMON_ASSERT(exp, msg) \
1.258 - (static_cast<void> (!!(exp) ? 0 : ( \
1.259 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
1.260 - __PRETTY_FUNCTION__, \
1.261 - msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
1.262 -# endif
1.263 -#endif
1.264 -
1.265 -/**
1.266 - * \brief Macro for mark not yet implemented features.
1.267 - *
1.268 - * \todo Is this the right place for this? It should be used only in
1.269 - * modules under development.
1.270 - *
1.271 - * \todo __PRETTY_FUNCTION__ should be replaced by something
1.272 - * compiler-independent, like BOOST_CURRENT_FUNCTION
1.273 - */
1.274 -
1.275 -#define LEMON_FIXME(msg) \
1.276 - (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
1.277 - "FIXME: " msg))