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 {
111 Exception() throw() : message(0) {}
113 explicit Exception(const char *msg) throw()
116 virtual ~Exception() throw() {}
119 virtual const char* what() const throw() {
120 if( message ) return message;
121 return "lemon::Exception";
126 class LogicError : public Exception {
129 explicit LogicError() {}
131 explicit LogicError(const char *s)
136 class RuntimeError : public Exception {
139 explicit RuntimeError() {}
141 explicit RuntimeError(const char *s)
146 class RangeError : public RuntimeError {
149 explicit RangeError(const char *s)
154 class IOError : public RuntimeError {
157 explicit IOError(const char *s)
162 class DataFormatError : public IOError {
165 boost::shared_ptr<std::string> file;
169 explicit DataFormatError(const char *message)
170 : IOError(message), line(0) {}
172 DataFormatError(const std::string &file_name, int line_num,
174 : IOError(message), line(line_num) { set_file(file_name); }
177 void set_line(int line_num) { line=line_num; }
179 void set_file(const std::string &file_name) {
181 file.reset(new std::string);
190 int get_line() const { return line; }
192 /// \brief Returns the filename.
194 /// Returns \e "(unknown)" if the filename was not specified.
195 const char* get_file() const {
197 return file->c_str();
203 virtual const char* what() const throw() {
206 std::ostringstream ostr;
207 ostr << IOError::what();
210 if( file ) ostr << "in file '" << *file << "'";
211 if( file && line ) ostr << " ";
212 if( line ) ostr << "at line " << line;
215 mes = ostr.str().c_str();
218 if( mes ) return mes;
219 return "lemon::DataFormatError";
222 virtual ~DataFormatError() throw() {}
227 class AssertionFailedError : public LogicError {
229 const char *assertion;
232 const char *function;
236 AssertionFailedError(const char *_file, int _line, const char *func,
237 const char *msg, const char *_assertion = 0) :
238 assertion(_assertion), file(_file), line(_line), function(func),
242 const char* get_assertion() const { return assertion; }
244 const char* get_message() const { return message; }
246 const char* get_file() const { return file; }
248 const char* get_function() const { return function; }
250 int get_line() const { return line; }
253 virtual const char* what() const throw() {
256 std::ostringstream ostr;
257 ostr << file << ":" << line << ": ";
259 ostr << function << ": ";
262 ostr << " (assertion '" << assertion << "' failed)";
263 mes = ostr.str().c_str();
266 if( mes ) return mes;
267 return "lemon::AssertionFailedError";
270 virtual ~AssertionFailedError() throw() {}
274 /**************** Macros ****************/
278 void assert_fail(const char *file, int line, const char *func,
279 const char *message, const char *assertion = 0,
283 cerr << file << ":" << line << ": ";
285 cerr << func << ": ";
288 cerr << " (assertion '" << assertion << "' failed)";
295 void assert_fail_throw(const char *file, int line, const char *func,
296 const char *message, const char *assertion = 0,
299 throw AssertionFailedError(file, line, func, message, assertion);
304 #endif // LEMON_ERROR_H
309 #ifndef LEMON_ASSERT_ABORT
310 # define LEMON_ASSERT_ABORT 1
313 #ifndef LEMON_ASSERT_HANDLER
314 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail
317 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
319 # define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
324 * \brief Macro for assertions with customizable message
326 * \todo __PRETTY_FUNCTION__ should be replaced by something
327 * compiler-independant, like BOOST_CURRENT_FUNCTION
330 # define LEMON_ASSERT(exp, msg) \
331 (static_cast<void> (!!(exp) ? 0 : ( \
332 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
333 __PRETTY_FUNCTION__, \
334 (msg), #exp, LEMON_ASSERT_ABORT), 0)))
339 * \brief Macro for mark not yet implemented features.
341 * \todo Is this the right place for this? It should be used only in
342 * modules under development.
344 * \todo __PRETTY_FUNCTION__ should be replaced by something
345 * compiler-independant, like BOOST_CURRENT_FUNCTION
348 # define LEMON_FIXME(msg) \
349 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \