Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

error.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi
00006  * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
00007  * EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
00016  *
00017  */
00018 
00019 #ifndef LEMON_ERROR_H
00020 #define LEMON_ERROR_H
00021 
00025 
00026 #include <exception>
00027 #include <string>
00028 #include <sstream>
00029 #include <iostream>
00030 #include <cstdlib>
00031 #include <memory>
00032 
00033 namespace lemon {
00034 
00037 
00039 
00043   class ErrorMessage {
00044   protected:
00047     mutable
00048     std::auto_ptr<std::ostringstream> buf;
00049     
00051     bool init() throw() {
00052       try {
00053         buf.reset(new std::ostringstream);
00054       }
00055       catch(...) {
00056         buf.reset();
00057       }
00058       return buf.get();
00059     }
00060 
00061   public:
00062 
00064     ErrorMessage() throw() { init(); }
00065 
00066     ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
00067 
00069     ErrorMessage(const char *message) throw() {
00070       init();
00071       *this << message;
00072     }
00073 
00075     ErrorMessage(const std::string &message) throw() {
00076       init();
00077       *this << message;
00078     }
00079 
00081     template <typename T>
00082     ErrorMessage& operator<<(const T &t) throw() {
00083       if( ! buf.get() ) return *this;
00084 
00085       try {
00086         *buf << t;
00087       }
00088       catch(...) {
00089         buf.reset();
00090       }
00091     }
00092 
00094     const char* message() throw() {
00095       if( ! buf.get() ) return 0;
00096 
00097       const char* mes = 0;
00098       try {
00099         mes = buf->str().c_str();
00100       }
00101       catch(...) {}
00102       return mes;
00103     }
00104     
00105   };
00106 
00112   class Exception : public std::exception {
00113   public:
00115     Exception() {}
00117     virtual ~Exception() throw() {}
00118 
00120     virtual const char* exceptionName() const {
00121       return "lemon::Exception";
00122     }
00123     
00125     virtual const char* what() const throw() {
00126       return exceptionName();
00127     }
00128   };
00129 
00139   class LogicError : public Exception {
00140   public:
00141     virtual const char* exceptionName() const {
00142       return "lemon::LogicError";
00143     }
00144   };
00145 
00152   class UninitializedParameter : public LogicError {
00153   public:
00154     virtual const char* exceptionName() const {
00155       return "lemon::UninitializedParameter";
00156     }
00157   };
00158 
00159   
00167   class RuntimeError : public Exception {
00168   public:
00169     virtual const char* exceptionName() const {
00170       return "lemon::RuntimeError";
00171     }
00172   };
00173 
00175   class RangeError : public RuntimeError {
00176   public:
00177     virtual const char* exceptionName() const {
00178       return "lemon::RangeError";
00179     }
00180   };
00181 
00183   class IOError : public RuntimeError {
00184   public:
00185     virtual const char* exceptionName() const {
00186       return "lemon::IOError";
00187     }
00188   };
00189 
00191   class DataFormatError : public IOError {
00192   protected:
00193     const char *_message;
00194     int _line;
00195 
00197     mutable
00198     std::auto_ptr<std::string> _file;
00199 
00200   public:
00201 
00202     DataFormatError(const DataFormatError &dfe) : 
00203       IOError(dfe), _message(dfe._message), _line(dfe._line),
00204       _file(dfe._file) {}
00205 
00207     explicit DataFormatError(const char *the_message)
00208       : _message(the_message), _line(0) {}
00210     DataFormatError(const std::string &file_name, int line_num,
00211                     const char *the_message)
00212       : _message(the_message), _line(line_num) { file(file_name); }
00213 
00215     void line(int line_num) { _line=line_num; }
00217     void message(char *the_message) { _message=the_message; }
00219     void file(const std::string &file_name) {
00220       try {
00221         _file.reset(new std::string);
00222         *_file = file_name;
00223       }
00224       catch(...) {
00225         _file.reset();
00226       }
00227     }
00228 
00230     int line() const { return _line; }
00232     const char* message() const { return _message; }
00233 
00237     const char* file() const {
00238       if( _file.get() )
00239         return _file->c_str();
00240       else
00241         return "(unknown)";
00242     }
00243 
00245     virtual const char* what() const throw() {
00246       const char *mes = 0;
00247       try {
00248         std::ostringstream ostr;
00249         ostr << _message;
00250         if( _file.get() || _line ) {
00251           ostr << " (";
00252           if( _file.get() ) ostr << "in file '" << *_file << "'";
00253           if( _file.get() && _line ) ostr << " ";
00254           if( _line ) ostr << "at line " << _line;
00255           ostr << ")";
00256         }
00257         mes = ostr.str().c_str();
00258       }
00259       catch(...) {}
00260       if( mes ) return mes;
00261       return exceptionName();
00262     }
00263 
00264     virtual const char* exceptionName() const {
00265       return "lemon::DataFormatError";
00266     }
00267 
00268     virtual ~DataFormatError() throw() {}
00269   };
00270 
00271 
00273   class AssertionFailedError : public LogicError {
00274   protected:
00275     const char *assertion;
00276     const char *file;
00277     int line;
00278     const char *function;
00279     const char *message;
00280   public:
00282     AssertionFailedError(const char *_file, int _line, const char *func,
00283                          const char *msg, const char *_assertion = 0) :
00284       assertion(_assertion), file(_file), line(_line), function(func),
00285       message(msg) {}
00286 
00288     const char* get_assertion() const { return assertion; }
00290     const char* get_message() const { return message; }
00292     const char* get_file() const { return file; }
00294     const char* get_function() const { return function; }
00296     int get_line() const { return line; }
00297 
00298 
00299     virtual const char* what() const throw() {
00300       const char *mes = 0;
00301       try {
00302         std::ostringstream ostr;
00303         ostr << file << ":" << line << ": ";
00304         if( function )
00305           ostr << function << ": ";
00306         ostr << message;
00307         if( assertion )
00308           ostr << " (assertion '" << assertion << "' failed)";
00309         mes = ostr.str().c_str();
00310       }
00311       catch(...) {}
00312       if( mes ) return mes;
00313       return exceptionName();
00314     }
00315 
00316     virtual const char* exceptionName() const {
00317       return "lemon::AssertionFailedError";
00318     }
00319 
00320     virtual ~AssertionFailedError() throw() {}
00321   };
00322 
00323 
00324   /****************  Macros  ****************/
00325 
00326 
00327   inline
00328   void assert_fail(const char *file, int line, const char *func,
00329                    const char *message, const char *assertion = 0,
00330                    bool do_abort=true)
00331   {
00332     using namespace std;
00333     cerr << file << ":" << line << ": ";
00334     if( func )
00335       cerr << func << ": ";
00336     cerr << message;
00337     if( assertion )
00338       cerr << " (assertion '" << assertion << "' failed)";
00339     cerr << endl;
00340     if(do_abort)
00341       abort();
00342   }
00343 
00344   inline
00345   void assert_fail_throw(const char *file, int line, const char *func,
00346                    const char *message, const char *assertion = 0,
00347                    bool = true)
00348   {
00349     throw AssertionFailedError(file, line, func, message, assertion);
00350   }
00351 
00353 
00354 }
00355 #endif // LEMON_ERROR_H
00356 
00357 #undef LEMON_ASSERT
00358 #undef LEMON_FIXME
00359 
00360 #ifndef LEMON_ASSERT_ABORT
00361 #  define LEMON_ASSERT_ABORT 1
00362 #endif
00363 
00364 #ifndef LEMON_ASSERT_HANDLER
00365 #  ifdef LEMON_ASSERT_EXCEPTION
00366 #    define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
00367 #  else
00368 #    define LEMON_ASSERT_HANDLER ::lemon::assert_fail
00369 #  endif
00370 #endif
00371 
00372 #if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
00373 
00374 #  define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
00375 
00376 #else
00377 
00397 #  define LEMON_ASSERT(exp, msg)                 \
00398      (static_cast<void> (!!(exp) ? 0 : (         \
00399        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
00400                             __PRETTY_FUNCTION__, \
00401                             (msg), #exp, LEMON_ASSERT_ABORT), 0)))
00402 
00403 #endif // NDEBUG || LEMON_DISABLE_ASSERTS
00404 
00415 # define LEMON_FIXME(msg) \
00416     (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
00417                           "FIXME: " msg))

Generated on Mon Feb 21 15:02:21 2005 for LEMON by  doxygen 1.4.1