lemon/error.h
changeset 290 f6899946c1ac
parent 280 e7f8647ce760
child 291 d901321d6555
     1.1 --- a/lemon/error.h	Sat Sep 27 14:33:28 2008 +0200
     1.2 +++ b/lemon/error.h	Tue Sep 30 20:53:18 2008 +0200
     1.3 @@ -35,380 +35,238 @@
     1.4    /// \addtogroup exceptions
     1.5    /// @{
     1.6  
     1.7 -  /// \brief Exception safe wrapper class.
     1.8 +  /// \brief Generic exception class.
     1.9    ///
    1.10 -  /// Exception safe wrapper class to implement the members of exceptions.
    1.11 -  template <typename _Type>
    1.12 -  class ExceptionMember {
    1.13 -  public:
    1.14 -    typedef _Type Type;
    1.15 -
    1.16 -    ExceptionMember() throw() {
    1.17 -      try {
    1.18 -        ptr.reset(new Type());
    1.19 -      } catch (...) {}
    1.20 -    }
    1.21 -
    1.22 -    ExceptionMember(const Type& type) throw() {
    1.23 -      try {
    1.24 -        ptr.reset(new Type());
    1.25 -        if (ptr.get() == 0) return;
    1.26 -        *ptr = type;
    1.27 -      } catch (...) {}
    1.28 -    }
    1.29 -
    1.30 -    ExceptionMember(const ExceptionMember& copy) throw() {
    1.31 -      try {
    1.32 -        if (!copy.valid()) return;
    1.33 -        ptr.reset(new Type());
    1.34 -        if (ptr.get() == 0) return;
    1.35 -        *ptr = copy.get();
    1.36 -      } catch (...) {}
    1.37 -    }
    1.38 -
    1.39 -    ExceptionMember& operator=(const ExceptionMember& copy) throw() {
    1.40 -      if (ptr.get() == 0) return;
    1.41 -      try {
    1.42 -        if (!copy.valid()) return;
    1.43 -        *ptr = copy.get();
    1.44 -      } catch (...) {}
    1.45 -    }
    1.46 -
    1.47 -    void set(const Type& type) throw() {
    1.48 -      if (ptr.get() == 0) return;
    1.49 -      try {
    1.50 -        *ptr = type;
    1.51 -      } catch (...) {}
    1.52 -    }
    1.53 -
    1.54 -    const Type& get() const {
    1.55 -      return *ptr;
    1.56 -    }
    1.57 -
    1.58 -    bool valid() const throw() {
    1.59 -      return ptr.get() != 0;
    1.60 -    }
    1.61 -
    1.62 -  private:
    1.63 -    std::auto_ptr<_Type> ptr;
    1.64 -  };
    1.65 -
    1.66 -  /// Exception-safe convenient error message builder class.
    1.67 -
    1.68 -  /// Helper class which provides a convenient ostream-like (operator <<
    1.69 -  /// based) interface to create a string message. Mostly useful in
    1.70 -  /// exception classes (therefore the name).
    1.71 -  class ErrorMessage {
    1.72 -  protected:
    1.73 -    ///\e
    1.74 -
    1.75 -    mutable std::auto_ptr<std::ostringstream> buf;
    1.76 -
    1.77 -    ///\e
    1.78 -    bool init() throw() {
    1.79 -      try {
    1.80 -        buf.reset(new std::ostringstream);
    1.81 -      }
    1.82 -      catch(...) {
    1.83 -        buf.reset();
    1.84 -      }
    1.85 -      return buf.get();
    1.86 -    }
    1.87 -
    1.88 -  public:
    1.89 -
    1.90 -    ///\e
    1.91 -    ErrorMessage() throw() { init(); }
    1.92 -
    1.93 -    ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
    1.94 -
    1.95 -    ///\e
    1.96 -    ErrorMessage(const char *msg) throw() {
    1.97 -      init();
    1.98 -      *this << msg;
    1.99 -    }
   1.100 -
   1.101 -    ///\e
   1.102 -    ErrorMessage(const std::string &msg) throw() {
   1.103 -      init();
   1.104 -      *this << msg;
   1.105 -    }
   1.106 -
   1.107 -    ///\e
   1.108 -    template <typename T>
   1.109 -    ErrorMessage& operator<<(const T &t) throw() {
   1.110 -      if( ! buf.get() ) return *this;
   1.111 -
   1.112 -      try {
   1.113 -        *buf << t;
   1.114 -      }
   1.115 -      catch(...) {
   1.116 -        buf.reset();
   1.117 -      }
   1.118 -      return *this;
   1.119 -    }
   1.120 -
   1.121 -    ///\e
   1.122 -    const char* message() throw() {
   1.123 -      if( ! buf.get() ) return 0;
   1.124 -
   1.125 -      const char* mes = 0;
   1.126 -      try {
   1.127 -        mes = buf->str().c_str();
   1.128 -      }
   1.129 -      catch(...) {}
   1.130 -      return mes;
   1.131 -    }
   1.132 -
   1.133 -  };
   1.134 -
   1.135 -  /// Generic exception class.
   1.136 -
   1.137    /// Base class for exceptions used in LEMON.
   1.138    ///
   1.139    class Exception : public std::exception {
   1.140    public:
   1.141 -    ///\e
   1.142 +    ///\e Constructor
   1.143      Exception() {}
   1.144 -    ///\e
   1.145 +    ///\e Virtual destructor
   1.146      virtual ~Exception() throw() {}
   1.147 -    ///\e
   1.148 +    ///\e A short description of the exception
   1.149      virtual const char* what() const throw() {
   1.150        return "lemon::Exception";
   1.151      }
   1.152    };
   1.153  
   1.154 -  /// One of the two main subclasses of \ref Exception.
   1.155 +  /// \brief Input-Output error
   1.156 +  ///
   1.157 +  /// This exception is thrown when a file operation cannot be
   1.158 +  /// succeeded.
   1.159 +  class IoError : public Exception {
   1.160 +  protected:
   1.161 +    std::string _message;
   1.162 +    std::string _file;
   1.163  
   1.164 -  /// Logic errors represent problems in the internal logic of a program;
   1.165 -  /// in theory, these are preventable, and even detectable before the
   1.166 -  /// program runs (e.g. violations of class invariants).
   1.167 -  ///
   1.168 -  /// A typical example for this is \ref UninitializedParameter.
   1.169 -  class LogicError : public Exception {
   1.170 +    mutable std::string _what;
   1.171    public:
   1.172 +
   1.173 +    /// Copy constructor
   1.174 +    IoError(const IoError &error) {
   1.175 +      message(error._message);
   1.176 +      file(error._file);
   1.177 +    }
   1.178 +
   1.179 +    /// Constructor
   1.180 +    explicit IoError(const char *message) {
   1.181 +      IoError::message(message);
   1.182 +    }
   1.183 +
   1.184 +    /// Constructor
   1.185 +    explicit IoError(const std::string &message) {
   1.186 +      IoError::message(message);
   1.187 +    }
   1.188 +
   1.189 +    /// Constructor
   1.190 +    IoError(const std::string &file, const char *message) {
   1.191 +      IoError::message(message);
   1.192 +      IoError::file(file);
   1.193 +    }
   1.194 +
   1.195 +    /// Constructor
   1.196 +    IoError(const std::string &file, const std::string &message) {
   1.197 +      IoError::message(message);
   1.198 +      IoError::file(file);
   1.199 +    }
   1.200 +
   1.201 +    /// Virtual destructor
   1.202 +    virtual ~IoError() throw() {}
   1.203 +
   1.204 +    /// Set the error message
   1.205 +    void message(const char *message) {
   1.206 +      try {
   1.207 +        _message = message;
   1.208 +      } catch (...) {}
   1.209 +    }
   1.210 +
   1.211 +    /// Set the error message
   1.212 +    void message(const std::string& message) {
   1.213 +      try {
   1.214 +        _message = message;
   1.215 +      } catch (...) {}
   1.216 +    }
   1.217 +
   1.218 +    /// Set the file name
   1.219 +    void file(const std::string &file) {
   1.220 +      try {
   1.221 +        _file = file;
   1.222 +      } catch (...) {}
   1.223 +    }
   1.224 +
   1.225 +    /// Returns the error message
   1.226 +    const std::string& message() const {
   1.227 +      return _message;
   1.228 +    }
   1.229 +
   1.230 +    /// \brief Returns the filename
   1.231 +    ///
   1.232 +    /// Returns the filename or empty string if the filename was not
   1.233 +    /// specified.
   1.234 +    const std::string& file() const {
   1.235 +      return _file;
   1.236 +    }
   1.237 +
   1.238 +    /// \brief Returns a short error message
   1.239 +    ///
   1.240 +    /// Returns a short error message which contains the message, the
   1.241 +    /// file name and the line number.
   1.242      virtual const char* what() const throw() {
   1.243 -      return "lemon::LogicError";
   1.244 +      try {
   1.245 +        _what.clear();
   1.246 +        std::ostringstream oss;
   1.247 +        oss << "lemon:IoError" << ": ";
   1.248 +        oss << message();
   1.249 +        if (!file().empty()) {
   1.250 +          oss << " (";
   1.251 +          if (!file().empty()) oss << "with file '" << file() << "'";
   1.252 +          oss << ")";
   1.253 +        }
   1.254 +        _what = oss.str();
   1.255 +      }
   1.256 +      catch (...) {}
   1.257 +      if (!_what.empty()) return _what.c_str();
   1.258 +      else return "lemon:IoError";
   1.259      }
   1.260 +
   1.261    };
   1.262  
   1.263 -  /// \ref Exception for uninitialized parameters.
   1.264 -
   1.265 -  /// This error represents problems in the initialization
   1.266 -  /// of the parameters of the algorithms.
   1.267 -  class UninitializedParameter : public LogicError {
   1.268 -  public:
   1.269 -    virtual const char* what() const throw() {
   1.270 -      return "lemon::UninitializedParameter";
   1.271 -    }
   1.272 -  };
   1.273 -
   1.274 -
   1.275 -  /// One of the two main subclasses of \ref Exception.
   1.276 -
   1.277 -  /// Runtime errors represent problems outside the scope of a program;
   1.278 -  /// they cannot be easily predicted and can generally only be caught
   1.279 -  /// as the program executes.
   1.280 -  class RuntimeError : public Exception {
   1.281 -  public:
   1.282 -    virtual const char* what() const throw() {
   1.283 -      return "lemon::RuntimeError";
   1.284 -    }
   1.285 -  };
   1.286 -
   1.287 -  ///\e
   1.288 -  class RangeError : public RuntimeError {
   1.289 -  public:
   1.290 -    virtual const char* what() const throw() {
   1.291 -      return "lemon::RangeError";
   1.292 -    }
   1.293 -  };
   1.294 -
   1.295 -  ///\e
   1.296 -  class IoError : public RuntimeError {
   1.297 -  public:
   1.298 -    virtual const char* what() const throw() {
   1.299 -      return "lemon::IoError";
   1.300 -    }
   1.301 -  };
   1.302 -
   1.303 -  ///\e
   1.304 -  class DataFormatError : public IoError {
   1.305 +  /// \brief Format error
   1.306 +  ///
   1.307 +  /// This class is used to indicate if an input file has wrong
   1.308 +  /// formatting, or a data representation is not legal.
   1.309 +  class FormatError : public Exception {
   1.310    protected:
   1.311 -    ExceptionMember<std::string> _message;
   1.312 -    ExceptionMember<std::string> _file;
   1.313 +    std::string _message;
   1.314 +    std::string _file;
   1.315      int _line;
   1.316  
   1.317 -    mutable ExceptionMember<std::string> _message_holder;
   1.318 +    mutable std::string _what;
   1.319    public:
   1.320  
   1.321 -    DataFormatError(const DataFormatError &dfe) :
   1.322 -      IoError(dfe), _message(dfe._message), _file(dfe._file),
   1.323 -      _line(dfe._line) {}
   1.324 -
   1.325 -    ///\e
   1.326 -    explicit DataFormatError(const char *the_message)
   1.327 -      : _message(the_message), _line(0) {}
   1.328 -
   1.329 -    ///\e
   1.330 -    DataFormatError(const std::string &file_name, int line_num,
   1.331 -                    const char *the_message)
   1.332 -      : _message(the_message), _line(line_num) { file(file_name); }
   1.333 -
   1.334 -    ///\e
   1.335 -    void line(int ln) { _line = ln; }
   1.336 -    ///\e
   1.337 -    void message(const std::string& msg) { _message.set(msg); }
   1.338 -    ///\e
   1.339 -    void file(const std::string &fl) { _file.set(fl); }
   1.340 -
   1.341 -    ///\e
   1.342 -    int line() const { return _line; }
   1.343 -    ///\e
   1.344 -    const char* message() const {
   1.345 -      if (_message.valid() && !_message.get().empty()) {
   1.346 -        return _message.get().c_str();
   1.347 -      } else {
   1.348 -        return 0;
   1.349 -      }
   1.350 +    /// Copy constructor
   1.351 +    FormatError(const FormatError &error) {
   1.352 +      message(error._message);
   1.353 +      file(error._file);
   1.354 +      line(error._line);
   1.355      }
   1.356  
   1.357 -    /// \brief Returns the filename.
   1.358 -    ///
   1.359 -    /// Returns \e null if the filename was not specified.
   1.360 -    const char* file() const {
   1.361 -      if (_file.valid() && !_file.get().empty()) {
   1.362 -        return _file.get().c_str();
   1.363 -      } else {
   1.364 -        return 0;
   1.365 -      }
   1.366 +    /// Constructor
   1.367 +    explicit FormatError(const char *message) {
   1.368 +      FormatError::message(message);
   1.369 +      _line = 0;
   1.370      }
   1.371  
   1.372 -    ///\e
   1.373 +    /// Constructor
   1.374 +    explicit FormatError(const std::string &message) {
   1.375 +      FormatError::message(message);
   1.376 +      _line = 0;
   1.377 +    }
   1.378 +
   1.379 +    /// Constructor
   1.380 +    FormatError(const std::string &file, int line, const char *message) {
   1.381 +      FormatError::message(message);
   1.382 +      FormatError::file(file);
   1.383 +      FormatError::line(line);
   1.384 +    }
   1.385 +
   1.386 +    /// Constructor
   1.387 +    FormatError(const std::string &file, int line, const std::string &message) {
   1.388 +      FormatError::message(message);
   1.389 +      FormatError::file(file);
   1.390 +      FormatError::line(line);
   1.391 +    }
   1.392 +
   1.393 +    /// Virtual destructor
   1.394 +    virtual ~FormatError() throw() {}
   1.395 +
   1.396 +    /// Set the line number
   1.397 +    void line(int line) { _line = line; }
   1.398 +
   1.399 +    /// Set the error message
   1.400 +    void message(const char *message) {
   1.401 +      try {
   1.402 +        _message = message;
   1.403 +      } catch (...) {}
   1.404 +    }
   1.405 +
   1.406 +    /// Set the error message
   1.407 +    void message(const std::string& message) {
   1.408 +      try {
   1.409 +        _message = message;
   1.410 +      } catch (...) {}
   1.411 +    }
   1.412 +
   1.413 +    /// Set the file name
   1.414 +    void file(const std::string &file) {
   1.415 +      try {
   1.416 +        _file = file;
   1.417 +      } catch (...) {}
   1.418 +    }
   1.419 +
   1.420 +    /// \brief Returns the line number
   1.421 +    ///
   1.422 +    /// Returns the line number or zero if it was not specified.
   1.423 +    int line() const { return _line; }
   1.424 +
   1.425 +    /// Returns the error message
   1.426 +    const std::string& message() const {
   1.427 +      return _message;
   1.428 +    }
   1.429 +
   1.430 +    /// \brief Returns the filename
   1.431 +    ///
   1.432 +    /// Returns the filename or empty string if the filename was not
   1.433 +    /// specified.
   1.434 +    const std::string& file() const {
   1.435 +      return _file;
   1.436 +    }
   1.437 +
   1.438 +    /// \brief Returns a short error message
   1.439 +    ///
   1.440 +    /// Returns a short error message which contains the message, the
   1.441 +    /// file name and the line number.
   1.442      virtual const char* what() const throw() {
   1.443        try {
   1.444 -        std::ostringstream ostr;
   1.445 -        ostr << "lemon:DataFormatError" << ": ";
   1.446 -        if (message()) ostr << message();
   1.447 -        if( file() || line() != 0 ) {
   1.448 -          ostr << " (";
   1.449 -          if( file() ) ostr << "in file '" << file() << "'";
   1.450 -          if( file() && line() != 0 ) ostr << " ";
   1.451 -          if( line() != 0 ) ostr << "at line " << line();
   1.452 -          ostr << ")";
   1.453 +        _what.clear();
   1.454 +        std::ostringstream oss;
   1.455 +        oss << "lemon:FormatError" << ": ";
   1.456 +        oss << message();
   1.457 +        if (!file().empty() || line() != 0) {
   1.458 +          oss << " (";
   1.459 +          if (!file().empty()) oss << "in file '" << file() << "'";
   1.460 +          if (!file().empty() && line() != 0) oss << " ";
   1.461 +          if (line() != 0) oss << "at line " << line();
   1.462 +          oss << ")";
   1.463          }
   1.464 -        _message_holder.set(ostr.str());
   1.465 +        _what = oss.str();
   1.466        }
   1.467        catch (...) {}
   1.468 -      if( _message_holder.valid()) return _message_holder.get().c_str();
   1.469 -      return "lemon:DataFormatError";
   1.470 +      if (!_what.empty()) return _what.c_str();
   1.471 +      else return "lemon:FormatError";
   1.472      }
   1.473  
   1.474 -    virtual ~DataFormatError() throw() {}
   1.475 -  };
   1.476 -
   1.477 -  ///\e
   1.478 -  class FileOpenError : public IoError {
   1.479 -  protected:
   1.480 -    ExceptionMember<std::string> _file;
   1.481 -
   1.482 -    mutable ExceptionMember<std::string> _message_holder;
   1.483 -  public:
   1.484 -
   1.485 -    FileOpenError(const FileOpenError &foe) :
   1.486 -      IoError(foe), _file(foe._file) {}
   1.487 -
   1.488 -    ///\e
   1.489 -    explicit FileOpenError(const std::string& fl)
   1.490 -      : _file(fl) {}
   1.491 -
   1.492 -
   1.493 -    ///\e
   1.494 -    void file(const std::string &fl) { _file.set(fl); }
   1.495 -
   1.496 -    /// \brief Returns the filename.
   1.497 -    ///
   1.498 -    /// Returns \e null if the filename was not specified.
   1.499 -    const char* file() const {
   1.500 -      if (_file.valid() && !_file.get().empty()) {
   1.501 -        return _file.get().c_str();
   1.502 -      } else {
   1.503 -        return 0;
   1.504 -      }
   1.505 -    }
   1.506 -
   1.507 -    ///\e
   1.508 -    virtual const char* what() const throw() {
   1.509 -      try {
   1.510 -        std::ostringstream ostr;
   1.511 -        ostr << "lemon::FileOpenError" << ": ";
   1.512 -        ostr << "Cannot open file - " << file();
   1.513 -        _message_holder.set(ostr.str());
   1.514 -      }
   1.515 -      catch (...) {}
   1.516 -      if( _message_holder.valid()) return _message_holder.get().c_str();
   1.517 -      return "lemon::FileOpenError";
   1.518 -    }
   1.519 -    virtual ~FileOpenError() throw() {}
   1.520 -  };
   1.521 -
   1.522 -  class IoParameterError : public IoError {
   1.523 -  protected:
   1.524 -    ExceptionMember<std::string> _message;
   1.525 -    ExceptionMember<std::string> _file;
   1.526 -
   1.527 -    mutable ExceptionMember<std::string> _message_holder;
   1.528 -  public:
   1.529 -
   1.530 -    IoParameterError(const IoParameterError &ile) :
   1.531 -      IoError(ile), _message(ile._message), _file(ile._file) {}
   1.532 -
   1.533 -    ///\e
   1.534 -    explicit IoParameterError(const char *the_message)
   1.535 -      : _message(the_message) {}
   1.536 -
   1.537 -    ///\e
   1.538 -    IoParameterError(const char *file_name, const char *the_message)
   1.539 -      : _message(the_message), _file(file_name) {}
   1.540 -
   1.541 -     ///\e
   1.542 -    void message(const std::string& msg) { _message.set(msg); }
   1.543 -    ///\e
   1.544 -    void file(const std::string &fl) { _file.set(fl); }
   1.545 -
   1.546 -     ///\e
   1.547 -    const char* message() const {
   1.548 -      if (_message.valid()) {
   1.549 -        return _message.get().c_str();
   1.550 -      } else {
   1.551 -        return 0;
   1.552 -      }
   1.553 -    }
   1.554 -
   1.555 -    /// \brief Returns the filename.
   1.556 -    ///
   1.557 -    /// Returns \c 0 if the filename was not specified.
   1.558 -    const char* file() const {
   1.559 -      if (_file.valid()) {
   1.560 -        return _file.get().c_str();
   1.561 -      } else {
   1.562 -        return 0;
   1.563 -      }
   1.564 -    }
   1.565 -
   1.566 -    ///\e
   1.567 -    virtual const char* what() const throw() {
   1.568 -      try {
   1.569 -        std::ostringstream ostr;
   1.570 -        if (message()) ostr << message();
   1.571 -        if (file()) ostr << "(when reading file '" << file() << "')";
   1.572 -        _message_holder.set(ostr.str());
   1.573 -      }
   1.574 -      catch (...) {}
   1.575 -      if( _message_holder.valid() ) return _message_holder.get().c_str();
   1.576 -      return "lemon:IoParameterError";
   1.577 -    }
   1.578 -    virtual ~IoParameterError() throw() {}
   1.579    };
   1.580  
   1.581    /// @}