1.1 --- a/lemon/error.h Wed Oct 01 12:44:16 2008 +0200
1.2 +++ b/lemon/error.h Wed Oct 01 13:56:40 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 - Exception() {}
1.143 - ///\e
1.144 + ///Constructor
1.145 + Exception() throw() {}
1.146 + ///Virtual destructor
1.147 virtual ~Exception() throw() {}
1.148 - ///\e
1.149 + ///A short description of the exception
1.150 virtual const char* what() const throw() {
1.151 return "lemon::Exception";
1.152 }
1.153 };
1.154
1.155 - /// One of the two main subclasses of \ref Exception.
1.156 + /// \brief Input-Output error
1.157 + ///
1.158 + /// This exception is thrown when a file operation cannot be
1.159 + /// succeeded.
1.160 + class IoError : public Exception {
1.161 + protected:
1.162 + std::string _message;
1.163 + std::string _file;
1.164
1.165 - /// Logic errors represent problems in the internal logic of a program;
1.166 - /// in theory, these are preventable, and even detectable before the
1.167 - /// program runs (e.g. violations of class invariants).
1.168 - ///
1.169 - /// A typical example for this is \ref UninitializedParameter.
1.170 - class LogicError : public Exception {
1.171 + mutable std::string _what;
1.172 public:
1.173 +
1.174 + /// Copy constructor
1.175 + IoError(const IoError &error) throw() : Exception() {
1.176 + message(error._message);
1.177 + file(error._file);
1.178 + }
1.179 +
1.180 + /// Constructor
1.181 + explicit IoError(const char *message) throw() {
1.182 + IoError::message(message);
1.183 + }
1.184 +
1.185 + /// Constructor
1.186 + explicit IoError(const std::string &message) throw() {
1.187 + IoError::message(message);
1.188 + }
1.189 +
1.190 + /// Constructor
1.191 + explicit IoError(const char *message,
1.192 + const std::string &file) throw() {
1.193 + IoError::message(message);
1.194 + IoError::file(file);
1.195 + }
1.196 +
1.197 + /// Constructor
1.198 + explicit IoError(const std::string &message,
1.199 + const std::string &file) throw() {
1.200 + IoError::message(message);
1.201 + IoError::file(file);
1.202 + }
1.203 +
1.204 + /// Virtual destructor
1.205 + virtual ~IoError() throw() {}
1.206 +
1.207 + /// Set the error message
1.208 + void message(const char *message) throw() {
1.209 + try {
1.210 + _message = message;
1.211 + } catch (...) {}
1.212 + }
1.213 +
1.214 + /// Set the error message
1.215 + void message(const std::string& message) throw() {
1.216 + try {
1.217 + _message = message;
1.218 + } catch (...) {}
1.219 + }
1.220 +
1.221 + /// Set the file name
1.222 + void file(const std::string &file) throw() {
1.223 + try {
1.224 + _file = file;
1.225 + } catch (...) {}
1.226 + }
1.227 +
1.228 + /// Returns the error message
1.229 + const std::string& message() const throw() {
1.230 + return _message;
1.231 + }
1.232 +
1.233 + /// \brief Returns the filename
1.234 + ///
1.235 + /// Returns the filename or an empty string if it was not specified.
1.236 + const std::string& file() const throw() {
1.237 + return _file;
1.238 + }
1.239 +
1.240 + /// \brief Returns a short error message
1.241 + ///
1.242 + /// Returns a short error message which contains the message and the
1.243 + /// file name.
1.244 virtual const char* what() const throw() {
1.245 - return "lemon::LogicError";
1.246 + try {
1.247 + _what.clear();
1.248 + std::ostringstream oss;
1.249 + oss << "lemon:IoError" << ": ";
1.250 + oss << _message;
1.251 + if (!_file.empty()) {
1.252 + oss << " ('" << _file << "')";
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 exception is thrown when an input file has wrong
1.308 + /// format 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) throw() : Exception() {
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) throw() {
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) throw() {
1.375 + FormatError::message(message);
1.376 + _line = 0;
1.377 + }
1.378 +
1.379 + /// Constructor
1.380 + explicit FormatError(const char *message,
1.381 + const std::string &file, int line = 0) throw() {
1.382 + FormatError::message(message);
1.383 + FormatError::file(file);
1.384 + FormatError::line(line);
1.385 + }
1.386 +
1.387 + /// Constructor
1.388 + explicit FormatError(const std::string &message,
1.389 + const std::string &file, int line = 0) throw() {
1.390 + FormatError::message(message);
1.391 + FormatError::file(file);
1.392 + FormatError::line(line);
1.393 + }
1.394 +
1.395 + /// Virtual destructor
1.396 + virtual ~FormatError() throw() {}
1.397 +
1.398 + /// Set the line number
1.399 + void line(int line) throw() { _line = line; }
1.400 +
1.401 + /// Set the error message
1.402 + void message(const char *message) throw() {
1.403 + try {
1.404 + _message = message;
1.405 + } catch (...) {}
1.406 + }
1.407 +
1.408 + /// Set the error message
1.409 + void message(const std::string& message) throw() {
1.410 + try {
1.411 + _message = message;
1.412 + } catch (...) {}
1.413 + }
1.414 +
1.415 + /// Set the file name
1.416 + void file(const std::string &file) throw() {
1.417 + try {
1.418 + _file = file;
1.419 + } catch (...) {}
1.420 + }
1.421 +
1.422 + /// \brief Returns the line number
1.423 + ///
1.424 + /// Returns the line number or zero if it was not specified.
1.425 + int line() const throw() { return _line; }
1.426 +
1.427 + /// Returns the error message
1.428 + const std::string& message() const throw() {
1.429 + return _message;
1.430 + }
1.431 +
1.432 + /// \brief Returns the filename
1.433 + ///
1.434 + /// Returns the filename or an empty string if it was not specified.
1.435 + const std::string& file() const throw() {
1.436 + return _file;
1.437 + }
1.438 +
1.439 + /// \brief Returns a short error message
1.440 + ///
1.441 + /// Returns a short error message which contains the message, the
1.442 + /// file name and the line number.
1.443 virtual const char* what() const throw() {
1.444 try {
1.445 - std::ostringstream ostr;
1.446 - ostr << "lemon:DataFormatError" << ": ";
1.447 - if (message()) ostr << message();
1.448 - if( file() || line() != 0 ) {
1.449 - ostr << " (";
1.450 - if( file() ) ostr << "in file '" << file() << "'";
1.451 - if( file() && line() != 0 ) ostr << " ";
1.452 - if( line() != 0 ) ostr << "at line " << line();
1.453 - ostr << ")";
1.454 + _what.clear();
1.455 + std::ostringstream oss;
1.456 + oss << "lemon:FormatError" << ": ";
1.457 + oss << _message;
1.458 + if (!_file.empty() || _line != 0) {
1.459 + oss << " (";
1.460 + if (!_file.empty()) oss << "in file '" << _file << "'";
1.461 + if (!_file.empty() && _line != 0) oss << " ";
1.462 + if (_line != 0) oss << "at line " << _line;
1.463 + oss << ")";
1.464 }
1.465 - _message_holder.set(ostr.str());
1.466 + _what = oss.str();
1.467 }
1.468 catch (...) {}
1.469 - if( _message_holder.valid()) return _message_holder.get().c_str();
1.470 - return "lemon:DataFormatError";
1.471 + if (!_what.empty()) return _what.c_str();
1.472 + else return "lemon:FormatError";
1.473 }
1.474
1.475 - virtual ~DataFormatError() throw() {}
1.476 - };
1.477 -
1.478 - ///\e
1.479 - class FileOpenError : public IoError {
1.480 - protected:
1.481 - ExceptionMember<std::string> _file;
1.482 -
1.483 - mutable ExceptionMember<std::string> _message_holder;
1.484 - public:
1.485 -
1.486 - FileOpenError(const FileOpenError &foe) :
1.487 - IoError(foe), _file(foe._file) {}
1.488 -
1.489 - ///\e
1.490 - explicit FileOpenError(const std::string& fl)
1.491 - : _file(fl) {}
1.492 -
1.493 -
1.494 - ///\e
1.495 - void file(const std::string &fl) { _file.set(fl); }
1.496 -
1.497 - /// \brief Returns the filename.
1.498 - ///
1.499 - /// Returns \e null if the filename was not specified.
1.500 - const char* file() const {
1.501 - if (_file.valid() && !_file.get().empty()) {
1.502 - return _file.get().c_str();
1.503 - } else {
1.504 - return 0;
1.505 - }
1.506 - }
1.507 -
1.508 - ///\e
1.509 - virtual const char* what() const throw() {
1.510 - try {
1.511 - std::ostringstream ostr;
1.512 - ostr << "lemon::FileOpenError" << ": ";
1.513 - ostr << "Cannot open file - " << file();
1.514 - _message_holder.set(ostr.str());
1.515 - }
1.516 - catch (...) {}
1.517 - if( _message_holder.valid()) return _message_holder.get().c_str();
1.518 - return "lemon::FileOpenError";
1.519 - }
1.520 - virtual ~FileOpenError() throw() {}
1.521 - };
1.522 -
1.523 - class IoParameterError : public IoError {
1.524 - protected:
1.525 - ExceptionMember<std::string> _message;
1.526 - ExceptionMember<std::string> _file;
1.527 -
1.528 - mutable ExceptionMember<std::string> _message_holder;
1.529 - public:
1.530 -
1.531 - IoParameterError(const IoParameterError &ile) :
1.532 - IoError(ile), _message(ile._message), _file(ile._file) {}
1.533 -
1.534 - ///\e
1.535 - explicit IoParameterError(const char *the_message)
1.536 - : _message(the_message) {}
1.537 -
1.538 - ///\e
1.539 - IoParameterError(const char *file_name, const char *the_message)
1.540 - : _message(the_message), _file(file_name) {}
1.541 -
1.542 - ///\e
1.543 - void message(const std::string& msg) { _message.set(msg); }
1.544 - ///\e
1.545 - void file(const std::string &fl) { _file.set(fl); }
1.546 -
1.547 - ///\e
1.548 - const char* message() const {
1.549 - if (_message.valid()) {
1.550 - return _message.get().c_str();
1.551 - } else {
1.552 - return 0;
1.553 - }
1.554 - }
1.555 -
1.556 - /// \brief Returns the filename.
1.557 - ///
1.558 - /// Returns \c 0 if the filename was not specified.
1.559 - const char* file() const {
1.560 - if (_file.valid()) {
1.561 - return _file.get().c_str();
1.562 - } else {
1.563 - return 0;
1.564 - }
1.565 - }
1.566 -
1.567 - ///\e
1.568 - virtual const char* what() const throw() {
1.569 - try {
1.570 - std::ostringstream ostr;
1.571 - if (message()) ostr << message();
1.572 - if (file()) ostr << "(when reading file '" << file() << "')";
1.573 - _message_holder.set(ostr.str());
1.574 - }
1.575 - catch (...) {}
1.576 - if( _message_holder.valid() ) return _message_holder.get().c_str();
1.577 - return "lemon:IoParameterError";
1.578 - }
1.579 - virtual ~IoParameterError() throw() {}
1.580 };
1.581
1.582 /// @}