some minor changes, docs, etc.
3 * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
6 * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
22 //! \ingroup exceptions
24 //! \brief Basic exception classes and error handling.
35 /// \addtogroup exceptions
38 /// Exception-safe convenient "error message" class.
40 /// Helper class which provides a convenient ostream-like (operator <<
41 /// based) interface to create a string message. Mostly useful in
42 /// exception classes (therefore the name).
46 ///\todo The good solution is boost:shared_ptr...
48 std::auto_ptr<std::ostringstream> buf;
53 buf.reset(new std::ostringstream);
64 ErrorMessage() throw() { init(); }
66 ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
69 ErrorMessage(const char *message) throw() {
75 ErrorMessage(const std::string &message) throw() {
82 ErrorMessage& operator<<(const T &t) throw() {
83 if( ! buf.get() ) return *this;
94 const char* message() throw() {
95 if( ! buf.get() ) return 0;
99 mes = buf->str().c_str();
108 * \brief Generic exception class.
110 * Base class for exceptions used in LEMON.
112 class Exception : public std::exception {
117 virtual ~Exception() throw() {}
120 virtual const char* exceptionName() const {
121 return "lemon::Exception";
125 virtual const char* what() const throw() {
126 return exceptionName();
131 * \brief One of the two main subclasses of \ref Exception.
133 * Logic errors represent problems in the internal logic of a program;
134 * in theory, these are preventable, and even detectable before the
135 * program runs (e.g., violations of class invariants).
137 * A typical example for this is \ref UninitializedParameter.
139 class LogicError : public Exception {
141 virtual const char* exceptionName() const {
142 return "lemon::LogicError";
147 * \brief \ref Exception for uninitialized parameters.
149 * This error represents problems in the initialization
150 * of the parameters of the algorithms.
152 class UninitializedParameter : public LogicError {
154 virtual const char* exceptionName() const {
155 return "lemon::UninitializedParameter";
161 * \brief One of the two main subclasses of \ref Exception.
163 * Runtime errors represent problems outside the scope of a program;
164 * they cannot be easily predicted and can generally only be caught as
165 * the program executes.
167 class RuntimeError : public Exception {
169 virtual const char* exceptionName() const {
170 return "lemon::RuntimeError";
175 class RangeError : public RuntimeError {
177 virtual const char* exceptionName() const {
178 return "lemon::RangeError";
183 class IOError : public RuntimeError {
185 virtual const char* exceptionName() const {
186 return "lemon::IOError";
191 class DataFormatError : public IOError {
193 const char *_message;
196 ///\todo Much better solution is boost::shared_ptr
198 std::auto_ptr<std::string> _file;
202 DataFormatError(const DataFormatError &dfe) :
203 IOError(dfe), _message(dfe._message), _line(dfe._line),
207 explicit DataFormatError(const char *the_message)
208 : _message(the_message), _line(0) {}
210 DataFormatError(const std::string &file_name, int line_num,
211 const char *the_message)
212 : _message(the_message), _line(line_num) { file(file_name); }
215 void line(int line_num) { _line=line_num; }
217 void message(char *the_message) { _message=the_message; }
219 void file(const std::string &file_name) {
221 _file.reset(new std::string);
230 int line() const { return _line; }
232 const char* message() const { return _message; }
234 /// \brief Returns the filename.
236 /// Returns \e "(unknown)" if the filename was not specified.
237 const char* file() const {
239 return _file->c_str();
245 virtual const char* what() const throw() {
248 std::ostringstream ostr;
250 if( _file.get() || _line ) {
252 if( _file.get() ) ostr << "in file '" << *_file << "'";
253 if( _file.get() && _line ) ostr << " ";
254 if( _line ) ostr << "at line " << _line;
257 mes = ostr.str().c_str();
260 if( mes ) return mes;
261 return exceptionName();
264 virtual const char* exceptionName() const {
265 return "lemon::DataFormatError";
268 virtual ~DataFormatError() throw() {}
273 class AssertionFailedError : public LogicError {
275 const char *assertion;
278 const char *function;
282 AssertionFailedError(const char *_file, int _line, const char *func,
283 const char *msg, const char *_assertion = 0) :
284 assertion(_assertion), file(_file), line(_line), function(func),
288 const char* get_assertion() const { return assertion; }
290 const char* get_message() const { return message; }
292 const char* get_file() const { return file; }
294 const char* get_function() const { return function; }
296 int get_line() const { return line; }
299 virtual const char* what() const throw() {
302 std::ostringstream ostr;
303 ostr << file << ":" << line << ": ";
305 ostr << function << ": ";
308 ostr << " (assertion '" << assertion << "' failed)";
309 mes = ostr.str().c_str();
312 if( mes ) return mes;
313 return exceptionName();
316 virtual const char* exceptionName() const {
317 return "lemon::AssertionFailedError";
320 virtual ~AssertionFailedError() throw() {}
324 /**************** Macros ****************/
328 void assert_fail(const char *file, int line, const char *func,
329 const char *message, const char *assertion = 0,
333 cerr << file << ":" << line << ": ";
335 cerr << func << ": ";
338 cerr << " (assertion '" << assertion << "' failed)";
345 void assert_fail_throw(const char *file, int line, const char *func,
346 const char *message, const char *assertion = 0,
349 throw AssertionFailedError(file, line, func, message, assertion);
355 #endif // LEMON_ERROR_H
360 #ifndef LEMON_ASSERT_ABORT
361 # define LEMON_ASSERT_ABORT 1
364 #ifndef LEMON_ASSERT_HANDLER
365 # ifdef LEMON_ASSERT_EXCEPTION
366 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
368 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail
372 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
374 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
379 * \brief Macro for assertions with customizable message
381 * Macro for assertions with customizable message.
383 * The behaviour can be customized with LEMON_ASSERT_HANDLER,
384 * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
385 * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
387 * \todo We should provide some way to reset to the default behaviour,
390 * \todo This whole 'assert' business should be placed in a separate
393 * \todo __PRETTY_FUNCTION__ should be replaced by something
394 * compiler-independant, like BOOST_CURRENT_FUNCTION
397 # define LEMON_ASSERT(exp, msg) \
398 (static_cast<void> (!!(exp) ? 0 : ( \
399 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
400 __PRETTY_FUNCTION__, \
401 (msg), #exp, LEMON_ASSERT_ABORT), 0)))
403 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
406 * \brief Macro for mark not yet implemented features.
408 * \todo Is this the right place for this? It should be used only in
409 * modules under development.
411 * \todo __PRETTY_FUNCTION__ should be replaced by something
412 * compiler-independant, like BOOST_CURRENT_FUNCTION
415 # define LEMON_FIXME(msg) \
416 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \