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 /// @}