COIN-OR::LEMON - Graph Library

Changeset 1056:cbc27743e17a in lemon-0.x for src


Ignore:
Timestamp:
01/07/05 01:43:54 (15 years ago)
Author:
Mihaly Barasz
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1452
Message:

Exception hierarchy sketch.
Exception safe exception classes.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • src/work/klao/error.h

    r993 r1056  
    2626#include <sstream>
    2727
     28#include <boost/shared_ptr.hpp>
    2829
    2930namespace lemon {
     31
     32  /// Exception-safe convenient "error message" class.
     33  class ErrorMessage {
     34  protected:
     35    boost::shared_ptr<std::ostringstream> buf;
     36   
     37    bool init() throw() {
     38      try {
     39        buf.reset(new std::ostringstream);
     40      }
     41      catch(...) {
     42        buf.reset();
     43      }
     44      return buf;
     45    }
     46
     47  public:
     48
     49    ErrorMessage() throw() { init(); }
     50
     51    ErrorMessage(const char *message) throw() {
     52      init();
     53      *this << message;
     54    }
     55
     56    ErrorMessage(const std::string &message) throw() {
     57      init();
     58      *this << message;
     59    }
     60
     61    template <typename T>
     62    ErrorMessage& operator<<(const T &t) throw() {
     63      if( !buf ) return *this;
     64
     65      try {
     66        *buf << t;
     67      }
     68      catch(...) {
     69        buf.reset();
     70      }
     71    }
     72
     73    const char* message() throw() {
     74      if( !buf ) return 0;
     75
     76      const char* mes = 0;
     77      try {
     78        mes = buf->str().c_str();
     79      }
     80      catch(...) {}
     81      return mes;
     82    }
     83   
     84  };
    3085
    3186  /**
    3287   * \brief Generic exception class.
    3388   *
    34    * \todo Do we need this?
    35    *
    36    * \todo Don't we need different kind of exceptions for different kind
    37    * of errors?
    38    * Shouldn't we use \<stdexcept\> instead?
     89   * Base class for exceptions used in LEMON.
    3990   */
    40   class Exception : public std::exception {
    41   protected:
    42     std::ostringstream buf;
     91  class Exception : public std::exception, public ErrorMessage {
    4392  public:
    44     Exception() {}
    45     explicit Exception(const std::string &s) { buf << s; }
    46     Exception(const Exception &e) : std::exception() {
    47       buf << e.buf.str();
    48     }
     93    Exception() throw() {}
     94    explicit Exception(const std::string &s) throw()
     95      : ErrorMessage(s) {}
    4996    virtual ~Exception() throw() {}
    5097   
    5198    virtual const char* what() const throw() {
    52       return buf.str().c_str();
     99      const char *mes = message();
     100      if( mes ) return mes;
     101      return "lemon::Exception";
     102    }
     103  };
     104
     105
     106  class LogicError : public Exception {
     107    explicit LogicError(const std::string &s)
     108      : Exception(s) {}
     109  };
     110
     111  class RuntimeError : public Exception {
     112    explicit RuntimeError(const std::string &s)
     113      : Exception(s) {}
     114  };
     115
     116  class RangeError : public RuntimeError {
     117    explicit RangeError(const std::string &s)
     118      : RuntimeError(s) {}
     119  };
     120
     121  class IOError : public RuntimeError {
     122    explicit IOError(const std::string &s)
     123      : RuntimeError(s) {}
     124  };
     125
     126  class DataFormatError : public IOError {
     127    explicit DataFormatError(const std::string &message)
     128      : IOError(message) : line(0) {}
     129    DataFormatError(const std::string &file_name, int line_num,
     130                    sconst std::string &message)
     131      : IOError(message), line(line_num) { set_file(file_name); }
     132
     133    void set_line(int line_num) { line=line_num; }
     134    void set_file(const std::string &file_name) {
     135      try {
     136        file.reset(new std::string);
     137        *file = file_name;
     138      }
     139      catch(...) {
     140        file.reset();
     141      }
    53142    }
    54143
    55     template <typename T>
    56     Exception& operator<<(T const& t) { buf << t; return *this; }
     144    virtual const char* what() const {
     145      const char *mes = 0;
     146      try {
     147        std::ostringstream ostr;
     148        ostr << IOError::what();
     149        if( file || line ) {
     150          ostr << " (";
     151          if( file ) ostr << "in file" << *file;
     152          if( line ) ostr << " at line" << line;
     153        }
     154        mes = ostr.str().c_str();
     155      }
     156      catch(...) {}
     157      if( mes ) return mes;
     158      return "lemon::DataFormatError";
     159    }
    57160  };
    58161
     162
     163
     164  /****************  Macros  ****************/
     165
     166
    59167  /**
    60    * \brief Generic error signaling function.
    61    *
    62    * \todo Do we really need this? Is it helpful?
     168   * \brief Macro for assertions with customizable message
    63169   */
    64   inline void fault(const std::string &msg) {
    65     throw Exception(msg);
    66   }
     170
     171# define lemon_assert(exp, msg) \
     172    if(!(exp)) { \
     173      std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
     174      abort; \
     175    }
     176
    67177
    68178  /**
     
    73183   */
    74184
    75 # define FIXME(msg) \
    76     do { throw ::lemon::Exception() << "FIXME: " msg " (in: "    \
    77       __FILE__ ", " << __LINE__ << ")";                          \
    78     } while(false)
     185# define FIXME(msg) lemon_assert(0, "FIXME: " msg)
    79186
    80187}
Note: See TracChangeset for help on using the changeset viewer.