Changeset 290:f6899946c1ac in lemon-1.2 for lemon/error.h
- Timestamp:
- 09/30/08 20:53:18 (16 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/error.h
r280 r290 36 36 /// @{ 37 37 38 /// \brief Exception safe wrapper class. 39 /// 40 /// Exception safe wrapper class to implement the members of exceptions. 41 template <typename _Type> 42 class ExceptionMember { 43 public: 44 typedef _Type Type; 45 46 ExceptionMember() throw() { 47 try { 48 ptr.reset(new Type()); 49 } catch (...) {} 50 } 51 52 ExceptionMember(const Type& type) throw() { 53 try { 54 ptr.reset(new Type()); 55 if (ptr.get() == 0) return; 56 *ptr = type; 57 } catch (...) {} 58 } 59 60 ExceptionMember(const ExceptionMember& copy) throw() { 61 try { 62 if (!copy.valid()) return; 63 ptr.reset(new Type()); 64 if (ptr.get() == 0) return; 65 *ptr = copy.get(); 66 } catch (...) {} 67 } 68 69 ExceptionMember& operator=(const ExceptionMember& copy) throw() { 70 if (ptr.get() == 0) return; 71 try { 72 if (!copy.valid()) return; 73 *ptr = copy.get(); 74 } catch (...) {} 75 } 76 77 void set(const Type& type) throw() { 78 if (ptr.get() == 0) return; 79 try { 80 *ptr = type; 81 } catch (...) {} 82 } 83 84 const Type& get() const { 85 return *ptr; 86 } 87 88 bool valid() const throw() { 89 return ptr.get() != 0; 90 } 91 92 private: 93 std::auto_ptr<_Type> ptr; 94 }; 95 96 /// Exception-safe convenient error message builder class. 97 98 /// Helper class which provides a convenient ostream-like (operator << 99 /// based) interface to create a string message. Mostly useful in 100 /// exception classes (therefore the name). 101 class ErrorMessage { 102 protected: 103 ///\e 104 105 mutable std::auto_ptr<std::ostringstream> buf; 106 107 ///\e 108 bool init() throw() { 109 try { 110 buf.reset(new std::ostringstream); 111 } 112 catch(...) { 113 buf.reset(); 114 } 115 return buf.get(); 116 } 117 118 public: 119 120 ///\e 121 ErrorMessage() throw() { init(); } 122 123 ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { } 124 125 ///\e 126 ErrorMessage(const char *msg) throw() { 127 init(); 128 *this << msg; 129 } 130 131 ///\e 132 ErrorMessage(const std::string &msg) throw() { 133 init(); 134 *this << msg; 135 } 136 137 ///\e 138 template <typename T> 139 ErrorMessage& operator<<(const T &t) throw() { 140 if( ! buf.get() ) return *this; 141 142 try { 143 *buf << t; 144 } 145 catch(...) { 146 buf.reset(); 147 } 148 return *this; 149 } 150 151 ///\e 152 const char* message() throw() { 153 if( ! buf.get() ) return 0; 154 155 const char* mes = 0; 156 try { 157 mes = buf->str().c_str(); 158 } 159 catch(...) {} 160 return mes; 161 } 162 163 }; 164 165 /// Generic exception class. 166 38 /// \brief Generic exception class. 39 /// 167 40 /// Base class for exceptions used in LEMON. 168 41 /// 169 42 class Exception : public std::exception { 170 43 public: 171 ///\e 44 ///\e Constructor 172 45 Exception() {} 173 ///\e 46 ///\e Virtual destructor 174 47 virtual ~Exception() throw() {} 175 ///\e 48 ///\e A short description of the exception 176 49 virtual const char* what() const throw() { 177 50 return "lemon::Exception"; … … 179 52 }; 180 53 181 /// One of the two main subclasses of \ref Exception. 182 183 /// Logic errors represent problems in the internal logic of a program; 184 /// in theory, these are preventable, and even detectable before the 185 /// program runs (e.g. violations of class invariants). 186 /// 187 /// A typical example for this is \ref UninitializedParameter. 188 class LogicError : public Exception { 54 /// \brief Input-Output error 55 /// 56 /// This exception is thrown when a file operation cannot be 57 /// succeeded. 58 class IoError : public Exception { 59 protected: 60 std::string _message; 61 std::string _file; 62 63 mutable std::string _what; 189 64 public: 65 66 /// Copy constructor 67 IoError(const IoError &error) { 68 message(error._message); 69 file(error._file); 70 } 71 72 /// Constructor 73 explicit IoError(const char *message) { 74 IoError::message(message); 75 } 76 77 /// Constructor 78 explicit IoError(const std::string &message) { 79 IoError::message(message); 80 } 81 82 /// Constructor 83 IoError(const std::string &file, const char *message) { 84 IoError::message(message); 85 IoError::file(file); 86 } 87 88 /// Constructor 89 IoError(const std::string &file, const std::string &message) { 90 IoError::message(message); 91 IoError::file(file); 92 } 93 94 /// Virtual destructor 95 virtual ~IoError() throw() {} 96 97 /// Set the error message 98 void message(const char *message) { 99 try { 100 _message = message; 101 } catch (...) {} 102 } 103 104 /// Set the error message 105 void message(const std::string& message) { 106 try { 107 _message = message; 108 } catch (...) {} 109 } 110 111 /// Set the file name 112 void file(const std::string &file) { 113 try { 114 _file = file; 115 } catch (...) {} 116 } 117 118 /// Returns the error message 119 const std::string& message() const { 120 return _message; 121 } 122 123 /// \brief Returns the filename 124 /// 125 /// Returns the filename or empty string if the filename was not 126 /// specified. 127 const std::string& file() const { 128 return _file; 129 } 130 131 /// \brief Returns a short error message 132 /// 133 /// Returns a short error message which contains the message, the 134 /// file name and the line number. 190 135 virtual const char* what() const throw() { 191 return "lemon::LogicError"; 192 } 193 }; 194 195 /// \ref Exception for uninitialized parameters. 196 197 /// This error represents problems in the initialization 198 /// of the parameters of the algorithms. 199 class UninitializedParameter : public LogicError { 200 public: 201 virtual const char* what() const throw() { 202 return "lemon::UninitializedParameter"; 203 } 204 }; 205 206 207 /// One of the two main subclasses of \ref Exception. 208 209 /// Runtime errors represent problems outside the scope of a program; 210 /// they cannot be easily predicted and can generally only be caught 211 /// as the program executes. 212 class RuntimeError : public Exception { 213 public: 214 virtual const char* what() const throw() { 215 return "lemon::RuntimeError"; 216 } 217 }; 218 219 ///\e 220 class RangeError : public RuntimeError { 221 public: 222 virtual const char* what() const throw() { 223 return "lemon::RangeError"; 224 } 225 }; 226 227 ///\e 228 class IoError : public RuntimeError { 229 public: 230 virtual const char* what() const throw() { 231 return "lemon::IoError"; 232 } 233 }; 234 235 ///\e 236 class DataFormatError : public IoError { 237 protected: 238 ExceptionMember<std::string> _message; 239 ExceptionMember<std::string> _file; 240 int _line; 241 242 mutable ExceptionMember<std::string> _message_holder; 243 public: 244 245 DataFormatError(const DataFormatError &dfe) : 246 IoError(dfe), _message(dfe._message), _file(dfe._file), 247 _line(dfe._line) {} 248 249 ///\e 250 explicit DataFormatError(const char *the_message) 251 : _message(the_message), _line(0) {} 252 253 ///\e 254 DataFormatError(const std::string &file_name, int line_num, 255 const char *the_message) 256 : _message(the_message), _line(line_num) { file(file_name); } 257 258 ///\e 259 void line(int ln) { _line = ln; } 260 ///\e 261 void message(const std::string& msg) { _message.set(msg); } 262 ///\e 263 void file(const std::string &fl) { _file.set(fl); } 264 265 ///\e 266 int line() const { return _line; } 267 ///\e 268 const char* message() const { 269 if (_message.valid() && !_message.get().empty()) { 270 return _message.get().c_str(); 271 } else { 272 return 0; 273 } 274 } 275 276 /// \brief Returns the filename. 277 /// 278 /// Returns \e null if the filename was not specified. 279 const char* file() const { 280 if (_file.valid() && !_file.get().empty()) { 281 return _file.get().c_str(); 282 } else { 283 return 0; 284 } 285 } 286 287 ///\e 288 virtual const char* what() const throw() { 289 try { 290 std::ostringstream ostr; 291 ostr << "lemon:DataFormatError" << ": "; 292 if (message()) ostr << message(); 293 if( file() || line() != 0 ) { 294 ostr << " ("; 295 if( file() ) ostr << "in file '" << file() << "'"; 296 if( file() && line() != 0 ) ostr << " "; 297 if( line() != 0 ) ostr << "at line " << line(); 298 ostr << ")"; 136 try { 137 _what.clear(); 138 std::ostringstream oss; 139 oss << "lemon:IoError" << ": "; 140 oss << message(); 141 if (!file().empty()) { 142 oss << " ("; 143 if (!file().empty()) oss << "with file '" << file() << "'"; 144 oss << ")"; 299 145 } 300 _ message_holder.set(ostr.str());146 _what = oss.str(); 301 147 } 302 148 catch (...) {} 303 if( _message_holder.valid()) return _message_holder.get().c_str(); 304 return "lemon:DataFormatError"; 305 } 306 307 virtual ~DataFormatError() throw() {} 149 if (!_what.empty()) return _what.c_str(); 150 else return "lemon:IoError"; 151 } 152 308 153 }; 309 154 310 ///\e 311 class FileOpenError : public IoError { 155 /// \brief Format error 156 /// 157 /// This class is used to indicate if an input file has wrong 158 /// formatting, or a data representation is not legal. 159 class FormatError : public Exception { 312 160 protected: 313 ExceptionMember<std::string> _file; 314 315 mutable ExceptionMember<std::string> _message_holder; 161 std::string _message; 162 std::string _file; 163 int _line; 164 165 mutable std::string _what; 316 166 public: 317 167 318 FileOpenError(const FileOpenError &foe) : 319 IoError(foe), _file(foe._file) {} 320 321 ///\e 322 explicit FileOpenError(const std::string& fl) 323 : _file(fl) {} 324 325 326 ///\e 327 void file(const std::string &fl) { _file.set(fl); } 328 329 /// \brief Returns the filename. 330 /// 331 /// Returns \e null if the filename was not specified. 332 const char* file() const { 333 if (_file.valid() && !_file.get().empty()) { 334 return _file.get().c_str(); 335 } else { 336 return 0; 337 } 338 } 339 340 ///\e 168 /// Copy constructor 169 FormatError(const FormatError &error) { 170 message(error._message); 171 file(error._file); 172 line(error._line); 173 } 174 175 /// Constructor 176 explicit FormatError(const char *message) { 177 FormatError::message(message); 178 _line = 0; 179 } 180 181 /// Constructor 182 explicit FormatError(const std::string &message) { 183 FormatError::message(message); 184 _line = 0; 185 } 186 187 /// Constructor 188 FormatError(const std::string &file, int line, const char *message) { 189 FormatError::message(message); 190 FormatError::file(file); 191 FormatError::line(line); 192 } 193 194 /// Constructor 195 FormatError(const std::string &file, int line, const std::string &message) { 196 FormatError::message(message); 197 FormatError::file(file); 198 FormatError::line(line); 199 } 200 201 /// Virtual destructor 202 virtual ~FormatError() throw() {} 203 204 /// Set the line number 205 void line(int line) { _line = line; } 206 207 /// Set the error message 208 void message(const char *message) { 209 try { 210 _message = message; 211 } catch (...) {} 212 } 213 214 /// Set the error message 215 void message(const std::string& message) { 216 try { 217 _message = message; 218 } catch (...) {} 219 } 220 221 /// Set the file name 222 void file(const std::string &file) { 223 try { 224 _file = file; 225 } catch (...) {} 226 } 227 228 /// \brief Returns the line number 229 /// 230 /// Returns the line number or zero if it was not specified. 231 int line() const { return _line; } 232 233 /// Returns the error message 234 const std::string& message() const { 235 return _message; 236 } 237 238 /// \brief Returns the filename 239 /// 240 /// Returns the filename or empty string if the filename was not 241 /// specified. 242 const std::string& file() const { 243 return _file; 244 } 245 246 /// \brief Returns a short error message 247 /// 248 /// Returns a short error message which contains the message, the 249 /// file name and the line number. 341 250 virtual const char* what() const throw() { 342 251 try { 343 std::ostringstream ostr; 344 ostr << "lemon::FileOpenError" << ": "; 345 ostr << "Cannot open file - " << file(); 346 _message_holder.set(ostr.str()); 252 _what.clear(); 253 std::ostringstream oss; 254 oss << "lemon:FormatError" << ": "; 255 oss << message(); 256 if (!file().empty() || line() != 0) { 257 oss << " ("; 258 if (!file().empty()) oss << "in file '" << file() << "'"; 259 if (!file().empty() && line() != 0) oss << " "; 260 if (line() != 0) oss << "at line " << line(); 261 oss << ")"; 262 } 263 _what = oss.str(); 347 264 } 348 265 catch (...) {} 349 if ( _message_holder.valid()) return _message_holder.get().c_str();350 return "lemon::FileOpenError";351 } 352 virtual ~FileOpenError() throw() {} 266 if (!_what.empty()) return _what.c_str(); 267 else return "lemon:FormatError"; 268 } 269 353 270 }; 354 271 355 class IoParameterError : public IoError {356 protected:357 ExceptionMember<std::string> _message;358 ExceptionMember<std::string> _file;359 360 mutable ExceptionMember<std::string> _message_holder;361 public:362 363 IoParameterError(const IoParameterError &ile) :364 IoError(ile), _message(ile._message), _file(ile._file) {}365 366 ///\e367 explicit IoParameterError(const char *the_message)368 : _message(the_message) {}369 370 ///\e371 IoParameterError(const char *file_name, const char *the_message)372 : _message(the_message), _file(file_name) {}373 374 ///\e375 void message(const std::string& msg) { _message.set(msg); }376 ///\e377 void file(const std::string &fl) { _file.set(fl); }378 379 ///\e380 const char* message() const {381 if (_message.valid()) {382 return _message.get().c_str();383 } else {384 return 0;385 }386 }387 388 /// \brief Returns the filename.389 ///390 /// Returns \c 0 if the filename was not specified.391 const char* file() const {392 if (_file.valid()) {393 return _file.get().c_str();394 } else {395 return 0;396 }397 }398 399 ///\e400 virtual const char* what() const throw() {401 try {402 std::ostringstream ostr;403 if (message()) ostr << message();404 if (file()) ostr << "(when reading file '" << file() << "')";405 _message_holder.set(ostr.str());406 }407 catch (...) {}408 if( _message_holder.valid() ) return _message_holder.get().c_str();409 return "lemon:IoParameterError";410 }411 virtual ~IoParameterError() throw() {}412 };413 414 272 /// @} 415 273
Note: See TracChangeset
for help on using the changeset viewer.