if you have a nuclear power plant and wanna compute small magic squares, then let's do it
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
20 //! \ingroup exceptions
22 //! \brief Basic exception classes and error handling.
30 #include <boost/shared_ptr.hpp>
34 /// \addtogroup exceptions
37 /// Exception-safe convenient "error message" class.
39 /// Helper class which provides a convenient ostream-like (operator <<
40 /// based) interface to create a string message. Mostly useful in
41 /// exception classes (therefore the name).
45 boost::shared_ptr<std::ostringstream> buf;
50 buf.reset(new std::ostringstream);
61 ErrorMessage() throw() { init(); }
64 ErrorMessage(const char *message) throw() {
70 ErrorMessage(const std::string &message) throw() {
77 ErrorMessage& operator<<(const T &t) throw() {
78 if( !buf ) return *this;
89 const char* message() throw() {
94 mes = buf->str().c_str();
103 * \brief Generic exception class.
105 * Base class for exceptions used in LEMON.
107 class Exception : public std::exception {
112 virtual ~Exception() throw() {}
115 virtual const char* exceptionName() const {
116 return "lemon::Exception";
120 virtual const char* what() const throw() {
121 return exceptionName();
126 * \brief One of the two main subclasses of \ref Exception.
128 * Logic errors represent problems in the internal logic of a program;
129 * in theory, these are preventable, and even detectable before the
130 * program runs (e.g., violations of class invariants).
132 * A typical example for this is \ref UninitializedParameter.
134 class LogicError : public Exception {
136 virtual const char* exceptionName() const {
137 return "lemon::LogicError";
142 * \brief \ref Exception for uninitialized parameters.
144 * This error represents problems in the initialization
145 * of the parameters of the algorithms.
147 class UninitializedParameter : public LogicError {
149 virtual const char* exceptionName() const {
150 return "lemon::UninitializedParameter";
156 * \brief One of the two main subclasses of \ref Exception.
158 * Runtime errors represent problems outside the scope of a program;
159 * they cannot be easily predicted and can generally only be caught as
160 * the program executes.
162 class RuntimeError : public Exception {
164 virtual const char* exceptionName() const {
165 return "lemon::RuntimeError";
170 class RangeError : public RuntimeError {
172 virtual const char* exceptionName() const {
173 return "lemon::RangeError";
178 class IOError : public RuntimeError {
180 virtual const char* exceptionName() const {
181 return "lemon::IOError";
186 class DataFormatError : public IOError {
188 const char *_message;
190 boost::shared_ptr<std::string> _file;
194 explicit DataFormatError(const char *the_message)
195 : _message(the_message), _line(0) {}
197 DataFormatError(const std::string &file_name, int line_num,
198 const char *the_message)
199 : _message(the_message), _line(line_num) { file(file_name); }
202 void line(int line_num) { _line=line_num; }
204 void message(char *the_message) { _message=the_message; }
206 void file(const std::string &file_name) {
208 _file.reset(new std::string);
217 int line() const { return _line; }
219 const char* message() const { return _message; }
221 /// \brief Returns the filename.
223 /// Returns \e "(unknown)" if the filename was not specified.
224 const char* file() const {
226 return _file->c_str();
232 virtual const char* what() const throw() {
235 std::ostringstream ostr;
237 if( _file || _line ) {
239 if( _file ) ostr << "in file '" << *_file << "'";
240 if( _file && _line ) ostr << " ";
241 if( _line ) ostr << "at line " << _line;
244 mes = ostr.str().c_str();
247 if( mes ) return mes;
248 return exceptionName();
251 virtual const char* exceptionName() const {
252 return "lemon::DataFormatError";
255 virtual ~DataFormatError() throw() {}
260 class AssertionFailedError : public LogicError {
262 const char *assertion;
265 const char *function;
269 AssertionFailedError(const char *_file, int _line, const char *func,
270 const char *msg, const char *_assertion = 0) :
271 assertion(_assertion), file(_file), line(_line), function(func),
275 const char* get_assertion() const { return assertion; }
277 const char* get_message() const { return message; }
279 const char* get_file() const { return file; }
281 const char* get_function() const { return function; }
283 int get_line() const { return line; }
286 virtual const char* what() const throw() {
289 std::ostringstream ostr;
290 ostr << file << ":" << line << ": ";
292 ostr << function << ": ";
295 ostr << " (assertion '" << assertion << "' failed)";
296 mes = ostr.str().c_str();
299 if( mes ) return mes;
300 return exceptionName();
303 virtual const char* exceptionName() const {
304 return "lemon::AssertionFailedError";
307 virtual ~AssertionFailedError() throw() {}
311 /**************** Macros ****************/
315 void assert_fail(const char *file, int line, const char *func,
316 const char *message, const char *assertion = 0,
320 cerr << file << ":" << line << ": ";
322 cerr << func << ": ";
325 cerr << " (assertion '" << assertion << "' failed)";
332 void assert_fail_throw(const char *file, int line, const char *func,
333 const char *message, const char *assertion = 0,
336 throw AssertionFailedError(file, line, func, message, assertion);
342 #endif // LEMON_ERROR_H
347 #ifndef LEMON_ASSERT_ABORT
348 # define LEMON_ASSERT_ABORT 1
351 #ifndef LEMON_ASSERT_HANDLER
352 # ifdef LEMON_ASSERT_EXCEPTION
353 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
355 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail
359 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
361 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
366 * \brief Macro for assertions with customizable message
368 * Macro for assertions with customizable message.
370 * The behaviour can be customized with LEMON_ASSERT_HANDLER,
371 * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
372 * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
374 * \todo We should provide some way to reset to the default behaviour,
377 * \todo This whole 'assert' business should be placed in a separate
380 * \todo __PRETTY_FUNCTION__ should be replaced by something
381 * compiler-independant, like BOOST_CURRENT_FUNCTION
384 # define LEMON_ASSERT(exp, msg) \
385 (static_cast<void> (!!(exp) ? 0 : ( \
386 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
387 __PRETTY_FUNCTION__, \
388 (msg), #exp, LEMON_ASSERT_ABORT), 0)))
390 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
393 * \brief Macro for mark not yet implemented features.
395 * \todo Is this the right place for this? It should be used only in
396 * modules under development.
398 * \todo __PRETTY_FUNCTION__ should be replaced by something
399 * compiler-independant, like BOOST_CURRENT_FUNCTION
402 # define LEMON_FIXME(msg) \
403 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \