2 * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
22 //! \brief Basic exception classes and error handling.
30 #include <boost/shared_ptr.hpp>
34 /// Exception-safe convenient "error message" class.
36 /// Helper class which provides a convenient ostream-like (operator <<
37 /// based) interface to create a string message. Mostly useful in
38 /// exception classes (therefore the name).
42 boost::shared_ptr<std::ostringstream> buf;
47 buf.reset(new std::ostringstream);
58 ErrorMessage() throw() { init(); }
61 ErrorMessage(const char *message) throw() {
67 ErrorMessage(const std::string &message) throw() {
74 ErrorMessage& operator<<(const T &t) throw() {
75 if( !buf ) return *this;
86 const char* message() throw() {
91 mes = buf->str().c_str();
100 * \brief Generic exception class.
102 * Base class for exceptions used in LEMON.
104 class Exception : public std::exception {
109 virtual ~Exception() throw() {}
112 virtual const char* exceptionName() const {
113 return "lemon::Exception";
117 virtual const char* what() const throw() {
118 return exceptionName();
123 * \brief One of the two main subclasses of \ref Exception.
125 * Logic errors represent problems in the internal logic of a program;
126 * in theory, these are preventable, and even detectable before the
127 * program runs (e.g., violations of class invariants).
129 * A typical example for this is \ref UninitializedParameter.
131 class LogicError : public Exception {
133 virtual const char* exceptionName() const {
134 return "lemon::LogicError";
139 * \brief \ref Exception for uninitialized parameters.
141 * This error represents problems in the initialization
142 * of the parameters of the algorithms.
144 class UninitializedParameter : public LogicError {
146 virtual const char* exceptionName() const {
147 return "lemon::UninitializedParameter";
153 * \brief One of the two main subclasses of \ref Exception.
155 * Runtime errors represent problems outside the scope of a program;
156 * they cannot be easily predicted and can generally only be caught as
157 * the program executes.
159 class RuntimeError : public Exception {
161 virtual const char* exceptionName() const {
162 return "lemon::RuntimeError";
167 class RangeError : public RuntimeError {
169 virtual const char* exceptionName() const {
170 return "lemon::RangeError";
175 class IOError : public RuntimeError {
177 virtual const char* exceptionName() const {
178 return "lemon::IOError";
183 class DataFormatError : public IOError {
185 const char *_message;
187 boost::shared_ptr<std::string> _file;
191 explicit DataFormatError(const char *the_message)
192 : _message(the_message), _line(0) {}
194 DataFormatError(const std::string &file_name, int line_num,
195 const char *the_message)
196 : _message(the_message), _line(line_num) { file(file_name); }
199 void line(int line_num) { _line=line_num; }
201 void message(char *the_message) { _message=the_message; }
203 void file(const std::string &file_name) {
205 _file.reset(new std::string);
214 int line() const { return _line; }
216 const char* message() const { return _message; }
218 /// \brief Returns the filename.
220 /// Returns \e "(unknown)" if the filename was not specified.
221 const char* file() const {
223 return _file->c_str();
229 virtual const char* what() const throw() {
232 std::ostringstream ostr;
234 if( _file || _line ) {
236 if( _file ) ostr << "in file '" << *_file << "'";
237 if( _file && _line ) ostr << " ";
238 if( _line ) ostr << "at line " << _line;
241 mes = ostr.str().c_str();
244 if( mes ) return mes;
245 return exceptionName();
248 virtual const char* exceptionName() const {
249 return "lemon::DataFormatError";
252 virtual ~DataFormatError() throw() {}
257 class AssertionFailedError : public LogicError {
259 const char *assertion;
262 const char *function;
266 AssertionFailedError(const char *_file, int _line, const char *func,
267 const char *msg, const char *_assertion = 0) :
268 assertion(_assertion), file(_file), line(_line), function(func),
272 const char* get_assertion() const { return assertion; }
274 const char* get_message() const { return message; }
276 const char* get_file() const { return file; }
278 const char* get_function() const { return function; }
280 int get_line() const { return line; }
283 virtual const char* what() const throw() {
286 std::ostringstream ostr;
287 ostr << file << ":" << line << ": ";
289 ostr << function << ": ";
292 ostr << " (assertion '" << assertion << "' failed)";
293 mes = ostr.str().c_str();
296 if( mes ) return mes;
297 return exceptionName();
300 virtual const char* exceptionName() const {
301 return "lemon::AssertionFailedError";
304 virtual ~AssertionFailedError() throw() {}
308 /**************** Macros ****************/
312 void assert_fail(const char *file, int line, const char *func,
313 const char *message, const char *assertion = 0,
317 cerr << file << ":" << line << ": ";
319 cerr << func << ": ";
322 cerr << " (assertion '" << assertion << "' failed)";
329 void assert_fail_throw(const char *file, int line, const char *func,
330 const char *message, const char *assertion = 0,
333 throw AssertionFailedError(file, line, func, message, assertion);
338 #endif // LEMON_ERROR_H
343 #ifndef LEMON_ASSERT_ABORT
344 # define LEMON_ASSERT_ABORT 1
347 #ifndef LEMON_ASSERT_HANDLER
348 # ifdef LEMON_ASSERT_EXCEPTION
349 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
351 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail
355 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
357 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
362 * \brief Macro for assertions with customizable message
364 * Macro for assertions with customizable message.
366 * The behaviour can be customized with LEMON_ASSERT_HANDLER,
367 * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
368 * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
370 * \todo We should provide some way to reset to the default behaviour,
373 * \todo This whole 'assert' business should be placed in a separate
376 * \todo __PRETTY_FUNCTION__ should be replaced by something
377 * compiler-independant, like BOOST_CURRENT_FUNCTION
380 # define LEMON_ASSERT(exp, msg) \
381 (static_cast<void> (!!(exp) ? 0 : ( \
382 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
383 __PRETTY_FUNCTION__, \
384 (msg), #exp, LEMON_ASSERT_ABORT), 0)))
386 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
389 * \brief Macro for mark not yet implemented features.
391 * \todo Is this the right place for this? It should be used only in
392 * modules under development.
394 * \todo __PRETTY_FUNCTION__ should be replaced by something
395 * compiler-independant, like BOOST_CURRENT_FUNCTION
398 # define LEMON_FIXME(msg) \
399 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \